NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
gmshGen.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
30 #define _USE_MATH_DEFINES
31 #endif
32 
33 #include "AuxiliaryFunctions.H"
34 #include "MeshGeneration/gmshGen.H"
36 #include "Mesh/gmshTypes.H"
37 
38 #include <gmsh.h>
39 
40 #include <iostream>
41 #include <utility>
42 #include <vector>
43 
44 #include <cmath>
45 
46 namespace NEM {
47 
48 namespace GEN {
49 
50 // Default Constructor
52  // Default meshing parameters
53  meshParams = new gmshParams();
54 }
55 
56 gmshGen::gmshGen(gmshParams *params) : meshParams(params) {}
57 
59 
60 int gmshGen::createMeshFromSTL(const char *fname) {
61  int ret;
62  ret = createMeshFromSTEP(fname);
63  if (ret == 0)
64  return 0;
65  else
66  return 1;
67 }
68 
69 int gmshGen::createMeshFromSTEP(const char *fname) {
70  std::cout << "Mimimum mesh size " << meshParams->minSize << "\n"
71  << "Maximum mesh size " << meshParams->maxSize << "\n"
72  << "Surface algorithm " << meshParams->algo2D << "\n"
73  << "Volume algorithm " << meshParams->algo3D << std::endl;
74  // Initialize Gmsh
75  gmsh::initialize();
76  // Set global options from JSON
77  globalOptions();
78 
79  std::string file = fname;
80  std::vector<std::pair<int, int>> imported;
81  std::ifstream f;
82  f.open(file);
83  if (!f.good()) {
84  std::cerr << "Error: Input Geometry File " << file << " not found."
85  << std::endl;
86  gmsh::finalize();
87  exit(-1);
88  }
89  f.close();
90  gmsh::model::occ::importShapes(file, imported, false);
91  gmsh::model::occ::synchronize();
92 
93  // getGeomNames();
94 
95  if(meshParams->fragmentAll) {
96  // get all volumes
97  gmsh::vectorpair volumes;
98  gmsh::model::getEntities(volumes, 3);
99  // fragment
100  gmsh::vectorpair outTags;
101  std::vector<gmsh::vectorpair> outDimTagsMap;
102  gmsh::model::occ::fragment(volumes, {}, outTags, outDimTagsMap);
103  gmsh::model::occ::synchronize();
104  }
105 
106  // Apply mesh size fields
107  if (!meshParams->sizeFields.empty()) meshSizeFields();
108 
109  // Apply mesh color naming
110  if (!meshParams->color2groupMap.empty()) applyColorNames();
111 
112  // Apply transfinite volumes
114 
115  gmsh::model::mesh::generate(3);
116  gmsh::model::mesh::removeDuplicateNodes();
117  // By default, ouput MSH file
118  mshFname = nemAux::trim_fname(fname, ".msh");
119  gmsh::write(mshFname);
120 
121  std::string ext = nemAux::find_ext(meshParams->ofname);
122 
123  if (ext != ".msh" && ext != ".vtu") {
124  auto &meshExtensions = gmshParams::getMeshExtensions();
125  auto pos = std::find(meshExtensions.begin(), meshExtensions.end(), ext);
126  if (pos == meshExtensions.end()) {
127  std::cerr << "Error: Output file extension " << ext
128  << " not supported in this mesh engine." << std::endl;
129  std::cout << "Supported formats are ";
130  for (auto meshExtension : meshExtensions) {
131  std::cout << meshExtension << " ";
132  }
133  std::cout << "\n" << std::endl;
134  } else {
135  // IF save format is INP or UNV, save physical groups to blocks/nodesets
136  if (ext == ".inp" || ext == ".unv") {
137  gmsh::option::setNumber("Mesh.SaveGroupsOfElements", 1);
138  gmsh::option::setNumber("Mesh.SaveGroupsOfNodes", 1);
139  }
140  gmsh::write(meshParams->ofname);
141  }
142  }
143  gmsh::finalize();
144  return 0;
145 }
146 
147 //********************************************************************//
148 // Sets the global geometry and mesh options
149 //********************************************************************//
151  //------------------------ General Options ----------------------//
152  //---------------------------------------------------------------//
153  gmsh::option::setNumber("General.Terminal", 1);
154 
155  //----------------------- Geometry Options ----------------------//
156  //---------------------------------------------------------------//
157  gmsh::option::setNumber("Geometry.OCCImportLabels", 1);
158 
159  //------------------------- Mesh Options ------------------------//
160  //---------------------------------------------------------------//
161  gmsh::option::setNumber("Mesh.MshFileVersion", 2.2);
162  gmsh::option::setNumber("Mesh.CharacteristicLengthMin", meshParams->minSize);
163  gmsh::option::setNumber("Mesh.CharacteristicLengthMax", meshParams->maxSize);
165  gmsh::option::setNumber("Mesh.CharacteristicLengthExtendFromBoundary", 1);
166  else
167  gmsh::option::setNumber("Mesh.CharacteristicLengthExtendFromBoundary", 0);
169  gmsh::option::setNumber("Mesh.CharacteristicLengthFromCurvature", 1);
170  else
171  gmsh::option::setNumber("Mesh.CharacteristicLengthFromCurvature", 0);
172  gmsh::option::setNumber("Mesh.MinimumElementsPerTwoPi",
174  if (meshParams->optimize)
175  gmsh::option::setNumber("Mesh.Optimize", 1);
176  else
177  gmsh::option::setNumber("Mesh.Optimize", 0);
178  gmsh::option::setNumber("Mesh.OptimizeThreshold",
180  gmsh::option::setNumber("Mesh.SaveAll", meshParams->saveAll);
181  gmsh::option::setNumber("Mesh.RecombineAll", 0);
182  gmsh::option::setNumber("Mesh.Smoothing", 1);
183  gmsh::option::setNumber("Mesh.CharacteristicLengthFactor", 1);
184  gmsh::option::setNumber("Mesh.CharacteristicLengthFromPoints", 1);
185  gmsh::option::setNumber("Mesh.LcIntegrationPrecision", 1e-09);
186  gmsh::option::setNumber("Mesh.MaxIterDelaunay3D", 0);
187  gmsh::option::setNumber("Mesh.RandomFactor", 1e-09);
188  gmsh::option::setNumber("Mesh.RandomFactor3D", 1e-12);
189  gmsh::option::setNumber("Mesh.ElementOrder",
191  gmsh::option::setNumber("Mesh.SubdivisionAlgorithm",
193 
194  std::string algo = meshParams->algo2D;
195  int a = ALGO_2D_FRONTAL; // default: "Frontal"
196  if (algo == "Frontal")
197  a = ALGO_2D_FRONTAL;
198  else if (algo == "MeshAdapt")
199  a = ALGO_2D_MESHADAPT;
200  else if (algo == "Automatic")
201  a = ALGO_2D_AUTO;
202  else if (algo == "Delaunay")
203  a = ALGO_2D_DELAUNAY;
204  else if (algo == "Frontal Quads" || algo == "Frontal Quad")
206  else if (algo == "Packing of Parallelograms")
208  else {
209  std::cerr << "Warning: Surface algorithm " << algo << " not supported. \n"
210  << "Using default Frontal algorithm." << std::endl;
211  }
212  gmsh::option::setNumber("Mesh.Algorithm", a);
213 
214  algo = meshParams->algo3D;
215  a = ALGO_3D_DELAUNAY;
216  if (algo == "Delaunay")
217  a = ALGO_3D_DELAUNAY;
218  else if (algo == "Frontal")
219  a = ALGO_3D_FRONTAL;
220  else if (algo == "HXT")
221  a = ALGO_3D_HXT;
222  else {
223  std::cerr << "Warning: Volume algorithm " << algo << " not supported. \n"
224  << "Using default Delaunay algorithm." << std::endl;
225  }
226  gmsh::option::setNumber("Mesh.Algorithm3D", a);
227 }
228 
229 //********************************************************************//
230 // Gets the surface colors from geometry
231 //********************************************************************//
233  // Get all surfaces
234  std::vector<std::pair<int, int>> surfaces;
235  gmsh::model::getEntities(surfaces, 2);
236  std::string name = "";
237  for (const std::pair<int, int> &s : surfaces) {
238  int dim = s.first;
239  int tag = s.second;
240  gmsh::model::getEntityName(dim, tag, name);
241  std::cout << "Surface " << tag << " name: " << name << std::endl;
242  }
243  gmsh::model::getEntityName(3, 1, name);
244  std::cout << "Volume " << 1 << " name: " << name << std::endl;
245 }
246 
247 //********************************************************************//
248 // Gets the surface colors from geometry
249 //********************************************************************//
251  // Get all surfaces
252  std::vector<std::pair<int, int>> surfaces;
253  gmsh::model::getEntities(surfaces, 2);
254  for (const std::pair<int, int> &s : surfaces) {
255  int dim = s.first;
256  int tag = s.second;
257  int r, g, b, a;
258  gmsh::model::getColor(dim, tag, r, g, b, a);
259  std::cout << "Surface " << tag << " color: " << r << "," << g << "," << b
260  << std::endl;
261  }
262 }
263 
264 //********************************************************************//
265 // Applies mesh size fields
266 //********************************************************************//
268  bool bgfAssigned = false;
269  int highest_id = -1;
270  int id = -1;
271 
272  // Loop through fields in search of Frustum.IField option
273  for (auto &sf : meshParams->sizeFields) {
274  std::string type = sf.type;
275  if (sf.type == "Frustum") {
276  double thick = 0.0;
277  for (auto &prm : sf.params) {
278  if (prm.first == "Thickness") {
279  thick = prm.second;
280  std::cout << "thickness = " << thick << std::endl;
281  break;
282  }
283  }
284  for (auto &prm : sf.params) {
285  std::string key = prm.first;
286  int val = static_cast<int>(prm.second);
287  if (key == "IField") {
288  for (auto &sf2 : meshParams->sizeFields) {
289  if (sf2.type == "Cylinder" && sf2.id == val) {
290  double radius = 0;
291  //double thick = 0;
292  double vin = 10.0;
293  double vout = 10.0;
294  double xc = 0.0;
295  double yc = 0.0;
296  double zc = 0.0;
297  double xa = 0.0;
298  double ya = 0.0;
299  double za = 0.0;
300  // Get Cylinder field parameters
301  for (auto &prm2 : sf2.params) {
302  if (prm2.first == "Radius") radius = prm2.second;
303  //if (prm2.first == "Thickness") thick = prm2.second;
304  if (prm2.first == "VIn") vin = prm2.second;
305  if (prm2.first == "VOut") vout = prm2.second;
306  if (prm2.first == "XCenter") xc = prm2.second;
307  if (prm2.first == "YCenter") yc = prm2.second;
308  if (prm2.first == "ZCenter") zc = prm2.second;
309  if (prm2.first == "XAxis") xa = prm2.second;
310  if (prm2.first == "YAxis") ya = prm2.second;
311  if (prm2.first == "ZAxis") za = prm2.second;
312  }
313 
314  // Clear the Frustum parameters
315  sf.params.clear();
316 
317  // Calculate Frustum parameters from Cylinder params and insert
318  std::pair<std::string, double> p;
319  p = {"R1_inner", radius};
320  sf.params.push_back(p);
321  p = {"R1_outer", radius + thick};
322  sf.params.push_back(p);
323  p = {"R2_inner", radius};
324  sf.params.push_back(p);
325  p = {"R2_outer", radius + thick};
326  sf.params.push_back(p);
327 
328  p = {"V1_inner", vin};
329  sf.params.push_back(p);
330  p = {"V2_inner", vin};
331  sf.params.push_back(p);
332  p = {"V1_outer", vout};
333  sf.params.push_back(p);
334  p = {"V2_outer", vout};
335  sf.params.push_back(p);
336 
337  double mag = sqrt(xa * xa + ya * ya + za * za);
338 
339  p = {"X1", xc - xa / 2 - xa * (thick / mag)};
340  sf.params.push_back(p);
341  p = {"Y1", yc - ya / 2 - ya * (thick / mag)};
342  sf.params.push_back(p);
343  p = {"Z1", zc - za / 2 - za * (thick / mag)};
344  sf.params.push_back(p);
345 
346  p = {"X2", xc + xa / 2 + xa * (thick / mag)};
347  sf.params.push_back(p);
348  p = {"Y2", yc + ya / 2 + ya * (thick / mag)};
349  sf.params.push_back(p);
350  p = {"Z2", zc + za / 2 + za * (thick / mag)};
351  sf.params.push_back(p);
352  }
353  }
354  break;
355  }
356  }
357  }
358  }
359 
360  // Loop through all size fields
361  for (auto sf = (meshParams->sizeFields).begin();
362  sf != (meshParams->sizeFields).end(); sf++) {
363  if (sf->id == meshParams->bgField) {
364  bgfAssigned = true;
365  id = sf->id;
366  }
367 
368  gmsh::model::mesh::field::add(sf->type, sf->id);
369  for (auto prm = (sf->params).begin(); prm != (sf->params).end(); prm++) {
370  if (prm->first != "")
371  gmsh::model::mesh::field::setNumber(sf->id, prm->first, prm->second);
372  }
373 
374  // Keep this code for later when surface names are used
375  // for (auto prm = (sf->strg_list_params).begin();
376  // prm != (sf->strg_list_params).end();
377  // prm++)
378  // {
379  // gmsh::model::mesh::field::setNumbers(sf->id, prm->first, prm->second);
380  // //std::cout << sf->id << " " << prm->first << " " << prm->second <<
381  // std::endl;
382  // }
383 
384  for (auto prm = (sf->num_list_params).begin();
385  prm != (sf->num_list_params).end(); prm++) {
386  gmsh::model::mesh::field::setNumbers(sf->id, prm->first, prm->second);
387  }
388 
389  highest_id = sf->id;
390  }
391 
392  // Assign the Background Field (size field)
393  if (bgfAssigned) {
394  gmsh::model::mesh::field::setAsBackgroundMesh(meshParams->bgField);
395  std::cout << "Using size field ID = " << id << std::endl;
396  } else {
397  gmsh::model::mesh::field::setAsBackgroundMesh(highest_id);
398  std::cout << "Warning: BackgroundField ID not found. "
399  << "Using size field with highest ID." << std::endl;
400  }
401  gmsh::model::occ::synchronize();
402 }
403 
405  // Get all volumes
406  std::vector<std::pair<int, int>> volumes;
407  gmsh::model::getEntities(volumes, 3);
408 
409  std::vector<int> volumeTags;
410  for(const std::pair<int,int> &v : volumes) {
411  // int dim = v.first;
412  int tag = v.second;
413  volumeTags.push_back(tag);
414  }
415  gmsh::model::addPhysicalGroup(3, volumeTags);
416 
417  // Get all surfaces
418  std::vector<std::pair<int, int>> surfaces;
419  gmsh::model::getEntities(surfaces, 2);
420 
421  /*
422  * 1. Find all surfaces with given color.
423  * 2. Name each surface with unique name based on group name.
424  * e.g. if name is <group_name>, surfaces will be
425  * named <group_name>_0, <group_name>_1, ...
426  * 3. Give physical group the assigned name <group_name>
427  */
428 
429  // loop over color, group names and find constituent surfaces
430  for(auto iter = meshParams->color2groupMap.begin();
431  iter != meshParams->color2groupMap.end(); ++iter) {
432  const auto &groupColor = iter->first;
433  std::string groupColorStr = std::to_string(groupColor.at(0)) + "," +
434  std::to_string(groupColor.at(1)) + "," +
435  std::to_string(groupColor.at(2));
436  std::string groupName = iter->second;
437  std::vector<int> surfTags;
438 
439  int id = 0;
440  for(const std::pair<int,int> &s : surfaces) {
441  int dim = s.first;
442  int tag = s.second;
443  int r, g, b, a;
444  gmsh::model::getColor(dim, tag, r, g, b, a);
445  if (groupColor != std::array<int, 3>{r, g, b}) continue;
446  std::string surfName = groupName + "_" + std::to_string(id);
447  gmsh::model::setEntityName(dim, tag, surfName);
448  surfTags.push_back(tag);
449  ++id;
450  }
451  if(surfTags.size() == 0) {
452  std::cout << "NO SURFACES WITH COLOR " << groupColorStr << " FOUND."
453  << std::endl;
454  } else {
455  std::cout << "Found "
456  << surfTags.size()
457  << ((surfTags.size() == 1) ? " surface" : " surfaces")
458  << " in group "
459  << groupName
460  << " mapped by color "
461  << groupColorStr
462  << std::endl;
463  std::cout << "Adding physical group " << groupName << std::endl;
464  int groupTag = gmsh::model::addPhysicalGroup(2, surfTags);
465  gmsh::model::setPhysicalName(2, groupTag, groupName.c_str());
466  }
467  }
468  gmsh::model::occ::synchronize();
469 }
470 
472  gmsh::vectorpair volumes;
473  gmsh::model::getEntities(volumes, 3);
474 
475  for(const std::pair<int,int> &v : volumes) {
476  // int volumeDim = v.first;
477  int volumeTag = v.second;
478 
479  // Use lower_bound because TransfiniteBlock::operator< is based on id
480  auto blockIter = std::lower_bound(
481  meshParams->transfiniteBlocks.begin(),
482  meshParams->transfiniteBlocks.end(), volumeTag,
483  [](const TransfiniteBlock &block, int tag) { return block.id < tag; });
484  // if not a transfinite volume, continue
485  if (blockIter == meshParams->transfiniteBlocks.end() ||
486  blockIter->id != volumeTag) {
487  continue;
488  }
489 
490  const auto &block = *blockIter;
491 
492  gmsh::vectorpair volume = { v };
493  gmsh::vectorpair surfaces;
494  gmsh::vectorpair curves;
495  // get all entities (combined - false, oriented - false, recursive - false)
496  gmsh::model::getBoundary(volume, surfaces, false, false, false);
497  gmsh::model::getBoundary(surfaces, curves, false, false, false);
498 
499  // loop over curves c, ignore duplicates
500  gmsh::vectorpair uniqueCurves;
501  for(const std::pair<int,int> &c : curves) {
502  auto iter = std::find(uniqueCurves.begin(), uniqueCurves.end(), c);
503  if (iter == uniqueCurves.end()) {
504  uniqueCurves.push_back(c);
505  }
506  }
507 
508  if(uniqueCurves.size() != 12) {
509  std::cout << "Found " << uniqueCurves.size() << " unique curves in volume " << volumeTag <<
510  ". There should be 12." << std::endl;
511  std::cout << "Error : only hexahedral transfinite volumes are supported." << std::endl;
512  throw;
513  }
514 
515  std::cout << "Found transfinite block : " << volumeTag << std::endl;
516 
517  struct CurveData {
518  int axis;
519  std::pair<int,int> curve;
520  bool reverse;
521  };
522 
523  std::vector<CurveData> orientedCurves;
524 
525  for(const std::pair<int,int> &c : uniqueCurves) {
526  // get points in curve, getBoundary requires vector of entities
527  gmsh::vectorpair curves = { c };
528  gmsh::vectorpair points;
529  gmsh::model::getBoundary(curves, points, false, true, true);
530 
531  std::pair<int,int> a = points[0];
532  std::pair<int,int> b = points[1];
533 
534  std::vector<double> a_vert, b_vert;
535  gmsh::model::getValue(a.first, a.second, {}, a_vert);
536  gmsh::model::getValue(b.first, b.second, {}, b_vert);
537 
538  // normalize
539  double ab[] = { b_vert[0]-a_vert[0],
540  b_vert[1]-a_vert[1],
541  b_vert[2]-a_vert[2] };
542  double ab_den = std::sqrt(ab[0]*ab[0] + ab[1]*ab[1] + ab[2]*ab[2]);
543  ab[0] = ab[0]/ab_den;
544  ab[1] = ab[1]/ab_den;
545  ab[2] = ab[2]/ab_den;
546 
547  // get corresponding direction
548  // i=0 -> x-axis
549  // i=1 -> y-axis
550  // i=2 -> z-axis
551  for(int axis = 0; axis < 3; ++axis) {
552  double dot = ab[0]*block.axis[axis][0] +
553  ab[1]*block.axis[axis][1] +
554  ab[2]*block.axis[axis][2];
555  double theta = std::acos(dot);
556  if(theta < M_PI/4 || theta > 3*M_PI/4) {
557  bool reverse = theta >= M_PI / 4;
558  CurveData data;
559  data.axis = axis;
560  data.curve = c;
561  data.reverse = reverse;
562  orientedCurves.push_back(data);
563  }
564  }
565  }
566 
567  for(auto &oc : orientedCurves) {
568  // curve data
569  std::pair<int,int> curve = oc.curve;
570  bool reverse = oc.reverse;
571 
572  // transfinite data
573  int vert = block.vert[oc.axis];
574  double coef = block.coef[oc.axis];
575  std::string type = block.type[oc.axis];
576 
577  if(type == "Progression") {
578  // take reciprocal of coefficient if curve is "reversed" w.r.t axis
579  coef = reverse ? 1/coef : coef;
580  }
581 
582  gmsh::model::mesh::setTransfiniteCurve(curve.second, vert, type, coef);
583  }
584 
585  std::cout << "Setting transfinite surfaces..." << std::endl;
586  for(const std::pair<int,int> &s : surfaces) {
587  gmsh::model::mesh::setTransfiniteSurface(s.second);
588  gmsh::model::mesh::setRecombine(s.first, s.second);
589  }
590 
591  std::cout << "Setting transfinite volume..." << std::endl;
592  gmsh::model::mesh::setTransfiniteVolume(v.second);
593  }
594 }
595 
596 } // namespace GEN
597 
598 } // namespace NEM
double maxSize
Maximum global mesh size.
Definition: gmshParams.H:108
~gmshGen()
gmshGen standard destructor
Definition: gmshGen.C:58
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
std::string mshFname
Name of .msh file output by gmsh.
Definition: gmshGen.H:100
int elementOrder
Element order.
Definition: gmshParams.H:145
static const std::array< const char *, 6 > & getMeshExtensions()
Get list of file extensions supported by gmsh.
Definition: gmshParams.H:178
bool sizeFromCurvature
Mesh size based on curvature option.
Definition: gmshParams.H:124
void globalOptions()
Sets the global geometry and meshing options.
Definition: gmshGen.C:150
int bgField
Size field ID to use as background field.
Definition: gmshParams.H:140
A struct for defining hexahedral transfinite volumes.
Definition: gmshParams.H:67
std::string find_ext(const std::string &fname)
int createMeshFromSTL(const char *fname) override
Creates mesh from input STEP file.
Definition: gmshGen.C:60
gmshGen()
gmshGen default constructor
Definition: gmshGen.C:51
std::set< TransfiniteBlock > transfiniteBlocks
Map from volume id to transfinite hexahedron information.
Definition: gmshParams.H:172
void meshSizeFields()
Applies mesh size fields.
Definition: gmshGen.C:267
bool extSizeFromBoundary
Extend mesh size from boundary option.
Definition: gmshParams.H:120
void getSurfaceColors()
Gets the surface colors of STEP geometry.
Definition: gmshGen.C:250
double minSize
Minimum global mesh size.
Definition: gmshParams.H:104
std::string trim_fname(const std::string &name, const std::string &ext)
std::string algo3D
Volume meshing algorithm.
Definition: gmshParams.H:116
void applyTransfiniteVolumes()
Applies transfinite settings to prescribed hexahedral volumes.
Definition: gmshGen.C:471
std::map< std::array< int, 3 >, std::string > color2groupMap
Map from RGB to physical name.
Definition: gmshParams.H:168
gmshParams contains all parameters essential for mesh generation using gmshGen class methods...
Definition: gmshParams.H:92
bool saveAll
Save all elements.
Definition: gmshParams.H:155
vtkIdType id
id in .inp file
Definition: inpGeoMesh.C:128
std::string ofname
Output mesh file name.
Definition: gmshParams.H:100
std::vector< vtkIdType > points
points given by id in .inp file
Definition: inpGeoMesh.C:133
std::string algo2D
Surface meshing algorithm.
Definition: gmshParams.H:112
std::map< std::string, std::vector< std::pair< vtkIdType, int > > > surfaces
Map from SURFACE name to (element id, side) (id and side both use .inp IDs)
Definition: inpGeoMesh.C:157
bool optimize
Whether to optimize mesh or not.
Definition: gmshParams.H:132
bool fragmentAll
Whether to call boolean fragments on all volumes.
Definition: gmshParams.H:160
double optimizeThreshold
Mesh optimization threshold, between 0 and 1.
Definition: gmshParams.H:136
int minElePer2Pi
Minimum number of mesh elements per two Pi.
Definition: gmshParams.H:128
int subdivisionAlg
Subdivision algorithm 0: none, 1: all quads, 2: all hexas.
Definition: gmshParams.H:150
int createMeshFromSTEP(const char *fname)
Definition: gmshGen.C:69
void applyColorNames()
Applies physical names based on color.
Definition: gmshGen.C:404
void getGeomNames()
Gets geometry entitiy names of STEP geometry.
Definition: gmshGen.C:232
gmshParams * meshParams
gmshParams object Parameters
Definition: gmshGen.H:96
std::vector< volSizeField > sizeFields
Vector for volSizeField struct.
Definition: gmshParams.H:164