31 #ifndef OOMPH_MESH_SMOOTH_HEADER 32 #define OOMPH_MESH_SMOOTH_HEADER 37 #include "../linear_elasticity/elasticity_tensor.h" 38 #include "../constitutive/constitutive_laws.h" 39 #include "../solid/solid_traction_elements.h" 50 namespace Helper_namespace_for_mesh_smoothing
104 template<
class ELEMENT>
124 const unsigned& max_steps=100000000)
131 controlled_boundary_id,
154 const unsigned& max_steps=100000000)
158 Orig_mesh_pt=orig_mesh_pt;
159 Dummy_mesh_pt=copy_of_mesh_pt;
161 unsigned nnode=orig_mesh_pt->
nnode();
162 unsigned nbound=orig_mesh_pt->
nboundary();
166 add_sub_mesh(Dummy_mesh_pt);
172 unsigned nnod=Orig_mesh_pt->nnode();
173 Orig_node_pos.resize(nnod);
174 for (
unsigned j=0;j<nnod;j++)
176 Orig_node_pos[j].resize(dim);
178 for (
unsigned i=0;
i<dim;
i++)
180 Orig_node_pos[j][
i]=nod_pt->
x(
i);
197 unsigned n=controlled_boundary_id.size();
198 for (
unsigned i=0;
i<n;
i++)
201 unsigned b=controlled_boundary_id[
i];
204 quadratic_surface_mesh_pt[b]=
new SolidMesh;
210 for(
unsigned e=0;
e<n_element;
e++)
213 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
214 Orig_mesh_pt->boundary_element_pt(b,
e));
217 int face_index = Orig_mesh_pt->face_index_at_boundary(b,
e);
224 quadratic_surface_mesh_pt[b]->add_element_pt(el_pt);
231 quadratic_surface_geom_obj_pt[b]=
239 for (
unsigned i=0;
i<n;
i++)
242 unsigned b=controlled_boundary_id[
i];
245 dummy_lagrange_multiplier_mesh_pt[
i]=
new SolidMesh;
251 for(
unsigned e=0;
e<n_element;
e++)
254 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
255 Dummy_mesh_pt->boundary_element_pt(b,
e));
258 int face_index = Dummy_mesh_pt->face_index_at_boundary(b,
e);
263 bulk_elem_pt,face_index);
266 dummy_lagrange_multiplier_mesh_pt[
i]->add_element_pt(el_pt);
272 quadratic_surface_geom_obj_pt[b],b);
276 add_sub_mesh(dummy_lagrange_multiplier_mesh_pt[
i]);
283 oomph_info <<
"Number of equations for nonlinear smoothing problem: " 284 << assign_eqn_numbers() << std::endl;
289 unsigned n_element = Dummy_mesh_pt->nelement();
290 for(
unsigned e=0;
e<n_element;
e++)
294 dynamic_cast<ELEMENT*
>(Dummy_mesh_pt->element_pt(
e));
297 el_pt->constitutive_law_pt() =
304 doc_solution(doc_info);
354 doc_solution(doc_info);
357 if (count==max_steps)
359 oomph_info <<
"Bailing out after " << count <<
" steps.\n";
366 oomph_info <<
"Done with Helper_namespace_for_mesh_smoothing::Scale=" 370 for (
unsigned j=0;j<nnode;j++)
374 Node* new_node_pt=Dummy_mesh_pt->node_pt(j);
377 for (
unsigned i=0;
i<dim;
i++)
379 orig_node_pt->
x(
i)=new_node_pt->
x(
i);
388 n=controlled_boundary_id.size();
389 for (
unsigned i=0;
i<n;
i++)
392 unsigned b=controlled_boundary_id[
i];
395 delete quadratic_surface_mesh_pt[b];
396 delete quadratic_surface_geom_obj_pt[b];
397 delete dummy_lagrange_multiplier_mesh_pt[
i];
410 oomph_info <<
"Solving nonlinear smoothing problem for scale " 412 unsigned nnod=Orig_mesh_pt->nnode();
413 for (
unsigned j=0;j<nnod;j++)
416 unsigned dim=nod_pt->
ndim();
417 for (
unsigned i=0;
i<dim;
i++)
419 nod_pt->
x(
i)=nod_pt->
xi(
i)+
421 (Orig_node_pos[j][
i]-nod_pt->
xi(
i));
431 unsigned nnod=Dummy_mesh_pt->nnode();
432 Backup_node_pos.resize(nnod);
433 for (
unsigned j=0;j<nnod;j++)
436 unsigned dim=nod_pt->
ndim();
437 Backup_node_pos[j].resize(dim);
438 for (
unsigned i=0;
i<dim;
i++)
440 Backup_node_pos[j][
i]=nod_pt->
x(
i);
451 unsigned nnod=Dummy_mesh_pt->nnode();
452 for (
unsigned j=0;j<nnod;j++)
455 unsigned dim=nod_pt->
ndim();
456 for (
unsigned i=0;
i<dim;
i++)
458 nod_pt->
x(
i)=Backup_node_pos[j][
i];
470 std::ofstream some_file;
471 std::ostringstream filename;
477 filename << doc_info.
directory() <<
"/smoothing_soln" 478 << doc_info.
number() <<
".dat";
480 some_file.open(filename.str().c_str());
481 Dummy_mesh_pt->output(some_file,npts);
485 bool mesh_has_inverted_elements;
486 std::ofstream inverted_fluid_elements;
488 filename << doc_info.
directory() <<
"/inverted_elements_during_smoothing" 489 << doc_info.
number() <<
".dat";
490 some_file.open(filename.str().c_str());
491 Dummy_mesh_pt->check_inverted_elements(mesh_has_inverted_elements,
495 if (!mesh_has_inverted_elements)
oomph_info <<
"not ";
541 template<
class LINEAR_ELASTICITY_ELEMENT>
551 std::set<Node*> pinned_nodes)
555 unsigned nelem=orig_mesh_pt->
nelement();
556 unsigned nnode=orig_mesh_pt->
nnode();
559 std::map<Node*,Node*> new_node;
562 for (
unsigned e=0;
e<nelem;
e++)
566 LINEAR_ELASTICITY_ELEMENT* el_pt=
new LINEAR_ELASTICITY_ELEMENT;
567 mesh_pt()->add_element_pt(el_pt);
570 el_pt->elasticity_tensor_pt()=
576 unsigned nnod=orig_elem_pt->
nnode();
579 for (
unsigned j=0;j<nnod;j++)
582 if (new_node[orig_elem_pt->
node_pt(j)]==0)
584 Node* new_nod_pt=mesh_pt()->finite_element_pt(
e)->construct_node(j);
585 new_node[orig_elem_pt->
node_pt(j)]=new_nod_pt;
586 mesh_pt()->add_node_pt(new_nod_pt);
587 unsigned dim=new_nod_pt->
ndim();
588 for (
unsigned i=0;
i<dim;
i++)
599 mesh_pt()->finite_element_pt(
e)->node_pt(j)=
600 new_node[orig_elem_pt->
node_pt(j)];
608 for (std::set<Node*>::iterator it=pinned_nodes.begin();
609 it!=pinned_nodes.end();it++)
611 unsigned dim=(*it)->
ndim();
612 for (
unsigned i=0;
i<dim;
i++)
614 new_node[*it]->pin(
i);
615 new_node[*it]->set_value(
i,scale*
616 (dynamic_cast<SolidNode*>(*it)->x(
i)-
621 oomph_info <<
"Number of equations for smoothing problem: " 622 << assign_eqn_numbers() << std::endl;
629 for (
unsigned j=0;j<nnode;j++)
633 Node* new_node_pt=new_node[orig_node_pt];
636 unsigned dim=new_node_pt->
ndim();
637 for (
unsigned i=0;
i<dim;
i++)
639 orig_node_pt->
x(
i)=orig_node_pt->
xi(
i)+new_node_pt->
value(
i);
678 template<
class POISSON_ELEMENT>
688 std::set<Node*> pinned_nodes)
692 unsigned nelem=orig_mesh_pt->
nelement();
693 unsigned nnode=orig_mesh_pt->
nnode();
696 std::map<Node*,Node*> new_node;
699 for (
unsigned e=0;
e<nelem;
e++)
701 mesh_pt()->add_element_pt(
new POISSON_ELEMENT);
706 unsigned nnod=orig_elem_pt->
nnode();
709 for (
unsigned j=0;j<nnod;j++)
712 if (new_node[orig_elem_pt->
node_pt(j)]==0)
714 Node* new_nod_pt=mesh_pt()->finite_element_pt(
e)->construct_node(j);
715 new_node[orig_elem_pt->
node_pt(j)]=new_nod_pt;
716 mesh_pt()->add_node_pt(new_nod_pt);
717 unsigned dim=new_nod_pt->
ndim();
718 for (
unsigned i=0;
i<dim;
i++)
729 mesh_pt()->finite_element_pt(
e)->node_pt(j)=
730 new_node[orig_elem_pt->
node_pt(j)];
737 for (std::set<Node*>::iterator it=pinned_nodes.begin();
738 it!=pinned_nodes.end();it++)
740 new_node[*it]->
pin(0);
743 oomph_info <<
"Number of equations for Poisson displacement smoothing: " 744 << assign_eqn_numbers() << std::endl;
748 for (
unsigned i=0;
i<dim;
i++)
751 for (
unsigned j=0;j<nnode;j++)
755 Node* new_node_pt=new_node[orig_node_pt];
765 for (
unsigned j=0;j<nnode;j++)
769 Node* new_node_pt=new_node[orig_node_pt];
772 orig_node_pt->
x(
i)=orig_node_pt->
xi(
i)+new_node_pt->
value(0);
void operator()(SolidMesh *orig_mesh_pt, SolidMesh *copy_of_mesh_pt, const Vector< unsigned > &controlled_boundary_id, DocInfo doc_info, const unsigned &max_steps=100000000)
Functor to update the nodal positions in SolidMesh pointed to by orig_mesh_pt in response to the disp...
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
A class to handle errors in the Newton solver.
bool is_doc_enabled() const
Are we documenting?
Information for documentation of results: Directory and file number to enable output in the form RESL...
std::string directory() const
Output directory.
SolidMesh * Dummy_mesh_pt
Copy of mesh to work on.
void doc_solution(DocInfo &doc_info)
Doc the solution.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
void set_boundary_number_in_bulk_mesh(const unsigned &b)
Set function for the boundary number in bulk mesh.
void pin(const unsigned &i)
Pin the i-th stored variable.
unsigned & number()
Number used (e.g.) for labeling output files.
unsigned long nelement() const
Return number of elements in the mesh.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
SolidNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global SolidNode.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
double & xi(const unsigned &i)
Reference to i-th Lagrangian position.
double Scale_increment
Increment for scale factor for displacement of quadratic boundary.
void reset(const unsigned &i)
Reset i-th timer.
unsigned nboundary() const
Return number of boundaries.
Vector< Vector< double > > Orig_node_pos
Original nodal positions.
void set_value(const unsigned &i, const double &value_)
Set the i-th stored data value to specified value. The only reason that we require an explicit set fu...
void operator()(SolidMesh *orig_mesh_pt, SolidMesh *copy_of_mesh_pt, const Vector< unsigned > &controlled_boundary_id, const unsigned &max_steps=100000000)
Functor to update the nodal positions in SolidMesh pointed to by orig_mesh_pt in response to the disp...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
void backup()
Backup nodal positions in dummy mesh to allow for reset after non-convergence of Newton method...
SolidMesh * Orig_mesh_pt
Bulk original mesh.
double Scale
Scale for displacement of quadratic boundary (0.0: simplex; 1.0: quadratic)
unsigned long nnode() const
Return number of nodes in the mesh.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
void disable_doc()
Disable documentation.
IsotropicElasticityTensor Isotropic_elasticity_tensor(Nu)
The elasticity tensor (for smoothing by linear elasticity)
A Class for nodes that deform elastically (i.e. position is an unknown in the problem). The idea is that the Eulerian positions are stored in a Data object and the Lagrangian coordinates are stored in addition. The pointer that addresses the Eulerian positions is set to the pointer to Value in the Data object. Hence, SolidNode uses knowledge of the internal structure of Data and must be a friend of the Data class. In order to allow a mesh to deform via an elastic-style equation in deforming-domain problems, the positions are stored separately from the values, so that elastic problems may be combined with any other type of problem.
void operator()(SolidMesh *orig_mesh_pt, std::set< Node *> pinned_nodes)
Constructor: Specify SolidMesh whose nodal positions are to be adjusted, and set of nodes in that mes...
~LinearElasticitySmoothMesh()
Destructor (empty)
~NonLinearElasticitySmoothMesh()
Destructor (empty)
Vector< Vector< double > > Backup_node_pos
Backup nodal positions.
void set_boundary_shape_geom_object_pt(GeomObject *boundary_shape_geom_object_pt, const unsigned &boundary_number_in_bulk_mesh)
Set GeomObject that specifies the prescribed boundary displacement; GeomObject is assumed to be param...
void operator()(SolidMesh *orig_mesh_pt, std::set< Node *> pinned_nodes)
Functor: Specify SolidMesh whose nodal positions are to be adjusted, and set of nodes in that mesh wh...
void actions_before_newton_solve()
Update nodal positions in main mesh – also moves the nodes of the FaceElements that impose the new p...
double Nu
Poisson's ratio (for smoothing by linear or nonlinear elasticity)
double E
Young's modulus (for smoothing by linear or nonlinear elasticity)
ConstitutiveLaw * Constitutive_law_pt
Create constitutive law (for smoothing by nonlinear elasticity)
unsigned nnode() const
Return the number of nodes.
void set_lagrangian_nodal_coordinates()
Make the current configuration the undeformed one by setting the nodal Lagrangian coordinates to thei...
SolidFiniteElement class.
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation...