27 #ifndef OOMPH_FULL_CIRCLE_MESH_TEMPLATE_CC
28 #define OOMPH_FULL_CIRCLE_MESH_TEMPLATE_CC
39 template<
class ELEMENT>
41 const Vector<double>& theta_positions,
42 const Vector<double>& radius_box,
43 TimeStepper* time_stepper_pt)
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);
69 Boundary_coordinate_exists[0] =
true;
72 const unsigned nelem = 5;
73 Element_pt.resize(nelem);
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));
86 Node_pt.resize(nnodes_total);
92 Vector<double> zeta(1);
95 for (
unsigned ielem = 0; ielem < nelem; ielem++)
98 Element_pt[ielem] =
new ELEMENT;
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;
110 Node* node_pt = finite_element_pt(ielem)->construct_node(
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);
116 Domain_pt->macro_element_pt(ielem)->macro_map(s, r);
118 node_pt->x(0) = r[0];
119 node_pt->x(1) = r[1];
125 unsigned node_count = 0;
128 double node_kill_tol = 1.0e-12;
134 const double pi = MathematicalConstants::Pi;
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;
156 Node_pt[node_count] =
157 finite_element_pt(ielem)->node_pt(jnod_local);
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(
197 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
198 finite_element_pt(ielem_neigh)
199 ->node_pt(jnod_local_neigh)
201 if (error > node_kill_tol)
203 oomph_info <<
"Error in node killing for i " << i <<
" "
204 << error << std::endl;
210 delete finite_element_pt(ielem)->node_pt(jnod_local);
214 finite_element_pt(ielem)->node_pt(jnod_local) =
215 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
221 Node_pt[node_count] =
222 finite_element_pt(ielem)->node_pt(jnod_local);
229 this->convert_to_boundary_node(Node_pt[node_count]);
230 add_boundary_node(0, Node_pt[node_count]);
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(
281 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
282 finite_element_pt(ielem_neigh)
283 ->node_pt(jnod_local_neigh)
285 if (error > node_kill_tol)
287 oomph_info <<
"Error in node killing for i " << i <<
" "
288 << error << std::endl;
294 delete finite_element_pt(ielem)->node_pt(jnod_local);
298 finite_element_pt(ielem)->node_pt(jnod_local) =
299 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
318 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
319 finite_element_pt(ielem_neigh)
320 ->node_pt(jnod_local_neigh)
322 if (error > node_kill_tol)
324 oomph_info <<
"Error in node killing for i " << i <<
" "
325 << error << std::endl;
331 delete finite_element_pt(ielem)->node_pt(jnod_local);
335 finite_element_pt(ielem)->node_pt(jnod_local) =
336 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
342 Node_pt[node_count] =
343 finite_element_pt(ielem)->node_pt(jnod_local);
350 this->convert_to_boundary_node(Node_pt[node_count]);
351 add_boundary_node(0, Node_pt[node_count]);
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(
402 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
403 finite_element_pt(ielem_neigh)
404 ->node_pt(jnod_local_neigh)
406 if (error > node_kill_tol)
408 oomph_info <<
"Error in node killing for i " << i <<
" "
409 << error << std::endl;
415 delete finite_element_pt(ielem)->node_pt(jnod_local);
419 finite_element_pt(ielem)->node_pt(jnod_local) =
420 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
438 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
439 finite_element_pt(ielem_neigh)
440 ->node_pt(jnod_local_neigh)
442 if (error > node_kill_tol)
444 oomph_info <<
"Error in node killing for i " << i <<
" "
445 << error << std::endl;
451 delete finite_element_pt(ielem)->node_pt(jnod_local);
455 finite_element_pt(ielem)->node_pt(jnod_local) =
456 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
462 Node_pt[node_count] =
463 finite_element_pt(ielem)->node_pt(jnod_local);
470 this->convert_to_boundary_node(Node_pt[node_count]);
471 add_boundary_node(0, Node_pt[node_count]);
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(
520 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
521 finite_element_pt(ielem_neigh)
522 ->node_pt(jnod_local_neigh)
524 if (error > node_kill_tol)
526 oomph_info <<
"Error in node killing for i " << i <<
" "
527 << error << std::endl;
533 delete finite_element_pt(ielem)->node_pt(jnod_local);
537 finite_element_pt(ielem)->node_pt(jnod_local) =
538 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
556 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
557 finite_element_pt(ielem_neigh)
558 ->node_pt(jnod_local_neigh)
560 if (error > node_kill_tol)
562 oomph_info <<
"Error in node killing for i " << i <<
" "
563 << error << std::endl;
569 delete finite_element_pt(ielem)->node_pt(jnod_local);
573 finite_element_pt(ielem)->node_pt(jnod_local) =
574 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
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(
592 finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
593 finite_element_pt(ielem_neigh)
594 ->node_pt(jnod_local_neigh)
596 if (error > node_kill_tol)
598 oomph_info <<
"Error in node killing for i " << i <<
" "
599 << error << std::endl;
605 delete finite_element_pt(ielem)->node_pt(jnod_local);
609 finite_element_pt(ielem)->node_pt(jnod_local) =
610 finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
617 Node_pt[node_count] =
618 finite_element_pt(ielem)->node_pt(jnod_local);
625 this->convert_to_boundary_node(Node_pt[node_count]);
626 add_boundary_node(0, Node_pt[node_count]);
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);
661 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.
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...
////////////////////////////////////////////////////////////////////// //////////////////////////////...