29 #ifndef OOMPH_QUAD_FROM_TRIANGLE_MESH_TEMPLATE_CC 30 #define OOMPH_QUAD_FROM_TRIANGLE_MESH_TEMPLATE_CC 36 using namespace oomph;
74 template<
class ELEMENT>
77 const bool &use_attributes)
80 unsigned nelem=tmp_mesh_pt->
nelement();
83 Element_pt.resize(3*nelem);
90 set_nboundary(nbound);
94 Boundary_element_pt.resize(nbound);
95 Face_index_at_boundary.resize(nbound);
98 ELEMENT* temp_el_pt=
new ELEMENT;
101 unsigned nnode_el=temp_el_pt->nnode();
104 unsigned nnode_1d=temp_el_pt->nnode_1d();
108 unsigned nnode_edge=2*nnode_1d-1;
123 unsigned n_position_type=1;
126 unsigned initial_n_value=0;
129 for (
unsigned j=0;j<4;j++)
131 dummy_element.node_pt(j)=
new Node(n_dim,n_position_type,initial_n_value);
136 unsigned corner_1=nnode_1d-1;
137 unsigned corner_2=nnode_el-nnode_1d;
138 unsigned corner_3=nnode_el-1;
148 std::map<Edge,Vector<Node*> > edge_nodes_map;
153 std::map<Node*,Node*> scaffold_to_quad_mesh_node;
156 unsigned new_el_count=0;
165 for (
unsigned e=0;
e<nelem;
e++)
172 for (
unsigned j=0;j<3;j++)
176 triangle_vertex[j].resize(2);
187 triangle_vertex[j][0]=x;
188 triangle_vertex[j][1]=y;
198 ELEMENT* el0_pt=
new ELEMENT;
199 ELEMENT* el1_pt=
new ELEMENT;
200 ELEMENT* el2_pt=
new ELEMENT;
206 el_vector_pt[0]=el0_pt;
207 el_vector_pt[1]=el1_pt;
208 el_vector_pt[2]=el2_pt;
217 for (
unsigned j=0;j<3;j++)
223 Node* qmesh_node_pt=scaffold_to_quad_mesh_node[scaffold_node_pt];
226 if (qmesh_node_pt==0)
230 std::set<unsigned>* boundaries_pt;
234 if (boundaries_pt!=0)
239 qmesh_node_pt=el_vector_pt[j]->construct_boundary_node(corner_0,
243 for (std::set<unsigned>::iterator it=boundaries_pt->begin();
244 it!=boundaries_pt->end();++it)
246 add_boundary_node(*it,qmesh_node_pt);
253 qmesh_node_pt=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);
354 unsigned q0_lower_boundary_id=0;
355 unsigned q0_left_boundary_id=0;
356 unsigned q1_lower_boundary_id=0;
357 unsigned q1_left_boundary_id=0;
358 unsigned q2_lower_boundary_id=0;
359 unsigned q2_left_boundary_id=0;
381 boundary_id_vector[0]=q0_lower_boundary_id;
382 boundary_id_vector[1]=q0_left_boundary_id;
383 boundary_id_vector[2]=q1_lower_boundary_id;
384 boundary_id_vector[3]=q1_left_boundary_id;
385 boundary_id_vector[4]=q2_lower_boundary_id;
386 boundary_id_vector[5]=q2_left_boundary_id;
390 for (
unsigned j=0;j<3;j++)
393 for (
unsigned k=0;k<2;k++)
396 if (boundary_id_vector[2*j+k]>0)
400 Boundary_element_pt[boundary_id_vector[2*j+k]-1].
401 push_back(el_vector_pt[j]);
413 Face_index_at_boundary[boundary_id_vector[2*j+k]-1].push_back(-2);
417 Face_index_at_boundary[boundary_id_vector[2*j+k]-1].push_back(-1);
429 Node* nod_pt=el0_pt->construct_node(corner_3,time_stepper_pt);
432 Node_pt.push_back(nod_pt);
435 el0_pt->node_pt(corner_3)->
x(0)=centroid[0];
436 el0_pt->node_pt(corner_3)->x(1)=centroid[1];
439 el1_pt->node_pt(corner_3)=el0_pt->node_pt(corner_3);
442 el2_pt->node_pt(corner_3)=el0_pt->node_pt(corner_3);
449 dummy_element.node_pt(0)->x(0)=triangle_vertex[0][0];
450 dummy_element.node_pt(0)->x(1)=triangle_vertex[0][1];
453 dummy_element.node_pt(1)->x(0)=
454 0.5*(triangle_vertex[0][0]+triangle_vertex[1][0]);
455 dummy_element.node_pt(1)->x(1)=
456 0.5*(triangle_vertex[0][1]+triangle_vertex[1][1]);
459 dummy_element.node_pt(2)->x(0)=
460 0.5*(triangle_vertex[0][0]+triangle_vertex[2][0]);
461 dummy_element.node_pt(2)->x(1)=
462 0.5*(triangle_vertex[0][1]+triangle_vertex[2][1]);
465 dummy_element.node_pt(3)->x(0)=centroid[0];
466 dummy_element.node_pt(3)->x(1)=centroid[1];
478 for (
unsigned j=1;j<corner_3;j++)
493 el0_pt->node_pt(j)=edge0_vector_pt[(nnode_edge-1)-j];
504 if (q0_lower_boundary_id>0)
507 Node* nod_pt=el0_pt->construct_boundary_node(j,time_stepper_pt);
510 add_boundary_node(q0_lower_boundary_id-1,nod_pt);
513 edge0_vector_pt[j]=nod_pt;
516 Node_pt.push_back(nod_pt);
527 Node* nod_pt=el0_pt->construct_node(j,time_stepper_pt);
530 edge0_vector_pt[j]=nod_pt;
533 Node_pt.push_back(nod_pt);
540 else if (j%nnode_1d==0)
548 el0_pt->node_pt(j)=edge2_vector_pt[j/nnode_1d];
557 if (q0_left_boundary_id>0)
560 Node* nod_pt=el0_pt->construct_boundary_node(j,time_stepper_pt);
563 add_boundary_node(q0_left_boundary_id-1,nod_pt);
566 edge2_vector_pt[(nnode_edge-1)-(j/nnode_1d)]=nod_pt;
569 Node_pt.push_back(nod_pt);
580 Node* nod_pt=el0_pt->construct_node(j,time_stepper_pt);
583 edge2_vector_pt[(nnode_edge-1)-(j/nnode_1d)]=nod_pt;
586 Node_pt.push_back(nod_pt);
597 Node* nod_pt=el0_pt->construct_node(j,time_stepper_pt);
600 Node_pt.push_back(nod_pt);
604 el0_pt->local_coordinate_of_node(j,s);
607 dummy_element.interpolated_x(s,x);
608 el0_pt->node_pt(j)->x(0)=x[0];
609 el0_pt->node_pt(j)->x(1)=x[1];
620 dummy_element.node_pt(0)->x(0)=triangle_vertex[1][0];
621 dummy_element.node_pt(0)->x(1)=triangle_vertex[1][1];
624 dummy_element.node_pt(1)->x(0)=
625 0.5*(triangle_vertex[1][0]+triangle_vertex[2][0]);
626 dummy_element.node_pt(1)->x(1)=
627 0.5*(triangle_vertex[1][1]+triangle_vertex[2][1]);
630 dummy_element.node_pt(2)->x(0)=
631 0.5*(triangle_vertex[0][0]+triangle_vertex[1][0]);
632 dummy_element.node_pt(2)->x(1)=
633 0.5*(triangle_vertex[0][1]+triangle_vertex[1][1]);
644 for (
unsigned j=1;j<corner_2;j++)
659 el1_pt->node_pt(j)=edge1_vector_pt[(nnode_edge-1)-j];
670 if (q1_lower_boundary_id>0)
673 Node* nod_pt=el1_pt->construct_boundary_node(j,time_stepper_pt);
676 add_boundary_node(q1_lower_boundary_id-1,nod_pt);
679 edge1_vector_pt[j]=nod_pt;
682 Node_pt.push_back(nod_pt);
693 Node* nod_pt=el1_pt->construct_node(j,time_stepper_pt);
696 edge1_vector_pt[j]=nod_pt;
699 Node_pt.push_back(nod_pt);
706 else if (j%nnode_1d==0)
714 el1_pt->node_pt(j)=edge0_vector_pt[j/nnode_1d];
723 if (q1_left_boundary_id>0)
726 Node* nod_pt=el1_pt->construct_boundary_node(j,time_stepper_pt);
729 add_boundary_node(q1_left_boundary_id-1,nod_pt);
732 edge0_vector_pt[(nnode_edge-1)-(j/nnode_1d)]=nod_pt;
735 Node_pt.push_back(nod_pt);
746 Node* nod_pt=el1_pt->construct_node(j,time_stepper_pt);
749 edge0_vector_pt[(nnode_edge-1)-(j/nnode_1d)]=nod_pt;
752 Node_pt.push_back(nod_pt);
763 Node* nod_pt=el1_pt->construct_node(j,time_stepper_pt);
766 Node_pt.push_back(nod_pt);
770 el1_pt->local_coordinate_of_node(j,s);
773 dummy_element.interpolated_x(s,x);
774 el1_pt->node_pt(j)->x(0)=x[0];
775 el1_pt->node_pt(j)->x(1)=x[1];
782 for (
unsigned j=corner_2;j<corner_3;j++)
787 el1_pt->node_pt(j)=el0_pt->node_pt(corner_1+(j-corner_2)*nnode_1d);
798 dummy_element.node_pt(0)->x(0)=triangle_vertex[2][0];
799 dummy_element.node_pt(0)->x(1)=triangle_vertex[2][1];
802 dummy_element.node_pt(1)->x(0)=
803 0.5*(triangle_vertex[0][0]+triangle_vertex[2][0]);
804 dummy_element.node_pt(1)->x(1)=
805 0.5*(triangle_vertex[0][1]+triangle_vertex[2][1]);
808 dummy_element.node_pt(2)->x(0)=
809 0.5*(triangle_vertex[1][0]+triangle_vertex[2][0]);
810 dummy_element.node_pt(2)->x(1)=
811 0.5*(triangle_vertex[1][1]+triangle_vertex[2][1]);
822 for (
unsigned j=1;j<corner_2;j++)
837 el2_pt->node_pt(j)=edge2_vector_pt[(nnode_edge-1)-j];
848 if (q2_lower_boundary_id>0)
851 Node* nod_pt=el2_pt->construct_boundary_node(j,time_stepper_pt);
854 add_boundary_node(q2_lower_boundary_id-1,nod_pt);
857 edge2_vector_pt[j]=nod_pt;
860 Node_pt.push_back(nod_pt);
871 Node* nod_pt=el2_pt->construct_node(j,time_stepper_pt);
874 edge2_vector_pt[j]=nod_pt;
877 Node_pt.push_back(nod_pt);
884 else if ((j+1)%nnode_1d==0)
887 el2_pt->node_pt(j)=el0_pt->node_pt((corner_2-1)+(j+1)/nnode_1d);
894 else if (j%nnode_1d==0)
902 el2_pt->node_pt(j)=edge1_vector_pt[j/nnode_1d];
911 if (q2_left_boundary_id>0)
914 Node* nod_pt=el2_pt->construct_boundary_node(j,time_stepper_pt);
917 add_boundary_node(q2_left_boundary_id-1,nod_pt);
920 edge1_vector_pt[(nnode_edge-1)-(j/nnode_1d)]=nod_pt;
923 Node_pt.push_back(nod_pt);
934 Node* nod_pt=el2_pt->construct_node(j,time_stepper_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);
954 Node_pt.push_back(nod_pt);
958 el2_pt->local_coordinate_of_node(j,s);
961 dummy_element.interpolated_x(s,x);
962 el2_pt->node_pt(j)->x(0)=x[0];
963 el2_pt->node_pt(j)->x(1)=x[1];
969 for (
unsigned j=corner_2;j<corner_3;j++)
974 el2_pt->node_pt(j)=el1_pt->node_pt(corner_1+(j-corner_2)*nnode_1d);
978 Element_pt[new_el_count]=el0_pt;
979 Element_pt[new_el_count+1]=el1_pt;
980 Element_pt[new_el_count+2]=el2_pt;
984 edge_nodes_map[edge0]=edge0_vector_pt;
985 edge_nodes_map[edge1]=edge1_vector_pt;
986 edge_nodes_map[edge2]=edge2_vector_pt;
990 Lookup_for_elements_next_boundary_is_setup=
true;
993 for (
unsigned j=0;j<4;j++)
996 delete dummy_element.node_pt(j);
999 dummy_element.node_pt(j)=0;
1014 template <
class ELEMENT>
1019 TreeBasedRefineableMeshBase::adapt(elem_error);
1021 #ifdef OOMPH_HAS_TRIANGLE_LIB 1025 this->snap_nodes_onto_geometric_objects();
1030 #endif // OOMPH_QUAD_FROM_TRIANGLE_MESH_TEMPLATE_CC
Triangle Mesh that is based on input files generated by the triangle mesh generator Triangle...
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned long nelement() const
Return number of elements in the mesh.
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...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Unstructured refineable QuadFromTriangleMesh.
unsigned nboundary() const
Return number of boundaries.
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...
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).
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...