27 #ifndef OOMPH_QUAD_FROM_TRIANGLE_MESH_TEMPLATE_CC
28 #define OOMPH_QUAD_FROM_TRIANGLE_MESH_TEMPLATE_CC
34 using namespace oomph;
70 template<
class ELEMENT>
72 TriangleScaffoldMesh* tmp_mesh_pt,
73 TimeStepper* time_stepper_pt,
74 const bool& use_attributes)
77 unsigned nelem = tmp_mesh_pt->nelement();
80 Element_pt.resize(3 * nelem);
83 unsigned nbound = tmp_mesh_pt->nboundary();
87 set_nboundary(nbound);
91 Boundary_element_pt.resize(nbound);
92 Face_index_at_boundary.resize(nbound);
95 ELEMENT* temp_el_pt =
new ELEMENT;
98 unsigned nnode_el = temp_el_pt->nnode();
101 unsigned nnode_1d = temp_el_pt->nnode_1d();
105 unsigned nnode_edge = 2 * nnode_1d - 1;
114 QElement<2, 2> dummy_element;
120 unsigned n_position_type = 1;
123 unsigned initial_n_value = 0;
126 for (
unsigned j = 0; j < 4; j++)
128 dummy_element.node_pt(j) =
129 new Node(n_dim, n_position_type, initial_n_value);
133 unsigned corner_0 = 0;
134 unsigned corner_1 = nnode_1d - 1;
135 unsigned corner_2 = nnode_el - nnode_1d;
136 unsigned corner_3 = nnode_el - 1;
146 std::map<Edge, Vector<Node*>> edge_nodes_map;
151 std::map<Node*, Node*> scaffold_to_quad_mesh_node;
154 unsigned new_el_count = 0;
157 Vector<double> centroid(2);
160 Vector<Vector<double>> triangle_vertex(3);
163 for (
unsigned e = 0; e < nelem; e++)
170 for (
unsigned j = 0; j < 3; j++)
174 triangle_vertex[j].resize(2);
177 double x = tmp_mesh_pt->finite_element_pt(e)->node_pt(j)->x(0);
178 double y = tmp_mesh_pt->finite_element_pt(e)->node_pt(j)->x(1);
185 triangle_vertex[j][0] = x;
186 triangle_vertex[j][1] = y;
196 ELEMENT* el0_pt =
new ELEMENT;
197 ELEMENT* el1_pt =
new ELEMENT;
198 ELEMENT* el2_pt =
new ELEMENT;
201 Vector<ELEMENT*> el_vector_pt(3, 0);
204 el_vector_pt[0] = el0_pt;
205 el_vector_pt[1] = el1_pt;
206 el_vector_pt[2] = el2_pt;
215 for (
unsigned j = 0; j < 3; j++)
218 Node* scaffold_node_pt = tmp_mesh_pt->finite_element_pt(e)->node_pt(j);
221 Node* qmesh_node_pt = scaffold_to_quad_mesh_node[scaffold_node_pt];
224 if (qmesh_node_pt == 0)
228 std::set<unsigned>* boundaries_pt;
229 scaffold_node_pt->get_boundaries_pt(boundaries_pt);
232 if (boundaries_pt != 0)
237 qmesh_node_pt = el_vector_pt[j]->construct_boundary_node(
238 corner_0, time_stepper_pt);
241 for (std::set<unsigned>::iterator it = boundaries_pt->begin();
242 it != boundaries_pt->end();
245 add_boundary_node(*it, qmesh_node_pt);
253 el_vector_pt[j]->construct_node(corner_0, time_stepper_pt);
257 scaffold_to_quad_mesh_node[scaffold_node_pt] = qmesh_node_pt;
263 Node_pt.push_back(qmesh_node_pt);
268 el_vector_pt[j]->node_pt(corner_0) = qmesh_node_pt;
273 el_vector_pt[j]->node_pt(corner_0)->x(0) = triangle_vertex[j][0];
274 el_vector_pt[j]->node_pt(corner_0)->x(1) = triangle_vertex[j][1];
282 Edge edge0(tmp_mesh_pt->finite_element_pt(e)->node_pt(0),
283 tmp_mesh_pt->finite_element_pt(e)->node_pt(1));
284 Edge edge1(tmp_mesh_pt->finite_element_pt(e)->node_pt(1),
285 tmp_mesh_pt->finite_element_pt(e)->node_pt(2));
286 Edge edge2(tmp_mesh_pt->finite_element_pt(e)->node_pt(2),
287 tmp_mesh_pt->finite_element_pt(e)->node_pt(0));
291 Vector<Node*> edge0_vector_pt = edge_nodes_map[edge0];
292 Vector<Node*> edge1_vector_pt = edge_nodes_map[edge1];
293 Vector<Node*> edge2_vector_pt = edge_nodes_map[edge2];
296 bool edge0_setup = (edge0_vector_pt.size() != 0);
297 bool edge1_setup = (edge1_vector_pt.size() != 0);
298 bool edge2_setup = (edge2_vector_pt.size() != 0);
304 edge0_vector_pt.resize(nnode_edge, 0);
307 edge0_vector_pt[0] = el_vector_pt[0]->node_pt(0);
310 edge0_vector_pt[nnode_edge - 1] = el_vector_pt[1]->node_pt(0);
317 edge1_vector_pt.resize(nnode_edge, 0);
320 edge1_vector_pt[0] = el_vector_pt[1]->node_pt(0);
323 edge1_vector_pt[nnode_edge - 1] = el_vector_pt[2]->node_pt(0);
330 edge2_vector_pt.resize(nnode_edge, 0);
333 edge2_vector_pt[0] = el_vector_pt[2]->node_pt(0);
336 edge2_vector_pt[nnode_edge - 1] = el_vector_pt[0]->node_pt(0);
355 unsigned q0_lower_boundary_id = 0;
356 unsigned q0_left_boundary_id = 0;
357 unsigned q1_lower_boundary_id = 0;
358 unsigned q1_left_boundary_id = 0;
359 unsigned q2_lower_boundary_id = 0;
360 unsigned q2_left_boundary_id = 0;
365 q0_lower_boundary_id = tmp_mesh_pt->edge_boundary(e, 0);
366 q0_left_boundary_id = tmp_mesh_pt->edge_boundary(e, 2);
371 q1_lower_boundary_id = tmp_mesh_pt->edge_boundary(e, 1);
372 q1_left_boundary_id = tmp_mesh_pt->edge_boundary(e, 0);
377 q2_lower_boundary_id = tmp_mesh_pt->edge_boundary(e, 2);
378 q2_left_boundary_id = tmp_mesh_pt->edge_boundary(e, 1);
381 Vector<unsigned> boundary_id_vector(6, 0);
382 boundary_id_vector[0] = q0_lower_boundary_id;
383 boundary_id_vector[1] = q0_left_boundary_id;
384 boundary_id_vector[2] = q1_lower_boundary_id;
385 boundary_id_vector[3] = q1_left_boundary_id;
386 boundary_id_vector[4] = q2_lower_boundary_id;
387 boundary_id_vector[5] = q2_left_boundary_id;
391 for (
unsigned j = 0; j < 3; j++)
394 for (
unsigned k = 0; k < 2; k++)
397 if (boundary_id_vector[2 * j + k] > 0)
402 Boundary_element_pt[boundary_id_vector[2 * j + k] - 1].push_back(
415 Face_index_at_boundary[boundary_id_vector[2 * j + k] - 1]
420 Face_index_at_boundary[boundary_id_vector[2 * j + k] - 1]
433 Node* nod_pt = el0_pt->construct_node(corner_3, time_stepper_pt);
436 Node_pt.push_back(nod_pt);
439 el0_pt->node_pt(corner_3)->x(0) = centroid[0];
440 el0_pt->node_pt(corner_3)->x(1) = centroid[1];
443 el1_pt->node_pt(corner_3) = el0_pt->node_pt(corner_3);
446 el2_pt->node_pt(corner_3) = el0_pt->node_pt(corner_3);
453 dummy_element.node_pt(0)->x(0) = triangle_vertex[0][0];
454 dummy_element.node_pt(0)->x(1) = triangle_vertex[0][1];
457 dummy_element.node_pt(1)->x(0) =
458 0.5 * (triangle_vertex[0][0] + triangle_vertex[1][0]);
459 dummy_element.node_pt(1)->x(1) =
460 0.5 * (triangle_vertex[0][1] + triangle_vertex[1][1]);
463 dummy_element.node_pt(2)->x(0) =
464 0.5 * (triangle_vertex[0][0] + triangle_vertex[2][0]);
465 dummy_element.node_pt(2)->x(1) =
466 0.5 * (triangle_vertex[0][1] + triangle_vertex[2][1]);
469 dummy_element.node_pt(3)->x(0) = centroid[0];
470 dummy_element.node_pt(3)->x(1) = centroid[1];
482 for (
unsigned j = 1; j < corner_3; j++)
497 el0_pt->node_pt(j) = edge0_vector_pt[(nnode_edge - 1) - j];
508 if (q0_lower_boundary_id > 0)
512 el0_pt->construct_boundary_node(j, time_stepper_pt);
515 add_boundary_node(q0_lower_boundary_id - 1, nod_pt);
518 edge0_vector_pt[j] = nod_pt;
521 Node_pt.push_back(nod_pt);
532 Node* nod_pt = el0_pt->construct_node(j, time_stepper_pt);
535 edge0_vector_pt[j] = nod_pt;
538 Node_pt.push_back(nod_pt);
545 else if (j % nnode_1d == 0)
553 el0_pt->node_pt(j) = edge2_vector_pt[j / nnode_1d];
562 if (q0_left_boundary_id > 0)
566 el0_pt->construct_boundary_node(j, time_stepper_pt);
569 add_boundary_node(q0_left_boundary_id - 1, nod_pt);
573 edge2_vector_pt[(nnode_edge - 1) - (j / nnode_1d)] = nod_pt;
576 Node_pt.push_back(nod_pt);
587 Node* nod_pt = el0_pt->construct_node(j, time_stepper_pt);
591 edge2_vector_pt[(nnode_edge - 1) - (j / nnode_1d)] = nod_pt;
594 Node_pt.push_back(nod_pt);
605 Node* nod_pt = el0_pt->construct_node(j, time_stepper_pt);
608 Node_pt.push_back(nod_pt);
612 el0_pt->local_coordinate_of_node(j, s);
615 dummy_element.interpolated_x(s, x);
616 el0_pt->node_pt(j)->x(0) = x[0];
617 el0_pt->node_pt(j)->x(1) = x[1];
628 dummy_element.node_pt(0)->x(0) = triangle_vertex[1][0];
629 dummy_element.node_pt(0)->x(1) = triangle_vertex[1][1];
632 dummy_element.node_pt(1)->x(0) =
633 0.5 * (triangle_vertex[1][0] + triangle_vertex[2][0]);
634 dummy_element.node_pt(1)->x(1) =
635 0.5 * (triangle_vertex[1][1] + triangle_vertex[2][1]);
638 dummy_element.node_pt(2)->x(0) =
639 0.5 * (triangle_vertex[0][0] + triangle_vertex[1][0]);
640 dummy_element.node_pt(2)->x(1) =
641 0.5 * (triangle_vertex[0][1] + triangle_vertex[1][1]);
652 for (
unsigned j = 1; j < corner_2; j++)
667 el1_pt->node_pt(j) = edge1_vector_pt[(nnode_edge - 1) - j];
678 if (q1_lower_boundary_id > 0)
682 el1_pt->construct_boundary_node(j, time_stepper_pt);
685 add_boundary_node(q1_lower_boundary_id - 1, nod_pt);
688 edge1_vector_pt[j] = nod_pt;
691 Node_pt.push_back(nod_pt);
702 Node* nod_pt = el1_pt->construct_node(j, time_stepper_pt);
705 edge1_vector_pt[j] = nod_pt;
708 Node_pt.push_back(nod_pt);
715 else if (j % nnode_1d == 0)
723 el1_pt->node_pt(j) = edge0_vector_pt[j / nnode_1d];
732 if (q1_left_boundary_id > 0)
736 el1_pt->construct_boundary_node(j, time_stepper_pt);
739 add_boundary_node(q1_left_boundary_id - 1, nod_pt);
743 edge0_vector_pt[(nnode_edge - 1) - (j / nnode_1d)] = nod_pt;
746 Node_pt.push_back(nod_pt);
757 Node* nod_pt = el1_pt->construct_node(j, time_stepper_pt);
761 edge0_vector_pt[(nnode_edge - 1) - (j / nnode_1d)] = nod_pt;
764 Node_pt.push_back(nod_pt);
775 Node* nod_pt = el1_pt->construct_node(j, time_stepper_pt);
778 Node_pt.push_back(nod_pt);
782 el1_pt->local_coordinate_of_node(j, s);
785 dummy_element.interpolated_x(s, x);
786 el1_pt->node_pt(j)->x(0) = x[0];
787 el1_pt->node_pt(j)->x(1) = x[1];
794 for (
unsigned j = corner_2; j < corner_3; j++)
800 el0_pt->node_pt(corner_1 + (j - corner_2) * nnode_1d);
811 dummy_element.node_pt(0)->x(0) = triangle_vertex[2][0];
812 dummy_element.node_pt(0)->x(1) = triangle_vertex[2][1];
815 dummy_element.node_pt(1)->x(0) =
816 0.5 * (triangle_vertex[0][0] + triangle_vertex[2][0]);
817 dummy_element.node_pt(1)->x(1) =
818 0.5 * (triangle_vertex[0][1] + triangle_vertex[2][1]);
821 dummy_element.node_pt(2)->x(0) =
822 0.5 * (triangle_vertex[1][0] + triangle_vertex[2][0]);
823 dummy_element.node_pt(2)->x(1) =
824 0.5 * (triangle_vertex[1][1] + triangle_vertex[2][1]);
835 for (
unsigned j = 1; j < corner_2; j++)
841 if (j < nnode_1d - 1)
850 el2_pt->node_pt(j) = edge2_vector_pt[(nnode_edge - 1) - j];
861 if (q2_lower_boundary_id > 0)
865 el2_pt->construct_boundary_node(j, time_stepper_pt);
868 add_boundary_node(q2_lower_boundary_id - 1, nod_pt);
871 edge2_vector_pt[j] = nod_pt;
874 Node_pt.push_back(nod_pt);
885 Node* nod_pt = el2_pt->construct_node(j, time_stepper_pt);
888 edge2_vector_pt[j] = nod_pt;
891 Node_pt.push_back(nod_pt);
898 else if ((j + 1) % nnode_1d == 0)
902 el0_pt->node_pt((corner_2 - 1) + (j + 1) / nnode_1d);
909 else if (j % nnode_1d == 0)
917 el2_pt->node_pt(j) = edge1_vector_pt[j / nnode_1d];
926 if (q2_left_boundary_id > 0)
930 el2_pt->construct_boundary_node(j, time_stepper_pt);
933 add_boundary_node(q2_left_boundary_id - 1, nod_pt);
937 edge1_vector_pt[(nnode_edge - 1) - (j / nnode_1d)] = nod_pt;
940 Node_pt.push_back(nod_pt);
951 Node* nod_pt = el2_pt->construct_node(j, time_stepper_pt);
955 edge1_vector_pt[(nnode_edge - 1) - (j / nnode_1d)] = nod_pt;
958 Node_pt.push_back(nod_pt);
969 Node* nod_pt = el2_pt->construct_node(j, time_stepper_pt);
972 Node_pt.push_back(nod_pt);
976 el2_pt->local_coordinate_of_node(j, s);
979 dummy_element.interpolated_x(s, x);
980 el2_pt->node_pt(j)->x(0) = x[0];
981 el2_pt->node_pt(j)->x(1) = x[1];
987 for (
unsigned j = corner_2; j < corner_3; j++)
993 el1_pt->node_pt(corner_1 + (j - corner_2) * nnode_1d);
997 Element_pt[new_el_count] = el0_pt;
998 Element_pt[new_el_count + 1] = el1_pt;
999 Element_pt[new_el_count + 2] = el2_pt;
1003 edge_nodes_map[edge0] = edge0_vector_pt;
1004 edge_nodes_map[edge1] = edge1_vector_pt;
1005 edge_nodes_map[edge2] = edge2_vector_pt;
1009 Lookup_for_elements_next_boundary_is_setup =
true;
1012 for (
unsigned j = 0; j < 4; j++)
1015 delete dummy_element.node_pt(j);
1018 dummy_element.node_pt(j) = 0;
1031 template<
class ELEMENT>
1033 const Vector<double>& elem_error)
1036 TreeBasedRefineableMeshBase::adapt(elem_error);
1038 #ifdef OOMPH_HAS_TRIANGLE_LIB
1042 this->snap_nodes_onto_geometric_objects();
Quad mesh built on top of triangle scaffold mesh coming from the triangle mesh generator Triangle....
///////////////////////////////////////////////////////////////// ///////////////////////////////////...
////////////////////////////////////////////////////////////////////// //////////////////////////////...