gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
meshGRegion.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 #include "meshGRegion.h"
7 #include "Context.h"
8 #include "ExtrudeParams.h"
9 #include "GEdge.h"
10 #include "GFace.h"
11 #include "GModel.h"
12 #include "GRegion.h"
13 #include "GmshConfig.h"
14 #include "GmshMessage.h"
15 #include "MLine.h"
16 #include "MPyramid.h"
17 #include "MTetrahedron.h"
18 #include "MTriangle.h"
19 #include "OS.h"
20 #include "discreteEdge.h"
21 #include "discreteFace.h"
22 #include "meshGFace.h"
23 #include "meshGFaceOptimize.h"
26 #include "meshGRegionHxt.h"
27 #include "meshGRegionMMG.h"
28 #include "meshGRegionNetgen.h"
29 #include "meshRelocateVertex.h"
30 #include <stdlib.h>
31 #include <vector>
32 
34 {
35  _quad[f] = v;
36  MFace f0(f.getVertex(0), f.getVertex(1), v);
37  MFace f1(f.getVertex(1), f.getVertex(2), v);
38  MFace f2(f.getVertex(2), f.getVertex(3), v);
39  MFace f3(f.getVertex(3), f.getVertex(0), v);
40  _tri[f0] = gf;
41  _tri[f1] = gf;
42  _tri[f2] = gf;
43  _tri[f3] = gf;
44 }
45 
47 {
48  if (_quad.empty())
49  return 0;
50 
51  Msg::Info("Generating pyramids for hybrid mesh...");
52  int npyram = 0;
53  for (auto it = gm->firstRegion(); it != gm->lastRegion(); it++)
54  {
55  GRegion *gr = *it;
57  continue;
58  if (gr->isFullyDiscrete())
59  continue;
61  if (ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY)
62  continue;
63 
64  std::vector<GFace *> faces = gr->faces();
65  for (std::size_t i = 0; i < faces.size(); i++)
66  {
67  GFace *gf = faces[i];
68  for (std::size_t j = 0; j < gf->quadrangles.size(); j++)
69  {
70  auto it2 = _quad.find(gf->quadrangles[j]->getFace(0));
71  if (it2 != _quad.end())
72  {
73  npyram++;
74  gr->pyramids.push_back(new MPyramid(it2->first.getVertex(0), it2->first.getVertex(1),
75  it2->first.getVertex(2), it2->first.getVertex(3), it2->second));
76  gr->mesh_vertices.push_back(it2->second);
77  if (it2->second->onWhat()->dim() == 3)
78  {
79  Msg::Error("Pyramid top vertex already classified on volume %d (!= %d) - "
80  "non-manifold quad boundaries not supported yet",
81  it2->second->onWhat()->tag(), gr->tag());
82  }
83  else
84  {
85  it2->second->setEntity(gr);
86  }
87  }
88  }
89  }
90  }
91  Msg::Info("Done generating %d pyramids for hybrid mesh", npyram);
92  return npyram;
93 }
94 
95 void MeshDelaunayVolume(std::vector<GRegion *> &regions)
96 {
97  if (regions.empty())
98  return;
99 
100  if (CTX::instance()->mesh.algo3d == ALGO_3D_HXT)
101  {
102  if (meshGRegionHxt(regions) != 0)
103  {
104  Msg::Error("HXT 3D mesh failed");
105  }
106  return;
107  }
108 
111  return;
112 
113  GRegion *gr = regions[0];
114  std::vector<GFace *> faces = gr->faces();
115 
116  std::set<GFace *, GEntityPtrLessThan> allFacesSet;
117  for (std::size_t i = 0; i < regions.size(); i++)
118  {
119  std::vector<GFace *> const &f = regions[i]->faces();
120  std::vector<GFace *> const &f_e = regions[i]->embeddedFaces();
121  allFacesSet.insert(f.begin(), f.end());
122  allFacesSet.insert(f_e.begin(), f_e.end());
123  }
124 
125  // replace faces with compounds if elements from compound surface meshes are
126  // not reclassified on the original surfaces
127  if (CTX::instance()->mesh.compoundClassify == 0)
128  {
129  std::set<GFace *, GEntityPtrLessThan> comp;
130  for (auto it = allFacesSet.begin(); it != allFacesSet.end(); it++)
131  {
132  GFace *gf = *it;
133  if (!gf->compoundSurface)
134  comp.insert(gf);
135  else if (gf->compoundSurface)
136  comp.insert(gf->compoundSurface);
137  }
138  allFacesSet = comp;
139  }
140 
141  std::vector<GFace *> allFaces(allFacesSet.begin(), allFacesSet.end());
142  gr->set(allFaces);
143 
144  std::set<GEdge *, GEntityPtrLessThan> allEmbEdgesSet;
145  for (std::size_t i = 0; i < regions.size(); i++)
146  {
147  std::vector<GEdge *> const &e = regions[i]->embeddedEdges();
148  allEmbEdgesSet.insert(e.begin(), e.end());
149  }
150  std::vector<GEdge *> allEmbEdges(allEmbEdgesSet.begin(), allEmbEdgesSet.end());
151  std::vector<GEdge *> oldEmbEdges = gr->embeddedEdges();
152  gr->embeddedEdges() = allEmbEdges;
153 
154  std::set<GVertex *> allEmbVerticesSet;
155  for (std::size_t i = 0; i < regions.size(); i++)
156  {
157  std::vector<GVertex *> const &e = regions[i]->embeddedVertices();
158  allEmbVerticesSet.insert(e.begin(), e.end());
159  }
160  std::vector<GVertex *> allEmbVertices(allEmbVerticesSet.begin(), allEmbVerticesSet.end());
161  std::vector<GVertex *> oldEmbVertices = gr->embeddedVertices();
162  gr->embeddedVertices() = allEmbVertices;
163 
165  bool success = meshGRegionBoundaryRecovery(gr, &sqr);
166 
167  // sort triangles in all model faces in order to be able to search in vectors
168  auto itf = allFaces.begin();
169  while (itf != allFaces.end())
170  {
171  std::sort((*itf)->triangles.begin(), (*itf)->triangles.end(), compareMTriangleLexicographic());
172  ++itf;
173  }
174 
175  // restore set of faces and embedded edges/vertices
176  if (CTX::instance()->mesh.compoundClassify == 0)
177  {
178  std::set<GFace *, GEntityPtrLessThan> comp;
179  for (std::size_t i = 0; i < faces.size(); i++)
180  {
181  GFace *gf = faces[i];
182  if (!gf->compoundSurface)
183  comp.insert(gf);
184  else if (gf->compoundSurface)
185  comp.insert(gf->compoundSurface);
186  }
187  std::vector<GFace *> lcomp(comp.begin(), comp.end());
188  gr->set(lcomp);
189  }
190  else
191  {
192  gr->set(faces);
193  }
194  gr->embeddedEdges() = oldEmbEdges;
195  gr->embeddedVertices() = oldEmbVertices;
196 
197  if (!success)
198  return;
199 
200  // now do insertion of points
201  if (CTX::instance()->mesh.algo3d == ALGO_3D_MMG3D)
202  {
203  for (std::size_t i = 0; i < regions.size(); i++)
204  {
205  refineMeshMMG(regions[i]);
206  }
207  }
208  else if (CTX::instance()->mesh.algo3d != ALGO_3D_INITIAL_ONLY)
209  {
210  insertVerticesInRegion(gr, CTX::instance()->mesh.maxIterDelaunay3D, 1., true, &sqr);
211 
212  if (sqr.buildPyramids(gr->model()))
213  {
214  Msg::Info("Optimizing pyramids for hybrid mesh...");
215  gr->model()->setAllVolumesPositive();
216  RelocateVerticesOfPyramids(regions, 3);
217  // RelocateVertices(regions, 3);
218  Msg::Info("Done optimizing pyramids for hybrid mesh");
219  }
220 
221  // test:
222  // bool createBoundaryLayerOneLayer(GRegion *gr, std::vector<GFace *> &
223  // bls); createBoundaryLayerOneLayer(gr, allFaces);
224  }
225 }
226 
228 {
229  if (gr->isFullyDiscrete())
230  return;
231  gr->deleteMesh();
232 }
233 
235 {
236  gr->model()->setCurrentMeshEntity(gr);
237 
238  if (gr->isFullyDiscrete())
239  return;
240  if (gr->meshAttributes.method == MESH_NONE)
241  return;
242  if (CTX::instance()->mesh.meshOnlyVisible && !gr->getVisibility())
243  return;
244  if (CTX::instance()->mesh.meshOnlyEmpty && gr->getNumMeshElements())
245  return;
246 
248  if (ep && ep->mesh.ExtrudeMesh)
249  return;
250 
251  // destroy the mesh if it exists
252  deMeshGRegion dem;
253  dem(gr);
254 
255  if (MeshTransfiniteVolume(gr))
256  return;
257 
258  if (CTX::instance()->mesh.algo3d != ALGO_3D_FRONTAL)
259  {
260  delaunay.push_back(gr);
261  }
262  else if (CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL)
263  {
264  meshGRegionNetgen(gr);
265  }
266 }
267 
269 {
270  gr->model()->setCurrentMeshEntity(gr);
271 
272  if (!always && gr->isFullyDiscrete())
273  return;
274 
275  // don't optimize extruded meshes
277  return;
279  if (ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY)
280  return;
281 
282  Msg::Info("Optimizing volume %d", gr->tag());
284 }
285 
286 bool buildFaceSearchStructure(GModel *model, fs_cont &search, bool onlyTriangles)
287 {
288  search.clear();
289 
290  std::set<GFace *> faces_to_consider;
291  auto rit = model->firstRegion();
292  while (rit != model->lastRegion())
293  {
294  std::vector<GFace *> _faces = (*rit)->faces();
295  faces_to_consider.insert(_faces.begin(), _faces.end());
296  rit++;
297  }
298 
299  auto fit = faces_to_consider.begin();
300  while (fit != faces_to_consider.end())
301  {
302  for (std::size_t i = 0; i < (*fit)->getNumMeshElements(); i++)
303  {
304  MFace ff = (*fit)->getMeshElement(i)->getFace(0);
305  if (!onlyTriangles || ff.getNumVertices() == 3)
306  search[ff] = *fit;
307  }
308  ++fit;
309  }
310  return true;
311 }
312 
314 {
315  search.clear();
316 
317  auto eit = model->firstEdge();
318  while (eit != model->lastEdge())
319  {
320  for (std::size_t i = 0; i < (*eit)->lines.size(); i++)
321  {
322  MVertex *p1 = (*eit)->lines[i]->getVertex(0);
323  MVertex *p2 = (*eit)->lines[i]->getVertex(1);
324  MVertex *p = std::min(p1, p2);
325  search.insert(std::pair<MVertex *, std::pair<MLine *, GEdge *>>(
326  p, std::pair<MLine *, GEdge *>((*eit)->lines[i], *eit)));
327  }
328  ++eit;
329  }
330  return true;
331 }
332 
334 {
335  MFace ff(p1, p2, p3);
336  auto it = search.find(ff);
337  if (it == search.end())
338  return nullptr;
339  return it->second;
340 }
341 
342 GFace *findInFaceSearchStructure(const MFace &ff, const fs_cont &search)
343 {
344  auto it = search.find(ff);
345  if (it == search.end())
346  return nullptr;
347  return it->second;
348 }
349 
351 {
352  MVertex *p = std::min(p1, p2);
353 
354  for (auto it = search.lower_bound(p); it != search.upper_bound(p); ++it)
355  {
356  MLine *l = it->second.first;
357  GEdge *ge = it->second.second;
358  if ((l->getVertex(0) == p1 || l->getVertex(0) == p2) && (l->getVertex(1) == p1 || l->getVertex(1) == p2))
359  return ge;
360  }
361  return nullptr;
362 }
MTriangle.h
es_cont
std::multimap< MVertex *, std::pair< MLine *, GEdge * > > es_cont
Definition: meshGRegion.h:61
sqr
static int sqr(int x)
Definition: gl2gif.cpp:266
GModel::firstEdge
eiter firstEdge()
Definition: GModel.h:356
GRegion::method
char method
Definition: GRegion.h:146
meshGRegionDelaunayInsertion.h
GFace.h
meshGRegionNetgen
void meshGRegionNetgen(GRegion *gr)
Definition: meshGRegionNetgen.cpp:313
ALGO_3D_MMG3D
#define ALGO_3D_MMG3D
Definition: GmshDefines.h:253
MLine::getVertex
virtual MVertex * getVertex(int num)
Definition: MLine.h:45
GFace
Definition: GFace.h:33
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEntity::model
GModel * model() const
Definition: GEntity.h:277
OS.h
MESH_TRANSFINITE
#define MESH_TRANSFINITE
Definition: GmshDefines.h:259
GRegion::deleteMesh
virtual void deleteMesh()
Definition: GRegion.cpp:39
meshGRegionHxt.h
MVertex
Definition: MVertex.h:24
splitQuadRecovery::buildPyramids
int buildPyramids(GModel *gm)
Definition: meshGRegion.cpp:46
meshGRegionNetgen.h
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
findInFaceSearchStructure
GFace * findInFaceSearchStructure(MVertex *p1, MVertex *p2, MVertex *p3, const fs_cont &search)
Definition: meshGRegion.cpp:333
GRegion::set
void set(std::vector< GFace * > const &f)
Definition: GRegion.h:67
meshGFaceOptimize.h
GRegion::getNumMeshElements
std::size_t getNumMeshElements() const
Definition: GRegion.cpp:60
MPyramid
Definition: MPyramid.h:32
GmshMessage.h
MLine.h
ExtrudeParams::geo
struct ExtrudeParams::@15 geo
GRegion::isFullyDiscrete
virtual bool isFullyDiscrete()
Definition: GRegion.cpp:948
meshGRegionBoundaryRecovery
bool meshGRegionBoundaryRecovery(GRegion *gr, splitQuadRecovery *sqr)
Definition: meshGRegionBoundaryRecovery.cpp:1356
GFace::quadrangles
std::vector< MQuadrangle * > quadrangles
Definition: GFace.h:429
refineMeshMMG
void refineMeshMMG(GRegion *gr)
Definition: meshGRegionMMG.cpp:359
insertVerticesInRegion
void insertVerticesInRegion(GRegion *gr, int maxIter, double worstTetRadiusTarget, bool _classify, splitQuadRecovery *sqr)
Definition: meshGRegionDelaunayInsertion.cpp:1217
meshGRegionMMG.h
MLine
Definition: MLine.h:21
deMeshGRegion
Definition: meshGRegion.h:48
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
RelocateVerticesOfPyramids
void RelocateVerticesOfPyramids(GRegion *region, int niter, double tol)
Definition: meshRelocateVertex.cpp:451
GRegion::faces
virtual std::vector< GFace * > faces() const
Definition: GRegion.h:64
GRegion::extrude
ExtrudeParams * extrude
Definition: GRegion.h:148
GEdge.h
MFace
Definition: MFace.h:20
GRegion.h
ExtrudeParams::mesh
struct ExtrudeParams::@14 mesh
buildEdgeSearchStructure
bool buildEdgeSearchStructure(GModel *model, es_cont &search)
Definition: meshGRegion.cpp:313
GEntity::mesh_vertices
std::vector< MVertex * > mesh_vertices
Definition: GEntity.h:56
EXTRUDED_ENTITY
#define EXTRUDED_ENTITY
Definition: ExtrudeParams.h:17
optimizeMeshGRegion::operator()
void operator()(GRegion *, bool always=false)
Definition: meshGRegion.cpp:268
meshGRegionBoundaryRecovery.h
MeshTransfiniteVolume
int MeshTransfiniteVolume(GRegion *gr)
Definition: meshGRegionTransfinite.cpp:342
contextMeshOptions::algo3d
int algo3d
Definition: Context.h:29
meshGRegion::delaunay
std::vector< GRegion * > & delaunay
Definition: meshGRegion.h:25
GModel
Definition: GModel.h:44
compareMTriangleLexicographic
Definition: MTriangle.h:452
splitQuadRecovery::add
void add(const MFace &f, MVertex *v, GFace *gf)
Definition: meshGRegion.cpp:33
ExtrudeParams.h
MESH_NONE
#define MESH_NONE
Definition: GmshDefines.h:258
MPyramid.h
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
splitQuadRecovery::_quad
std::map< MFace, MVertex *, MFaceLessThan > _quad
Definition: meshGRegion.h:74
ExtrudeParams::Mode
int Mode
Definition: ExtrudeParams.h:49
ALGO_3D_HXT
#define ALGO_3D_HXT
Definition: GmshDefines.h:255
deMeshGRegion::operator()
void operator()(GRegion *)
Definition: meshGRegion.cpp:227
GEntity::tag
int tag() const
Definition: GEntity.h:280
discreteFace.h
meshGRegion::operator()
void operator()(GRegion *)
Definition: meshGRegion.cpp:234
GFace::compoundSurface
GFace * compoundSurface
Definition: GFace.h:434
splitQuadRecovery
Definition: meshGRegion.h:72
MeshDelaunayVolume
void MeshDelaunayVolume(std::vector< GRegion * > &regions)
Definition: meshGRegion.cpp:95
GRegion
Definition: GRegion.h:28
findInEdgeSearchStructure
GEdge * findInEdgeSearchStructure(MVertex *p1, MVertex *p2, const es_cont &search)
Definition: meshGRegion.cpp:350
ExtrudeParams::ExtrudeMesh
bool ExtrudeMesh
Definition: ExtrudeParams.h:36
ALGO_3D_FRONTAL
#define ALGO_3D_FRONTAL
Definition: GmshDefines.h:252
GRegion::pyramids
std::vector< MPyramid * > pyramids
Definition: GRegion.h:166
GModel::firstRegion
riter firstRegion()
Definition: GModel.h:354
GModel::lastRegion
riter lastRegion()
Definition: GModel.h:358
meshGFace.h
discreteEdge.h
Context.h
GRegion::embeddedEdges
std::vector< GEdge * > & embeddedEdges()
Definition: GRegion.h:80
MTetrahedron.h
meshGRegionHxt
int meshGRegionHxt(std::vector< GRegion * > &regions)
Definition: meshGRegionHxt.cpp:674
GRegion::meshAttributes
struct GRegion::@20 meshAttributes
GEdge
Definition: GEdge.h:26
ALGO_3D_DELAUNAY
#define ALGO_3D_DELAUNAY
Definition: GmshDefines.h:250
qmTetrahedron::QMTET_GAMMA
@ QMTET_GAMMA
Definition: qualityMeasures.h:68
buildFaceSearchStructure
bool buildFaceSearchStructure(GModel *model, fs_cont &search, bool onlyTriangles)
Definition: meshGRegion.cpp:286
ALGO_3D_INITIAL_ONLY
#define ALGO_3D_INITIAL_ONLY
Definition: GmshDefines.h:251
meshGRegion.h
fs_cont
std::map< MFace, GFace *, MFaceLessThan > fs_cont
Definition: meshGRegion.h:60
GModel::lastEdge
eiter lastEdge()
Definition: GModel.h:360
GModel.h
MFace::getNumVertices
std::size_t getNumVertices() const
Definition: MFace.h:29
optimizeMesh
void optimizeMesh(GRegion *gr, const qmTetrahedron::Measures &qm)
Definition: meshGRegionDelaunayInsertion.cpp:876
splitQuadRecovery::_tri
std::map< MFace, GFace *, MFaceLessThan > _tri
Definition: meshGRegion.h:75
ExtrudeParams
Definition: ExtrudeParams.h:26
GEntity::getVisibility
virtual char getVisibility()
Definition: GEntity.cpp:35
GModel::setAllVolumesPositive
bool setAllVolumesPositive()
Definition: GModel.cpp:1085
GModel::setCurrentMeshEntity
void setCurrentMeshEntity(GEntity *e)
Definition: GModel.cpp:2202
meshRelocateVertex.h
GRegion::embeddedVertices
std::vector< GVertex * > & embeddedVertices()
Definition: GRegion.h:79
faces
static int faces[4][3]
Definition: meshGRegionDelaunayInsertion.cpp:165