gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
meshRefine.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 //
6 // Contributor(s):
7 // Brian Helenbrook
8 //
9 
10 #include "GModel.h"
11 #include "HighOrder.h"
12 #include "MLine.h"
13 #include "MTriangle.h"
14 #include "MQuadrangle.h"
15 #include "MTetrahedron.h"
16 #include "MHexahedron.h"
17 #include "MPrism.h"
18 #include "MPyramid.h"
19 #include "GmshMessage.h"
20 #include "OS.h"
21 #include "meshGFaceOptimize.h"
22 #include "Generator.h"
23 #include "Context.h"
24 
25 typedef std::map<MFace, std::vector<MVertex *>, MFaceLessThan> faceContainer;
26 
28  faceContainer &faceVertices,
29  std::vector<MHexahedron *> &dwarfs88);
30 
32  bool operator()(const MVertex *v1, const MVertex *v2) const
33  {
34  double u1 = 0., u2 = 1.;
35  v1->getParameter(0, u1);
36  v2->getParameter(0, u2);
37  return u1 < u2;
38  }
39 };
40 
41 // Set BM data on vertex
42 static void setBLData(MVertex *v)
43 {
44  switch(v->onWhat()->dim()) {
45  case 1: {
46  MEdgeVertex *ve = dynamic_cast<MEdgeVertex *>(v);
47  if(ve) ve->bl_data = new MVertexBoundaryLayerData();
48  break;
49  }
50  case 2: {
51  MFaceVertex *vf = dynamic_cast<MFaceVertex *>(v);
52  if(vf) vf->bl_data = new MVertexBoundaryLayerData();
53  break;
54  }
55  }
56 }
57 
58 // If all low-order nodes in are marked as BL, then mark high-order nodes as BL
59 // (only works in 2D)
60 static bool setBLData(MElement *el)
61 {
62  // Check whether all low-order nodes are marked as BL nodes (only works in 2D)
63  for(std::size_t i = 0; i < el->getNumPrimaryVertices(); i++) {
64  MVertex *v = el->getVertex(i);
65  bool isBL = false;
66  switch(v->onWhat()->dim()) {
67  case 0: isBL = true; break;
68  case 1: {
69  MEdgeVertex *ve = dynamic_cast<MEdgeVertex *>(v);
70  if(ve && ve->bl_data) isBL = true;
71  break;
72  }
73  case 2: {
74  MFaceVertex *vf = dynamic_cast<MFaceVertex *>(v);
75  if(vf && vf->bl_data) isBL = true;
76  break;
77  }
78  }
79  if(!isBL) return false;
80  }
81  // Mark high-order nodes as BL nodes (only works in 2D)
82  for(std::size_t i = el->getNumPrimaryVertices(); i < el->getNumVertices();
83  i++)
84  setBLData(el->getVertex(i));
85  return true;
86 }
87 
88 static void Subdivide(GEdge *ge)
89 {
90  std::vector<MLine *> lines2;
91  for(std::size_t i = 0; i < ge->lines.size(); i++) {
92  MLine *l = ge->lines[i];
93  if(l->getNumVertices() == 3) {
94  lines2.push_back(new MLine(l->getVertex(0), l->getVertex(2)));
95  lines2.push_back(new MLine(l->getVertex(2), l->getVertex(1)));
96  setBLData(l);
97  }
98  delete l;
99  }
100  ge->lines = lines2;
101 
102  // 2nd order meshing destroyed the ordering of the vertices on the edge
103  std::sort(ge->mesh_vertices.begin(), ge->mesh_vertices.end(),
105  for(std::size_t i = 0; i < ge->mesh_vertices.size(); i++)
106  ge->mesh_vertices[i]->setPolynomialOrder(1);
109  ge->correspondingHighOrderVertices.clear();
110  ge->deleteVertexArrays();
111 }
112 
113 static void Subdivide(GFace *gf, bool splitIntoQuads, bool splitIntoHexas,
114  faceContainer &faceVertices, bool linear)
115 {
116  if(!splitIntoQuads && !splitIntoHexas) {
117  std::vector<MTriangle *> triangles2;
118  for(std::size_t i = 0; i < gf->triangles.size(); i++) {
119  MTriangle *t = gf->triangles[i];
120  if(t->getNumVertices() == 6) {
121  triangles2.push_back(
122  new MTriangle(t->getVertex(0), t->getVertex(3), t->getVertex(5)));
123  triangles2.push_back(
124  new MTriangle(t->getVertex(3), t->getVertex(4), t->getVertex(5)));
125  triangles2.push_back(
126  new MTriangle(t->getVertex(3), t->getVertex(1), t->getVertex(4)));
127  triangles2.push_back(
128  new MTriangle(t->getVertex(5), t->getVertex(4), t->getVertex(2)));
129  setBLData(t);
130  }
131  delete t;
132  }
133  gf->triangles = triangles2;
134  }
135 
136  std::vector<MQuadrangle *> quadrangles2;
137  for(std::size_t i = 0; i < gf->quadrangles.size(); i++) {
138  MQuadrangle *q = gf->quadrangles[i];
139  if(q->getNumVertices() == 9) {
140  quadrangles2.push_back(new MQuadrangle(q->getVertex(0), q->getVertex(4),
141  q->getVertex(8), q->getVertex(7)));
142  quadrangles2.push_back(new MQuadrangle(q->getVertex(4), q->getVertex(1),
143  q->getVertex(5), q->getVertex(8)));
144  quadrangles2.push_back(new MQuadrangle(q->getVertex(8), q->getVertex(5),
145  q->getVertex(2), q->getVertex(6)));
146  quadrangles2.push_back(new MQuadrangle(q->getVertex(7), q->getVertex(8),
147  q->getVertex(6), q->getVertex(3)));
148  setBLData(q);
149  }
150  delete q;
151  }
152  if(splitIntoQuads || splitIntoHexas) {
153  for(std::size_t i = 0; i < gf->triangles.size(); i++) {
154  MTriangle *t = gf->triangles[i];
155  if(t->getNumVertices() == 6) {
156  MVertex *newv;
157  if(linear) {
158  SPoint3 ptx;
159  t->pnt(1. / 3., 1. / 3., 0., ptx); // is the barycenter
160  newv = new MVertex(ptx.x(), ptx.y(), ptx.z(), gf);
161  }
162  else {
163  SPoint3 ctr = t->barycenter();
164  const double pp[2] = {0.5, 0.5}; // should be improved...
165  GPoint gp = gf->closestPoint(ctr, pp); // orthogonal projection
166  newv = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, gp.u(), gp.v());
167  }
168  gf->mesh_vertices.push_back(newv);
169  if(splitIntoHexas) faceVertices[t->getFace(0)].push_back(newv);
170  quadrangles2.push_back(new MQuadrangle(t->getVertex(0), t->getVertex(3),
171  newv, t->getVertex(5)));
172  quadrangles2.push_back(new MQuadrangle(t->getVertex(3), t->getVertex(1),
173  t->getVertex(4), newv));
174  quadrangles2.push_back(new MQuadrangle(
175  t->getVertex(5), newv, t->getVertex(4), t->getVertex(2)));
176  if(setBLData(t)) setBLData(newv);
177  }
178  delete t;
179  }
180  gf->triangles.clear();
181  }
182  gf->quadrangles = quadrangles2;
183 
184  for(std::size_t i = 0; i < gf->mesh_vertices.size(); i++)
185  gf->mesh_vertices[i]->setPolynomialOrder(1);
188  gf->correspondingHighOrderVertices.clear();
189  gf->deleteVertexArrays();
190 }
191 
192 static void Subdivide(GRegion *gr, bool splitIntoHexas,
193  faceContainer &faceVertices)
194 {
195  if(!splitIntoHexas) {
196  // Split tets into other tets
197  std::vector<MTetrahedron *> tetrahedra2;
198  for(std::size_t i = 0; i < gr->tetrahedra.size(); i++) {
199  MTetrahedron *t = gr->tetrahedra[i];
200  // Use a template that maximizes the quality, which is a modification of
201  // Algorithm RedRefinement3D in: Bey, Jürgen. "Simplicial grid refinement:
202  // on Freudenthal's algorithm and the optimal number of congruence
203  // classes." Numerische Mathematik 85.1 (2000): 1-29. Contributed by Jose
204  // Paulo Moitinho de Almeida, April 2019.
205  if(t->getNumVertices() == 10) {
206  tetrahedra2.push_back(new MTetrahedron(
207  t->getVertex(0), t->getVertex(4), t->getVertex(6), t->getVertex(7)));
208  tetrahedra2.push_back(new MTetrahedron(
209  t->getVertex(4), t->getVertex(1), t->getVertex(5), t->getVertex(9)));
210  tetrahedra2.push_back(new MTetrahedron(
211  t->getVertex(6), t->getVertex(5), t->getVertex(2), t->getVertex(8)));
212  tetrahedra2.push_back(new MTetrahedron(
213  t->getVertex(7), t->getVertex(9), t->getVertex(8), t->getVertex(3)));
214  tetrahedra2.push_back(new MTetrahedron(
215  t->getVertex(4), t->getVertex(6), t->getVertex(7), t->getVertex(9)));
216  tetrahedra2.push_back(new MTetrahedron(
217  t->getVertex(4), t->getVertex(9), t->getVertex(5), t->getVertex(6)));
218  tetrahedra2.push_back(new MTetrahedron(
219  t->getVertex(6), t->getVertex(7), t->getVertex(9), t->getVertex(8)));
220  tetrahedra2.push_back(new MTetrahedron(
221  t->getVertex(6), t->getVertex(8), t->getVertex(9), t->getVertex(5)));
222  setBLData(t);
223  }
224  delete t;
225  }
226  gr->tetrahedra = tetrahedra2;
227  }
228 
229  // Split hexes into other hexes.
230  std::vector<MHexahedron *> hexahedra2;
231  for(std::size_t i = 0; i < gr->hexahedra.size(); i++) {
232  MHexahedron *h = gr->hexahedra[i];
233  if(h->getNumVertices() == 27) {
234  hexahedra2.push_back(new MHexahedron(h->getVertex(0), h->getVertex(8),
235  h->getVertex(20), h->getVertex(9),
236  h->getVertex(10), h->getVertex(21),
237  h->getVertex(26), h->getVertex(22)));
238  hexahedra2.push_back(new MHexahedron(
239  h->getVertex(10), h->getVertex(21), h->getVertex(26), h->getVertex(22),
240  h->getVertex(4), h->getVertex(16), h->getVertex(25), h->getVertex(17)));
241  hexahedra2.push_back(new MHexahedron(h->getVertex(8), h->getVertex(1),
242  h->getVertex(11), h->getVertex(20),
243  h->getVertex(21), h->getVertex(12),
244  h->getVertex(23), h->getVertex(26)));
245  hexahedra2.push_back(new MHexahedron(
246  h->getVertex(21), h->getVertex(12), h->getVertex(23), h->getVertex(26),
247  h->getVertex(16), h->getVertex(5), h->getVertex(18), h->getVertex(25)));
248  hexahedra2.push_back(new MHexahedron(h->getVertex(9), h->getVertex(20),
249  h->getVertex(13), h->getVertex(3),
250  h->getVertex(22), h->getVertex(26),
251  h->getVertex(24), h->getVertex(15)));
252  hexahedra2.push_back(new MHexahedron(
253  h->getVertex(22), h->getVertex(26), h->getVertex(24), h->getVertex(15),
254  h->getVertex(17), h->getVertex(25), h->getVertex(19), h->getVertex(7)));
255  hexahedra2.push_back(new MHexahedron(h->getVertex(20), h->getVertex(11),
256  h->getVertex(2), h->getVertex(13),
257  h->getVertex(26), h->getVertex(23),
258  h->getVertex(14), h->getVertex(24)));
259  hexahedra2.push_back(new MHexahedron(
260  h->getVertex(26), h->getVertex(23), h->getVertex(14), h->getVertex(24),
261  h->getVertex(25), h->getVertex(18), h->getVertex(6), h->getVertex(19)));
262  setBLData(h);
263  }
264  delete h;
265  }
266 
267  // Split tets into other hexes.
268  if(splitIntoHexas) {
269  for(std::size_t i = 0; i < gr->tetrahedra.size(); i++) {
270  MTetrahedron *t = gr->tetrahedra[i];
271  if(t->getNumVertices() == 10) {
272  std::vector<MVertex *> newv;
273  for(int j = 0; j < t->getNumFaces(); j++) {
274  MFace face = t->getFace(j);
275  auto fIter = faceVertices.find(face);
276  if(fIter != faceVertices.end()) { newv.push_back(fIter->second[0]); }
277  else {
278  SPoint3 pc = face.barycenter();
279  newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
280  faceVertices[face].push_back(newv.back());
281  gr->mesh_vertices.push_back(newv.back());
282  }
283  }
284  SPoint3 pc = t->barycenter();
285  newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
286  gr->mesh_vertices.push_back(newv.back());
287  hexahedra2.push_back(new MHexahedron(
288  t->getVertex(0), t->getVertex(4), newv[0], t->getVertex(6),
289  t->getVertex(7), newv[1], newv[4], newv[2]));
290  hexahedra2.push_back(
291  new MHexahedron(t->getVertex(4), t->getVertex(1), t->getVertex(5),
292  newv[0], newv[1], t->getVertex(9), newv[3], newv[4]));
293  hexahedra2.push_back(new MHexahedron(
294  t->getVertex(6), newv[0], t->getVertex(5), t->getVertex(2), newv[2],
295  newv[4], newv[3], t->getVertex(8)));
296  hexahedra2.push_back(new MHexahedron(
297  t->getVertex(3), t->getVertex(9), newv[1], t->getVertex(7),
298  t->getVertex(8), newv[3], newv[4], newv[2]));
299  if(setBLData(t)) {
300  setBLData(newv[0]);
301  setBLData(newv[1]);
302  setBLData(newv[2]);
303  setBLData(newv[3]);
304  setBLData(newv[4]);
305  }
306  }
307  delete t;
308  }
309  gr->tetrahedra.clear();
310 
311  for(std::size_t i = 0; i < gr->prisms.size(); i++) {
312  MPrism *p = gr->prisms[i];
313  if(p->getNumVertices() == 18) {
314  std::vector<MVertex *> newv;
315  for(int j = 0; j < 2; j++) {
316  MFace face = p->getFace(j);
317  auto fIter = faceVertices.find(face);
318  if(fIter != faceVertices.end()) { newv.push_back(fIter->second[0]); }
319  else {
320  SPoint3 pc = face.barycenter();
321  newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
322  faceVertices[face].push_back(newv.back());
323  gr->mesh_vertices.push_back(newv.back());
324  }
325  }
326  SPoint3 pc = p->barycenter();
327  newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
328  gr->mesh_vertices.push_back(newv.back());
329  hexahedra2.push_back(new MHexahedron(
330  p->getVertex(0), p->getVertex(6), newv[0], p->getVertex(7),
331  p->getVertex(8), p->getVertex(15), newv[2], p->getVertex(16)));
332  hexahedra2.push_back(new MHexahedron(
333  p->getVertex(1), p->getVertex(9), newv[0], p->getVertex(6),
334  p->getVertex(10), p->getVertex(17), newv[2], p->getVertex(15)));
335  hexahedra2.push_back(new MHexahedron(
336  p->getVertex(2), p->getVertex(7), newv[0], p->getVertex(9),
337  p->getVertex(11), p->getVertex(16), newv[2], p->getVertex(17)));
338  hexahedra2.push_back(new MHexahedron(
339  p->getVertex(8), p->getVertex(15), newv[2], p->getVertex(16),
340  p->getVertex(3), p->getVertex(12), newv[1], p->getVertex(13)));
341  hexahedra2.push_back(new MHexahedron(
342  p->getVertex(10), p->getVertex(17), newv[2], p->getVertex(15),
343  p->getVertex(4), p->getVertex(14), newv[1], p->getVertex(12)));
344  hexahedra2.push_back(new MHexahedron(
345  p->getVertex(11), p->getVertex(16), newv[2], p->getVertex(17),
346  p->getVertex(5), p->getVertex(13), newv[1], p->getVertex(14)));
347  if(setBLData(p)) {
348  setBLData(newv[0]);
349  setBLData(newv[1]);
350  setBLData(newv[2]);
351  }
352  }
353  delete p;
354  }
355  gr->prisms.clear();
356 
357  // Yamakawa subdivision of a pyramid into 88 hexes (thanks to Tristan
358  // Carrier Baudouin!)
359  std::vector<MHexahedron *> dwarfs88;
360  for(std::size_t i = 0; i < gr->pyramids.size(); i++) {
361  MPyramid *p = gr->pyramids[i];
362  if(p->getNumVertices() == 14) {
363  subdivide_pyramid(p, gr, faceVertices, dwarfs88);
364  for(int j = 0; j < 88; j++) hexahedra2.push_back(dwarfs88[j]);
365  }
366  delete p;
367  }
368  gr->pyramids.clear();
369  }
370  gr->hexahedra = hexahedra2;
371 
372  std::vector<MPrism *> prisms2;
373  for(std::size_t i = 0; i < gr->prisms.size(); i++) {
374  MPrism *p = gr->prisms[i];
375  if(p->getNumVertices() == 18) {
376  prisms2.push_back(new MPrism(p->getVertex(0), p->getVertex(6),
377  p->getVertex(7), p->getVertex(8),
378  p->getVertex(15), p->getVertex(16)));
379  prisms2.push_back(new MPrism(p->getVertex(8), p->getVertex(15),
380  p->getVertex(16), p->getVertex(3),
381  p->getVertex(12), p->getVertex(13)));
382  prisms2.push_back(new MPrism(p->getVertex(6), p->getVertex(1),
383  p->getVertex(9), p->getVertex(15),
384  p->getVertex(10), p->getVertex(17)));
385  prisms2.push_back(new MPrism(p->getVertex(15), p->getVertex(10),
386  p->getVertex(17), p->getVertex(12),
387  p->getVertex(4), p->getVertex(14)));
388  prisms2.push_back(new MPrism(p->getVertex(7), p->getVertex(9),
389  p->getVertex(2), p->getVertex(16),
390  p->getVertex(17), p->getVertex(11)));
391  prisms2.push_back(new MPrism(p->getVertex(16), p->getVertex(17),
392  p->getVertex(11), p->getVertex(13),
393  p->getVertex(14), p->getVertex(5)));
394  prisms2.push_back(new MPrism(p->getVertex(9), p->getVertex(7),
395  p->getVertex(6), p->getVertex(17),
396  p->getVertex(16), p->getVertex(15)));
397  prisms2.push_back(new MPrism(p->getVertex(17), p->getVertex(16),
398  p->getVertex(15), p->getVertex(14),
399  p->getVertex(13), p->getVertex(12)));
400  setBLData(p);
401  }
402  delete p;
403  }
404  gr->prisms = prisms2;
405 
406  std::vector<MPyramid *> pyramids2;
407  for(std::size_t i = 0; i < gr->pyramids.size(); i++) {
408  if(splitIntoHexas) {
409  Msg::Error("Full hexahedron subdivision is not implemented for pyramids");
410  return;
411  }
412  MPyramid *p = gr->pyramids[i];
413  if(p->getNumVertices() == 14) {
414  // Base
415  pyramids2.push_back(new MPyramid(p->getVertex(0), p->getVertex(5),
416  p->getVertex(13), p->getVertex(6),
417  p->getVertex(7)));
418  pyramids2.push_back(new MPyramid(p->getVertex(5), p->getVertex(1),
419  p->getVertex(8), p->getVertex(13),
420  p->getVertex(9)));
421  pyramids2.push_back(new MPyramid(p->getVertex(13), p->getVertex(8),
422  p->getVertex(2), p->getVertex(10),
423  p->getVertex(11)));
424  pyramids2.push_back(new MPyramid(p->getVertex(6), p->getVertex(13),
425  p->getVertex(10), p->getVertex(3),
426  p->getVertex(12)));
427 
428  // Split remaining into tets
429  // Top
430  gr->tetrahedra.push_back((new MTetrahedron(
431  p->getVertex(7), p->getVertex(9), p->getVertex(12), p->getVertex(4))));
432  gr->tetrahedra.push_back((new MTetrahedron(
433  p->getVertex(9), p->getVertex(11), p->getVertex(12), p->getVertex(4))));
434 
435  // Upside down one
436  gr->tetrahedra.push_back(
437  (new MTetrahedron(p->getVertex(9), p->getVertex(12), p->getVertex(11),
438  p->getVertex(13))));
439  gr->tetrahedra.push_back((new MTetrahedron(
440  p->getVertex(7), p->getVertex(12), p->getVertex(9), p->getVertex(13))));
441 
442  // Four tets around bottom perimeter
443  gr->tetrahedra.push_back((new MTetrahedron(
444  p->getVertex(7), p->getVertex(9), p->getVertex(5), p->getVertex(13))));
445  gr->tetrahedra.push_back((new MTetrahedron(
446  p->getVertex(9), p->getVertex(11), p->getVertex(8), p->getVertex(13))));
447  gr->tetrahedra.push_back(
448  (new MTetrahedron(p->getVertex(12), p->getVertex(10), p->getVertex(11),
449  p->getVertex(13))));
450  gr->tetrahedra.push_back((new MTetrahedron(
451  p->getVertex(7), p->getVertex(6), p->getVertex(12), p->getVertex(13))));
452  setBLData(p);
453  }
454  delete p;
455  }
456  gr->pyramids = pyramids2;
457 
458  for(std::size_t i = 0; i < gr->mesh_vertices.size(); i++)
459  gr->mesh_vertices[i]->setPolynomialOrder(1);
460  gr->deleteVertexArrays();
461 }
462 
463 void RefineMesh(GModel *m, bool linear, bool splitIntoQuads,
464  bool splitIntoHexas)
465 {
466  Msg::StatusBar(true, "Refining mesh...");
467  double t1 = Cpu(), w1 = TimeOfDay();
468 
469  // Create 2nd order mesh (using "2nd order complete" elements) to
470  // generate vertex positions
471  SetOrderN(m, 2, linear, false);
472 
473  // Optimize high order elements
474  if(CTX::instance()->mesh.hoOptimize == 2 ||
475  CTX::instance()->mesh.hoOptimize == 3)
476  OptimizeMesh(m, "HighOrderElastic");
477 
478  if(CTX::instance()->mesh.hoOptimize == 1 ||
479  CTX::instance()->mesh.hoOptimize == 2)
480  OptimizeMesh(m, "HighOrder");
481 
482  if(CTX::instance()->mesh.hoOptimize == 4)
483  OptimizeMesh(m, "HighOrderFastCurving");
484 
485  // store periodic node correspondences
486  FixPeriodicMesh(m);
487 
488  // only used when splitting tets into hexes
489  faceContainer faceVertices;
490 
491  // Subdivide the second order elements to create the refined linear
492  // mesh
493  for(auto it = m->firstEdge(); it != m->lastEdge(); ++it) Subdivide(*it);
494  for(auto it = m->firstFace(); it != m->lastFace(); ++it)
495  Subdivide(*it, splitIntoQuads, splitIntoHexas, faceVertices, linear);
496  for(auto it = m->firstRegion(); it != m->lastRegion(); ++it)
497  Subdivide(*it, splitIntoHexas, faceVertices);
498 
499  // Check all 3D elements for negative volume and reverse if needed
501 
502  double t2 = Cpu(), w2 = TimeOfDay();
503  Msg::StatusBar(true, "Done refining mesh (Wall %gs, CPU %gs)", w2 - w1,
504  t2 - t1);
505 }
506 
508 {
509  Msg::StatusBar(true, "Barycentrically refining mesh...");
510  double t1 = Cpu(), w1 = TimeOfDay();
511 
512  m->destroyMeshCaches();
513 
514  // Only update triangles in 2D, only update tets in 3D
515  if(m->getNumRegions() == 0) {
516  for(auto it = m->firstFace(); it != m->lastFace(); ++it) {
517  GFace *gf = *it;
518  std::size_t numt = gf->triangles.size();
519  if(!numt) continue;
520  std::vector<MTriangle *> triangles2(3 * numt);
521  for(std::size_t i = 0; i < numt; i++) {
522  MTriangle *t = gf->triangles[i];
523  SPoint3 bary = t->barycenter();
524  // FIXME: create an MFaceVertex (with correct parametric coordinates)?
525  MVertex *v = new MVertex(bary.x(), bary.y(), bary.z(), gf);
526  triangles2[3 * i] = new MTriangle(t->getVertex(0), t->getVertex(1), v);
527  triangles2[3 * i + 1] =
528  new MTriangle(t->getVertex(1), t->getVertex(2), v);
529  triangles2[3 * i + 2] =
530  new MTriangle(t->getVertex(2), t->getVertex(0), v);
531  delete t;
532  gf->mesh_vertices.push_back(v);
533  }
534  gf->triangles = triangles2;
535  gf->deleteVertexArrays();
536  }
537  }
538  else {
539  for(auto it = m->firstRegion(); it != m->lastRegion(); ++it) {
540  GRegion *gr = *it;
541  std::size_t numt = gr->tetrahedra.size();
542  if(!numt) continue;
543  std::vector<MTetrahedron *> tetrahedra2(4 * numt);
544  for(std::size_t i = 0; i < numt; i++) {
545  MTetrahedron *t = gr->tetrahedra[i];
546  SPoint3 bary = t->barycenter();
547  // FIXME: create an MFaceVertex (with correct parametric coordinates)?
548  MVertex *v = new MVertex(bary.x(), bary.y(), bary.z(), gr);
549  tetrahedra2[4 * i] = new MTetrahedron(t->getVertex(0), t->getVertex(1),
550  t->getVertex(2), v);
551  tetrahedra2[4 * i + 1] = new MTetrahedron(
552  t->getVertex(1), t->getVertex(2), t->getVertex(3), v);
553  tetrahedra2[4 * i + 2] = new MTetrahedron(
554  t->getVertex(2), t->getVertex(3), t->getVertex(0), v);
555  tetrahedra2[4 * i + 3] = new MTetrahedron(
556  t->getVertex(3), t->getVertex(0), t->getVertex(1), v);
557  delete t;
558  gr->mesh_vertices.push_back(v);
559  }
560  gr->tetrahedra = tetrahedra2;
561  gr->deleteVertexArrays();
562  }
563  }
564 
565  double t2 = Cpu(), w2 = TimeOfDay();
566  Msg::StatusBar(true, "Done barycentrically refining mesh (Wall %gs, CPU %gs)",
567  w2 - w1, t2 - t1);
568 }
569 
570 // Tristan Carrier Baudouin's contribution on Full Hex Meshing
571 
572 static double schneiders_x(int i)
573 {
574  double coord[105] = {
575  0.500000, 0.666667, 0.500000, 1.000000, 1.000000, 1.000000, 0.289057,
576  0.324970, 0.276710, 0.337200, 0.364878, 0.325197, 0.000000, 0.000000,
577  0.000000, 0.000000, 0.000000, 0.000000, -0.289057, -0.324970, -0.276710,
578  -0.337200, -0.364878, -0.325197, -0.500000, -0.666667, -0.500000, -1.000000,
579  -1.000000, -1.000000, 0.084599, 0.263953, 0.442960, 0.310954, 0.000000,
580  0.000000, 0.118244, 0.212082, 0.244049, 0.213940, 0.040495, 0.110306,
581  0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, -0.118244,
582  -0.212082, -0.244049, -0.213940, -0.040495, -0.110306, -0.084599, -0.263953,
583  -0.442960, -0.310954, 0.650493, 0.454537, 0.000000, 0.000000, 0.320508,
584  0.264129, 0.063695, 0.092212, 0.000000, 0.000000, 0.000000, 0.000000,
585  -0.320508, -0.264129, -0.063695, -0.092212, -0.650493, -0.454537, 0.619616,
586  0.000000, 0.277170, 0.124682, 0.000000, 0.000000, -0.277170, -0.124682,
587  -0.619616, 0.128101, 0.000000, 0.176104, 0.084236, 0.000000, 0.000000,
588  -0.176104, -0.084236, -0.128101, 0.000000, 0.000000, 0.000000, 0.000000,
589  0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000};
590 
591  return coord[i];
592 }
593 
594 static double schneiders_y(int i)
595 {
596  double coord[105] = {
597  0.707107, 0.471405, 0.707107, 0.000000, 0.000000, 0.000000, 0.474601,
598  0.421483, 0.463847, 0.367090, 0.344843, 0.361229, 0.429392, 0.410339,
599  0.435001, 0.407674, 0.401208, 0.404164, 0.474601, 0.421483, 0.463847,
600  0.367090, 0.344843, 0.361229, 0.707107, 0.471405, 0.707107, 0.000000,
601  0.000000, 0.000000, 0.536392, 0.697790, 0.569124, 0.742881, 0.558045,
602  0.946690, 0.497378, 0.532513, 0.500133, 0.541479, 0.530503, 0.666252,
603  0.463274, 0.465454, 0.430972, 0.451135, 0.515274, 0.589713, 0.497378,
604  0.532513, 0.500133, 0.541479, 0.530503, 0.666252, 0.536392, 0.697790,
605  0.569124, 0.742881, 0.080018, 0.104977, 0.216381, 0.200920, 0.326416,
606  0.339933, 0.280915, 0.305725, 0.396502, 0.394423, 0.310617, 0.337499,
607  0.326416, 0.339933, 0.280915, 0.305725, 0.080018, 0.104977, 0.081443,
608  0.204690, 0.354750, 0.334964, 0.403611, 0.367496, 0.354750, 0.334964,
609  0.081443, 0.501199, 0.538575, 0.447454, 0.486224, 0.431723, 0.470065,
610  0.447454, 0.486224, 0.501199, 0.488701, 0.471405, 0.017336, 0.000000,
611  0.452197, 0.471405, 0.057682, 0.000000, 1.414213, 0.015731, 0.000000};
612 
613  return coord[i];
614 }
615 
616 static double schneiders_z(int i)
617 {
618  double coord[105] = {
619  0.500000, 0.000000, -0.500000, 1.000000, 0.000000, -1.000000, 0.051666,
620  -0.058015, -0.148140, 0.071987, -0.057896, -0.181788, -0.016801, -0.054195,
621  -0.104114, -0.015276, -0.054392, -0.110605, 0.051666, -0.058015, -0.148140,
622  0.071987, -0.057896, -0.181788, 0.500000, 0.000000, -0.500000, 1.000000,
623  0.000000, -1.000000, -0.208673, -0.162945, 0.021476, 0.389516, -0.157646,
624  0.159885, -0.142645, -0.073557, -0.032793, 0.060339, -0.136482, 0.043449,
625  -0.111103, -0.079664, -0.047879, -0.008734, -0.124554, 0.008560, -0.142645,
626  -0.073557, -0.032793, 0.060339, -0.136482, 0.043449, -0.208673, -0.162945,
627  0.021476, 0.389516, -0.041899, -0.680880, -0.103504, -0.392255, -0.065989,
628  -0.212535, -0.093142, -0.227139, -0.056201, -0.124443, -0.087185, -0.182164,
629  -0.065989, -0.212535, -0.093142, -0.227139, -0.041899, -0.680880, 0.786284,
630  0.443271, 0.104202, 0.144731, -0.005330, 0.073926, 0.104202, 0.144731,
631  0.786284, -0.364254, -0.282882, -0.189794, -0.182143, -0.127036, -0.148665,
632  -0.189794, -0.182143, -0.364254, 0.642222, 0.666667, 0.959658, 1.000000,
633  -0.455079, -0.666667, -0.844452, -1.000000, 0.000000, -0.009020, 0.000000};
634 
635  return coord[i];
636 }
637 
638 static int schneiders_connect(int i, int j)
639 {
640  int n0[88] = {0, 1, 6, 7, 12, 13, 18, 19, 41, 39, 37, 41, 36, 40, 47,
641  45, 43, 47, 42, 46, 53, 51, 49, 53, 48, 52, 35, 57, 55, 35,
642  54, 34, 34, 35, 65, 63, 64, 62, 69, 67, 68, 66, 73, 71, 72,
643  70, 61, 75, 60, 74, 60, 61, 79, 78, 81, 80, 83, 82, 77, 84,
644  77, 88, 87, 90, 89, 92, 91, 86, 93, 86, 57, 24, 95, 85, 2,
645  99, 84, 74, 97, 104, 104, 97, 26, 35, 35, 24, 35, 24};
646 
647  int n1[88] = {1, 2, 7, 8, 13, 14, 19, 20, 39, 6, 38, 37, 37, 36, 45,
648  12, 44, 43, 43, 42, 51, 18, 50, 49, 49, 48, 57, 24, 56, 55,
649  55, 54, 40, 41, 63, 11, 62, 10, 67, 17, 66, 16, 71, 23, 70,
650  22, 75, 29, 74, 28, 64, 65, 78, 9, 80, 15, 82, 21, 84, 27,
651  79, 87, 8, 89, 14, 91, 20, 93, 26, 88, 35, 57, 94, 86, 85,
652  98, 77, 60, 96, 103, 28, 27, 99, 55, 102, 25, 31, 102};
653 
654  int n2[88] = {4, 5, 10, 11, 16, 17, 22, 23, 38, 7, 7, 36, 8, 87, 44,
655  13, 13, 42, 14, 89, 50, 19, 19, 48, 20, 91, 56, 25, 25, 54,
656  26, 93, 46, 47, 62, 10, 78, 9, 66, 16, 80, 15, 70, 22, 82,
657  21, 74, 28, 84, 27, 68, 69, 39, 6, 45, 12, 51, 18, 57, 24,
658  81, 63, 11, 67, 17, 71, 23, 75, 29, 90, 33, 94, 33, 93, 98,
659  93, 76, 58, 76, 58, 74, 84, 2, 26, 2, 26, 2, 0};
660 
661  int n3[88] = {3, 4, 9, 10, 15, 16, 21, 22, 37, 38, 8, 40, 87,
662  88, 43, 44, 14, 46, 89, 90, 49, 50, 20, 52, 91, 92,
663  55, 56, 26, 34, 93, 86, 52, 53, 64, 62, 79, 78, 68,
664  66, 81, 80, 72, 70, 83, 82, 60, 74, 77, 84, 72, 73,
665  41, 39, 47, 45, 53, 51, 35, 57, 83, 65, 63, 69, 67,
666  73, 71, 61, 75, 92, 94, 95, 0, 98, 99, 26, 96, 103,
667  3, 4, 103, 96, 102, 102, 31, 102, 102, 95};
668 
669  int n4[88] = {6, 7, 12, 13, 18, 19, 24, 25, 35, 33, 31, 35, 30, 34, 41,
670  39, 37, 41, 36, 40, 47, 45, 43, 47, 42, 46, 53, 51, 49, 53,
671  48, 52, 86, 34, 61, 59, 60, 58, 65, 63, 64, 62, 69, 67, 68,
672  66, 73, 71, 72, 70, 77, 60, 77, 76, 79, 78, 81, 80, 83, 82,
673  35, 86, 85, 88, 87, 90, 89, 92, 91, 61, 84, 27, 97, 59, 5,
674  101, 74, 75, 104, 101, 101, 104, 93, 34, 34, 57, 33, 57};
675 
676  int n5[88] = {7, 8, 13, 14, 19, 20, 25, 26, 33, 0, 32, 31, 31, 30, 39,
677  6, 38, 37, 37, 36, 45, 12, 44, 43, 43, 42, 51, 18, 50, 49,
678  49, 48, 88, 40, 59, 5, 58, 4, 63, 11, 62, 10, 67, 17, 66,
679  16, 71, 23, 70, 22, 79, 64, 76, 3, 78, 9, 80, 15, 82, 21,
680  41, 85, 2, 87, 8, 89, 14, 91, 20, 65, 77, 84, 96, 61, 59,
681  100, 60, 61, 103, 100, 29, 28, 98, 54, 86, 56, 32, 35};
682 
683  int n6[88] = {10, 11, 16, 17, 22, 23, 28, 29, 32, 1, 1, 30, 2, 85, 38,
684  7, 7, 36, 8, 87, 44, 13, 13, 42, 14, 89, 50, 19, 19, 48,
685  20, 91, 90, 46, 58, 4, 76, 3, 62, 10, 78, 9, 66, 16, 80,
686  15, 70, 22, 82, 21, 81, 68, 33, 0, 39, 6, 45, 12, 51, 18,
687  47, 59, 5, 63, 11, 67, 17, 71, 23, 69, 76, 96, 76, 75, 100,
688  75, 58, 59, 58, 59, 75, 74, 85, 93, 85, 55, 1, 33};
689 
690  int n7[88] = {9, 10, 15, 16, 21, 22, 27, 28, 31, 32, 2, 34, 85,
691  86, 37, 38, 8, 40, 87, 88, 43, 44, 14, 46, 89, 90,
692  49, 50, 20, 52, 91, 92, 92, 52, 60, 58, 77, 76, 64,
693  62, 79, 78, 68, 66, 81, 80, 72, 70, 83, 82, 83, 72,
694  35, 33, 41, 39, 47, 45, 53, 51, 53, 61, 59, 65, 63,
695  69, 67, 73, 71, 73, 96, 97, 3, 100, 101, 29, 103, 100,
696  4, 5, 100, 103, 86, 86, 30, 35, 0, 94};
697 
698  if(i == 0) { return n0[j]; }
699  else if(i == 1) {
700  return n1[j];
701  }
702  else if(i == 2) {
703  return n2[j];
704  }
705  else if(i == 3) {
706  return n3[j];
707  }
708  else if(i == 4) {
709  return n4[j];
710  }
711  else if(i == 5) {
712  return n5[j];
713  }
714  else if(i == 6) {
715  return n6[j];
716  }
717  else {
718  return n7[j];
719  }
720 }
721 
723  faceContainer &faceVertices,
724  std::vector<MHexahedron *> &dwarfs88)
725 {
726  std::vector<MVertex *> v(105, (MVertex *)nullptr);
727 
728  v[29] = element->getVertex(0);
729  v[27] = element->getVertex(1);
730  v[3] = element->getVertex(2);
731  v[5] = element->getVertex(3);
732  v[102] = element->getVertex(4);
733 
734  v[28] = element->getVertex(5);
735  v[97] = element->getVertex(8);
736  v[4] = element->getVertex(10);
737  v[101] = element->getVertex(6);
738  v[26] = element->getVertex(7);
739  v[24] = element->getVertex(9);
740  v[0] = element->getVertex(11);
741  v[2] = element->getVertex(12);
742 
743  // the one in the middle of rect face
744  v[104] = element->getVertex(13);
745 
746  SPoint3 point;
747 
748  auto fIter = faceVertices.find(MFace(v[29], v[27], v[102]));
749  if(fIter != faceVertices.end())
750  v[25] = fIter->second[0];
751  else {
752  element->pnt(0.0, -0.666667, 0.471405 / 1.414213, point);
753  v[25] = new MVertex(point.x(), point.y(), point.z(), gr);
754  gr->addMeshVertex(v[25]);
755  faceVertices[MFace(v[29], v[27], v[102])].push_back(v[25]);
756  }
757 
758  fIter = faceVertices.find(MFace(v[27], v[3], v[102]));
759  if(fIter != faceVertices.end())
760  v[95] = fIter->second[0];
761  else {
762  element->pnt(0.666667, 0.0, 0.471405 / 1.414213, point);
763  v[95] = new MVertex(point.x(), point.y(), point.z(), gr);
764  gr->addMeshVertex(v[95]);
765  faceVertices[MFace(v[27], v[3], v[102])].push_back(v[95]);
766  }
767 
768  fIter = faceVertices.find(MFace(v[3], v[5], v[102]));
769  if(fIter != faceVertices.end())
770  v[1] = fIter->second[0];
771  else {
772  element->pnt(0.0, 0.666667, 0.471405 / 1.414213, point);
773  v[1] = new MVertex(point.x(), point.y(), point.z(), gr);
774  gr->addMeshVertex(v[1]);
775  faceVertices[MFace(v[3], v[5], v[102])].push_back(v[1]);
776  }
777 
778  fIter = faceVertices.find(MFace(v[5], v[29], v[102]));
779  if(fIter != faceVertices.end())
780  v[99] = fIter->second[0];
781  else {
782  element->pnt(-0.666667, 0.0, 0.471405 / 1.414213, point);
783  v[99] = new MVertex(point.x(), point.y(), point.z(), gr);
784  gr->addMeshVertex(v[99]);
785  faceVertices[MFace(v[5], v[29], v[102])].push_back(v[99]);
786  }
787 
788  for(int i = 0; i < 105; i++) {
789  if(!v[i]) {
790  element->pnt(schneiders_z(i), schneiders_x(i), schneiders_y(i) / 1.414213,
791  point);
792  v[i] = new MVertex(point.x(), point.y(), point.z(), gr);
793  gr->addMeshVertex(v[i]);
794  }
795  }
796 
797  dwarfs88.resize(88);
798 
799  for(int i = 0; i < 88; i++) {
800  int const index1 = schneiders_connect(0, i);
801  int const index2 = schneiders_connect(1, i);
802  int const index3 = schneiders_connect(2, i);
803  int const index4 = schneiders_connect(3, i);
804  int const index5 = schneiders_connect(4, i);
805  int const index6 = schneiders_connect(5, i);
806  int const index7 = schneiders_connect(6, i);
807  int const index8 = schneiders_connect(7, i);
808 
809  dwarfs88[i] = new MHexahedron(v[index1], v[index2], v[index3], v[index4],
810  v[index5], v[index6], v[index7], v[index8]);
811  }
812 }
SetOrderN
void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisible)
Definition: HighOrder.cpp:1396
MTriangle.h
TimeOfDay
double TimeOfDay()
Definition: OS.cpp:399
MTriangle::getFace
virtual MFace getFace(int num) const
Definition: MTriangle.h:91
GModel::firstEdge
eiter firstEdge()
Definition: GModel.h:356
GEntity::correspondingHighOrderVertices
std::map< MVertex *, MVertex * > correspondingHighOrderVertices
Definition: GEntity.h:409
GPoint::y
double y() const
Definition: GPoint.h:22
MEdgeVertex::bl_data
MVertexBoundaryLayerData * bl_data
Definition: MVertex.h:142
MTetrahedron
Definition: MTetrahedron.h:34
MLine::getVertex
virtual MVertex * getVertex(int num)
Definition: MLine.h:45
GFace
Definition: GFace.h:33
GFace::triangles
std::vector< MTriangle * > triangles
Definition: GFace.h:428
MQuadrangle::getVertex
virtual MVertex * getVertex(int num)
Definition: MQuadrangle.h:64
GEdge::lines
std::vector< MLine * > lines
Definition: GEdge.h:42
OS.h
MVertex
Definition: MVertex.h:24
Subdivide
static void Subdivide(GEdge *ge)
Definition: meshRefine.cpp:88
MFace::barycenter
SPoint3 barycenter() const
Definition: MFace.h:65
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
Msg::StatusBar
static void StatusBar(bool log, const char *fmt,...)
Definition: GmshMessage.cpp:686
SPoint3
Definition: SPoint3.h:14
MTriangle::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MTriangle.h:61
MPrism::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MPrism.h:69
meshGFaceOptimize.h
MTriangle::getVertex
virtual MVertex * getVertex(int num)
Definition: MTriangle.h:62
MPyramid
Definition: MPyramid.h:32
MVertex::onWhat
GEntity * onWhat() const
Definition: MVertex.h:82
MPrism
Definition: MPrism.h:34
GModel::destroyMeshCaches
void destroyMeshCaches()
Definition: GModel.cpp:214
GmshMessage.h
MLine.h
w1
const double w1
Definition: GaussQuadratureHex.cpp:18
GPoint
Definition: GPoint.h:13
MLine::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MLine.h:44
GFace::closestPoint
virtual GPoint closestPoint(const SPoint3 &queryPoint, const double initialGuess[2]) const
Definition: GFace.cpp:1323
MTetrahedron::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MTetrahedron.h:66
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
GFace::quadrangles
std::vector< MQuadrangle * > quadrangles
Definition: GFace.h:429
FixPeriodicMesh
void FixPeriodicMesh(GModel *m)
Definition: Generator.cpp:1455
MLine
Definition: MLine.h:21
GPoint::z
double z() const
Definition: GPoint.h:23
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
GRegion::hexahedra
std::vector< MHexahedron * > hexahedra
Definition: GRegion.h:164
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
MFace
Definition: MFace.h:20
MQuadrangle::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MQuadrangle.h:63
MHexahedron::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MHexahedron.h:65
MPrism::getVertex
virtual MVertex * getVertex(int num)
Definition: MPrism.h:71
GPoint::u
double u() const
Definition: GPoint.h:27
GEntity::mesh_vertices
std::vector< MVertex * > mesh_vertices
Definition: GEntity.h:56
MHexahedron.h
MEdgeVertex
Definition: MVertex.h:137
HighOrder.h
faceContainer
std::map< MFace, std::vector< MVertex * >, MFaceLessThan > faceContainer
Definition: meshRefine.cpp:25
setBLData
static void setBLData(MVertex *v)
Definition: meshRefine.cpp:42
MTetrahedron::getVertex
virtual MVertex * getVertex(int num)
Definition: MTetrahedron.h:67
GModel
Definition: GModel.h:44
Cpu
double Cpu()
Definition: OS.cpp:366
MPyramid::getNumVertices
virtual std::size_t getNumVertices() const
Definition: MPyramid.h:73
MHexahedron::getVertex
virtual MVertex * getVertex(int num)
Definition: MHexahedron.h:66
faceContainer
std::map< MFace, std::vector< MVertex * >, MFaceLessThan > faceContainer
Definition: HighOrder.cpp:42
MPyramid.h
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
MHexahedron
Definition: MHexahedron.h:28
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
GModel::getNumRegions
std::size_t getNumRegions() const
Definition: GModel.h:344
MElement
Definition: MElement.h:30
MFaceVertex
Definition: MVertex.h:168
element
Definition: shapeFunctions.h:12
MTetrahedron::getNumFaces
virtual int getNumFaces()
Definition: MTetrahedron.h:87
GRegion
Definition: GRegion.h:28
GRegion::prisms
std::vector< MPrism * > prisms
Definition: GRegion.h:165
MTriangle
Definition: MTriangle.h:26
GRegion::pyramids
std::vector< MPyramid * > pyramids
Definition: GRegion.h:166
MElement::pnt
virtual void pnt(double u, double v, double w, SPoint3 &p) const
Definition: MElement.cpp:1072
MVertexPtrLessThanParam::operator()
bool operator()(const MVertex *v1, const MVertex *v2) const
Definition: meshRefine.cpp:32
GModel::firstRegion
riter firstRegion()
Definition: GModel.h:354
schneiders_z
static double schneiders_z(int i)
Definition: meshRefine.cpp:616
GModel::lastRegion
riter lastRegion()
Definition: GModel.h:358
MVertex::getParameter
virtual bool getParameter(int i, double &par) const
Definition: MVertex.h:97
Context.h
MTetrahedron.h
schneiders_x
static double schneiders_x(int i)
Definition: meshRefine.cpp:572
MQuadrangle.h
MElement::getNumPrimaryVertices
std::size_t getNumPrimaryVertices() const
Definition: MElement.h:160
MPyramid::getVertex
virtual MVertex * getVertex(int num)
Definition: MPyramid.h:74
GEdge
Definition: GEdge.h:26
MVertexBoundaryLayerData
Definition: MVertexBoundaryLayerData.h:18
MFaceVertex::bl_data
MVertexBoundaryLayerData * bl_data
Definition: MVertex.h:173
MVertexPtrLessThanParam
Definition: meshRefine.cpp:31
MPrism.h
MElement::barycenter
virtual SPoint3 barycenter(bool primary=false) const
Definition: MElement.cpp:520
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
GPoint::v
double v() const
Definition: GPoint.h:28
GModel::lastEdge
eiter lastEdge()
Definition: GModel.h:360
MFaceLessThan
Definition: MFace.h:130
RefineMesh
void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas)
Definition: meshRefine.cpp:463
GModel.h
schneiders_connect
static int schneiders_connect(int i, int j)
Definition: meshRefine.cpp:638
schneiders_y
static double schneiders_y(int i)
Definition: meshRefine.cpp:594
GEntity::dim
virtual int dim() const
Definition: GEntity.h:196
MTetrahedron::getFace
virtual MFace getFace(int num) const
Definition: MTetrahedron.h:88
OptimizeMesh
void OptimizeMesh(GModel *m, const std::string &how, bool force, int niter)
Definition: Generator.cpp:1101
Generator.h
GPoint::x
double x() const
Definition: GPoint.h:21
GEntity::correspondingVertices
std::map< MVertex *, MVertex * > correspondingVertices
Definition: GEntity.h:406
GModel::setAllVolumesPositive
bool setAllVolumesPositive()
Definition: GModel.cpp:1085
MQuadrangle
Definition: MQuadrangle.h:26
GEntity::deleteVertexArrays
void deleteVertexArrays()
Definition: GEntity.cpp:27
MPrism::getFace
virtual MFace getFace(int num) const
Definition: MPrism.h:94
subdivide_pyramid
void subdivide_pyramid(MElement *element, GRegion *gr, faceContainer &faceVertices, std::vector< MHexahedron * > &dwarfs88)
Definition: meshRefine.cpp:722
GRegion::tetrahedra
std::vector< MTetrahedron * > tetrahedra
Definition: GRegion.h:163
GEntity::addMeshVertex
void addMeshVertex(MVertex *v)
Definition: GEntity.h:382
BarycentricRefineMesh
void BarycentricRefineMesh(GModel *m)
Definition: meshRefine.cpp:507
contextMeshOptions::hoOptimize
int hoOptimize
Definition: Context.h:38