oomph::MeshHelper Namespace Reference

Functions

template<class MESH1 , class MESH2 >
void merge_spine_meshes (MESH1 *mesh_pt, unsigned bound1, MESH2 *addmesh_pt, int *addmesh_map_boundary, int total_boundaries, unsigned spine_flag)
 

Function Documentation

◆ merge_spine_meshes()

template<class MESH1 , class MESH2 >
void oomph::MeshHelper::merge_spine_meshes ( MESH1 *  mesh_pt,
unsigned  bound1,
MESH2 *  addmesh_pt,
int addmesh_map_boundary,
int  total_boundaries,
unsigned  spine_flag 
)

Now the surface elements

36  {
37  int bound2 = -1;
38 //Map of the commom nodes from the nodes in the added mesh to the old mesh (It is needed for the added elements to point to the old nodes and not duplicate this nodes)
39  std::map<Node*,Node*> map_bound_node;
40 
41  std::map<Spine*, Spine*> map_spines;
42 
43 // We have to look for the shared boundary of the second mwsh. We identify it giving a value of -1 in the mappring of the old to the new boundary conditions
44  for(unsigned i = 0; i<addmesh_pt->nboundary(); i++)
45  {
46  if(addmesh_map_boundary[i] == -1)
47  bound2 = i;
48  }
49 
50 #ifdef PARANOID
51 
52  if(bound2 == -1)
53  {
54  throw OomphLibError("Error setting the shared boundary conditions",
57  }
58 
59 
60 
61 // Another control. Test that the two shared boundaries have the same number of nodes
62  if(addmesh_pt->nboundary_node(bound2) != mesh_pt->nboundary_node(bound1) )
63  {
64  std::ostringstream error_stream;
65  error_stream
66  << "Error: different number of nodes in the shared boundaries:"
67  << "Boundary "<<bound1<<" in the original mesh has "
68  <<mesh_pt->nboundary_node(bound1)<<" nodes "<<std::endl<<
69  "and Boundary "<<bound2<<" in the added mesh has "
70  <<addmesh_pt->nboundary_node(bound2)<<" nodes."<<std::endl;
71 
72  throw OomphLibError(error_stream.str(),
75  }
76 #endif
77 
78 //We create the mappping
79 
80  //square distance between two nodes
81  double d;
82 // Minimun distance between two nodes (only useful in case of error)
83  double dmin;
84  //Dimession of the space
85  unsigned dim = addmesh_pt->node_pt(0)->ndim();
86 
87  unsigned long nodecounter;
88 
89 
90 
91  for( unsigned long i = 0; i< addmesh_pt->nboundary_node(bound2);i++)
92  {
93  nodecounter =0;
94  dmin = 100.0;
95  do
96  {
97  d = 0.0;
98  for(unsigned int k=0;k<dim;k++)
99  {
100  d += (addmesh_pt->boundary_node_pt(bound2,i)->x(k) - mesh_pt->boundary_node_pt(bound1,nodecounter)->x(k) )*
101  (addmesh_pt->boundary_node_pt(bound2,i)->x(k) - mesh_pt->boundary_node_pt(bound1,nodecounter)->x(k) );
102  }
103 
104 
105  nodecounter++;
106  if(dmin>d) dmin = d;
107 
108  }while((nodecounter < mesh_pt->nboundary_node(bound1)) && (d>1E-10));
109 
110  if((nodecounter == mesh_pt->nboundary_node(bound1)) && (d>1E-10))
111  {
112  std::ostringstream error_stream;
113  error_stream
114  <<"Error doing the mapping between shared boundaries:\n"<<
115  "it could not be found minimum distance in node "<<i<<"\n"
116  <<"Minimum found distance = "<<sqrt(dmin)<<"\n"
117  <<"Position in the added mesh = "
118  <<addmesh_pt->boundary_node_pt(bound2,i)->x(0)
119  <<" "<<addmesh_pt->boundary_node_pt(bound2,i)->x(1)<<" "
120  <<addmesh_pt->boundary_node_pt(bound2,i)->x(2)<<"\n";
121 
122  throw OomphLibError(error_stream.str(),
125  }
126  else
127  {
128 
129  // Creating the nodes map
130  map_bound_node[addmesh_pt->boundary_node_pt(bound2,i)] = mesh_pt->boundary_node_pt(bound1,nodecounter-1);
131  // Once we have indentified the corresponding nodes we map the spines
132  SpineNode *add_spinenode = dynamic_cast<SpineNode*>(addmesh_pt->boundary_node_pt(bound2,i));
133  SpineNode *org_spinenode = dynamic_cast<SpineNode*>( mesh_pt->boundary_node_pt(bound1,nodecounter-1) );
134 
135 #ifdef PARANOID
136  if(add_spinenode ==0)
137  {
138  throw OomphLibError(
139  "There are nodes on the shared boundary of the added mesh which are not Spine Nodes\n",
142  }
143 
144  if(org_spinenode ==0)
145  {
146  throw OomphLibError(
147  "There are nodes on the shared boundary of the original mesh which are not Spine Nodes\n",
150  } //mesh3_pt
151 #endif
152 
153  Spine *add_spine = add_spinenode->spine_pt();
154  Spine *org_spine = org_spinenode->spine_pt();
155 
156 
157  //we check the map from this spine has not been before asigned (one spine is pointed by many nodes)
158  if(map_spines[add_spine] == 0)
159  {
160  map_spines[add_spine] = org_spine;
161  }
162  else
163  {
164 //We assure that the nodes that belong to one spine in one mesh are as well belonging to only one spine in the other mesh
165 #ifdef PARANOID
166  if( map_spines[add_spine] != org_spine )
167  {
168  throw OomphLibError(
169  "The spines map could not be performed because the shared spines are pointing to different nodes\n",
172  }
173 #endif
174 
175  }
176  }
177 
178  }
179 
180 
181  //Now we loop over the elements of the added mesh on the shared boundary and reasign the node and spine pointers to the ones
182  // of the original mesh. We need to do a distition between ELMENTS and SURFACE ELEMENT
183 
184 // REMARCK!!!!! the boundary_element scheme was not implemented in the mesh design, so that we have to loop over all the elements
185 
186 
187  for(unsigned int i = 0; i< addmesh_pt->nbulk(); i++ )
188  {
189  //Pointer to the element
190  FiniteElement* el_pt = addmesh_pt->bulk_element_pt(i);
191 
192  // Loop over the nodes in the element
193  for(unsigned j =0;j< el_pt->nnode();j++)
194  {
195  //In case the node is in the boundary (and therefore in the map),
196  //we reasign the node
197  if(map_bound_node[ el_pt->node_pt(j) ] != 0)
198  {
199  el_pt->node_pt(j) = map_bound_node[ el_pt->node_pt(j)];
200  }
201  }
202  }
203 
204 
206 
207  for(unsigned int i = 0; i< addmesh_pt->ninterface_element(); i++ )
208  {
209 //Pointer to the element
210  FiniteElement* surfel_pt = addmesh_pt->interface_element_pt(i);
211 
212  // Loop over the nodes in the element
213  for(unsigned j =0;j< surfel_pt->nnode();j++)
214  {
215  //In case the node is in the boundary (and therefore in the map),
216  //we reasign the node
217  if(map_bound_node[ surfel_pt->node_pt(j) ] != 0)
218  {
219  surfel_pt->node_pt(j) = map_bound_node[ surfel_pt->node_pt(j)];
220  }
221  }
222  }
223 
224 
225 
226 //We add the nodes which are not in the shared boundary
227 // and set the spine flag and the mesh for a later update
228 
229  unsigned long n_nodes_addmesh = addmesh_pt->nnode();
230  unsigned int zaehler = 0;
231  for(unsigned j=0;j<n_nodes_addmesh;j++)
232  {
233  if( map_bound_node[ addmesh_pt->node_pt(j)] == 0)
234  {
235  addmesh_pt->node_pt(j)->node_update_fct_id() = spine_flag;
236  addmesh_pt->node_pt(j)->spine_mesh_pt() = mesh_pt;
237  mesh_pt->add_node_pt( addmesh_pt->node_pt(j) );
238  }
239  else
240  {
241  zaehler++;
242  }
243  }
244 
245 //We add the spines which are not in the shared boundary
246 //The ones in the shared boundary will be deleted
247  unsigned long n_spines_addmesh = addmesh_pt->nspine();
248  for(unsigned j=0;j<n_spines_addmesh;j++)
249  {
250  if( map_spines[ addmesh_pt->spine_pt(j)] == 0)
251  mesh_pt->add_spine_pt(addmesh_pt->spine_pt(j));
252  }
253 
254 
255 #ifdef PARANOID
256 
257 // Another control
258  if(zaehler != addmesh_pt->nboundary_node(bound2))
259  {
260  std::ostringstream error_stream;
261  error_stream
262  <<"Error: you have added "
263  <<(zaehler-addmesh_pt->nboundary_node(bound2))
264  <<" nodes too much to the mesh.\n"
265  <<"(This control should be removed in case we do not want to copy all the nodes of the shared boundaries)\n";
266 
267  throw OomphLibError(error_stream.str(),
270  }
271 
272 
273 #endif
274 
275  //We add the elements to the mesh
276 
277 
278 
279 // add all the elements to the mesh
280 for(unsigned i = 0; i< addmesh_pt->nelement(); i++)
281  {
282  mesh_pt->add_element_pt(addmesh_pt->element_pt(i));
283  }
284 
285 
286 
287 
288 //We reset the boundary conditions of the old mesh (the shared boundary is not more in a boundary)
289  mesh_pt->remove_boundary_nodes(bound1);
290 
291 
292  // We reset the number of boundaries
293  mesh_pt->set_nboundary(total_boundaries);
294 
295 
296 
297  //We reset the boundary conditions of the new nodes
298  for(int i=0;i<(int)(addmesh_pt->nboundary());i++)
299  {
300  //Loop over the boundary nodes
301  for(unsigned long j =0;j<addmesh_pt->nboundary_node(i);j++)
302  {
303 
304  //We do not reset the commom boundary,whose nodes will be deleted at the end
305  if(i!=bound2)
306  {
307  //Create a pointer to the node
308  Node* node_pt = addmesh_pt->boundary_node_pt(i,j);
309 
310  // We remove the old boundaries in case it is not yet included in a new boundary
311  bool alr_included = 0;
312  for(unsigned k =0;k<mesh_pt->nboundary_node(i);k++)
313  {
314  if(node_pt == mesh_pt->boundary_node_pt(i,k) )
315  alr_included = 1;
316  }
317  if(!alr_included)
318  node_pt->remove_from_boundary(i);
319 
320  // We test again not to include the nodes which will be deleted
321  if( map_bound_node[node_pt] == 0)
322  {
323  mesh_pt->add_boundary_node( addmesh_map_boundary[i], node_pt );
324  }
325  // if not we have to include to the boundarie (in the case that they were not included before)the maped nodes
326  else
327  {
328  Node* map_node_pt = map_bound_node[node_pt];
329  if(!map_node_pt->is_on_boundary(addmesh_map_boundary[i]) )
330  mesh_pt->add_boundary_node(addmesh_map_boundary[i], map_node_pt );
331  }
332  }
333  }
334  }
335 
336 
337 
338 
339 // We remove the shared spines of the second mesh
340  for(unsigned j=0;j<n_spines_addmesh;j++)
341  {
342  if( map_spines[ addmesh_pt->spine_pt(j)] != 0)
343  delete addmesh_pt->spine_pt(j);
344  }
345 
346 
347 
348 // At the end we remove the shared nodes of the second mesh for avoiding problems with memory leaking
349 
350  for(unsigned long j =0;j<addmesh_pt->nboundary_node(bound2);j++)
351  delete addmesh_pt->boundary_node_pt(bound2,j);
352 
353 
354 
355 // Small control
356 #ifdef PARANOID
357  for(unsigned i = 0; i<mesh_pt->nboundary(); i ++)
358  {
359  std::cout<<"Boundary "<<i<<" has "<<mesh_pt->nboundary_node(i)<<" nodes."<<std::endl;
360  }
361 #endif
362  }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define dmin(a, b)
Definition: datatypes.h:24
return int(ret)+1
char char char int int * k
Definition: level2_impl.h:374
double E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:68
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References dmin, Global_Physical_Variables::E, i, int(), oomph::Node::is_on_boundary(), j, k, oomph::FiniteElement::nnode(), oomph::FiniteElement::node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::Node::remove_from_boundary(), oomph::SpineNode::spine_pt(), and sqrt().

Referenced by STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_side_spinemesh(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_side_spinemesh(), and CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_side_spinemesh().