31 #ifndef OOMPH_FULL_CIRCLE_MESH_TEMPLATE_CC 32 #define OOMPH_FULL_CIRCLE_MESH_TEMPLATE_CC 44 template <
class ELEMENT>
46 const Vector<double> &theta_positions,
47 const Vector<double> &radius_box,
48 TimeStepper* time_stepper_pt) :
54 if(radius_box.size() != 4 || theta_positions.size() != 4)
56 std::string err =
"This mesh is hard coded to only work for the case when there are 5 elements: the central square and 4 surrounding elements, but you gave vectors inconsistent with this.";
57 throw OomphLibError(err, OOMPH_CURRENT_FUNCTION,
58 OOMPH_EXCEPTION_LOCATION);
63 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
72 Boundary_coordinate_exists[0] =
true;
75 const unsigned nelem=5;
76 Element_pt.resize(nelem);
79 ELEMENT* dummy_el_pt=
new ELEMENT;
82 unsigned n_p = dummy_el_pt->nnode_1d();
88 unsigned nnodes_total=
89 (n_p*n_p + 4*(n_p-1)*(n_p -1));
90 Node_pt.resize(nnodes_total);
96 Vector<double> zeta(1);
99 for (
unsigned ielem=0;ielem<nelem;ielem++)
102 Element_pt[ielem] =
new ELEMENT;
105 for (
unsigned i1=0;i1<n_p;i1++)
108 for (
unsigned i0=0;i0<n_p;i0++)
111 unsigned jnod_local=i0+i1*n_p;
114 Node* node_pt=finite_element_pt(ielem)->
115 construct_node(jnod_local,time_stepper_pt);
118 s[0]=-1.0+2.0*double(i0)/double(n_p-1);
119 s[1]=-1.0+2.0*double(i1)/double(n_p-1);
120 Domain_pt->macro_element_pt(ielem)->macro_map(s,r);
122 node_pt->x(0) = r[0];
123 node_pt->x(1) = r[1];
129 unsigned node_count=0;
132 double node_kill_tol=1.0e-12;
138 const double pi = MathematicalConstants::Pi;
141 for (
unsigned ielem=0;ielem<nelem;ielem++)
151 for (
unsigned i1=0;i1<n_p;i1++)
155 for (
unsigned i0=0;i0<n_p;i0++)
159 unsigned jnod_local=i0+i1*n_p;
162 Node_pt[node_count]=finite_element_pt(ielem)->node_pt(jnod_local);
176 for (
unsigned i1=0;i1<n_p;i1++)
180 for (
unsigned i0=0;i0<n_p;i0++)
184 unsigned jnod_local=i0+i1*n_p;
193 unsigned ielem_neigh=ielem-1;
196 unsigned i0_neigh=i0;
198 unsigned jnod_local_neigh = i0_neigh + i1_neigh*n_p;
201 for (
unsigned i=0;i<2;i++)
203 double error=std::fabs(
204 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
205 finite_element_pt(ielem_neigh)->
206 node_pt(jnod_local_neigh)->x(i));
207 if (error>node_kill_tol)
209 oomph_info <<
"Error in node killing for i " 210 << i <<
" " << error << std::endl;
216 delete finite_element_pt(ielem)->node_pt(jnod_local);
220 finite_element_pt(ielem)->node_pt(jnod_local)=
221 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
228 finite_element_pt(ielem)->node_pt(jnod_local);
235 this->convert_to_boundary_node(Node_pt[node_count]);
236 add_boundary_node(0,Node_pt[node_count]);
239 zeta[0]= theta_positions[0] +
240 double(i1)/double(n_p-1)*0.5*
241 (theta_positions[1]-theta_positions[0]);
243 Node_pt[node_count]->set_coordinates_on_boundary(0,zeta);
261 for (
unsigned i1=0;i1<n_p;i1++)
265 for (
unsigned i0=0;i0<n_p;i0++)
269 unsigned jnod_local=i0+i1*n_p;
279 unsigned ielem_neigh=ielem-1;
282 unsigned i0_neigh=n_p-1;
283 unsigned i1_neigh= n_p-1 - i0;
285 unsigned jnod_local_neigh =i0_neigh+i1_neigh*n_p;
288 for (
unsigned i=0;i<2;i++)
290 double error=std::fabs(
291 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
292 finite_element_pt(ielem_neigh)->
293 node_pt(jnod_local_neigh)->x(i));
294 if (error>node_kill_tol)
296 oomph_info <<
"Error in node killing for i " 297 << i <<
" " << error << std::endl;
303 delete finite_element_pt(ielem)->node_pt(jnod_local);
307 finite_element_pt(ielem)->node_pt(jnod_local)=
308 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
314 if ((i0==0)&&(i1!=0))
318 unsigned ielem_neigh=ielem-2;
321 unsigned i0_neigh=n_p-1;
322 unsigned i1_neigh=i1;
323 unsigned jnod_local_neigh = i0_neigh+i1_neigh*n_p;
326 for (
unsigned i=0;i<2;i++)
328 double error=std::fabs(
329 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
330 finite_element_pt(ielem_neigh)->
331 node_pt(jnod_local_neigh)->x(i));
332 if (error>node_kill_tol)
334 oomph_info <<
"Error in node killing for i " 335 << i <<
" " << error << std::endl;
341 delete finite_element_pt(ielem)->node_pt(jnod_local);
345 finite_element_pt(ielem)->node_pt(jnod_local)=
346 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
353 Node_pt[node_count]=finite_element_pt(ielem)->
361 this->convert_to_boundary_node(Node_pt[node_count]);
362 add_boundary_node(0,Node_pt[node_count]);
365 zeta[0]=theta_positions[1] +
366 double(i1)/double(n_p-1)*0.5*
367 (theta_positions[2]-theta_positions[1]);
369 Node_pt[node_count]->set_coordinates_on_boundary(0,zeta);
388 for (
unsigned i1=0;i1<n_p;i1++)
392 for (
unsigned i0=0;i0<n_p;i0++)
396 unsigned jnod_local=i0+i1*n_p;
407 unsigned ielem_neigh=ielem-1;
410 unsigned i0_neigh=i1;
411 unsigned i1_neigh= n_p-1;
412 unsigned jnod_local_neigh=i0_neigh+i1_neigh*n_p;
415 for (
unsigned i=0;i<2;i++)
417 double error=std::fabs(
418 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
419 finite_element_pt(ielem_neigh)->
420 node_pt(jnod_local_neigh)->x(i));
421 if (error>node_kill_tol)
423 oomph_info <<
"Error in node killing for i " 424 << i <<
" " << error << std::endl;
430 delete finite_element_pt(ielem)->node_pt(jnod_local);
434 finite_element_pt(ielem)->node_pt(jnod_local)=
435 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
440 if ((i1==0)&&(i0!=n_p-1))
444 unsigned ielem_neigh=ielem-3;
447 unsigned i0_neigh=i0;
448 unsigned i1_neigh=n_p-1;
449 unsigned jnod_local_neigh= i0_neigh+i1_neigh*n_p;
452 for (
unsigned i=0;i<2;i++)
454 double error=std::fabs(
455 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
456 finite_element_pt(ielem_neigh)->
457 node_pt(jnod_local_neigh)->x(i));
458 if (error>node_kill_tol)
460 oomph_info <<
"Error in node killing for i " 461 << i <<
" " << error << std::endl;
467 delete finite_element_pt(ielem)->node_pt(jnod_local);
471 finite_element_pt(ielem)->node_pt(jnod_local)=
472 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
479 Node_pt[node_count]=finite_element_pt(ielem)->
487 this->convert_to_boundary_node(Node_pt[node_count]);
488 add_boundary_node(0,Node_pt[node_count]);
491 zeta[0]=theta_positions[3] +
492 double(i0)/double(n_p-1)*0.5*
493 (theta_positions[2]-theta_positions[3]);
495 Node_pt[node_count]->set_coordinates_on_boundary(0,zeta);
513 for (
unsigned i1=0;i1<n_p;i1++)
517 for (
unsigned i0=0;i0<n_p;i0++)
521 unsigned jnod_local=i0+i1*n_p;
531 unsigned ielem_neigh=ielem-1;
535 unsigned i1_neigh= n_p - 1 -i0;
536 unsigned jnod_local_neigh=i0_neigh+i1_neigh*n_p;
539 for (
unsigned i=0;i<2;i++)
541 double error=std::fabs(
542 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
543 finite_element_pt(ielem_neigh)->
544 node_pt(jnod_local_neigh)->x(i));
545 if (error>node_kill_tol)
547 oomph_info <<
"Error in node killing for i " 548 << i <<
" " << error << std::endl;
554 delete finite_element_pt(ielem)->node_pt(jnod_local);
558 finite_element_pt(ielem)->node_pt(jnod_local)=
559 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
564 if ((i0==n_p-1)&&(i1!=n_p-1))
568 unsigned ielem_neigh=ielem-4;
572 unsigned i1_neigh=i1;
573 unsigned jnod_local_neigh = i0_neigh+i1_neigh*n_p;
576 for (
unsigned i=0;i<2;i++)
578 double error=std::fabs(
579 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
580 finite_element_pt(ielem_neigh)->
581 node_pt(jnod_local_neigh)->x(i));
582 if (error>node_kill_tol)
584 oomph_info <<
"Error in node killing for i " 585 << i <<
" " << error << std::endl;
591 delete finite_element_pt(ielem)->node_pt(jnod_local);
595 finite_element_pt(ielem)->node_pt(jnod_local)=
596 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
601 if ((i1==0)&&(i0!=n_p-1))
605 unsigned ielem_neigh=ielem-3;
609 unsigned i1_neigh=i0;
610 unsigned jnod_local_neigh = i0_neigh+i1_neigh*n_p;
613 for (
unsigned i=0;i<2;i++)
615 double error=std::fabs(
616 finite_element_pt(ielem)->node_pt(jnod_local)->x(i)-
617 finite_element_pt(ielem_neigh)->
618 node_pt(jnod_local_neigh)->x(i));
619 if (error>node_kill_tol)
621 oomph_info <<
"Error in node killing for i " 622 << i <<
" " << error << std::endl;
628 delete finite_element_pt(ielem)->node_pt(jnod_local);
632 finite_element_pt(ielem)->node_pt(jnod_local)=
633 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
641 Node_pt[node_count]=finite_element_pt(ielem)->
649 this->convert_to_boundary_node(Node_pt[node_count]);
650 add_boundary_node(0,Node_pt[node_count]);
653 zeta[0]=theta_positions[0] + 2.0*pi +
654 double(i1)/double(n_p-1)*0.5*
655 (theta_positions[3]-theta_positions[0] + 2.0*pi);
657 Node_pt[node_count]->set_coordinates_on_boundary(0,zeta);
674 std::ostringstream error_stream;
675 error_stream <<
"Error in killing nodes\n" 676 <<
"The most probable cause is that the domain is not\n" 677 <<
"compatible with the mesh.\n" 678 <<
"For the FullCircleMesh, the domain must be\n" 679 <<
"topologically consistent with a quarter tube with a\n" 680 <<
"non-curved centreline.\n";
681 throw OomphLibError(error_stream.str(),
682 OOMPH_CURRENT_FUNCTION,
683 OOMPH_EXCEPTION_LOCATION);
687 setup_boundary_element_info();
Topologically circular domain, e.g. a tube cross section. The entire domain must be defined by a Geom...
FullCircleDomain * Domain_pt
Pointer to domain.
FullCircleMesh(GeomObject *wall_pt, const Vector< double > &theta_positions, const Vector< double > &radius_box, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that specifies the area; values of theta at which divid...