27 #ifndef OOMPH_FULL_CIRCLE_MESH_TEMPLATE_CC
28 #define OOMPH_FULL_CIRCLE_MESH_TEMPLATE_CC
39 template<
class ELEMENT>
48 if (radius_box.size() != 4 || theta_positions.size() != 4)
51 "This mesh is hard coded to only work for the case when there are 5 "
52 "elements: the central square and 4 surrounding elements, but you gave "
53 "vectors inconsistent with this.";
55 err, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
60 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
72 const unsigned nelem = 5;
76 ELEMENT* dummy_el_pt =
new ELEMENT;
79 unsigned n_p = dummy_el_pt->nnode_1d();
85 unsigned nnodes_total = (n_p * n_p + 4 * (n_p - 1) * (n_p - 1));
95 for (
unsigned ielem = 0; ielem < nelem; ielem++)
101 for (
unsigned i1 = 0; i1 < n_p; i1++)
104 for (
unsigned i0 = 0; i0 < n_p; i0++)
107 unsigned jnod_local = i0 + i1 * n_p;
111 jnod_local, time_stepper_pt);
114 s[0] = -1.0 + 2.0 * double(i0) / double(n_p - 1);
115 s[1] = -1.0 + 2.0 * double(i1) / double(n_p - 1);
125 unsigned node_count = 0;
128 double node_kill_tol = 1.0e-12;
137 for (
unsigned ielem = 0; ielem < nelem; ielem++)
147 for (
unsigned i1 = 0; i1 < n_p; i1++)
150 for (
unsigned i0 = 0; i0 < n_p; i0++)
153 unsigned jnod_local = i0 + i1 * n_p;
171 for (
unsigned i1 = 0; i1 < n_p; i1++)
174 for (
unsigned i0 = 0; i0 < n_p; i0++)
177 unsigned jnod_local = i0 + i1 * n_p;
186 unsigned ielem_neigh = ielem - 1;
189 unsigned i0_neigh = i0;
190 unsigned i1_neigh = 0;
191 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
194 for (
unsigned i = 0;
i < 2;
i++)
196 double error = std::fabs(
201 if (error > node_kill_tol)
203 oomph_info <<
"Error in node killing for i " <<
i <<
" "
204 << error << std::endl;
233 zeta[0] = theta_positions[0] +
234 double(i1) / double(n_p - 1) * 0.5 *
235 (theta_positions[1] - theta_positions[0]);
237 Node_pt[node_count]->set_coordinates_on_boundary(0, zeta);
254 for (
unsigned i1 = 0; i1 < n_p; i1++)
257 for (
unsigned i0 = 0; i0 < n_p; i0++)
260 unsigned jnod_local = i0 + i1 * n_p;
269 unsigned ielem_neigh = ielem - 1;
272 unsigned i0_neigh = n_p - 1;
273 unsigned i1_neigh = n_p - 1 - i0;
275 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
278 for (
unsigned i = 0;
i < 2;
i++)
280 double error = std::fabs(
285 if (error > node_kill_tol)
287 oomph_info <<
"Error in node killing for i " <<
i <<
" "
288 << error << std::endl;
304 if ((i0 == 0) && (i1 != 0))
307 unsigned ielem_neigh = ielem - 2;
310 unsigned i0_neigh = n_p - 1;
311 unsigned i1_neigh = i1;
312 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
315 for (
unsigned i = 0;
i < 2;
i++)
317 double error = std::fabs(
322 if (error > node_kill_tol)
324 oomph_info <<
"Error in node killing for i " <<
i <<
" "
325 << error << std::endl;
354 zeta[0] = theta_positions[1] +
355 double(i1) / double(n_p - 1) * 0.5 *
356 (theta_positions[2] - theta_positions[1]);
358 Node_pt[node_count]->set_coordinates_on_boundary(0, zeta);
375 for (
unsigned i1 = 0; i1 < n_p; i1++)
378 for (
unsigned i0 = 0; i0 < n_p; i0++)
381 unsigned jnod_local = i0 + i1 * n_p;
391 unsigned ielem_neigh = ielem - 1;
394 unsigned i0_neigh = i1;
395 unsigned i1_neigh = n_p - 1;
396 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
399 for (
unsigned i = 0;
i < 2;
i++)
401 double error = std::fabs(
406 if (error > node_kill_tol)
408 oomph_info <<
"Error in node killing for i " <<
i <<
" "
409 << error << std::endl;
424 if ((i1 == 0) && (i0 != n_p - 1))
427 unsigned ielem_neigh = ielem - 3;
430 unsigned i0_neigh = i0;
431 unsigned i1_neigh = n_p - 1;
432 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
435 for (
unsigned i = 0;
i < 2;
i++)
437 double error = std::fabs(
442 if (error > node_kill_tol)
444 oomph_info <<
"Error in node killing for i " <<
i <<
" "
445 << error << std::endl;
474 zeta[0] = theta_positions[3] +
475 double(i0) / double(n_p - 1) * 0.5 *
476 (theta_positions[2] - theta_positions[3]);
478 Node_pt[node_count]->set_coordinates_on_boundary(0, zeta);
494 for (
unsigned i1 = 0; i1 < n_p; i1++)
497 for (
unsigned i0 = 0; i0 < n_p; i0++)
500 unsigned jnod_local = i0 + i1 * n_p;
509 unsigned ielem_neigh = ielem - 1;
512 unsigned i0_neigh = 0;
513 unsigned i1_neigh = n_p - 1 - i0;
514 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
517 for (
unsigned i = 0;
i < 2;
i++)
519 double error = std::fabs(
524 if (error > node_kill_tol)
526 oomph_info <<
"Error in node killing for i " <<
i <<
" "
527 << error << std::endl;
542 if ((i0 == n_p - 1) && (i1 != n_p - 1))
545 unsigned ielem_neigh = ielem - 4;
548 unsigned i0_neigh = 0;
549 unsigned i1_neigh = i1;
550 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
553 for (
unsigned i = 0;
i < 2;
i++)
555 double error = std::fabs(
560 if (error > node_kill_tol)
562 oomph_info <<
"Error in node killing for i " <<
i <<
" "
563 << error << std::endl;
578 if ((i1 == 0) && (i0 != n_p - 1))
581 unsigned ielem_neigh = ielem - 3;
584 unsigned i0_neigh = 0;
585 unsigned i1_neigh = i0;
586 unsigned jnod_local_neigh = i0_neigh + i1_neigh * n_p;
589 for (
unsigned i = 0;
i < 2;
i++)
591 double error = std::fabs(
596 if (error > node_kill_tol)
598 oomph_info <<
"Error in node killing for i " <<
i <<
" "
599 << error << std::endl;
630 theta_positions[0] + 2.0 * pi +
631 double(i1) / double(n_p - 1) * 0.5 *
632 (theta_positions[3] - theta_positions[0] + 2.0 * pi);
634 Node_pt[node_count]->set_coordinates_on_boundary(0, zeta);
649 std::ostringstream error_stream;
650 error_stream <<
"Error in killing nodes\n"
651 <<
"The most probable cause is that the domain is not\n"
652 <<
"compatible with the mesh.\n"
653 <<
"For the FullCircleMesh, the domain must be\n"
654 <<
"topologically consistent with a quarter tube with a\n"
655 <<
"non-curved centreline.\n";
657 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Topologically circular domain, e.g. a tube cross section. The entire domain must be defined by a Geom...
FullCircleDomain * Domain_pt
Pointer to domain.
GeomObject *& area_pt()
Access function to GeomObject representing wall.
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...
/////////////////////////////////////////////////////////////////////
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Vector< Node * > Node_pt
Vector of pointers to nodes.
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this,...
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
An OomphLibError object which should be thrown when an run-time error is encountered....
void setup_boundary_element_info()
Setup lookup schemes which establish whic elements are located next to mesh's boundaries (wrapper to ...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
const double Pi
50 digits from maple
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...