mesh_tetgen_wrapper.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 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 #include "libmesh/libmesh_config.h" 00019 #ifdef LIBMESH_HAVE_TETGEN 00020 00021 // C++ includes 00022 #include <iostream> 00023 00024 // Local includes 00025 #include "libmesh/libmesh_common.h" 00026 #include "libmesh/mesh_tetgen_wrapper.h" 00027 00028 namespace libMesh 00029 { 00030 // 00031 // TetGenWrapper member functions 00032 // 00033 00034 TetGenWrapper::TetGenWrapper() 00035 { 00036 tetgen_output = new tetgenio; 00037 00038 this->tetgen_data.mesh_dim = 3; 00039 this->tetgen_data.numberofpointattributes = 0; 00040 this->tetgen_data.firstnumber = 0; 00041 } 00042 00043 00044 00045 TetGenWrapper::~TetGenWrapper() 00046 { 00047 delete tetgen_output; 00048 } 00049 00050 00051 00052 void TetGenWrapper::set_node(unsigned i, REAL x, REAL y, REAL z) 00053 { 00054 unsigned index = i*3; 00055 tetgen_data.pointlist[index++] = x; 00056 tetgen_data.pointlist[index++] = y; 00057 tetgen_data.pointlist[index++] = z; 00058 } 00059 00060 00061 00062 void TetGenWrapper::set_hole(unsigned i, REAL x, REAL y, REAL z) 00063 { 00064 unsigned index = i*3; 00065 tetgen_data.holelist[index++] = x; 00066 tetgen_data.holelist[index++] = y; 00067 tetgen_data.holelist[index++] = z; 00068 } 00069 00070 00071 00072 void TetGenWrapper::set_numberofpoints(int i) 00073 { 00074 // This is an int in tetgen, so use an int here even though it should be unsigned 00075 tetgen_data.numberofpoints = i; 00076 } 00077 00078 00079 00080 void TetGenWrapper::get_output_node(unsigned i, REAL& x, REAL& y, REAL& z) 00081 { 00082 // Bounds checking... 00083 if (i >= static_cast<unsigned>(tetgen_output->numberofpoints)) 00084 { 00085 std::cerr << "Error, requested point " 00086 << i 00087 << ", but there are only " 00088 << tetgen_output->numberofpoints 00089 << " points available." 00090 << std::endl; 00091 libmesh_error(); 00092 } 00093 00094 x = tetgen_output->pointlist[3*i]; 00095 y = tetgen_output->pointlist[3*i+1]; 00096 z = tetgen_output->pointlist[3*i+2]; 00097 } 00098 00099 00100 00101 int TetGenWrapper::get_numberoftetrahedra() 00102 { 00103 return tetgen_output->numberoftetrahedra; 00104 } 00105 00106 00107 00108 int TetGenWrapper::get_numberoftrifaces() 00109 { 00110 return tetgen_output->numberoftrifaces; 00111 } 00112 00113 00114 00115 int TetGenWrapper::get_numberofpoints() 00116 { 00117 return tetgen_output->numberofpoints; 00118 } 00119 00120 00121 00122 int TetGenWrapper::get_element_node(unsigned i, unsigned j) 00123 { 00124 return tetgen_output->tetrahedronlist[i*4+j]; 00125 } 00126 00127 00128 00129 int TetGenWrapper::get_triface_node(unsigned i, unsigned j) 00130 { 00131 return tetgen_output->trifacelist[i*3+j]; 00132 } 00133 00134 00135 00136 REAL TetGenWrapper::get_element_attribute(unsigned i) 00137 { 00138 libmesh_assert(tetgen_output->numberoftetrahedronattributes>0); 00139 return tetgen_output->tetrahedronattributelist[tetgen_output->numberoftetrahedronattributes*i]; 00140 } 00141 00142 00143 00144 void TetGenWrapper::allocate_pointlist(int numofpoints) 00145 { 00146 // This is stored as an int in tetgen, so we store it that way as well. 00147 this->set_numberofpoints(numofpoints); 00148 00149 // Don't try to allocate an array of size zero, this is not portable... 00150 if (this->tetgen_data.numberofpoints > 0) 00151 { 00152 // Is there previously-allocated memory here? 00153 if (this->tetgen_data.pointlist != NULL) 00154 { 00155 libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl; 00156 libmesh_error(); 00157 } 00158 00159 // We allocate memory here, the tetgenio destructor will delete it. 00160 this->tetgen_data.pointlist = new REAL[this->tetgen_data.numberofpoints * 3]; 00161 } 00162 } 00163 00164 00165 00166 void TetGenWrapper::set_switches(const std::string& s) 00167 { 00168 // A temporary buffer for passing to the C API, it requires 00169 // a char*, not a const char*... 00170 char buffer[256]; 00171 00172 // Make sure char buffer has enough room 00173 if (s.size() >= sizeof(buffer)-1) 00174 { 00175 libMesh::err << "Fixed size buffer of length " 00176 << sizeof(buffer) 00177 << " not large enough to hold TetGen switches." 00178 << std::endl; 00179 libmesh_error(); 00180 } 00181 00182 // Copy the string, don't forget to NULL-terminate! 00183 buffer[ s.copy( buffer , sizeof( buffer ) - 1 ) ] = '\0' ; 00184 00185 if (!tetgen_be.parse_commandline(buffer)) 00186 libMesh::out << "TetGen replies: Wrong switches!" << std::endl; 00187 } 00188 00189 00190 00191 void TetGenWrapper::run_tetgen() 00192 { 00193 // Call tetrahedralize from the TetGen library. 00194 tetrahedralize(&tetgen_be, &tetgen_data, tetgen_output); 00195 } 00196 00197 00198 00199 void TetGenWrapper::set_numberoffacets(int i) 00200 { 00201 // This is stored as an int in TetGen 00202 this->tetgen_data.numberoffacets = i; 00203 } 00204 00205 00206 00207 void TetGenWrapper::set_numberofholes(int i) 00208 { 00209 // This is stored as an int in TetGen 00210 this->tetgen_data.numberofholes = i; 00211 } 00212 00213 00214 00215 void TetGenWrapper::set_numberofregions(int i) 00216 { 00217 // This is stored as an int in TetGen 00218 this->tetgen_data.numberofregions = i; 00219 } 00220 00221 00222 00223 void TetGenWrapper::allocate_facetlist(int numoffacets, int numofholes) 00224 { 00225 // These are both stored as ints in TetGen 00226 this->set_numberoffacets(numoffacets); 00227 this->set_numberofholes(numofholes); 00228 00229 // Don't try to allocate an array of size zero, this is not portable... 00230 if (this->tetgen_data.numberoffacets > 0) 00231 { 00232 // Is there previously-allocated memory here? 00233 if (this->tetgen_data.facetlist != NULL) 00234 { 00235 libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl; 00236 libmesh_error(); 00237 } 00238 00239 // We allocate memory here, the tetgenio destructor cleans it up. 00240 this->tetgen_data.facetlist = new tetgenio::facet[this->tetgen_data.numberoffacets]; 00241 00242 for (int i=0; i<numoffacets; i++) 00243 this->tetgen_data.init(&(this->tetgen_data.facetlist[i])); 00244 } 00245 00246 00247 // Don't try to allocate an array of size zero, this is not portable... 00248 if (this->tetgen_data.numberofholes > 0) 00249 { 00250 // Is there previously-allocated memory here? 00251 if (this->tetgen_data.holelist != NULL) 00252 { 00253 libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl; 00254 libmesh_error(); 00255 } 00256 00257 this->tetgen_data.holelist = new REAL[this->tetgen_data.numberofholes * 3]; 00258 } 00259 } 00260 00261 00262 00263 void TetGenWrapper::allocate_regionlist(int numofregions) 00264 { 00265 this->set_numberofregions(numofregions); 00266 00267 // Don't try to allocate an array of size zero, this is not portable... 00268 if (this->tetgen_data.numberofregions > 0) 00269 { 00270 // Is there previously-allocated memory here? 00271 if (this->tetgen_data.regionlist != NULL) 00272 { 00273 libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl; 00274 libmesh_error(); 00275 } 00276 00277 // We allocate memory here, the tetgenio destructor cleans it up. 00278 this->tetgen_data.regionlist = new REAL[this->tetgen_data.numberofregions * 5]; 00279 } 00280 } 00281 00282 00283 00284 void TetGenWrapper::set_facet_numberofpolygons(unsigned i, int num) 00285 { 00286 // numberofpolygons is stored as an int in TetGen 00287 this->tetgen_data.facetlist[i].numberofpolygons = num; 00288 } 00289 00290 00291 00292 void TetGenWrapper::set_facet_numberofholes(unsigned i, int num) 00293 { 00294 // numberofholes is stored as an int in TetGen 00295 this->tetgen_data.facetlist[i].numberofholes = num; 00296 } 00297 00298 00299 00300 00301 void TetGenWrapper::allocate_facet_polygonlist(unsigned i, int numofpolygons) 00302 { 00303 this->set_facet_numberofpolygons(i, numofpolygons); 00304 this->set_facet_numberofholes(i, 0); 00305 00306 // Don't try to create an array of size zero, this isn't portable 00307 if (numofpolygons > 0) 00308 { 00309 // Is there previously-allocated memory here? 00310 if (this->tetgen_data.facetlist[i].polygonlist != NULL) 00311 { 00312 libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl; 00313 libmesh_error(); 00314 } 00315 00316 // We allocate memory here, the tetgenio destructor cleans it up. 00317 this->tetgen_data.facetlist[i].polygonlist = new tetgenio::polygon[numofpolygons]; 00318 00319 for (int j=0; j<this->tetgen_data.facetlist[i].numberofpolygons; j++) 00320 this->tetgen_data.init(&(this->tetgen_data.facetlist[i].polygonlist[j])); 00321 } 00322 } 00323 00324 00325 00326 void TetGenWrapper::set_polygon_numberofvertices(unsigned i, unsigned j, int num) 00327 { 00328 // numberofvertices is stored as an int in TetGen 00329 this->tetgen_data.facetlist[i].polygonlist[j].numberofvertices = num; 00330 } 00331 00332 00333 00334 void TetGenWrapper::allocate_polygon_vertexlist(unsigned i, unsigned j, int numofvertices) 00335 { 00336 this->set_polygon_numberofvertices(i, j, numofvertices); 00337 00338 // Don't try to create an array of size zero, this isn't portable 00339 if (numofvertices > 0) 00340 { 00341 // Is there previously-allocated memory here? 00342 if (this->tetgen_data.facetlist[i].polygonlist[j].vertexlist != NULL) 00343 { 00344 libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl; 00345 libmesh_error(); 00346 } 00347 00348 // We allocate memory here, the tetgenio destructor cleans it up. 00349 this->tetgen_data.facetlist[i].polygonlist[j].vertexlist = new int[numofvertices]; 00350 } 00351 } 00352 00353 00354 00355 00356 void TetGenWrapper::set_vertex(unsigned i, unsigned j, unsigned k, int nodeindex) 00357 { 00358 // vertexlist entries are stored as ints in TetGen 00359 this->tetgen_data.facetlist[i].polygonlist[j].vertexlist[k] = nodeindex; 00360 } 00361 00362 00363 00364 void TetGenWrapper::set_region(unsigned i, REAL x, REAL y, REAL z, 00365 REAL attribute, REAL vol_constraint) 00366 { 00367 unsigned index = i*5; 00368 tetgen_data.regionlist[index++] = x; 00369 tetgen_data.regionlist[index++] = y; 00370 tetgen_data.regionlist[index++] = z; 00371 tetgen_data.regionlist[index++] = attribute; 00372 tetgen_data.regionlist[index++] = vol_constraint; 00373 } 00374 00375 } // namespace libMesh 00376 00377 00378 #endif // LIBMESH_HAVE_TETGEN
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:47 UTC
Hosted By: