mesh_tetgen_wrapper.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #include "libmesh/libmesh_config.h"
19 #ifdef LIBMESH_HAVE_TETGEN
20 
21 // C++ includes
22 #include <iostream>
23 
24 // Local includes
25 #include "libmesh/libmesh_common.h"
27 
28 namespace libMesh
29 {
30  //
31  // TetGenWrapper member functions
32  //
33 
35  {
36  tetgen_output = new tetgenio;
37 
38  this->tetgen_data.mesh_dim = 3;
39  this->tetgen_data.numberofpointattributes = 0;
40  this->tetgen_data.firstnumber = 0;
41  }
42 
43 
44 
46  {
47  delete tetgen_output;
48  }
49 
50 
51 
52  void TetGenWrapper::set_node(unsigned i, REAL x, REAL y, REAL z)
53  {
54  unsigned index = i*3;
55  tetgen_data.pointlist[index++] = x;
56  tetgen_data.pointlist[index++] = y;
57  tetgen_data.pointlist[index++] = z;
58  }
59 
60 
61 
62  void TetGenWrapper::set_hole(unsigned i, REAL x, REAL y, REAL z)
63  {
64  unsigned index = i*3;
65  tetgen_data.holelist[index++] = x;
66  tetgen_data.holelist[index++] = y;
67  tetgen_data.holelist[index++] = z;
68  }
69 
70 
71 
73  {
74  // This is an int in tetgen, so use an int here even though it should be unsigned
75  tetgen_data.numberofpoints = i;
76  }
77 
78 
79 
80  void TetGenWrapper::get_output_node(unsigned i, REAL& x, REAL& y, REAL& z)
81  {
82  // Bounds checking...
83  if (i >= static_cast<unsigned>(tetgen_output->numberofpoints))
84  {
85  libMesh::err << "Error, requested point "
86  << i
87  << ", but there are only "
88  << tetgen_output->numberofpoints
89  << " points available."
90  << std::endl;
91  libmesh_error();
92  }
93 
94  x = tetgen_output->pointlist[3*i];
95  y = tetgen_output->pointlist[3*i+1];
96  z = tetgen_output->pointlist[3*i+2];
97  }
98 
99 
100 
102  {
103  return tetgen_output->numberoftetrahedra;
104  }
105 
106 
107 
109  {
110  return tetgen_output->numberoftrifaces;
111  }
112 
113 
114 
116  {
117  return tetgen_output->numberofpoints;
118  }
119 
120 
121 
122  int TetGenWrapper::get_element_node(unsigned i, unsigned j)
123  {
124  return tetgen_output->tetrahedronlist[i*4+j];
125  }
126 
127 
128 
129  int TetGenWrapper::get_triface_node(unsigned i, unsigned j)
130  {
131  return tetgen_output->trifacelist[i*3+j];
132  }
133 
134 
135 
137  {
138  libmesh_assert(tetgen_output->numberoftetrahedronattributes>0);
139  return tetgen_output->tetrahedronattributelist[tetgen_output->numberoftetrahedronattributes*i];
140  }
141 
142 
143 
144  void TetGenWrapper::allocate_pointlist(int numofpoints)
145  {
146  // This is stored as an int in tetgen, so we store it that way as well.
147  this->set_numberofpoints(numofpoints);
148 
149  // Don't try to allocate an array of size zero, this is not portable...
150  if (this->tetgen_data.numberofpoints > 0)
151  {
152  // Is there previously-allocated memory here?
153  if (this->tetgen_data.pointlist != NULL)
154  {
155  libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl;
156  libmesh_error();
157  }
158 
159  // We allocate memory here, the tetgenio destructor will delete it.
160  this->tetgen_data.pointlist = new REAL[this->tetgen_data.numberofpoints * 3];
161  }
162  }
163 
164 
165 
166  void TetGenWrapper::set_switches(const std::string& s)
167  {
168  // A temporary buffer for passing to the C API, it requires
169  // a char*, not a const char*...
170  char buffer[256];
171 
172  // Make sure char buffer has enough room
173  if (s.size() >= sizeof(buffer)-1)
174  {
175  libMesh::err << "Fixed size buffer of length "
176  << sizeof(buffer)
177  << " not large enough to hold TetGen switches."
178  << std::endl;
179  libmesh_error();
180  }
181 
182  // Copy the string, don't forget to NULL-terminate!
183  buffer[ s.copy( buffer , sizeof( buffer ) - 1 ) ] = '\0' ;
184 
185  if (!tetgen_be.parse_commandline(buffer))
186  libMesh::out << "TetGen replies: Wrong switches!" << std::endl;
187  }
188 
189 
190 
192  {
193  // Call tetrahedralize from the TetGen library.
194  tetrahedralize(&tetgen_be, &tetgen_data, tetgen_output);
195  }
196 
197 
198 
200  {
201  // This is stored as an int in TetGen
202  this->tetgen_data.numberoffacets = i;
203  }
204 
205 
206 
208  {
209  // This is stored as an int in TetGen
210  this->tetgen_data.numberofholes = i;
211  }
212 
213 
214 
216  {
217  // This is stored as an int in TetGen
218  this->tetgen_data.numberofregions = i;
219  }
220 
221 
222 
223  void TetGenWrapper::allocate_facetlist(int numoffacets, int numofholes)
224  {
225  // These are both stored as ints in TetGen
226  this->set_numberoffacets(numoffacets);
227  this->set_numberofholes(numofholes);
228 
229  // Don't try to allocate an array of size zero, this is not portable...
230  if (this->tetgen_data.numberoffacets > 0)
231  {
232  // Is there previously-allocated memory here?
233  if (this->tetgen_data.facetlist != NULL)
234  {
235  libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl;
236  libmesh_error();
237  }
238 
239  // We allocate memory here, the tetgenio destructor cleans it up.
240  this->tetgen_data.facetlist = new tetgenio::facet[this->tetgen_data.numberoffacets];
241 
242  for (int i=0; i<numoffacets; i++)
243  this->tetgen_data.init(&(this->tetgen_data.facetlist[i]));
244  }
245 
246 
247  // Don't try to allocate an array of size zero, this is not portable...
248  if (this->tetgen_data.numberofholes > 0)
249  {
250  // Is there previously-allocated memory here?
251  if (this->tetgen_data.holelist != NULL)
252  {
253  libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl;
254  libmesh_error();
255  }
256 
257  this->tetgen_data.holelist = new REAL[this->tetgen_data.numberofholes * 3];
258  }
259  }
260 
261 
262 
263  void TetGenWrapper::allocate_regionlist(int numofregions)
264  {
265  this->set_numberofregions(numofregions);
266 
267  // Don't try to allocate an array of size zero, this is not portable...
268  if (this->tetgen_data.numberofregions > 0)
269  {
270  // Is there previously-allocated memory here?
271  if (this->tetgen_data.regionlist != NULL)
272  {
273  libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl;
274  libmesh_error();
275  }
276 
277  // We allocate memory here, the tetgenio destructor cleans it up.
278  this->tetgen_data.regionlist = new REAL[this->tetgen_data.numberofregions * 5];
279  }
280  }
281 
282 
283 
285  {
286  // numberofpolygons is stored as an int in TetGen
287  this->tetgen_data.facetlist[i].numberofpolygons = num;
288  }
289 
290 
291 
292  void TetGenWrapper::set_facet_numberofholes(unsigned i, int num)
293  {
294  // numberofholes is stored as an int in TetGen
295  this->tetgen_data.facetlist[i].numberofholes = num;
296  }
297 
298 
299 
300 
301  void TetGenWrapper::allocate_facet_polygonlist(unsigned i, int numofpolygons)
302  {
303  this->set_facet_numberofpolygons(i, numofpolygons);
304  this->set_facet_numberofholes(i, 0);
305 
306  // Don't try to create an array of size zero, this isn't portable
307  if (numofpolygons > 0)
308  {
309  // Is there previously-allocated memory here?
310  if (this->tetgen_data.facetlist[i].polygonlist != NULL)
311  {
312  libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl;
313  libmesh_error();
314  }
315 
316  // We allocate memory here, the tetgenio destructor cleans it up.
317  this->tetgen_data.facetlist[i].polygonlist = new tetgenio::polygon[numofpolygons];
318 
319  for (int j=0; j<this->tetgen_data.facetlist[i].numberofpolygons; j++)
320  this->tetgen_data.init(&(this->tetgen_data.facetlist[i].polygonlist[j]));
321  }
322  }
323 
324 
325 
326  void TetGenWrapper::set_polygon_numberofvertices(unsigned i, unsigned j, int num)
327  {
328  // numberofvertices is stored as an int in TetGen
329  this->tetgen_data.facetlist[i].polygonlist[j].numberofvertices = num;
330  }
331 
332 
333 
334  void TetGenWrapper::allocate_polygon_vertexlist(unsigned i, unsigned j, int numofvertices)
335  {
336  this->set_polygon_numberofvertices(i, j, numofvertices);
337 
338  // Don't try to create an array of size zero, this isn't portable
339  if (numofvertices > 0)
340  {
341  // Is there previously-allocated memory here?
342  if (this->tetgen_data.facetlist[i].polygonlist[j].vertexlist != NULL)
343  {
344  libMesh::err << "Cannot allocate on top of previously allocated memory!" << std::endl;
345  libmesh_error();
346  }
347 
348  // We allocate memory here, the tetgenio destructor cleans it up.
349  this->tetgen_data.facetlist[i].polygonlist[j].vertexlist = new int[numofvertices];
350  }
351  }
352 
353 
354 
355 
356  void TetGenWrapper::set_vertex(unsigned i, unsigned j, unsigned k, int nodeindex)
357  {
358  // vertexlist entries are stored as ints in TetGen
359  this->tetgen_data.facetlist[i].polygonlist[j].vertexlist[k] = nodeindex;
360  }
361 
362 
363 
364  void TetGenWrapper::set_region(unsigned i, REAL x, REAL y, REAL z,
365  REAL attribute, REAL vol_constraint)
366  {
367  unsigned index = i*5;
368  tetgen_data.regionlist[index++] = x;
369  tetgen_data.regionlist[index++] = y;
370  tetgen_data.regionlist[index++] = z;
371  tetgen_data.regionlist[index++] = attribute;
372  tetgen_data.regionlist[index++] = vol_constraint;
373  }
374 
375 } // namespace libMesh
376 
377 
378 #endif // LIBMESH_HAVE_TETGEN

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:06 UTC

Hosted By:
SourceForge.net Logo