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.
foamGeoMesh.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 "Mesh/foamGeoMesh.H"
34 #include "getDicts.H"
35 
36 #include <iostream>
37 #include <set>
38 #include <string>
39 #include <utility>
40 
41 #ifdef HAVE_GMSH
42 # include <gmsh.h>
43 #endif
44 #include <vtkDataArray.h>
45 #include <vtkDoubleArray.h>
46 #include <vtkIdList.h>
47 #include <vtkStringArray.h>
48 
49 #include <IOobjectList.H>
50 #include <cellZone.H>
51 #include <cellZoneSet.H>
52 #include <fileName.H>
53 #include <foamVtkVtuAdaptor.H>
54 #include <globalMeshData.H>
55 #include <timeSelector.H>
56 #include <topoSetSource.H>
57 
58 #include "AuxiliaryFunctions.H"
59 
60 namespace NEM {
61 namespace MSH {
62 
64 
65 foamGeoMesh *foamGeoMesh::Read(const std::string &fileName,
66  const std::string &geoArrayName) {
67  auto foamGM = new foamGeoMesh();
68  Foam::word regionName;
69 
70  if (fileName.empty()) {
71  regionName = Foam::fvMesh::defaultRegion;
72  } else {
73  regionName = fileName;
74  }
75 
76  bool writeDicts = false;
77  std::unique_ptr<getDicts> initFoam;
78  initFoam = std::unique_ptr<getDicts>(new getDicts());
79  foamGM->controlDict_ = initFoam->createControlDict(writeDicts);
80 
81  foamGM->runTime_ = std::unique_ptr<Foam::Time>(
82  new Foam::Time(foamGM->controlDict_.get(), ".", "."));
83 
84  foamGM->fmesh_.reset(new Foam::fvMesh(
85  Foam::IOobject(regionName, foamGM->runTime_->timeName(),
86  *foamGM->runTime_, Foam::IOobject::MUST_READ)));
87 
88  auto gmMesh = foam2GM(foamGM->fmesh_.get());
89 
90  foamGM->setGeoMesh(gmMesh);
91 
92  return foamGM;
93 }
94 
96 
97 foamGeoMesh::foamGeoMesh(Foam::fvMesh *foamMesh,
98  const std::string &phyGrpArrayName)
99  : geoMeshBase(foam2GM(foamMesh, phyGrpArrayName)), fmesh_(foamMesh) {
100  std::cout << "foamGeoMesh Constructed" << std::endl;
101 }
102 
104  std::cout << "foamGeoMesh destructed" << std::endl;
105 }
106 
108  const std::string &phyGrpArrayName) {
109  // create vtk database
110  vtkSmartPointer<vtkUnstructuredGrid> vtkdataSet =
112 
113  // Check for cellsets and cellzones
114  if (!foamMesh) {
115  return {vtkdataSet, "", "", {}};
116  } else {
117  const Foam::cellZoneMesh &cellZones =
118  foamMesh->cellZones(); // get cellZoneMesh
119  Foam::label zoneI = cellZones.size();
120 
121  // creating equivalent vtk topology from fvMesh
122  // by default polyhedral cells will be decomposed to
123  // tets and pyramids. Additional points will be added
124  // to underlying fvMesh.
125  std::cout << "Performing topological decomposition.\n";
126  auto objVfoam = Foam::vtk::vtuAdaptor();
127  vtkdataSet = objVfoam.internal(*foamMesh);
128 
129  // Check for cellZones and extract physical groups
130  Foam::List<Foam::scalar> physGrps(foamMesh->nCells(), 0.0);
131  if (zoneI > 0) {
132  for (int i = 0; i < zoneI; i++) {
133  const Foam::cellZone &cz = cellZones[i];
134  forAll (cz, j)
135  physGrps[cz[j]] = i;
136  }
137 
138  vtkSmartPointer<vtkDoubleArray> pg =
140  pg->SetName(phyGrpArrayName.c_str());
141  pg->SetNumberOfComponents(1);
142  for (int i = 0; i < foamMesh->nCells(); i++)
143  pg->InsertNextTuple1(physGrps[i]);
144  vtkdataSet->GetCellData()->AddArray(pg);
145  }
146 
147  // Create boundary patches arrays and add to VTK
148  const Foam::polyBoundaryMesh &patches = foamMesh->boundaryMesh();
149  Foam::wordList patchNames = patches.names();
150  Foam::wordList patchTypes = patches.types();
151  // const Foam::labelList &patchIds = patches.patchID();
152  Foam::label patchSize = patches.size();
153  std::vector<int> face_patch_map; // Which patch the current face is in
154  Foam::label nFaces = foamMesh->nFaces();
155  for (int i = 0; i < nFaces; i++)
156  face_patch_map.push_back(int(patches.whichPatch(i)));
157 
158  // Create sideSets
159  vtkSmartPointer<vtkPolyData> sideSet = vtkSmartPointer<vtkPolyData>::New();
160  Foam::faceList allFaces = foamMesh->faces();
161  Foam::labelList faceOwners = foamMesh->faceOwner();
162  Foam::pointField allPoints = foamMesh->points();
163 
164  // Filter internal faces out
165  int nonInternalFaces = 0;
166  for (int i = 0; i < patchSize; i++) nonInternalFaces += patches[i].size();
167  Foam::faceList sideSetOnlyFaces(nonInternalFaces);
168  Foam::labelList sideSetOnlyFaceLabels(nonInternalFaces);
169  Foam::labelList sideSetOnlyOwners(nonInternalFaces);
170  int indx = 0;
171  for (int i = 0; i < static_cast<int>(face_patch_map.size()); i++) {
172  if (face_patch_map[i] != -1) {
173  sideSetOnlyFaces[indx] = allFaces[i];
174  sideSetOnlyOwners[indx] = faceOwners[i];
175  sideSetOnlyFaceLabels[indx] = i;
176  indx++;
177  }
178  }
179 
180  sideSet->SetPoints(vtkdataSet->GetPoints());
181  sideSet->Allocate();
182 
183  // Start adding cells (2D faces)
184  std::vector<int> facePntIds;
185  for (int i = 0; i < sideSetOnlyFaces.size(); i++) {
186  if (sideSetOnlyFaces[i].size() == 3) {
187  // add triangle face (#5)
188  vtkSmartPointer<vtkIdList> vtkCellIds =
190  vtkCellIds->SetNumberOfIds(sideSetOnlyFaces[i].size());
191  for (int j = 0; j < sideSetOnlyFaces[i].size(); j++)
192  vtkCellIds->SetId(j, sideSetOnlyFaces[i][j]);
193  sideSet->InsertNextCell(5, vtkCellIds);
194  } else if (sideSetOnlyFaces[i].size() == 4) {
195  // add quad face (#9)
196  vtkSmartPointer<vtkIdList> vtkCellIds =
198  vtkCellIds->SetNumberOfIds(sideSetOnlyFaces[i].size());
199  for (int j = 0; j < sideSetOnlyFaces[i].size(); j++)
200  vtkCellIds->SetId(j, sideSetOnlyFaces[i][j]);
201  sideSet->InsertNextCell(9, vtkCellIds);
202  } else if (sideSetOnlyFaces[i].size() > 4) {
203  // add polygon face (#7)
204  vtkSmartPointer<vtkIdList> vtkCellIds =
206  vtkCellIds->SetNumberOfIds(sideSetOnlyFaces[i].size());
207  for (int j = 0; j < sideSetOnlyFaces[i].size(); j++)
208  vtkCellIds->SetId(j, sideSetOnlyFaces[i][j]);
209  sideSet->InsertNextCell(7, vtkCellIds);
210  } else {
211  Foam::Info << "Face type not supported yet!" << Foam::nl;
212  }
213  }
214 
215  auto sideSetEntities = vtkSmartPointer<vtkIntArray>::New();
216  sideSetEntities->SetName("GeoEnt");
217 
218  auto sideSetOrigCellId = vtkSmartPointer<vtkIdTypeArray>::New();
219  sideSetOrigCellId->SetName("OrigCellIds");
220  sideSetOrigCellId->SetNumberOfComponents(2);
221 
222  auto sideSetCellFaceId = vtkSmartPointer<vtkIntArray>::New();
223  sideSetCellFaceId->SetName("CellFaceIds");
224  sideSetCellFaceId->SetNumberOfComponents(2);
225 
226  auto sideSetPatchId = vtkSmartPointer<vtkIntArray>::New();
227  sideSetPatchId->SetName("PatchIds");
228 
229  auto sideSetPatchName = vtkSmartPointer<vtkStringArray>::New();
230  sideSetPatchName->SetName("PatchNames");
231 
232  for (int i = 0; i < sideSetOnlyFaces.size(); i++) {
233  sideSetEntities->InsertNextValue(
234  static_cast<int>(physGrps[sideSetOnlyOwners[i]]));
235  sideSetOrigCellId->InsertNextTuple2(sideSetOnlyOwners[i],-1);
236  }
237 
238  for (int i = 0; i < sideSetOnlyOwners.size(); i++) {
239  const Foam::cell& facesCell = foamMesh->cells()[sideSetOnlyOwners[i]];
240  for (int j = 0; j < facesCell.size(); j++) {
241  if (foamMesh->faces()[facesCell[j]] == sideSetOnlyFaces[i]) {
242  sideSetCellFaceId->InsertNextTuple2(j,-1);
243  }
244  }
245  }
246 
247  for (int i = 0; i < sideSetOnlyFaces.size(); i++) {
248  sideSetPatchId->InsertNextValue(face_patch_map[sideSetOnlyFaceLabels[i]]);
249  sideSetPatchName->InsertNextValue(
250  patchNames[face_patch_map[sideSetOnlyFaceLabels[i]]]);
251  }
252 
253  // Add arrays to sideSet
254  sideSet->GetCellData()->AddArray(sideSetPatchId);
255  sideSet->GetFieldData()->AddArray(sideSetPatchName);
256 
257  // Create sideSet struct
258  auto sideSetStruct =
259  SideSet(sideSet, sideSetEntities, sideSetOrigCellId, sideSetCellFaceId);
260 
261  std::string gmshMesh = "foamGeoMesh_" + nemAux::getRandomString(6);
262 #ifdef HAVE_GMSH
264  gmsh::model::add(gmshMesh);
265  gmsh::model::setCurrent(gmshMesh);
266 
267  { // Add geometric entities and physical groups
268  std::set<std::pair<int, int>> dim_phyGrp;
269  int idx = 0;
270  auto phyGrpArray = vtkArrayDownCast<vtkDataArray>(
271  vtkdataSet->GetCellData()->GetArray(phyGrpArrayName.c_str(), idx));
272  vtkSmartPointer<vtkGenericCell> vtkGC =
274 
275  if (idx != -1) {
276  // First sort
277  for (vtkIdType i = 0; i < vtkdataSet->GetNumberOfCells(); ++i) {
278  vtkGC->SetCellType(vtkdataSet->GetCellType(i));
279  int dim = vtkGC->GetCellDimension();
280  int phyGrp = static_cast<int>(phyGrpArray->GetComponent(i, 0));
281 
282  dim_phyGrp.insert({dim, phyGrp});
283  }
284 
285  // then add. Each phyGrp gets its own geoEnt
286  for (const auto &dp : dim_phyGrp) {
287  gmsh::model::addDiscreteEntity(dp.first, dp.second);
288  gmsh::model::addPhysicalGroup(dp.first, {dp.second}, dp.second);
289  }
290  }
291  }
292 #endif
293  return {vtkdataSet, gmshMesh, phyGrpArrayName, sideSetStruct};
294  }
295 }
296 
297 std::unique_ptr<Foam::fvMesh> foamGeoMesh::GM2foam(
298  const GeoMesh &geoMesh, Foam::Time *runTime,
299  const std::string &phyGrpArrayName) {
300  int numPoints = static_cast<int>(geoMesh.mesh->GetNumberOfPoints());
301  int numCells = static_cast<int>(geoMesh.mesh->GetNumberOfCells());
302 
303  Foam::pointField pointData(numPoints);
304  Foam::pointField pointData2(numPoints);
305  Foam::cellShapeList cellShapeData(numCells);
306  Foam::cellShapeList cellShapeData2(numCells);
307 
308  if (numPoints > 0) {
309  // Fetch all points and coordinates
310  std::vector<std::vector<double>> verts;
311  verts.resize(numPoints);
312  for (int ipt = 0; ipt < numPoints; ipt++) {
313  std::vector<double> getPt = std::vector<double>(3);
314  geoMesh.mesh->GetPoint(ipt, &getPt[0]);
315  verts[ipt].resize(3);
316  verts[ipt][0] = getPt[0];
317  verts[ipt][1] = getPt[1];
318  verts[ipt][2] = getPt[2];
319  }
320 
321  // Gets Ids for cells
322  std::vector<std::vector<int>> cellIds;
323  cellIds.resize(numCells);
324 
325  // Gets celltypes for all cells in mesh
326  std::vector<int> typeCell;
327  typeCell.resize(numCells);
328 
329  for (int i = 0; i < numPoints; i++) {
330  pointData[i] = Foam::vector(verts[i][0], verts[i][1], verts[i][2]);
331  pointData2[i] = Foam::vector(verts[i][0], verts[i][1], verts[i][2]);
332  }
333 
334  for (int i = 0; i < numCells; i++) {
335  vtkIdList *ptIds = vtkIdList::New();
336  geoMesh.mesh->GetCellPoints(i, ptIds);
337  int numIds = static_cast<int>(ptIds->GetNumberOfIds());
338  cellIds[i].resize(numIds);
339  for (int j = 0; j < numIds; j++) cellIds[i][j] = static_cast<int>(ptIds->GetId(j));
340  Foam::labelList meshPoints(numIds);
341  for (int k = 0; k < numIds; k++) meshPoints[k] = cellIds[i][k];
342  typeCell[i] = geoMesh.mesh->GetCellType(i);
343  if (typeCell[i] == 12) {
344  cellShapeData[i] = Foam::cellShape("hex", meshPoints, true);
345  cellShapeData2[i] = Foam::cellShape("hex", meshPoints, true);
346  } else if (typeCell[i] == 14) {
347  cellShapeData[i] = Foam::cellShape("pyr", meshPoints, true);
348  cellShapeData2[i] = Foam::cellShape("pyr", meshPoints, true);
349  } else if (typeCell[i] == 10) {
350  cellShapeData[i] = Foam::cellShape("tet", meshPoints, true);
351  cellShapeData2[i] = Foam::cellShape("tet", meshPoints, true);
352  } else {
353  std::cerr << "Only Hexahedral, Tetrahedral,"
354  << " and Pyramid cells are supported in foamGeoMesh!"
355  << std::endl;
356  throw;
357  }
358  }
359  } else {
360  return nullptr;
361  }
362 
363  // Foam::word regName = Foam::polyMesh::defaultRegion;
364  Foam::word regName = "";
365 
366  // Get patch names from mesh
367  int idx1 = 0;
368  int idx2 = 0;
369  std::map<int, std::string> ptchNameIDMap;
370  Foam::faceListList bndryFaces(0);
371  Foam::wordList BndryPatchNames(0);
372  Foam::wordList BndryPatchTypes(0);
373  Foam::wordList boundaryPatchPhysicalTypes(0);
374  int totalPatches;
375  std::vector<int> startIds;
376  std::vector<int> nFacesInPatch;
377  Foam::PtrList<Foam::polyPatch> patchPtrList(0);
378  Foam::cellList cellLst2(0);
379  Foam::faceList faceLst2(0);
380 
381  if (geoMesh.sideSet.sides) {
382  auto ptchIds = vtkIntArray::FastDownCast(
383  geoMesh.sideSet.sides->GetCellData()->GetArray("PatchIds", idx1));
384  auto ptchNms = vtkStringArray::SafeDownCast(
385  geoMesh.sideSet.sides->GetFieldData()->GetAbstractArray("PatchNames",
386  idx2));
387 
388  if (idx1 != -1 && idx2 != -1) {
389  // Patches exist
390  for (int i = 0; i < ptchIds->GetNumberOfTuples(); ++i) {
391  // Get patch Id
392  auto cc = ptchIds->GetTypedComponent(i, 0);
393  int id_p = cc;
394 
395  // Get patch name
396  std::string nm = ptchNms->GetValue(i);
397 
398  // Create maps
399  ptchNameIDMap[id_p] = nm;
400  }
401 
402  totalPatches = static_cast<int>(ptchNameIDMap.size());
403  std::vector<int> faceCounts(totalPatches,
404  0); // Counts faces for each patch
405  std::vector<std::vector<int>> facePatchIds;
406  facePatchIds.resize(totalPatches);
407  for (int i = 0; i < ptchIds->GetNumberOfTuples(); ++i) {
408  // Get patch Id
409  auto cc = ptchIds->GetTypedComponent(i, 0);
410  int id_p = cc;
411  faceCounts[id_p] += 1;
412  facePatchIds[id_p].push_back(i);
413  }
414 
415  BndryPatchNames.setSize(totalPatches);
416  BndryPatchTypes.setSize(totalPatches);
417 
418  auto iter = ptchNameIDMap.begin();
419  int r_indx = 0;
420  while (iter != ptchNameIDMap.end()) {
421  BndryPatchNames[r_indx] = iter->second;
422  BndryPatchTypes[r_indx] = "patch";
423  iter++;
424  r_indx++;
425  }
426 
427  // Start pulling out cell (2D faces) point order from sideSets and create
428  // faceList. Append those into faceListList at the end of every patch.
429  bndryFaces.clear();
430  for (int i = 0; i < totalPatches; i++) {
431  Foam::faceList thisPatch(0);
432  thisPatch.clear();
433  for (int j : facePatchIds[i]) {
434  vtkIdList *ptIds = vtkIdList::New();
435  geoMesh.sideSet.sides->GetCellPoints(j, ptIds);
436  int numIds = static_cast<int>(ptIds->GetNumberOfIds());
437  Foam::labelList lstLbl(0);
438  lstLbl.clear();
439  for (int k = 0; k < numIds; k++) {
440  lstLbl.append(static_cast<int>(ptIds->GetId(k)));
441  }
442  if (!lstLbl.empty()) thisPatch.append(Foam::face(lstLbl));
443  }
444  bndryFaces.append(thisPatch);
445  nFacesInPatch.push_back(thisPatch.size());
446  }
447  boundaryPatchPhysicalTypes.resize(totalPatches,
448  Foam::polyPatch::typeName);
449  }
450  }
451 
452  {
453  Foam::polyMesh tmpfm(
454  Foam::IOobject(regName, runTime->timeName(), *runTime,
455  Foam::IOobject::NO_READ, Foam::IOobject::AUTO_WRITE),
456  std::move(pointData), // Vertices
457  cellShapeData, // Cell shape and points
458  bndryFaces, // Boundary faces
459  BndryPatchNames, // Boundary Patch Names
460  BndryPatchTypes, // Boundary Patch Types
461  "defaultPatch", // Default Patch Name
462  Foam::polyPatch::typeName, // Default Patch Type
463  Foam::wordList());
464 
465  const Foam::polyBoundaryMesh &patches2 = tmpfm.boundaryMesh();
466 
467  for (int i = 0; i < patches2.size(); i++) {
468  auto *tmpPtch = new Foam::polyPatch(patches2[i]);
469  patchPtrList.append(tmpPtch);
470  }
471 
472  // Get pointField (points), faceList (faces), and cellList (cells).
473  const Foam::cellList &cellLst = tmpfm.cells();
474  cellLst2 = cellLst;
475  const Foam::faceList &faceLst = tmpfm.faces();
476  faceLst2 = faceLst;
477  }
478 
479  auto fm = std::unique_ptr<Foam::fvMesh>(new Foam::fvMesh(
480  Foam::IOobject(regName, runTime->timeName(), *runTime,
481  Foam::IOobject::NO_READ, Foam::IOobject::AUTO_WRITE),
482  std::move(pointData2), std::move(faceLst2), std::move(cellLst2)));
483 
484  // Add boundary patches to fvMesh using patchPtrList
485  fm->addFvPatches(patchPtrList, true);
486 
487  // Get Physical Groups Vector from GeoMesh
488  std::vector<double> allGroups;
489  int idx;
490  vtkSmartPointer<vtkDataArray> cd =
491  geoMesh.mesh->GetCellData()->GetArray(phyGrpArrayName.c_str(), idx);
492  if (idx != -1) {
493  // allGroups.resize(cd->GetNumberOfTuples());
494  double x[1];
495  for (nemId_t i = 0; i < cd->GetNumberOfTuples(); ++i) {
496  cd->GetTuple(i, x);
497  allGroups.push_back(x[0]);
498  }
499 
500  // Figure out number of physical groups
501  std::vector<double> scratchVec = allGroups;
502  std::sort(scratchVec.begin(), scratchVec.end());
503  scratchVec.erase(unique(scratchVec.begin(), scratchVec.end()),
504  scratchVec.end());
505  int totalGroups = static_cast<int>(scratchVec.size());
506 
507  // Create cellZones
508  Foam::label zoneI;
509  for (int i = 0; i < totalGroups; i++) {
510  Foam::labelList currentGroupList;
511  //for (int j : allGroups) {
512  for (int j = 0; j < static_cast<int>(allGroups.size()); j++) {
513  if (static_cast<int>(allGroups[j]) == i) currentGroupList.append(j);
514  }
515 
516  const Foam::cellZoneMesh &cellZones = fm->cellZones();
517  zoneI = cellZones.size();
518  fm->cellZones().setSize(zoneI + 1);
519  Foam::word nameSet = "pg_" + std::to_string(i);
520  auto clzn =
521  new Foam::cellZone(nameSet, currentGroupList, zoneI, cellZones);
522  fm->cellZones().set(zoneI, clzn);
523  }
524  fm->cellZones().writeOpt() = Foam::IOobject::AUTO_WRITE;
525  }
526  return fm;
527 }
528 
529 void foamGeoMesh::write(const std::string &fileName) {
530  // Create system directory
531  Foam::word w = "system";
532  if (!Foam::isDir(w)) Foam::mkDir(w);
533 
534  // Write ControlDict
535  Foam::fileName fcontrolDict = "system/controlDict";
536  if (!Foam::exists(fcontrolDict)) {
537  Foam::OFstream outcontrolDict(fcontrolDict);
538  Foam::IOobject::writeBanner(outcontrolDict);
539  controlDict_->write(outcontrolDict, false);
540  }
541 
542  // Write fvSchemes
543  Foam::fileName ffvSchemes = "system/fvSchemes";
544  if (!Foam::exists(ffvSchemes)) {
545  Foam::OFstream outfvSchemes(ffvSchemes);
546  Foam::IOobject::writeBanner(outfvSchemes);
547  fvSchemes_->write(outfvSchemes, false);
548  }
549 
550  // Write fvSolution
551  Foam::fileName ffvSolution = "system/fvSolution";
552  if (!Foam::exists(ffvSolution)) {
553  Foam::OFstream outfvSolution(ffvSolution);
554  Foam::IOobject::writeBanner(outfvSolution);
555  fvSolution_->write(outfvSolution, false);
556  }
557 
558  // Region to write in
559  Foam::fileName newReg = "";
560  if (fileName.empty())
561  newReg = "";
562  else
563  newReg = fileName;
564 
565  // Write dictionaries to the specific region too
566  if (!Foam::isDir("system/" + newReg)) Foam::mkDir("system/" + newReg);
567 
568  Foam::fileName fcontrolDict_2 = "system/" + newReg + "/controlDict";
569  if (!Foam::exists(fcontrolDict_2)) { Foam::cp(fcontrolDict, fcontrolDict_2); }
570 
571  // Write fvSchemes
572  Foam::fileName ffvSchemes_2 = "system/" + newReg + "/fvSchemes";
573  if (!Foam::exists(ffvSchemes_2)) { Foam::cp(ffvSchemes, ffvSchemes_2); }
574 
575  // Write fvSolution
576  Foam::fileName ffvSolution_2 = "system/" + newReg + "/fvSolution";
577  if (!Foam::exists(ffvSolution_2)) { Foam::cp(ffvSolution, ffvSolution_2); }
578 
579  // Write mesh in fileName
580  if (!Foam::isDir("0")) Foam::mkDir("0");
581 
582  // Write cellZones and cellSets
583  const Foam::cellZoneMesh &czMesh = fmesh_->cellZones();
584  Foam::label numZones = czMesh.size();
585 
586  fmesh_->setInstance("0");
587  fmesh_->write();
588 
589  if (numZones > 0) {
590  for (int i = 0; i < numZones; i++) {
591  const Foam::cellZone &cz = czMesh[i];
592  Foam::cellSet(*fmesh_, cz.name(), cz).write();
593  }
594  }
595 
596  Foam::fileName currentDir = "0";
597  Foam::fileName currentReg = fmesh_->dbDir();
598  Foam::fileName newDir = "constant";
599  Foam::fileName finalMesh = "";
600 
601  if (currentReg.empty()) {
602  if (!Foam::isDir(currentDir + "/" + newReg))
603  Foam::mkDir(currentDir + "/" + newReg);
604  if (!newReg.empty()) {
605  Foam::mv(currentDir + "/polyMesh",
606  currentDir + "/" + newReg + "/polyMesh");
607  finalMesh = currentDir + "/" + newReg;
608  } else {
609  finalMesh = currentDir + "/polyMesh";
610  }
611  } else {
612  if (!newReg.empty()) {
613  Foam::mv(currentDir + "/" + currentReg, currentDir + "/" + newReg);
614  finalMesh = currentDir + "/" + newReg;
615  } else {
616  Foam::mv(currentDir + "/" + currentReg, currentDir + "/");
617  finalMesh = currentDir + "/polyMesh";
618  }
619  }
620 
621  if (!Foam::isDir(newDir + "/" + newReg)) {
622  if (!newReg.empty()) {
623  Foam::mkDir(newDir + "/" + newReg);
624  Foam::mv(finalMesh, newDir + "/" + newReg);
625  } else {
626  Foam::mkDir(newDir + "/polyMesh");
627  Foam::mv(finalMesh, newDir + "/polyMesh");
628  }
629  }
630 
631  if (!newReg.empty()) {
632  if (!Foam::isDir(newDir + "/" + newReg)) {
633  Foam::mkDir(newDir + "/" + newReg);
634  Foam::mv(finalMesh, newDir + "/" + newReg);
635  }
636  } else {
637  if (!Foam::isDir(newDir + "/polyMesh")) Foam::mkDir(newDir + "/polyMesh");
638  Foam::mv(finalMesh, newDir + "/polyMesh");
639  }
640 }
641 
642 void foamGeoMesh::report(std::ostream &out) const { geoMeshBase::report(out); }
643 
644 void foamGeoMesh::setFoamMesh(std::unique_ptr<Foam::fvMesh> foamMesh) {
645  // Setting class parameters
646  fmesh_ = std::unique_ptr<Foam::fvMesh>(foamMesh.get());
647 
648  // Parent
649  setGeoMesh(foam2GM(foamMesh.get()));
650 }
651 
653  // Clear
654  controlDict_.reset();
655  fvSchemes_.reset();
656  fvSolution_.reset();
657  runTime_.reset();
658  fmesh_.reset();
659 
660  // Initialize required variables
661  InitializeFoam();
662 
663  // Reset fvMesh
664  fmesh_ = GM2foam(getGeoMesh(), runTime_.get());
665 }
666 
668  bool writeDicts = false;
669  std::unique_ptr<getDicts> initFoam;
670  initFoam = std::unique_ptr<getDicts>(new getDicts());
671  controlDict_ = initFoam->createControlDict(writeDicts);
672  fvSchemes_ = initFoam->createFvSchemes(writeDicts);
673  fvSolution_ = initFoam->createFvSolution(writeDicts);
674 
675  // Create time class without reading controlDict
676  runTime_ =
677  std::unique_ptr<Foam::Time>(new Foam::Time(controlDict_.get(), ".", "."));
678  Foam::argList::noParallel();
679 }
680 
681 } // namespace MSH
682 } // namespace NEM
683 
virtual void report(std::ostream &out) const =0
Print a report about the mesh.
Definition: geoMeshBase.C:97
void write(const std::string &fileName) override
Writes foam mesh into current directory.
Definition: foamGeoMesh.C:529
vtkSmartPointer< vtkUnstructuredGrid > mesh
Definition: geoMeshBase.H:419
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
~foamGeoMesh() override
foamGeoMesh destructor
Definition: foamGeoMesh.C:103
static GeoMesh foam2GM(Foam::fvMesh *foamMesh, const std::string &phyGrpArrayName=std::string())
Create a GeoMesh from a fvMesh.
Definition: foamGeoMesh.C:107
void setGeoMesh(const geoMeshBase::GeoMesh &geoMesh)
Set the underlying geometry object.
Definition: geoMeshBase.H:538
static void Initialize()
Initialize Gmsh.
Definition: geoMeshBase.C:67
static std::unique_ptr< Foam::fvMesh > GM2foam(const GeoMesh &geoMesh, Foam::Time *runTime, const std::string &phyGrpArrayName=std::string())
Create a fvMesh from geoMeshBase.
Definition: foamGeoMesh.C:297
void report(std::ostream &out) const override
Reports data about mesh.
Definition: foamGeoMesh.C:642
std::unique_ptr< Foam::dictionary > controlDict_
Definition: foamGeoMesh.H:150
foamGeoMesh()
Create a foamMesh from mesh in current directory.
Definition: foamGeoMesh.C:95
std::string getRandomString(int length)
std::unique_ptr< Foam::dictionary > fvSolution_
Definition: foamGeoMesh.H:156
void setFoamMesh(std::unique_ptr< Foam::fvMesh > foamMesh)
Set the foamGeoMesh&#39;s mesh to foamMesh.
Definition: foamGeoMesh.C:644
vtkSmartPointer< vtkPolyData > sides
Cells represent edges/faces of some GeoMesh.
Definition: geoMeshBase.H:399
void InitializeFoam()
Initializes arguments and runtime objects.
Definition: foamGeoMesh.C:667
std::unique_ptr< Foam::fvMesh > fmesh_
Definition: foamGeoMesh.H:162
vtkStandardNewMacro(exoGeoMesh)
Definition: exoGeoMesh.C:247
std::int64_t nemId_t
Definition: geoMeshBase.H:56
A concrete implementation of geoMeshBase representing a mesh in a fvMesh.
Definition: foamGeoMesh.H:52
std::unique_ptr< Foam::dictionary > fvSchemes_
Definition: foamGeoMesh.H:153
abstract class to specify geometry and mesh data
Definition: geoMeshBase.H:102
void resetNative() override
Resets the class members and initiates an empty foam mesh.
Definition: foamGeoMesh.C:652
std::unique_ptr< Foam::Time > runTime_
Definition: foamGeoMesh.H:159
const GeoMesh & getGeoMesh() const
Get the underlying geometry object.
Definition: geoMeshBase.H:533