27 #ifndef OOMPH_HERMITE_QUAD_MESH_TEMPLATE_CC
28 #define OOMPH_HERMITE_QUAD_MESH_TEMPLATE_CC
33 #include <oomph-lib-config.h>
47 template<
class ELEMENT>
49 const unsigned& node_num_x,
const unsigned& node_num_y, Node* node_pt)
52 DenseMatrix<double> m_gen(4, 2);
53 generalised_macro_element_position_of_node(node_num_x, node_num_y, m_gen);
56 Vector<double> node_macro_position(2);
57 node_macro_position[0] = m_gen(0, 0);
58 node_macro_position[1] = m_gen(0, 1);
61 Vector<double> x_node(2);
62 Domain_pt->macro_element_pt(0)->macro_map(node_macro_position, x_node);
65 DenseMatrix<double> jacobian_MX(2, 2);
66 Domain_pt->macro_element_pt(0)->assemble_macro_to_eulerian_jacobian(
67 node_macro_position, jacobian_MX);
71 DenseMatrix<double> jacobian2_MX(3, 2);
72 Domain_pt->macro_element_pt(0)->assemble_macro_to_eulerian_jacobian2(
73 node_macro_position, jacobian2_MX);
76 node_pt->x_gen(0, 0) = x_node[0];
78 node_pt->x_gen(0, 1) = x_node[1];
82 for (
unsigned i = 0; i < 2; i++)
84 for (
unsigned j = 0; j < 2; j++)
86 node_pt->x_gen(j + 1, i) = m_gen(j + 1, 0) * jacobian_MX(0, i) +
87 m_gen(j + 1, 1) * jacobian_MX(1, i);
96 for (
unsigned i = 0; i < 2; i++)
98 node_pt->x_gen(3, i) =
99 m_gen(3, 0) * jacobian_MX(0, i) + m_gen(3, 1) * jacobian_MX(1, i) +
100 m_gen(1, 0) * (m_gen(2, 0) * jacobian2_MX(0, i) +
101 m_gen(2, 1) * jacobian2_MX(2, i)) +
103 (m_gen(2, 0) * jacobian2_MX(2, i) + m_gen(2, 1) * jacobian2_MX(1, i));
115 template<
class ELEMENT>
117 const unsigned& node_num_x,
118 const unsigned& node_num_y,
119 BoundaryNode<Node>* node_pt)
122 DenseMatrix<double> m_gen(4, 2, 0.0);
123 generalised_macro_element_position_of_node(node_num_x, node_num_y, m_gen);
126 Vector<double> node_macro_position(2);
127 node_macro_position[0] = m_gen(0, 0);
128 node_macro_position[1] = m_gen(0, 1);
131 Vector<double> x_node(2);
132 Domain_pt->macro_element_pt(0)->macro_map(node_macro_position, x_node);
135 DenseMatrix<double> jacobian_MX(2, 2);
136 Domain_pt->macro_element_pt(0)->assemble_macro_to_eulerian_jacobian(
137 node_macro_position, jacobian_MX);
140 DenseMatrix<double> jacobian2_MX(3, 2);
141 Domain_pt->macro_element_pt(0)->assemble_macro_to_eulerian_jacobian2(
142 node_macro_position, jacobian2_MX);
145 node_pt->x_gen(0, 0) = x_node[0];
147 node_pt->x_gen(0, 1) = x_node[1];
151 for (
unsigned i = 0; i < 2; i++)
153 for (
unsigned j = 0; j < 2; j++)
155 node_pt->x_gen(j + 1, i) = m_gen(j + 1, 0) * jacobian_MX(0, i) +
156 m_gen(j + 1, 1) * jacobian_MX(1, i);
165 for (
unsigned i = 0; i < 2; i++)
167 node_pt->x_gen(3, i) =
168 m_gen(3, 0) * jacobian_MX(0, i) + m_gen(3, 1) * jacobian_MX(1, i) +
169 m_gen(1, 0) * (m_gen(2, 0) * jacobian2_MX(0, i) +
170 m_gen(2, 1) * jacobian2_MX(2, i)) +
172 (m_gen(2, 0) * jacobian2_MX(2, i) + m_gen(2, 1) * jacobian2_MX(1, i));
178 for (
unsigned b = 0; b < 4; b++)
180 if (node_pt->is_on_boundary(b))
182 Vector<double> boundary_macro_position(2, 0);
183 boundary_macro_position[0] = m_gen(0, b % 2);
184 boundary_macro_position[1] = m_gen(1 + b % 2, b % 2);
185 node_pt->set_coordinates_on_boundary(b, boundary_macro_position);
199 template<
class ELEMENT>
201 const unsigned& node_num_x,
202 const unsigned& node_num_y,
203 DenseMatrix<double>& m_gen)
206 Vector<double> s_macro_N(2);
207 macro_coordinate_position(node_num_x, node_num_y, s_macro_N);
210 m_gen(0, 0) = s_macro_N[0];
211 m_gen(0, 1) = s_macro_N[1];
219 Vector<double> s_macro_R(2);
220 macro_coordinate_position(node_num_x + 1, node_num_y, s_macro_R);
223 m_gen(1, 0) = 0.5 * (s_macro_R[0] - s_macro_N[0]);
226 m_gen(1, 1) = 0.5 * (s_macro_R[1] - s_macro_N[1]);
234 Vector<double> s_macro_UR(2);
235 macro_coordinate_position(node_num_x + 1, node_num_y + 1, s_macro_UR);
238 Vector<double> s_macro_U(2);
239 macro_coordinate_position(node_num_x, node_num_y + 1, s_macro_U);
243 0.5 * (0.5 * (s_macro_UR[0] - s_macro_U[0]) - m_gen(1, 0));
247 0.5 * (0.5 * (s_macro_UR[1] - s_macro_U[1]) - m_gen(1, 1));
251 else if (node_num_y == Nelement[1])
254 Vector<double> s_macro_DR(2);
255 macro_coordinate_position(node_num_x + 1, node_num_y - 1, s_macro_DR);
258 Vector<double> s_macro_D(2);
259 macro_coordinate_position(node_num_x, node_num_y - 1, s_macro_D);
263 0.5 * (m_gen(1, 0) - 0.5 * (s_macro_DR[0] - s_macro_D[0]));
267 0.5 * (m_gen(1, 1) - 0.5 * (s_macro_DR[1] - s_macro_D[1]));
274 Vector<double> s_macro_DR(2);
275 macro_coordinate_position(node_num_x + 1, node_num_y - 1, s_macro_DR);
278 Vector<double> s_macro_D(2);
279 macro_coordinate_position(node_num_x, node_num_y - 1, s_macro_D);
282 Vector<double> s_macro_UR(2);
283 macro_coordinate_position(node_num_x + 1, node_num_y + 1, s_macro_UR);
286 Vector<double> s_macro_U(2);
287 macro_coordinate_position(node_num_x, node_num_y + 1, s_macro_U);
291 0.5 * std::min(m_gen(1, 0) - 0.5 * (s_macro_DR[0] - s_macro_D[0]),
292 0.5 * (s_macro_UR[0] - s_macro_U[0]) - m_gen(1, 0));
296 0.5 * std::min(m_gen(1, 1) - 0.5 * (s_macro_DR[1] - s_macro_D[1]),
297 0.5 * (s_macro_UR[1] - s_macro_U[1]) - m_gen(1, 1));
302 else if (node_num_x == Nelement[0])
307 Vector<double> s_macro_L(2);
308 macro_coordinate_position(node_num_x - 1, node_num_y, s_macro_L);
311 m_gen(1, 0) = 0.5 * (s_macro_N[0] - s_macro_L[0]);
314 m_gen(1, 1) = 0.5 * (s_macro_N[1] - s_macro_L[1]);
322 Vector<double> s_macro_UL(2);
323 macro_coordinate_position(node_num_x - 1, node_num_y + 1, s_macro_UL);
326 Vector<double> s_macro_U(2);
327 macro_coordinate_position(node_num_x, node_num_y + 1, s_macro_U);
331 0.5 * (0.5 * (s_macro_U[0] - s_macro_UL[0]) - m_gen(1, 0));
335 0.5 * (0.5 * (s_macro_U[1] - s_macro_UL[1]) - m_gen(1, 1));
339 else if (node_num_y == Nelement[1])
342 Vector<double> s_macro_DL(2);
343 macro_coordinate_position(node_num_x - 1, node_num_y - 1, s_macro_DL);
346 Vector<double> s_macro_D(2);
347 macro_coordinate_position(node_num_x, node_num_y - 1, s_macro_D);
351 0.5 * (m_gen(1, 0) - 0.5 * (s_macro_D[0] - s_macro_DL[0]));
355 0.5 * (m_gen(1, 1) - 0.5 * (s_macro_D[1] - s_macro_DL[1]));
362 Vector<double> s_macro_DL(2);
363 macro_coordinate_position(node_num_x - 1, node_num_y - 1, s_macro_DL);
366 Vector<double> s_macro_D(2);
367 macro_coordinate_position(node_num_x, node_num_y - 1, s_macro_D);
370 Vector<double> s_macro_UL(2);
371 macro_coordinate_position(node_num_x - 1, node_num_y + 1, s_macro_UL);
374 Vector<double> s_macro_U(2);
375 macro_coordinate_position(node_num_x, node_num_y + 1, s_macro_U);
379 0.5 * std::min(m_gen(1, 0) - 0.5 * (s_macro_D[0] - s_macro_DL[0]),
380 0.5 * (s_macro_U[0] - s_macro_UL[0]) - m_gen(1, 0));
384 0.5 * std::min(m_gen(1, 1) - 0.5 * (s_macro_D[1] - s_macro_DL[1]),
385 0.5 * (s_macro_U[1] - s_macro_UL[1]) - m_gen(1, 1));
392 Vector<double> s_macro_L(2);
393 macro_coordinate_position(node_num_x - 1, node_num_y, s_macro_L);
396 Vector<double> s_macro_R(2);
397 macro_coordinate_position(node_num_x + 1, node_num_y, s_macro_R);
400 m_gen(1, 0) = 0.5 * std::min(s_macro_N[0] - s_macro_L[0],
401 s_macro_R[0] - s_macro_N[0]);
404 Vector<double> node_space(2);
405 node_space[0] = s_macro_N[1] - s_macro_L[1];
406 node_space[1] = s_macro_R[1] - s_macro_N[1];
408 if (node_space[0] > 0 && node_space[1] > 0)
409 m_gen(1, 1) = 0.5 * std::min(node_space[0], node_space[1]);
410 else if (node_space[0] < 0 && node_space[1] < 0)
411 m_gen(1, 1) = 0.5 * std::max(node_space[0], node_space[1]);
422 Vector<double> s_macro_U(2);
423 macro_coordinate_position(node_num_x, node_num_y + 1, s_macro_U);
426 m_gen(2, 0) = 0.5 * (s_macro_U[0] - s_macro_N[0]);
429 m_gen(2, 1) = 0.5 * (s_macro_U[1] - s_macro_N[1]);
432 if (node_num_x > 0 && node_num_x < Nelement[0])
437 Vector<double> s_macro_UL(2);
438 macro_coordinate_position(node_num_x - 1, node_num_y + 1, s_macro_UL);
441 Vector<double> s_macro_L(2);
442 macro_coordinate_position(node_num_x - 1, node_num_y, s_macro_L);
445 Vector<double> s_macro_R(2);
446 macro_coordinate_position(node_num_x + 1, node_num_y, s_macro_R);
449 Vector<double> s_macro_UR(2);
450 macro_coordinate_position(node_num_x + 1, node_num_y + 1, s_macro_UR);
454 0.5 * std::min(m_gen(2, 0) - 0.5 * (s_macro_UL[0] - s_macro_L[0]),
455 0.5 * (s_macro_UR[0] - s_macro_R[0]) - m_gen(2, 0));
459 0.5 * std::min(m_gen(2, 1) - 0.5 * (s_macro_UL[1] - s_macro_L[1]),
460 0.5 * (s_macro_UR[1] - s_macro_R[1]) - m_gen(2, 1));
465 else if (node_num_y == Nelement[1])
470 Vector<double> s_macro_D(2);
471 macro_coordinate_position(node_num_x, node_num_y - 1, s_macro_D);
474 m_gen(2, 0) = 0.5 * (s_macro_N[0] - s_macro_D[0]);
477 m_gen(2, 1) = 0.5 * (s_macro_N[1] - s_macro_D[1]);
480 if (node_num_x > 0 && node_num_x < Nelement[0])
485 Vector<double> s_macro_DL(2);
486 macro_coordinate_position(node_num_x - 1, node_num_y - 1, s_macro_DL);
489 Vector<double> s_macro_L(2);
490 macro_coordinate_position(node_num_x - 1, node_num_y, s_macro_L);
493 Vector<double> s_macro_R(2);
494 macro_coordinate_position(node_num_x + 1, node_num_y, s_macro_R);
497 Vector<double> s_macro_DR(2);
498 macro_coordinate_position(node_num_x + 1, node_num_y - 1, s_macro_DR);
502 0.5 * std::min(m_gen(2, 0) - 0.5 * (s_macro_L[0] - s_macro_DL[0]),
503 0.5 * (s_macro_R[0] - s_macro_DR[0]) - m_gen(2, 0));
507 0.5 * std::min(m_gen(2, 1) - 0.5 * (s_macro_L[1] - s_macro_DL[1]),
508 0.5 * (s_macro_R[1] - s_macro_DR[1]) - m_gen(2, 1));
514 Vector<double> s_macro_U(2);
515 macro_coordinate_position(node_num_x, node_num_y + 1, s_macro_U);
518 Vector<double> s_macro_D(2);
519 macro_coordinate_position(node_num_x, node_num_y - 1, s_macro_D);
522 Vector<double> node_space(2);
523 node_space[0] = s_macro_N[0] - s_macro_D[0];
524 node_space[1] = s_macro_U[0] - s_macro_N[0];
526 if (node_space[0] > 0 && node_space[1] > 0)
527 m_gen(2, 0) = 0.5 * std::min(node_space[0], node_space[1]);
528 else if (node_space[0] < 0 && node_space[1] < 0)
529 m_gen(2, 0) = 0.5 * std::max(node_space[0], node_space[1]);
534 m_gen(2, 1) = 0.5 * std::min(s_macro_N[1] - s_macro_D[1],
535 s_macro_U[1] - s_macro_N[1]);
538 if (node_num_x > 0 && node_num_x < Nelement[0])
541 Vector<double> s_macro_L(2);
542 macro_coordinate_position(node_num_x - 1, node_num_y, s_macro_L);
545 Vector<double> s_macro_UL(2);
546 macro_coordinate_position(node_num_x - 1, node_num_y + 1, s_macro_UL);
549 Vector<double> s_macro_UR(2);
550 macro_coordinate_position(node_num_x + 1, node_num_y + 1, s_macro_UR);
553 Vector<double> s_macro_R(2);
554 macro_coordinate_position(node_num_x + 1, node_num_y, s_macro_R);
557 Vector<double> s_macro_DR(2);
558 macro_coordinate_position(node_num_x + 1, node_num_y - 1, s_macro_DR);
561 Vector<double> s_macro_DL(2);
562 macro_coordinate_position(node_num_x - 1, node_num_y - 1, s_macro_DL);
564 Vector<double> node_space(2);
567 m_gen(1, 0) - 0.5 * std::min(s_macro_D[0] - s_macro_DL[0],
568 s_macro_DR[0] - s_macro_D[0]);
569 node_space[1] = 0.5 * std::min(s_macro_U[0] - s_macro_UL[0],
570 s_macro_UR[0] - s_macro_U[0]) -
573 if (node_space[0] > 0 && node_space[1] > 0)
574 m_gen(3, 0) = 0.5 * std::min(node_space[0], node_space[1]);
575 else if (node_space[0] < 0 && node_space[1] < 0)
576 m_gen(3, 0) = 0.5 * std::max(node_space[0], node_space[1]);
582 m_gen(2, 1) - 0.5 * std::min(s_macro_L[0] - s_macro_DL[0],
583 s_macro_UL[0] - s_macro_L[0]);
584 node_space[1] = 0.5 * std::min(s_macro_R[0] - s_macro_DR[0],
585 s_macro_UR[0] - s_macro_R[0]) -
588 if (node_space[0] > 0 && node_space[1] > 0)
589 m_gen(3, 1) = 0.5 * std::min(node_space[0], node_space[1]);
590 else if (node_space[0] < 0 && node_space[1] < 0)
591 m_gen(3, 1) = 0.5 * std::max(node_space[0], node_space[1]);
602 template<
class ELEMENT>
606 MeshChecker::assert_geometric_element<QHermiteElementBase, ELEMENT>(2);
612 Element_pt.resize(Nelement[0] * Nelement[1]);
615 Element_pt[0] =
new ELEMENT;
616 finite_element_pt(0)->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
619 Node_pt.resize((1 + Nelement[0]) * (1 + Nelement[1]));
622 unsigned long node_count = 0;
644 Node_pt[node_count] =
645 finite_element_pt(0)->construct_boundary_node(0, time_stepper_pt);
648 add_boundary_node(0, Node_pt[node_count]);
649 add_boundary_node(3, Node_pt[node_count]);
652 set_position_of_boundary_node(
653 0, 0,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
661 Node_pt[node_count] =
662 finite_element_pt(0)->construct_boundary_node(1, time_stepper_pt);
665 add_boundary_node(0, Node_pt[node_count]);
668 if (Nelement[0] == 1)
670 add_boundary_node(1, Node_pt[node_count]);
674 set_position_of_boundary_node(
675 1, 0,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
683 Node_pt[node_count] =
684 finite_element_pt(0)->construct_boundary_node(2, time_stepper_pt);
687 add_boundary_node(3, Node_pt[node_count]);
690 if (Nelement[1] == 1)
692 add_boundary_node(2, Node_pt[node_count]);
696 set_position_of_boundary_node(
697 0, 1,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
705 Node_pt[node_count] =
706 finite_element_pt(0)->construct_node(3, time_stepper_pt);
709 if (Nelement[0] == 1)
711 add_boundary_node(1, Node_pt[node_count]);
714 if (Nelement[1] == 1)
716 add_boundary_node(2, Node_pt[node_count]);
720 if (Nelement[0] == 1 || Nelement[1] == 1)
723 set_position_of_boundary_node(
724 1, 1,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
729 set_position_of_node(1, 1, Node_pt[node_count]);
743 for (
unsigned j = 1; j < (Nelement[0] - 1); j++)
746 Element_pt[j] =
new ELEMENT;
747 finite_element_pt(j)->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
753 finite_element_pt(j)->node_pt(0) = finite_element_pt(j - 1)->node_pt(1);
758 Node_pt[node_count] =
759 finite_element_pt(j)->construct_boundary_node(1, time_stepper_pt);
762 add_boundary_node(0, Node_pt[node_count]);
765 set_position_of_boundary_node(
766 j + 1, 0,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
774 finite_element_pt(j)->node_pt(2) = finite_element_pt(j - 1)->node_pt(3);
779 Node_pt[node_count] =
780 finite_element_pt(j)->construct_node(3, time_stepper_pt);
783 if (Nelement[0] == 1)
785 add_boundary_node(2, Node_pt[node_count]);
789 if (Nelement[0] == 1)
790 set_position_of_boundary_node(
791 j + 1, 1,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
793 set_position_of_node(j + 1, 1, Node_pt[node_count]);
807 Element_pt[Nelement[0] - 1] =
new ELEMENT;
808 finite_element_pt(Nelement[0] - 1)
809 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
814 finite_element_pt(Nelement[0] - 1)->node_pt(0) =
815 finite_element_pt(Nelement[0] - 2)->node_pt(1);
821 if (Xperiodic ==
true)
824 finite_element_pt(Nelement[0] - 1)->node_pt(1) =
825 finite_element_pt(0)->node_pt(0);
831 Node_pt[node_count] = finite_element_pt(Nelement[0] - 1)
832 ->construct_boundary_node(1, time_stepper_pt);
836 add_boundary_node(0, Node_pt[node_count]);
837 add_boundary_node(1, Node_pt[node_count]);
840 set_position_of_boundary_node(
841 Nelement[0], 0,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
844 if (Xperiodic ==
false)
852 finite_element_pt(Nelement[0] - 1)->node_pt(2) =
853 finite_element_pt(Nelement[0] - 2)->node_pt(3);
856 if (Nelement[1] == 1)
858 add_boundary_node(2, Node_pt[node_count]);
862 if (Nelement[1] == 1)
863 set_position_of_boundary_node(
866 dynamic_cast<BoundaryNode<Node>*
>(
867 finite_element_pt(Nelement[0] - 2)->node_pt(3)));
873 if (Xperiodic ==
true)
876 finite_element_pt(Nelement[0] - 1)->node_pt(3) =
877 finite_element_pt(0)->node_pt(2);
883 Node_pt[node_count] = finite_element_pt(Nelement[0] - 1)
884 ->construct_boundary_node(3, time_stepper_pt);
888 if (Nelement[1] == 1)
890 add_boundary_node(2, Node_pt[node_count]);
894 add_boundary_node(1, Node_pt[node_count]);
897 set_position_of_boundary_node(
898 Nelement[0], 1,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
901 if (Xperiodic ==
false)
914 for (
unsigned i = 1; i < (Nelement[1] - 1); i++)
921 Element_pt[Nelement[0] * i] =
new ELEMENT;
922 finite_element_pt(Nelement[0] * i)
923 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
926 for (
unsigned l = 0; l < 2; l++)
928 finite_element_pt(Nelement[0] * i)->node_pt(l) =
929 finite_element_pt(Nelement[0] * (i - 1))->node_pt(2 + l);
935 Node_pt[node_count] = finite_element_pt(Nelement[0] * i)
936 ->construct_boundary_node(2, time_stepper_pt);
939 add_boundary_node(3, Node_pt[node_count]);
942 set_position_of_boundary_node(
943 0, i + 1,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
951 if (Nelement[0] == 1)
953 Node_pt[node_count] = finite_element_pt(Nelement[0] * i)
954 ->construct_boundary_node(3, time_stepper_pt);
958 Node_pt[node_count] = finite_element_pt(Nelement[0] * i)
959 ->construct_node(3, time_stepper_pt);
964 if (Nelement[0] == 1)
966 add_boundary_node(1, Node_pt[node_count]);
970 if (Nelement[0] == 1)
971 set_position_of_boundary_node(
972 1, i + 1,
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
974 set_position_of_node(1, i + 1, Node_pt[node_count]);
984 for (
unsigned j = 1; j < (Nelement[0] - 1); j++)
987 Element_pt[Nelement[0] * i + j] =
new ELEMENT;
988 finite_element_pt(Nelement[0] * i + j)
989 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
994 for (
unsigned l = 0; l < 2; l++)
996 finite_element_pt(Nelement[0] * i + j)->node_pt(l) =
997 finite_element_pt(Nelement[0] * (i - 1) + j)->node_pt(2 + l);
1003 finite_element_pt(Nelement[0] * i + j)->node_pt(2) =
1004 finite_element_pt(Nelement[0] * i + (j - 1))->node_pt(3);
1009 Node_pt[node_count] = finite_element_pt(Nelement[0] * i + j)
1010 ->construct_node(3, time_stepper_pt);
1013 set_position_of_node(j + 1, i + 1, Node_pt[node_count]);
1025 if (Nelement[0] > 1)
1028 Element_pt[Nelement[0] * i + Nelement[0] - 1] =
new ELEMENT;
1029 finite_element_pt(Nelement[0] * i + Nelement[0] - 1)
1030 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
1035 for (
unsigned l = 0; l < 2; l++)
1037 finite_element_pt(Nelement[0] * i + Nelement[0] - 1)->node_pt(l) =
1038 finite_element_pt(Nelement[0] * (i - 1) + Nelement[0] - 1)
1045 finite_element_pt(Nelement[0] * i + Nelement[0] - 1)->node_pt(2) =
1046 finite_element_pt(Nelement[0] * i + Nelement[0] - 2)->node_pt(3);
1052 if (Xperiodic ==
true)
1055 finite_element_pt(Nelement[0] * i + Nelement[0] - 1)->node_pt(3) =
1056 finite_element_pt(Nelement[0] * i)->node_pt(2);
1061 Node_pt[node_count] =
1062 finite_element_pt(Nelement[0] * i + Nelement[0] - 1)
1063 ->construct_boundary_node(3, time_stepper_pt);
1067 add_boundary_node(1, Node_pt[node_count]);
1070 set_position_of_boundary_node(
1073 dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
1087 if (Nelement[1] > 1)
1093 Element_pt[Nelement[0] * (Nelement[1] - 1)] =
new ELEMENT;
1094 finite_element_pt(Nelement[0] * (Nelement[1] - 1))
1095 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
1100 for (
unsigned l = 0; l < 2; l++)
1102 finite_element_pt(Nelement[0] * (Nelement[1] - 1))->node_pt(l) =
1103 finite_element_pt(Nelement[0] * (Nelement[1] - 2))->node_pt(2 + l);
1109 Node_pt[node_count] = finite_element_pt(Nelement[0] * (Nelement[1] - 1))
1110 ->construct_boundary_node(2, time_stepper_pt);
1113 add_boundary_node(2, Node_pt[node_count]);
1114 add_boundary_node(3, Node_pt[node_count]);
1117 set_position_of_boundary_node(
1118 0, Nelement[1],
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
1126 Node_pt[node_count] = finite_element_pt(Nelement[0] * (Nelement[1] - 1))
1127 ->construct_boundary_node(3, time_stepper_pt);
1130 add_boundary_node(2, Node_pt[node_count]);
1133 set_position_of_boundary_node(
1134 1, Nelement[1],
dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
1145 for (
unsigned j = 1; j < (Nelement[0] - 1); j++)
1148 Element_pt[Nelement[0] * (Nelement[1] - 1) + j] =
new ELEMENT;
1149 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + j)
1150 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
1155 for (
unsigned l = 0; l < 2; l++)
1157 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + j)->node_pt(l) =
1158 finite_element_pt(Nelement[0] * (Nelement[1] - 2) + j)
1165 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + j)->node_pt(2) =
1166 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + (j - 1))
1172 Node_pt[node_count] =
1173 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + j)
1174 ->construct_boundary_node(3, time_stepper_pt);
1177 add_boundary_node(2, Node_pt[node_count]);
1180 set_position_of_boundary_node(
1183 dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
1195 if (Nelement[0] > 1)
1198 Element_pt[Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 1] =
1200 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 1)
1201 ->set_macro_elem_pt(Domain_pt->macro_element_pt(0));
1206 for (
unsigned l = 0; l < 2; l++)
1208 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 1)
1210 finite_element_pt(Nelement[0] * (Nelement[1] - 2) + Nelement[0] - 1)
1217 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 1)
1219 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 2)
1226 if (Xperiodic ==
true)
1229 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 1)
1231 finite_element_pt(Nelement[0] * (Nelement[1] - 1))->node_pt(2);
1236 Node_pt[node_count] =
1237 finite_element_pt(Nelement[0] * (Nelement[1] - 1) + Nelement[0] - 1)
1238 ->construct_boundary_node(3, time_stepper_pt);
1242 add_boundary_node(1, Node_pt[node_count]);
1243 add_boundary_node(2, Node_pt[node_count]);
1246 set_position_of_boundary_node(
1249 dynamic_cast<BoundaryNode<Node>*
>(Node_pt[node_count]));
1257 setup_boundary_element_info();
1270 template<
class ELEMENT>
1272 std::ostream& outfile)
1275 if (outfile) doc =
true;
1278 unsigned nbound = nboundary();
1281 Boundary_element_pt.clear();
1282 Face_index_at_boundary.clear();
1283 Boundary_element_pt.resize(nbound);
1284 Face_index_at_boundary.resize(nbound);
1287 Vector<Vector<FiniteElement*>> vector_of_boundary_element_pt;
1288 vector_of_boundary_element_pt.resize(nbound);
1291 MapMatrixMixed<unsigned, FiniteElement*, Vector<int>*> boundary_identifier;
1296 unsigned nel = nelement();
1297 for (
unsigned e = 0; e < nel; e++)
1300 FiniteElement* fe_pt = finite_element_pt(e);
1302 if (doc) outfile <<
"Element: " << e <<
" " << fe_pt << std::endl;
1305 if (fe_pt->dim() == 2)
1310 unsigned nnode_1d = fe_pt->nnode_1d();
1313 for (
unsigned i0 = 0; i0 < nnode_1d; i0++)
1315 for (
unsigned i1 = 0; i1 < nnode_1d; i1++)
1318 unsigned j = i0 + i1 * nnode_1d;
1322 std::set<unsigned>* boundaries_pt = 0;
1323 fe_pt->node_pt(j)->get_boundaries_pt(boundaries_pt);
1326 if (boundaries_pt != 0)
1330 for (std::set<unsigned>::iterator it = boundaries_pt->begin();
1331 it != boundaries_pt->end();
1337 unsigned temp_size = vector_of_boundary_element_pt[*it].size();
1338 bool temp_flag =
true;
1339 for (
unsigned temp_i = 0; temp_i < temp_size; temp_i++)
1341 if (vector_of_boundary_element_pt[*it][temp_i] == fe_pt)
1345 vector_of_boundary_element_pt[*it].push_back(fe_pt);
1356 if (boundary_identifier(*it, fe_pt) == 0)
1358 boundary_identifier(*it, fe_pt) =
new Vector<int>;
1362 if (((i0 == 0) || (i0 == nnode_1d - 1)) &&
1363 ((i1 == 0) || (i1 == nnode_1d - 1)))
1366 (*boundary_identifier(*it, fe_pt))
1367 .push_back(1 * (2 * i0 / (nnode_1d - 1) - 1));
1370 (*boundary_identifier(*it, fe_pt))
1371 .push_back(2 * (2 * i1 / (nnode_1d - 1) - 1));
1402 for (
unsigned i = 0; i < nbound; i++)
1405 unsigned nel = vector_of_boundary_element_pt[i].size();
1408 Face_index_at_boundary[i].resize(nel);
1412 unsigned e_count = 0;
1413 typedef Vector<FiniteElement*>::iterator IT;
1414 for (IT it = vector_of_boundary_element_pt[i].begin();
1415 it != vector_of_boundary_element_pt[i].end();
1419 FiniteElement* fe_pt = *it;
1422 std::map<int, unsigned> count;
1425 for (
unsigned ii = 0; ii < 2; ii++)
1428 for (
int sign = -1; sign < 3; sign += 2)
1430 count[(ii + 1) * sign] = 0;
1435 unsigned n_indicators = (*boundary_identifier(i, fe_pt)).size();
1436 for (
unsigned j = 0; j < n_indicators; j++)
1438 count[(*boundary_identifier(i, fe_pt))[j]]++;
1440 delete boundary_identifier(i, fe_pt);
1445 int indicator = -10;
1451 for (
unsigned ii = 0; ii < 2; ii++)
1454 for (
int sign = -1; sign < 3; sign += 2)
1456 if (count[(ii + 1) * sign] == 2)
1461 std::string error_message =
1462 "Trouble: Multiple boundary identifiers!\n";
1463 error_message +=
"Elements should only have at most 2 corner ";
1464 error_message +=
"nodes on any one boundary.\n";
1466 throw OomphLibError(error_message,
1467 OOMPH_CURRENT_FUNCTION,
1468 OOMPH_EXCEPTION_LOCATION);
1471 indicator = (ii + 1) * sign;
1480 Boundary_element_pt[i].push_back(fe_pt);
1489 Face_index_at_boundary[i][e_count] = -2;
1495 Face_index_at_boundary[i][e_count] = -1;
1502 Face_index_at_boundary[i][e_count] = 1;
1508 Face_index_at_boundary[i][e_count] = 2;
1513 throw OomphLibError(
"Never get here",
1514 OOMPH_CURRENT_FUNCTION,
1515 OOMPH_EXCEPTION_LOCATION);
1530 for (
unsigned i = 0; i < nbound; i++)
1532 unsigned nel = Boundary_element_pt[i].size();
1533 outfile <<
"Boundary: " << i <<
" is adjacent to " << nel <<
" elements"
1537 for (
unsigned e = 0; e < nel; e++)
1539 FiniteElement* fe_pt = Boundary_element_pt[i][e];
1540 outfile <<
"Boundary element:" << fe_pt
1541 <<
" Face index of element along boundary is "
1542 << Face_index_at_boundary[i][e] << std::endl;
1549 Lookup_for_elements_next_boundary_is_setup =
true;
void generalised_macro_element_position_of_node(const unsigned &node_num_x, const unsigned &node_num_y, DenseMatrix< double > &m_gen)
computes the generalised position of the node at position (node_num_x, node_num_y) in the macro eleme...
virtual void setup_boundary_element_info()
Setup lookup schemes which establish whic elements are located next to mesh's boundaries (wrapper to ...
void set_position_of_boundary_node(const unsigned &node_num_x, const unsigned &node_num_y, BoundaryNode< Node > *node_pt)
sets the generalised position of the node (i.e. - x_i, dx_i/ds_0, dx_i/ds_1 & d2x_i/ds_0ds_1 for i = ...
void set_position_of_node(const unsigned &node_num_x, const unsigned &node_num_y, Node *node_pt)
sets the generalised position of the node (i.e. - x_i, dx_i/ds_0, dx_i/ds_1 & d2x_i/ds_0ds_1 for i = ...
virtual void build_mesh(TimeStepper *time_stepper_pt)
Generic mesh construction function to build the mesh.
////////////////////////////////////////////////////////////////////// //////////////////////////////...