$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 #include "libmesh/libmesh_config.h" 00020 00021 #ifdef LIBMESH_HAVE_TRIANGLE 00022 00023 // Local includes 00024 #include "libmesh/mesh_triangle_wrapper.h" 00025 #include "libmesh/unstructured_mesh.h" 00026 #include "libmesh/point.h" 00027 #include "libmesh/face_tri3.h" 00028 #include "libmesh/face_tri6.h" 00029 00030 namespace libMesh 00031 { 00032 00033 void TriangleWrapper::init(TriangleWrapper::triangulateio& t) 00034 { 00035 t.pointlist = static_cast<REAL*>(NULL); 00036 t.pointattributelist = static_cast<REAL*>(NULL); 00037 t.pointmarkerlist = static_cast<int* >(NULL); 00038 t.numberofpoints = 0 ; 00039 t.numberofpointattributes = 0 ; 00040 00041 t.trianglelist = static_cast<int* >(NULL); 00042 t.triangleattributelist = static_cast<REAL*>(NULL); 00043 t.trianglearealist = static_cast<REAL*>(NULL); 00044 t.neighborlist = static_cast<int* >(NULL); 00045 t.numberoftriangles = 0; 00046 t.numberofcorners = 0; 00047 t.numberoftriangleattributes = 0; 00048 00049 t.segmentlist = static_cast<int* >(NULL); 00050 t.segmentmarkerlist = static_cast<int* >(NULL); 00051 t.numberofsegments = 0; 00052 00053 t.holelist = static_cast<REAL*>(NULL); 00054 t.numberofholes = 0; 00055 00056 t.regionlist = static_cast<REAL*>(NULL); 00057 t.numberofregions = 0; 00058 00059 t.edgelist = static_cast<int* >(NULL); 00060 t.edgemarkerlist = static_cast<int* >(NULL); 00061 t.normlist = static_cast<REAL*>(NULL); 00062 t.numberofedges = 0; 00063 } 00064 00065 00066 00067 00068 00069 00070 void TriangleWrapper::destroy(TriangleWrapper::triangulateio& t, TriangleWrapper::IO_Type io_type) 00071 { 00072 std::free (t.pointlist ); 00073 std::free (t.pointattributelist ); 00074 std::free (t.pointmarkerlist ); 00075 std::free (t.trianglelist ); 00076 std::free (t.triangleattributelist); 00077 std::free (t.trianglearealist ); 00078 std::free (t.neighborlist ); 00079 std::free (t.segmentlist ); 00080 std::free (t.segmentmarkerlist ); 00081 00082 // Only attempt to free these when t was used as an input struct! 00083 if (io_type==INPUT) 00084 { 00085 std::free (t.holelist ); 00086 std::free (t.regionlist); 00087 } 00088 00089 std::free (t.edgelist ); 00090 std::free (t.edgemarkerlist); 00091 std::free (t.normlist ); 00092 00093 // Reset 00094 // TriangleWrapper::init(t); 00095 } 00096 00097 00098 00099 00100 00101 00102 void TriangleWrapper::copy_tri_to_mesh(const triangulateio& triangle_data_input, 00103 UnstructuredMesh& mesh_output, 00104 const ElemType type) 00105 { 00106 // Transfer the information into the LibMesh mesh. 00107 mesh_output.clear(); 00108 00109 // Make sure the new Mesh will be 2D 00110 mesh_output.set_mesh_dimension(2); 00111 00112 // Node information 00113 for (int i=0, c=0; c<triangle_data_input.numberofpoints; i+=2, ++c) 00114 { 00115 // Specify ID when adding point, otherwise, if this is ParallelMesh, 00116 // it might add points with a non-sequential numbering... 00117 mesh_output.add_point( Point(triangle_data_input.pointlist[i], 00118 triangle_data_input.pointlist[i+1]), 00119 /*id=*/c); 00120 } 00121 00122 // Element information 00123 for (int i=0; i<triangle_data_input.numberoftriangles; ++i) 00124 { 00125 switch (type) 00126 { 00127 case TRI3: 00128 { 00129 Elem* elem = mesh_output.add_elem (new Tri3); 00130 00131 for (unsigned int n=0; n<3; ++n) 00132 elem->set_node(n) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*3 + n]); 00133 00134 break; 00135 } 00136 00137 case TRI6: 00138 { 00139 Elem* elem = mesh_output.add_elem (new Tri6); 00140 00141 // Triangle number TRI6 nodes in a different way to libMesh 00142 elem->set_node(0) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 0]); 00143 elem->set_node(1) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 1]); 00144 elem->set_node(2) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 2]); 00145 elem->set_node(3) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 5]); 00146 elem->set_node(4) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 3]); 00147 elem->set_node(5) = mesh_output.node_ptr(triangle_data_input.trianglelist[i*6 + 4]); 00148 00149 break; 00150 } 00151 00152 default: 00153 libmesh_error_msg("ERROR: Unrecognized triangular element type."); 00154 } 00155 } 00156 00157 // Note: If the input mesh was a parallel one, calling 00158 // prepare_for_use() now will re-parallelize it by a call to 00159 // delete_remote_elements()... We do not actually want to 00160 // reparallelize it here though: the triangulate() function may 00161 // still do some Mesh smoothing. The main thing needed (for 00162 // smoothing) is the neighbor information, so let's just find 00163 // neighbors... 00164 //mesh_output.prepare_for_use(/*skip_renumber =*/false); 00165 mesh_output.find_neighbors(); 00166 } 00167 00168 00169 } 00170 00171 #endif // LIBMESH_HAVE_TRIANGLE