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.
NEM::DRV::HexPackMeshDriver Class Reference

Detailed Description

Hexahedral meshing pipeline creates different objects for different meshing engines in NEMoSys, as well as objects of mesh manipulation utilities to complete the meshing workflow.

  • Geometry generation using RocPack output file.
  • Generation of STL file for workflow downstream.
  • Generation of background mesh for snappyHexMesh
  • Snapping of pack surfaces onto background volume mesh to create conformal

interfaces.

  • Splitting multiple pack regions into different cellZones (volumes).
  • Merging all different volumes into two different foam mesh (1.

Packs, 2. Surrounding)

  • Creating patch for Packs and Surrounding regions.
  • Conversion of foam mesh to VTK.
  • Provides mesh quality statistics to users in a text file.

Definition at line 59 of file HexPackMeshDriver.H.

Classes

struct  Files
 
struct  Opts
 

Public Member Functions

 HexPackMeshDriver (Files files, Opts opts)
 
const FilesgetFiles () const
 
void setFiles (Files files)
 
const OptsgetOpts () const
 
void setOpts (Opts opts)
 
void execute () const override
 Run the workflow represented by the driver. More...
 

Static Public Member Functions

static std::unique_ptr< NemDriverreadJSON (const jsoncons::json &inputjson)
 Factory method for all drivers. More...
 

Private Member Functions

 HexPackMeshDriver ()
 

Private Attributes

Files files_
 
Opts opts_
 

Inherits NEM::DRV::PackMeshDriver.

Constructor & Destructor Documentation

◆ HexPackMeshDriver() [1/2]

NEM::DRV::HexPackMeshDriver::HexPackMeshDriver ( Files  files,
Opts  opts 
)

Definition at line 67 of file HexPackMeshDriver.C.

68  : files_(std::move(files)), opts_(std::move(opts)) {}

◆ HexPackMeshDriver() [2/2]

NEM::DRV::HexPackMeshDriver::HexPackMeshDriver ( )
private

Definition at line 70 of file HexPackMeshDriver.C.

71  : HexPackMeshDriver({{}, {}, {}, {}}, {}) {}

Member Function Documentation

◆ execute()

void NEM::DRV::HexPackMeshDriver::execute ( ) const
overridevirtual

Implements NEM::DRV::NemDriver.

Definition at line 142 of file HexPackMeshDriver.C.

References NEM::DRV::HexPackMeshDriver::Opts::bmParams, bmBox::coordsBox, MeshManipulationFoamParams::createPatchParams, files_, NEM::DRV::HexPackMeshDriver::Files::getInputFile(), NEM::DRV::HexPackMeshDriver::Files::isInputRocpackFile(), blockMeshParams::isPackMesh, snappymeshParams::isPackMesh, NEM::DRV::HexPackMeshDriver::Opts::locAdjust, MeshManipulationFoamParams::mergeMeshesParams, mesh, NEM::DRV::HexPackMeshDriver::Opts::mmfCreatePatchParams, NEM::DRV::HexPackMeshDriver::Opts::mmfMergeParams, NEM::MSH::New(), opts_, NEM::DRV::HexPackMeshDriver::Files::outCombinedFile, MeshManipulationFoamParams::SurfaceSplitByManifold::pckRegionNames, NEM::MSH::Read(), NEM::DRV::HexPackMeshDriver::Opts::smParams, and MeshManipulationFoamParams::surfSplitParams.

142  {
143  // Makes sure that constant and triSurface directories are present.
144  // If directories are already present, it will not do anything.
145  const char dir_path[] = "./constant";
146  boost::filesystem::path dir(dir_path);
147  try {
148  boost::filesystem::create_directory(dir);
149  } catch (boost::filesystem::filesystem_error &e) {
150  std::cerr << "Problem in creating triSurface directory"
151  << "for the snappyHexMesh"
152  << "\n";
153  std::cerr << e.what() << std::endl;
154  throw;
155  }
156 
157  const char dir_path1[] = "./constant/triSurface";
158  boost::filesystem::path dir1(dir_path1);
159  try {
160  boost::filesystem::create_directory(dir1);
161  } catch (boost::filesystem::filesystem_error &e) {
162  std::cerr << "Problem in creating triSurface directory"
163  << "for the snappyHexMesh"
164  << "\n";
165  std::cerr << e.what() << std::endl;
166  throw;
167  }
168 
169  // This object has access to all MeshManipulation utilities.
170  MeshManipulationFoamParams mmfParams; // should outlive objMsh
171  mmfParams.mergeMeshesParams = this->opts_.mmfMergeParams;
172  mmfParams.createPatchParams = this->opts_.mmfCreatePatchParams;
173  auto objMsh = std::unique_ptr<MeshManipulationFoam>(
174  new MeshManipulationFoam(&mmfParams));
175  const char *nameFile = "a"; // Dummy name for input
176 
177  // A rocpack method that creates stl and then moves it to triSurface using
178  // boost.
179  if (this->files_.isInputRocpackFile()) {
180 #ifdef HAVE_GMSH
181  std::string hexOutSTL = this->files_.getInputFile() + ".stl";
182  auto objrocPck = std::unique_ptr<NEM::GEO::rocPack>(
183  new NEM::GEO::rocPack(this->files_.getInputFile(), hexOutSTL));
184 
185  objrocPck->removeBoundaryVolumes();
186  objrocPck->rocPack2Surf();
187 
188  // const std::string dir_path11 = hexOutSTL;
189  boost::filesystem::path dir11(hexOutSTL);
190 
191  const std::string dir_path2 =
192  "./constant/triSurface/" + this->files_.getInputFile() + ".stl";
193  boost::filesystem::path dir2(dir_path2);
194 
195  boost::filesystem::copy_file(
196  dir11, dir2, boost::filesystem::copy_option::overwrite_if_exists);
197 #else
198  std::cerr << "Cannot process rocPack input file without gmsh.\n";
199  std::exit(1);
200 #endif
201  } else {
202  const std::string dir_path11 = this->files_.getInputFile();
203  boost::filesystem::path dir11(dir_path11);
204 
205  const std::string dir_path2 =
206  "./constant/triSurface/" + this->files_.getInputFile();
207  boost::filesystem::path dir2(dir_path2);
208 
209  boost::filesystem::copy_file(
210  dir11, dir2, boost::filesystem::copy_option::overwrite_if_exists);
211  }
212 
213  // blockMesh utility takes user input for surrounding box region and
214  // generates mesh block in constant/polyMesh folder. It will overwrite the
215  // previous mesh created by CfMesh. This mesh will be used as background mesh
216  // by snappyHexMesh later.
217  auto bmParamsCopy = this->opts_.bmParams; // should outlive objBM
218  bmParamsCopy.isPackMesh = true;
219  auto objBM = std::unique_ptr<blockMeshGen>(new blockMeshGen(&bmParamsCopy));
220  objBM->createMeshFromSTL(nameFile);
221 
222  // Updating location for next process
223  auto adjust = this->opts_.locAdjust >= 0. ? this->opts_.locAdjust : 0.;
224  auto smParamsCopy = this->opts_.smParams; // should outlive objSHM
225  smParamsCopy.isPackMesh = true;
226  smParamsCopy.castMeshControls.locMesh[0] =
227  std::dynamic_pointer_cast<bmBox>(bmParamsCopy.shape)->coordsBox.first[0] +
228  0.001 + adjust;
229  smParamsCopy.castMeshControls.locMesh[1] =
230  std::dynamic_pointer_cast<bmBox>(bmParamsCopy.shape)->coordsBox.first[1] +
231  0.001 + adjust;
232  smParamsCopy.castMeshControls.locMesh[2] =
233  std::dynamic_pointer_cast<bmBox>(bmParamsCopy.shape)->coordsBox.first[2] +
234  0.001 + adjust;
235 
236  // snappyHexMesh reads background mesh created using blockMesh and takes
237  // surface file from foamToSurface utility to snap pack surface onto back-
238  // ground mesh and creates different cellZones (i.e different solids). These
239  // interfaces between pack and surrounding regions are completely conformal
240  // due to snappyHexMesh's unique snapping abilities.
241  auto objSHM =
242  std::unique_ptr<snappymeshGen>(new snappymeshGen(&smParamsCopy));
243  objSHM->createMeshFromSTL(nameFile);
244 
245  // splitMeshRegions reads mesh from constant/polyMesh directory and splits
246  // mesh into separate regions. Each region will represent one solid. It will
247  // write bunch of domain.* directories inside constant/ and system/ folders.
248  // This function does a random walking around mesh to identify different
249  // regions and in that process, while naming all domains as domain.*
250  // in constant folder, it skips one number for the disconnected region it
251  // encounters first. This number is taken out to provide as input to merge
252  // mesh.
253  std::pair<std::vector<int>, std::vector<std::string>> dirStat =
254  objMsh->splitMshRegions();
255 
256  std::string surroundingRegion = dirStat.second[0];
257  mmfParams.surfSplitParams.pckRegionNames = dirStat.second;
258 
259  /*std::pair<std::vector<int>, std::string> dirStat =
260  objMsh->splitMshRegions(); int skippedDir = dirStat.first[0]; int totalRegs =
261  dirStat.first[1] - 1; std::string surroundingRegion = dirStat.second;
262  */
263 
264  // *************** Merge meshes using geoMeshBase and write
265  // *******************// packRegNames is a vector containing all names of pack
266  // regions
267  mmfParams.surfSplitParams.pckRegionNames.erase(
268  mmfParams.surfSplitParams.pckRegionNames.begin());
269  std::vector<std::string> packRegNames =
271 
272  // FoamGeoMesh
273  auto fgm_ = NEM::MSH::Read(surroundingRegion + ".foam");
275  mesh->takeGeoMesh(fgm_);
276 
277  for (auto &packRegName : packRegNames) {
278  auto fgm_loop = NEM::MSH::Read(packRegName + ".foam");
279  mesh->mergeGeoMesh(fgm_loop);
280  }
281 
282  mesh->write(this->files_.outCombinedFile);
283 
284  mesh->Delete();
285  fgm_->Delete();
286 
287  // *************** Merge meshes using meshBase and write *******************//
288 
289  // bool readDB = false;
290  // // Create surrounding region database
291  // meshBase *fm = new FOAM::foamMesh(readDB);
292  // fm->read(surroundingRegion);
293  // std::vector<double> physId = std::vector<double>(fm->getNumberOfCells(),
294  // 0); auto *vm = new vtkMesh(fm->getDataSet(),
295  // this->files_.outCombinedFile); vm->setCellDataArray("PhysGrpId", physId);
296  //
297  // // Loop through all pack particles and merge their databases into main
298  // // database
299  // for (int i = 0; i < (int) packRegNames.size(); i++) {
300  // fm->read(packRegNames[i]);
301  // std::vector<double> physIdLoop =
302  // std::vector<double>(fm->getNumberOfCells(), i + 1);
303  // auto *vm2 =
304  // new vtkMesh(fm->getDataSet(), "pack" + std::to_string(i) + ".vtu");
305  // vm2->setCellDataArray("PhysGrpId", physIdLoop);
306  // // vm2->write();
307  // vm->merge(vm2->getDataSet());
308  // }
309  //
310  // // Write mesh and clean up objects
311  // vm->report();
312  // vm->write();
313  // delete vm;
314  // delete fm;
315 
316  // *************** Merge meshes using OF and write ************************ //
317  // Use this method for writing pack and surrounding meshes separately. This
318  // uses mergeMeshes method from "src/MeshManipulation/MeshManipulationFoam.C".
319  // It also writes merged mesh at the end. Use this as a replacement for the
320  // method directly above (Merge meshes using meshBase).
321 
322  // mergeMeshes will read master domain (defined by user) from constant folder
323  // and start merging other domain to it untill all slave domains are attached
324  // to master domain. It loops through all domains in sequential manner and
325  // skips the missing domain.* (also skipped by splitMeshRegions) to avoid
326  // runtime error.
327  // std::cout << "Total # of domains are = " << totalRegs << std::endl;
328  // if (totalRegs == 1) {
329  // // Nothing
330  // } else {
331  // objMsh->mergeMeshes(skippedDir, totalRegs);
332  // }
333 
334  // // Reads current mesh and write it to separate VTK/VTU files
335  // // Reads and converts pack mesh
336  // bool readDB = false;
337  // std::string regNme;
338  // if (skippedDir == 1)
339  // regNme = "domain2";
340  // else
341  // regNme = "domain1";
342 
343  // if (totalRegs == 1) regNme = _snappyparams->singleSolidPatch;
344 
345  // meshBase *fm = new FOAM::foamMesh(readDB);
346  // fm->read(regNme);
347  // vtkMesh *vm2 = new vtkMesh(fm->getDataSet(), ofname_pack);
348  // std::vector<double> physIdPack
349  // = std::vector<double>(fm->getNumberOfCells(),1);
350  // vm2->setCellDataArray("PhysGrpId",physIdPack);
351  // vm2->write();
352 
353  // // Reads and converts surronding mesh
354  // regNme = surroundingRegion;
355 
356  // if (totalRegs == 1) regNme = surroundingRegion;
357  // meshBase *fm2 = new FOAM::foamMesh(readDB);
358  // fm2->read(regNme);
359  // std::vector<double> physIdSurrounding
360  // = std::vector<double>(fm2->getNumberOfCells(),0);
361  // vtkMesh *vm3 = new vtkMesh(fm2->getDataSet(), ofname_surrndng);
362  // vm3->setCellDataArray("PhysGrpId",physIdSurrounding);
363  // vm3->write();
364 
365  // // Merge meshes and write
366  // vtkMesh *vm = new vtkMesh(vm2->getDataSet(),ofname_merged);
367  // vm->merge(vm3->getDataSet());
368  // vm->report();
369  // vm->write();
370  // if (vm) delete vm;
371  // if (fm) delete fm;
372  // if (vm2) delete vm2;
373  // if (fm2) delete fm2;
374  // if (vm3) delete vm3;
375 
376  // // Outputs useful mesh quality parameters for users
377  // std::string SurroundingName = "surroundingMeshQuality";
378  // std::string Surroundingmesh = "geom_surrounding_mesh.vtu";
379  // std::string PackName = "packMeshQuality";
380  // std::string Packmesh = "geom_pack_mesh.vtu";
381  // MeshQualityDriver *objSurrQ =
382  // new MeshQualityDriver(Surroundingmesh, SurroundingName);
383  // MeshQualityDriver *objPackQ = new MeshQualityDriver(Packmesh, PackName);
384  // if (objSurrQ) delete objSurrQ;
385  // if (objPackQ) delete objPackQ;
386  // *************** Merge meshes using OF and write ************************ //
387 
388  // End of workflow
389 }
snappymeshGen facilitates full-hexahedral/hex-dominent meshing of complex geometries with surface...
Definition: snappymeshGen.H:55
blockMeshGen <– meshGen <– meshBase This class incorporates mesh generating method of blockMesh uti...
Definition: blockMeshGen.H:54
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
This class converts Rockpack output file into periodic geometry and writes into STL, VTK, .MSH, and ExodusII file format.
Definition: rocPack.H:77
MeshManipulationFoamParams::CreatePatch mmfCreatePatchParams
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
MeshManipulationFoamParams defines basic parameters needed for utilities in MeshManipulationFoam clas...
std::string outCombinedFile
Combined mesh file name.
std::vector< std::string > pckRegionNames
A vector containing all region names for packs.
bool isPackMesh
Boolean for packmesh.
bool isPackMesh
Boolean for if the operation is packmesh.
MeshManipulation class contains several OpenFOAM utilities to perform various mesh manipulation opera...
SurfaceSplitByManifold surfSplitParams
double locAdjust
Perturb location in mesh if snappy fails.
std::shared_ptr< meshBase > mesh
std::pair< std::array< double, 3 >, std::array< double, 3 > > coordsBox
Pair of min and max box locations for autogenerate.
const std::string & getInputFile() const
MeshManipulationFoamParams::MergeMeshes mmfMergeParams

◆ getFiles()

const HexPackMeshDriver::Files & NEM::DRV::HexPackMeshDriver::getFiles ( ) const

Definition at line 73 of file HexPackMeshDriver.C.

References files_.

Referenced by setOpts().

73  {
74  return files_;
75 }

◆ getOpts()

const HexPackMeshDriver::Opts & NEM::DRV::HexPackMeshDriver::getOpts ( ) const

Definition at line 90 of file HexPackMeshDriver.C.

References opts_.

90  {
91  return opts_;
92 }

◆ readJSON()

std::unique_ptr< NemDriver > NEM::DRV::NemDriver::readJSON ( const jsoncons::json &  inputjson)
staticinherited
Parameters
inputjsonjson input with "Program Type" key
Returns
pointer to base NemDriver class

Definition at line 37 of file NemDriver.C.

Referenced by NEM::DRV::MeshGenDriver::MeshGenDriver().

37  {
38  return inputjson.as<std::unique_ptr<NemDriver>>();
39 }

◆ setFiles()

void NEM::DRV::HexPackMeshDriver::setFiles ( Files  files)

Definition at line 77 of file HexPackMeshDriver.C.

References NEM::DRV::HexPackMeshDriver::Opts::bmParams, files_, snappymeshParams::geomFileName, NEM::DRV::HexPackMeshDriver::Files::getInputFile(), NEM::DRV::HexPackMeshDriver::Files::isInputRocpackFile(), opts_, blockMeshParams::shape, and NEM::DRV::HexPackMeshDriver::Opts::smParams.

77  {
78  const auto stlFile = files.isInputRocpackFile()
79  ? files.getInputFile() + ".stl"
80  : files.getInputFile();
81  this->opts_.smParams.geomFileName = stlFile;
82  if (auto box = dynamic_cast<bmBox *>(this->opts_.bmParams.shape.get())) {
83  if (box->autoGenerate.has_value()) {
84  box->autoGenerate.value().packFileName = stlFile;
85  }
86  }
87  this->files_ = std::move(files);
88 }
std::string geomFileName
Input geometry STL name.
std::shared_ptr< bmShape > shape
3D block, sphere, cylinder, or tapered cone

◆ setOpts()

void NEM::DRV::HexPackMeshDriver::setOpts ( Opts  opts)

Definition at line 94 of file HexPackMeshDriver.C.

References MeshManipulationFoamParams::MergeMeshes::addCasePath, NEM::DRV::HexPackMeshDriver::Opts::bmParams, snappymeshParams::geomFileName, getFiles(), NEM::DRV::HexPackMeshDriver::Files::getInputFile(), NEM::DRV::HexPackMeshDriver::Files::isInputRocpackFile(), MeshManipulationFoamParams::MergeMeshes::masterCasePath, NEM::DRV::HexPackMeshDriver::Opts::mmfCreatePatchParams, NEM::DRV::HexPackMeshDriver::Opts::mmfMergeParams, opts_, MeshManipulationFoamParams::CreatePatch::packsName, MeshManipulationFoamParams::CreatePatch::packsPatchType, blockMeshParams::shape, NEM::DRV::HexPackMeshDriver::Opts::smParams, MeshManipulationFoamParams::CreatePatch::srrndngPatchType, and MeshManipulationFoamParams::CreatePatch::surroundingName.

94  {
95  const auto stlFile = getFiles().isInputRocpackFile()
96  ? getFiles().getInputFile() + ".stl"
97  : getFiles().getInputFile();
98  if (auto box = dynamic_cast<bmBox *>(opts.bmParams.shape.get())) {
99  if (box->autoGenerate.has_value()) {
100  if (!box->autoGenerate.value().packFileName.empty()) {
101  std::cerr
102  << "opts.bmParams.shape.autoGenerate.packFileName is ignored. "
103  "Using getFiles().getInputFile() for geometry file"
104  << std::endl;
105  }
106  box->autoGenerate.value().packFileName = stlFile;
107  }
108  } else {
109  std::cerr << "HexPackMeshDriver only accepts box shape for blockmesh.\n";
110  exit(1);
111  }
112 
113  if (!opts.smParams.geomFileName.empty()) {
114  std::cerr << "opts.smParams.geomFileName is ignored. Using "
115  "getFiles().getInputFile() for geometry file"
116  << std::endl;
117  }
118  opts.smParams.geomFileName = stlFile;
119 
120  // Default values specific to this driver
121  if (opts.mmfMergeParams.masterCasePath.empty()) {
122  opts.mmfMergeParams.masterCasePath = ".";
123  }
124  if (opts.mmfMergeParams.addCasePath.empty()) {
125  opts.mmfMergeParams.addCasePath = ".";
126  }
127  if (opts.mmfCreatePatchParams.surroundingName.empty()) {
128  opts.mmfCreatePatchParams.surroundingName = "Soil";
129  }
130  if (opts.mmfCreatePatchParams.packsName.empty()) {
131  opts.mmfCreatePatchParams.packsName = "Rocks";
132  }
133  if (opts.mmfCreatePatchParams.srrndngPatchType.empty()) {
134  opts.mmfCreatePatchParams.srrndngPatchType = "wall";
135  }
136  if (opts.mmfCreatePatchParams.packsPatchType.empty()) {
137  opts.mmfCreatePatchParams.packsPatchType = "wall";
138  }
139  this->opts_ = std::move(opts);
140 }
const Files & getFiles() const
const std::string & getInputFile() const

Member Data Documentation

◆ files_

Files NEM::DRV::HexPackMeshDriver::files_
private

Definition at line 119 of file HexPackMeshDriver.H.

Referenced by execute(), getFiles(), and setFiles().

◆ opts_

Opts NEM::DRV::HexPackMeshDriver::opts_
private

Definition at line 120 of file HexPackMeshDriver.H.

Referenced by execute(), getOpts(), setFiles(), and setOpts().


The documentation for this class was generated from the following files: