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>
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;
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;
163 for (
unsigned e = 0;
e < nelem;
e++)
170 for (
unsigned j = 0; j < 3; j++)
174 triangle_vertex[j].resize(2);
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;
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++)
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;
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];
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;
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>
1036 TreeBasedRefineableMeshBase::adapt(elem_error);
1038 #ifdef OOMPH_HAS_TRIANGLE_LIB
1042 this->snap_nodes_onto_geometric_objects();
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
unsigned nboundary() const
Return number of boundaries.
unsigned long nelement() const
Return number of elements in the mesh.
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.
virtual void get_boundaries_pt(std::set< unsigned > *&boundaries_pt)
Return a pointer to set of mesh boundaries that this node occupies; this will be overloaded by Bounda...
Quad mesh built on top of triangle scaffold mesh coming from the triangle mesh generator Triangle....
///////////////////////////////////////////////////////////////// ///////////////////////////////////...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Triangle Mesh that is based on input files generated by the triangle mesh generator Triangle.
unsigned edge_boundary(const unsigned &e, const unsigned &i) const
Return the boundary id of the i-th edge in the e-th element: This is zero-based as in triangle....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...