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.
MeshManipulationFoam Class Reference

MeshManipulation class contains several OpenFOAM utilities to perform various mesh manipulation operations. More...

Detailed Description

These utilities reads Foam mesh and outputs Foam mesh. Some of them are surface mesh manipulation utilities. Manipulation utilities include

  • surfaceLambdaMuSmooth
  • splitMeshRegions
  • mergeMeshes
  • createPatch
  • foamToSurface
  • surfaceSplitByTopology.

Foam mesh reading and writing capabilities are built inside each manipulation utility.

Definition at line 68 of file MeshManipulationFoam.H.

Public Member Functions

 MeshManipulationFoam ()
 Standard MeshManipulationFoam Constructor. More...
 
 MeshManipulationFoam (MeshManipulationFoamParams *params)
 Custom MeshManipulationFoam Constructor. More...
 
 ~MeshManipulationFoam ()
 Standard MeshManipulationFoam Destructor. More...
 
void surfLambdaMuSmooth ()
 surfLambdaMuSmooth performs laplacian smoothing over surface and writes it into output surface file. More...
 
std::pair< std::vector< int >, std::vector< std::string > > splitMshRegions ()
 splitMshRegions walks through mesh using cell-face-cell walk and identifies different cellZones as different regions. More...
 
void mergeMesh (int dirStat, int nDomains)
 mergeMesh method merges two fvMesh datasets into one fvMesh including the patches and domain information More...
 
void createPtch (int dirStat)
 createPtch utility creates user-defined patches in Foam mesh. More...
 
void foamToSurf ()
 foamToSurf utility reads Foam mesh, extracts its surface and writes into an STL file. More...
 
int surfSpltByTopology ()
 surfSpltByTopology utility takes a surface file as an input and automatically divides disconnected regions into separate patches. More...
 
void addCohesiveElements (double tol, const std::string &outName)
 addCohesiveElements method supports addition of zero-sized connectivity elements at conformal shared interface between two meshes. More...
 
void addArtificialThicknessElements (double &tol, const std::string &outName, double &thickness)
 This method adds connectivity elements with finite thickness at shared interface between two conformal meshes. More...
 
void periodicMeshMapper (std::string &patch1, std::string &patch2)
 periodicMeshMapper method generates map of nodes on periodic mesh interfaces at boundaries for FEM analysis. More...
 

Private Member Functions

void createPatchDict (const int &dirStat, const bool &write)
 createPatchDict utility creates a dictionary needed for createPatch method. More...
 

Private Attributes

MeshManipulationFoamParams_mshMnipPrms
 MeshManipulationFoam object. More...
 
std::unique_ptr< Foam::dictionary > cpDict_
 

Constructor & Destructor Documentation

◆ MeshManipulationFoam() [1/2]

MeshManipulationFoam::MeshManipulationFoam ( )
inline

Definition at line 74 of file MeshManipulationFoam.H.

74 {}; // Standard Constructor

◆ MeshManipulationFoam() [2/2]

MeshManipulationFoam::MeshManipulationFoam ( MeshManipulationFoamParams params)
inline
Parameters
paramsMeshManipulationFoamParams Object

Definition at line 80 of file MeshManipulationFoam.H.

80  {
81  _mshMnipPrms = params;
82  } // Alternate Constructor
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.

◆ ~MeshManipulationFoam()

MeshManipulationFoam::~MeshManipulationFoam ( )

Definition at line 75 of file MeshManipulationFoam.C.

75  {
76  // class destructor
77 }

Member Function Documentation

◆ addArtificialThicknessElements()

void MeshManipulationFoam::addArtificialThicknessElements ( double &  tol,
const std::string &  outName,
double &  thickness 
)
Parameters
tolTolerance for conformal duplicate nodes between two meshes.
outNameOutput mesh name with extension (i.e "output.vtu")
thicknessDesired thickness for new cohesive elements.

Definition at line 707 of file MeshManipulationFoam.C.

References NEM::MSH::foamGeoMesh::getFoamMesh(), NEM::MSH::New(), and NEM::MSH::Read().

708  {
709  // Initializing FOAM
710  bool writeDicts = true;
711  std::unique_ptr<getDicts> initFoam;
712  initFoam = std::unique_ptr<getDicts>(new getDicts());
713  auto controlDict_ = initFoam->createControlDict(writeDicts);
714 
715  Foam::Time runTime(controlDict_.get(), ".", ".");
716 
717  auto _fmeshSurr = std::unique_ptr<NEM::MSH::foamGeoMesh>(
718  NEM::MSH::foamGeoMesh::Read("domain0.foam"));
719 
720  auto _fmeshPacks = std::unique_ptr<NEM::MSH::foamGeoMesh>(
721  NEM::MSH::foamGeoMesh::Read("domain1.foam"));
722 
723  // declare vtk datasets
724  vtkSmartPointer<vtkUnstructuredGrid> dataSetSurr =
726 
727  vtkSmartPointer<vtkUnstructuredGrid> surrTmp =
729  auto objVfoamSurr = Foam::vtk::vtuAdaptor();
730  surrTmp = objVfoamSurr.internal(_fmeshSurr->getFoamMesh());
731 
732  int impPts = (surrTmp->GetNumberOfPoints());
733 
734  vtkSmartPointer<vtkUnstructuredGrid> pckTmp =
736  auto objVfoamPck = Foam::vtk::vtuAdaptor();
737  pckTmp = objVfoamPck.internal(_fmeshPacks->getFoamMesh());
738 
739  // Merge two foam meshes
740  vtkSmartPointer<vtkAppendFilter> appendFilter =
742  appendFilter->AddInputData(surrTmp);
743  appendFilter->AddInputData(surrTmp);
744  appendFilter->MergePointsOn();
745  appendFilter->Update();
746  dataSetSurr = appendFilter->GetOutput();
747 
748  int numPoints = (int)(dataSetSurr->GetNumberOfPoints());
749 
750  int nDim = 3;
751  ANNpointArray pntCrd;
752  pntCrd = annAllocPts(numPoints, nDim);
753  for (int iPnt = 0; iPnt < numPoints; iPnt++) {
754  std::vector<double> getPt = std::vector<double>(3);
755  dataSetSurr->GetPoint(iPnt, &getPt[0]);
756  pntCrd[iPnt][0] = getPt[0];
757  pntCrd[iPnt][1] = getPt[1];
758  pntCrd[iPnt][2] = getPt[2];
759  }
760 
761  ANNkd_tree *kdTree = new ANNkd_tree(pntCrd, numPoints, nDim);
762 
763  // Finding duplicate nodes
764  double rad = 1e-05;
765  std::map<int, int> dupNdeMap;
766  ANNpoint qryPnt; // Query point.
767  int nNib = 2; // Number of neighbours to return (including query pt. itself).
768  ANNidxArray nnIdx = new ANNidx[nNib]; // Nearest neighbour ID array.
769  ANNdistArray dists = new ANNdist[nNib]; // Neighbour distance array.
770  qryPnt = annAllocPt(nDim); // Initializing query point
771 
772  for (int iNde = 0; iNde < impPts; iNde++) {
773  std::vector<double> getPt = std::vector<double>(3);
774  dataSetSurr->GetPoint(iNde, &getPt[0]);
775  qryPnt[0] = getPt[0];
776  qryPnt[1] = getPt[1];
777  qryPnt[2] = getPt[2];
778  kdTree->annkFRSearch(qryPnt, rad, nNib, nnIdx, dists, 0);
779  if (dists[1] <= tol) {
780  if ((nnIdx[1]) >= impPts) {
781  dupNdeMap[nnIdx[0]] = nnIdx[1]; // Format Surrounding::Pack
782  } else {
783  dupNdeMap[nnIdx[1]] = nnIdx[0]; // Format Surrounding::Pack
784  }
785  }
786  }
787 
788  int numDupPnts = (int)dupNdeMap.size();
789  std::cout << "Found " << numDupPnts << " duplicate nodes.\n";
790 
791  // Getting cells in packs
792  std::map<int, int>::iterator it = dupNdeMap.begin();
793  std::vector<int> cellID;
794  for (int i = 0; i < (int)(dupNdeMap.size()); i++) {
795  int nCells, cellNum;
796  vtkIdList *cells = vtkIdList::New();
797 
798  // get cells the point belongs to
799  dataSetSurr->GetPointCells(it->second, cells);
800  nCells = (int)(cells->GetNumberOfIds());
801 
802  for (cellNum = 0; cellNum < nCells; cellNum++) {
803  cellID.push_back(
804  (int)(cells->GetId(cellNum))); // get cell id from the list
805  }
806  it++;
807  }
808 
809  sort(cellID.begin(), cellID.end());
810  cellID.erase(unique(cellID.begin(), cellID.end()), cellID.end());
811 
812  int know = cellID.size();
813 
814  // Determines which cells are useful
815  std::vector<int> newCellIds;
816  std::vector<int> debugCellIds;
817 
818  for (int i = 0; i < know; i++) {
819  // Getting all cell defining points
820  std::vector<int> ptIdzz(8);
821  int cntr = 0;
822  vtkCell *cell;
823  cell = dataSetSurr->GetCell(cellID[i]);
824 
825  vtkIdList *pts = cell->GetPointIds();
826 
827  for (int j = 0; j < 8; j++) { ptIdzz[j] = pts->GetId(j); }
828 
829  // Checking if any cell contains any 4 or more of duplicate nodes.
830  std::map<int, int>::iterator it2 = dupNdeMap.begin();
831  while (it2 != dupNdeMap.end()) {
832  for (int k = 0; k < 8; k++) {
833  if ((it2->second) == ptIdzz[k]) {
834  cntr++;
835  } else {
836  // Nothing
837  }
838  }
839  it2++;
840  }
841 
842  if (cntr >= 4) {
843  newCellIds.push_back(cellID[i]);
844  } else {
845  debugCellIds.push_back(cellID[i]);
846  }
847  }
848 
849  int size2 = (int)(newCellIds.size());
850 
851  // Getting useful faces from cells
852  std::vector<int> globalPtIds;
853  std::vector<int> surroundingArray;
854  std::vector<int> packArray;
855  for (int i = 0; i < size2; i++) {
856  vtkCell *cell;
857  cell = dataSetSurr->GetCell(newCellIds[i]);
858  vtkIdList *pts = cell->GetPointIds();
859 
860  for (int j = 0; j < 6; j++) {
861  int isFour = 0;
862  int *ptFaces = nullptr;
863  vtkCell3D *cell3d = static_cast<vtkCell3D *>(cell);
864  cell3d->GetFacePoints(j, ptFaces);
865  std::vector<int> keysDupMap = std::vector<int>(4);
866  std::map<int, int>::iterator it3 = dupNdeMap.begin();
867  while (it3 != dupNdeMap.end()) {
868  for (int h = 0; h < 4; h++) {
869  if ((it3->second) == (pts->GetId(ptFaces[h]))) {
870  isFour++;
871  keysDupMap[h] = it3->first;
872  } else {
873  // Nothing
874  }
875  }
876 
877  it3++;
878  }
879 
880  if (isFour == 4) {
881  for (int k = 0; k < 4; k++) { globalPtIds.push_back(keysDupMap[k]); }
882  }
883  }
884  }
885 
886  std::map<int, int>::iterator it5;
887 
888  // Creating node map with sequence.
889  std::unordered_multimap<int, int> cohesiveMap;
890 
891  for (int i = 0; i < (int)globalPtIds.size(); i++) {
892  it5 = dupNdeMap.find(globalPtIds[i]);
893 
894  if (it5 == dupNdeMap.end()) {
895  // Nothing
896  } else {
897  surroundingArray.push_back(it5->first);
898  packArray.push_back(it5->second);
899  }
900  }
901 
902  std::cout << "End of previous method" << std::endl;
903 
904  // Converting vtkUnstructuredData to vtkPolyData
905  vtkSmartPointer<vtkGeometryFilter> geometryFilter =
907  geometryFilter->SetInputData(dataSetSurr);
908  geometryFilter->Update();
909 
910  vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
911  polydata = geometryFilter->GetOutput();
912 
913  vtkSmartPointer<vtkPolyDataNormals> polyDataNormal =
915 
916  polyDataNormal->SetInputData(polydata);
917 
918  // Setting points normals calculation to ON with other options
919  polyDataNormal->ComputePointNormalsOn();
920  polyDataNormal->ComputeCellNormalsOff();
921  // polyDataNormal->SetNonManifoldTraversal(1);
922  // polyDataNormal->SetAutoOrientNormals(0);
923  polyDataNormal->SetSplitting(0);
924  // polyDataNormal->SetFeatureAngle(0.1);
925  polyDataNormal->SetConsistency(1);
926  // polyDataNormal->SetFlipNormals(0);
927  polyDataNormal->Update();
928 
929  // Extracting point normals from polyDataNormal
930  polydata = polyDataNormal->GetOutput();
931 
932  // Count points
933  vtkIdType numPointsNew = polydata->GetNumberOfPoints();
934  std::cout << "There are " << numPointsNew << " points." << std::endl;
935 
936  vtkDataArray *normalsGeneric = polydata->GetPointData()->GetNormals();
937 
938  // Number of normals should match number of points
939  std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
940  << " normals in normalsGeneric" << std::endl;
941 
942  // Changing point coordinates for adding artificial thickness;
943 
944  // Surrounding cells
945  for (int i = 0; i < (int)surroundingArray.size(); i++) {
946  double normalOfPt[3];
947  normalsGeneric->GetTuple(surroundingArray[i], normalOfPt);
948 
949  std::vector<double> getPt = std::vector<double>(3);
950  dataSetSurr->GetPoint(surroundingArray[i], &getPt[0]);
951 
952  // TODO : Need to figure out thickness formula considering pack and
953  // surrounding mesh cell size and unit normal scale.
954  double newCoords[3];
955  newCoords[0] = getPt[0] + 0.001 * normalOfPt[0];
956  newCoords[1] = getPt[1] + 0.001 * normalOfPt[1];
957  newCoords[2] = getPt[2] + 0.001 * normalOfPt[2];
958 
959  dataSetSurr->GetPoints()->SetPoint(surroundingArray[i], newCoords);
960  }
961 
962  // Pack cells
963  for (int i = 0; i < (int)packArray.size(); i++) {
964  double normalOfPt[3];
965  normalsGeneric->GetTuple(packArray[i], normalOfPt);
966 
967  std::vector<double> getPt = std::vector<double>(3);
968  dataSetSurr->GetPoint(packArray[i], &getPt[0]);
969 
970  double newCoords[3];
971  newCoords[0] = (getPt[0] + 0.001 * normalOfPt[0]);
972  newCoords[1] = (getPt[1] + 0.001 * normalOfPt[1]);
973  newCoords[2] = (getPt[2] + 0.001 * normalOfPt[2]);
974 
975  dataSetSurr->GetPoints()->SetPoint(packArray[i], newCoords);
976  }
977 
978  // Making cells now and plotting them
979  int newCells = (int)(packArray.size() / 4);
980  int startNum = (int)(dataSetSurr->GetNumberOfCells());
981 
982  // Finally, creating VTK cells
983  int it7 = 0;
984  std::vector<int> pntCohesiveIds;
985  int nCelCohesivePnts = 0;
986  for (int icl = 0; icl < newCells; icl++) {
987  nCelCohesivePnts = 4;
988  pntCohesiveIds.resize((nCelCohesivePnts * 2), -1);
989  for (int ip = 0; ip < nCelCohesivePnts; ip++) {
990  pntCohesiveIds[ip] = packArray[it7];
991  pntCohesiveIds[ip + 4] = surroundingArray[it7];
992  it7++;
993  }
994  vtkSmartPointer<vtkIdList> vtkCellIds = vtkSmartPointer<vtkIdList>::New();
995  vtkCellIds->SetNumberOfIds(pntCohesiveIds.size());
996  for (auto pit = pntCohesiveIds.begin(); pit != pntCohesiveIds.end(); pit++)
997  vtkCellIds->SetId(pit - pntCohesiveIds.begin(), *pit);
998  dataSetSurr->InsertNextCell(12, vtkCellIds);
999  }
1000 
1001  int endNum = dataSetSurr->GetNumberOfCells();
1002 
1003  // ****************************** //
1004  // Zero volume cells visualization method for debugging purpose.
1005  std::vector<int> cohCellIds;
1006  for (int i = startNum; i < endNum; i++) { cohCellIds.push_back(i); }
1007 
1008  int size3 = cohCellIds.size();
1009  // Takes cell Ids as input and writes VTK mesh
1010  vtkSmartPointer<vtkUnstructuredGrid> visDataSet =
1012 
1013  std::vector<int> ptIdzz2;
1014  for (int i = 0; i < size3; i++) {
1015  vtkCell *cell;
1016  cell = dataSetSurr->GetCell(cohCellIds[i]);
1017 
1018  vtkIdList *pts = cell->GetPointIds();
1019 
1020  for (int j = 0; j < 8; j++) { ptIdzz2.push_back(pts->GetId(j)); }
1021  }
1022 
1023  int lvar = 0;
1024 
1025  vtkSmartPointer<vtkPoints> pointsViz = vtkSmartPointer<vtkPoints>::New();
1026 
1027  for (int i = 0; i < (size3 * 8); i++) {
1028  std::vector<double> getPt = std::vector<double>(3);
1029  dataSetSurr->GetPoint(ptIdzz2[i], &getPt[0]);
1030  pointsViz->InsertNextPoint(getPt[0], getPt[1], getPt[2]);
1031  }
1032 
1033  visDataSet->SetPoints(pointsViz);
1034 
1035  for (int i = 0; i < size3; i++) {
1036  std::vector<int> ptnewIdz;
1037  for (int j = 0; j < 8; j++) {
1038  ptnewIdz.push_back(lvar);
1039  lvar++;
1040  }
1041  vtkSmartPointer<vtkIdList> vtkCellIds = vtkSmartPointer<vtkIdList>::New();
1042  vtkCellIds->SetNumberOfIds(ptnewIdz.size());
1043  for (auto pit = ptnewIdz.begin(); pit != ptnewIdz.end(); pit++)
1044  vtkCellIds->SetId(pit - ptnewIdz.begin(), *pit);
1045  visDataSet->InsertNextCell(12, vtkCellIds);
1046  }
1047 
1048  auto vm = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
1049  new NEM::MSH::vtkGeoMesh(visDataSet));
1050  vm->write("ArtificialElements.vtu");
1051 
1052  // ********************************************* //
1053  auto vm2 = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
1054  new NEM::MSH::vtkGeoMesh(dataSetSurr));
1055  vm2->write(outName);
1056 
1057  // Convert final mesh to tetrahedra
1058  bool tetra = false;
1059  std::string ofnameTet = "Tetra" + outName;
1060 
1061  if (tetra) {
1062  vtkSmartPointer<vtkDataSetTriangleFilter> triFilter =
1064  triFilter->SetInputData(dataSetSurr);
1065  triFilter->Update();
1066 
1067  auto newData_tet = triFilter->GetOutput();
1068 
1069  auto vm3 = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
1070  new NEM::MSH::vtkGeoMesh(newData_tet));
1071  vm3->write(ofnameTet);
1072  }
1073 }
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
A concrete implementation of geoMeshBase representing a mesh in a vtkUnstructuredGrid.
Definition: vtkGeoMesh.H:42
const Foam::fvMesh & getFoamMesh() const
Copy the mesh.
Definition: foamGeoMesh.H:105

◆ addCohesiveElements()

void MeshManipulationFoam::addCohesiveElements ( double  tol,
const std::string &  outName 
)

This method can take two .vtk/.vtu files or Foam meshes as input and outputs a single .vtk/.vtu file with original meshes plus cohesive elements.

Parameters
tolTolerance for conformal duplicate nodes between two meshes.
outNameOutput mesh name with extension (i.e "output.vtu")

Definition at line 414 of file MeshManipulationFoam.C.

References NEM::MSH::foamGeoMesh::getFoamMesh(), NEM::MSH::New(), and NEM::MSH::Read().

415  {
416  bool writeDicts = true;
417  std::unique_ptr<getDicts> initFoam;
418  initFoam = std::unique_ptr<getDicts>(new getDicts());
419  auto controlDict_ = initFoam->createControlDict(writeDicts);
420 
421  Foam::Time runTime(controlDict_.get(), ".", ".");
422 
423  auto _fmeshSurr = std::unique_ptr<NEM::MSH::foamGeoMesh>(
424  NEM::MSH::foamGeoMesh::Read("domain0.foam"));
425 
426  auto _fmeshPacks = std::unique_ptr<NEM::MSH::foamGeoMesh>(
427  NEM::MSH::foamGeoMesh::Read("domain1.foam"));
428 
429  // declare vtk datasets
430  vtkSmartPointer<vtkUnstructuredGrid> dataSetSurr =
432 
433  vtkSmartPointer<vtkUnstructuredGrid> surrTmp =
435  auto objVfoamSurr = Foam::vtk::vtuAdaptor();
436  surrTmp = objVfoamSurr.internal(_fmeshSurr->getFoamMesh());
437 
438  int impPts = (int)(surrTmp->GetNumberOfPoints());
439 
440  vtkSmartPointer<vtkUnstructuredGrid> pckTmp =
442  auto objVfoamPck = Foam::vtk::vtuAdaptor();
443  pckTmp = objVfoamPck.internal(_fmeshPacks->getFoamMesh());
444 
445  // Merge two foam meshes
446  vtkSmartPointer<vtkAppendFilter> appendFilter =
448  appendFilter->AddInputData(surrTmp);
449  appendFilter->AddInputData(pckTmp);
450  appendFilter->MergePointsOn();
451  appendFilter->Update();
452  dataSetSurr = appendFilter->GetOutput();
453 
454  int numPoints = (int)(dataSetSurr->GetNumberOfPoints());
455 
456  int nDim = 3;
457  ANNpointArray pntCrd;
458  pntCrd = annAllocPts(numPoints, nDim);
459  for (int iPnt = 0; iPnt < numPoints; iPnt++) {
460  std::vector<double> getPt = std::vector<double>(3);
461  dataSetSurr->GetPoint(iPnt, &getPt[0]);
462  pntCrd[iPnt][0] = getPt[0];
463  pntCrd[iPnt][1] = getPt[1];
464  pntCrd[iPnt][2] = getPt[2];
465  }
466 
467  ANNkd_tree *kdTree = new ANNkd_tree(pntCrd, numPoints, nDim);
468 
469  // Finding duplicate nodes
470  double rad = 1e-05;
471  std::map<int, int> dupNdeMap;
472  ANNpoint qryPnt; // Query point.
473  int nNib = 2; // Number of neighbours to return (including query pt. itself).
474  ANNidxArray nnIdx = new ANNidx[nNib]; // Nearest neighbour ID array.
475  ANNdistArray dists = new ANNdist[nNib]; // Neighbour distance array.
476  qryPnt = annAllocPt(nDim); // Initializing query point
477 
478  for (int iNde = 0; iNde < impPts; iNde++) {
479  std::vector<double> getPt = std::vector<double>(3);
480  dataSetSurr->GetPoint(iNde, &getPt[0]);
481  qryPnt[0] = getPt[0];
482  qryPnt[1] = getPt[1];
483  qryPnt[2] = getPt[2];
484  kdTree->annkFRSearch(qryPnt, rad, nNib, nnIdx, dists, 0);
485  if (dists[1] <= tol) {
486  if ((nnIdx[1]) >= impPts)
487  dupNdeMap[nnIdx[0]] = nnIdx[1]; // Format Surrounding::Pack
488  else
489  dupNdeMap[nnIdx[1]] = nnIdx[0]; // Format Surrounding::Pack
490  }
491  }
492 
493  int numDupPnts = (int)dupNdeMap.size();
494  std::cout << "Found " << numDupPnts << " duplicate nodes.\n";
495 
496  // Getting cells in packs
497  std::map<int, int>::iterator it = dupNdeMap.begin();
498  std::vector<int> cellID;
499  for (int i = 0; i < (int)(dupNdeMap.size()); i++) {
500  int nCells, cellNum;
501  vtkIdList *cells = vtkIdList::New();
502 
503  // get cells the point belongs to
504  dataSetSurr->GetPointCells(it->second, cells);
505  nCells = (int)cells->GetNumberOfIds();
506 
507  for (cellNum = 0; cellNum < nCells; cellNum++) {
508  cellID.push_back((int)(cells->GetId(cellNum))); // get cell id from list
509  }
510  it++;
511  }
512 
513  sort(cellID.begin(), cellID.end());
514  cellID.erase(unique(cellID.begin(), cellID.end()), cellID.end());
515 
516  int know = (int)cellID.size();
517 
518  // std::cout << "Total Cells Found Are " << know << std::endl;
519 
520  // Determines which cells are useful
521  std::vector<int> newCellIds;
522  std::vector<int> debugCellIds;
523 
524  for (int i = 0; i < know; i++) {
525  // Getting all cell defining points
526  std::vector<int> ptIdzz(8);
527  int cntr = 0;
528  vtkCell *cell;
529  cell = dataSetSurr->GetCell(cellID[i]);
530 
531  vtkIdList *pts = cell->GetPointIds();
532 
533  for (int j = 0; j < 8; j++) { ptIdzz[j] = (int)(pts->GetId(j)); }
534 
535  // Checking if any cell contains any 4 or more of duplicate nodes.
536  std::map<int, int>::iterator it2 = dupNdeMap.begin();
537  while (it2 != dupNdeMap.end()) {
538  for (int k = 0; k < 8; k++) {
539  if ((it2->second) == ptIdzz[k]) {
540  cntr++;
541  } else {
542  // Nothing
543  }
544  }
545  it2++;
546  }
547 
548  if (cntr >= 4) {
549  newCellIds.push_back(cellID[i]);
550  } else {
551  debugCellIds.push_back(cellID[i]);
552  }
553  }
554 
555  int size2 = (int)newCellIds.size();
556 
557  // Getting useful faces from cells
558  std::vector<int> globalPtIds;
559  std::vector<int> surroundingArray;
560  std::vector<int> packArray;
561  for (int i = 0; i < size2; i++) {
562  vtkCell *cell;
563  cell = dataSetSurr->GetCell(newCellIds[i]);
564  vtkIdList *pts = cell->GetPointIds();
565 
566  for (int j = 0; j < 6; j++) {
567  int isFour = 0;
568  int *ptFaces = nullptr;
569  vtkCell3D *cell3d = static_cast<vtkCell3D *>(cell);
570  cell3d->GetFacePoints(j, ptFaces);
571  std::vector<int> keysDupMap = std::vector<int>(4);
572  std::map<int, int>::iterator it3 = dupNdeMap.begin();
573  while (it3 != dupNdeMap.end()) {
574  for (int h = 0; h < 4; h++) {
575  if ((it3->second) == (pts->GetId(ptFaces[h]))) {
576  isFour++;
577  keysDupMap[h] = it3->first;
578  } else {
579  // Nothing
580  }
581  }
582 
583  it3++;
584  }
585 
586  if (isFour == 4) {
587  for (int k = 0; k < 4; k++) { globalPtIds.push_back(keysDupMap[k]); }
588  }
589  }
590  }
591 
592  std::map<int, int>::iterator it5;
593 
594  // Creating node map with sequence.
595  std::unordered_multimap<int, int> cohesiveMap;
596 
597  for (int i = 0; i < (int)globalPtIds.size(); i++) {
598  it5 = dupNdeMap.find(globalPtIds[i]);
599 
600  if (it5 == dupNdeMap.end()) {
601  // Nothing
602  } else {
603  surroundingArray.push_back(it5->first);
604  packArray.push_back(it5->second);
605  }
606  }
607 
608  // std::cout << "Size = " << packArray.size() << std::endl;
609  int newCells = (int)(packArray.size() / 4);
610  int startNum = (int)(dataSetSurr->GetNumberOfCells());
611 
612  // Finally, creating VTK cells
613  int it7 = 0;
614  std::vector<int> pntCohesiveIds;
615  int nCelCohesivePnts;
616  for (int icl = 0; icl < newCells; icl++) {
617  nCelCohesivePnts = 4;
618  pntCohesiveIds.resize((nCelCohesivePnts * 2), -1);
619  for (int ip = 0; ip < nCelCohesivePnts; ip++) {
620  pntCohesiveIds[ip] = packArray[it7];
621  pntCohesiveIds[ip + 4] = surroundingArray[it7];
622  it7++;
623  }
624  vtkSmartPointer<vtkIdList> vtkCellIds = vtkSmartPointer<vtkIdList>::New();
625  vtkCellIds->SetNumberOfIds(pntCohesiveIds.size());
626  for (auto pit = pntCohesiveIds.begin(); pit != pntCohesiveIds.end(); pit++)
627  vtkCellIds->SetId(pit - pntCohesiveIds.begin(), *pit);
628  dataSetSurr->InsertNextCell(12, vtkCellIds);
629  }
630 
631  int endNum = (int)(dataSetSurr->GetNumberOfCells());
632 
633  // ****************************** //
634  // Zero volume cells visualization method for debugging purpose.
635  std::vector<int> cohCellIds;
636  for (int i = startNum; i < endNum; i++) { cohCellIds.push_back(i); }
637 
638  int size3 = (int)cohCellIds.size();
639  // Takes cell Ids as input and writes VTK mesh
640  vtkSmartPointer<vtkUnstructuredGrid> visDataSet =
642 
643  std::vector<int> ptIdzz2;
644  for (int i = 0; i < size3; i++) {
645  vtkCell *cell;
646 
647  cell = dataSetSurr->GetCell(cohCellIds[i]);
648 
649  vtkIdList *pts = cell->GetPointIds();
650 
651  for (int j = 0; j < 8; j++) { ptIdzz2.push_back((int)(pts->GetId(j))); }
652  }
653 
654  int lvar = 0;
655 
656  vtkSmartPointer<vtkPoints> pointsViz = vtkSmartPointer<vtkPoints>::New();
657 
658  for (int i = 0; i < (size3 * 8); i++) {
659  std::vector<double> getPt = std::vector<double>(3);
660  dataSetSurr->GetPoint(ptIdzz2[i], &getPt[0]);
661  pointsViz->InsertNextPoint(getPt[0], getPt[1], getPt[2]);
662  }
663 
664  visDataSet->SetPoints(pointsViz);
665 
666  for (int i = 0; i < size3; i++) {
667  std::vector<int> ptnewIdz;
668  for (int j = 0; j < 8; j++) {
669  ptnewIdz.push_back(lvar);
670  lvar++;
671  }
672  vtkSmartPointer<vtkIdList> vtkCellIds = vtkSmartPointer<vtkIdList>::New();
673  vtkCellIds->SetNumberOfIds(ptnewIdz.size());
674  for (auto pit = ptnewIdz.begin(); pit != ptnewIdz.end(); pit++)
675  vtkCellIds->SetId(pit - ptnewIdz.begin(), *pit);
676  visDataSet->InsertNextCell(12, vtkCellIds);
677  }
678 
679  auto vm = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
680  new NEM::MSH::vtkGeoMesh(visDataSet));
681  vm->write("CohesiveElements.vtu");
682 
683  // ********************************************* //
684  auto vm2 = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
685  new NEM::MSH::vtkGeoMesh(dataSetSurr));
686  vm2->write(outName);
687 
688  // Convert final mesh to tetrahedral
689  bool tetra = false;
690  std::string ofnameTet = "Tetra" + outName;
691 
692  if (tetra) {
693  vtkSmartPointer<vtkDataSetTriangleFilter> triFilter =
695  triFilter->SetInputData(dataSetSurr);
696  triFilter->Update();
697 
698  auto newData_tet = triFilter->GetOutput();
699 
700  auto vm3 = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
701  new NEM::MSH::vtkGeoMesh(newData_tet));
702  vm3->write(ofnameTet);
703  }
704  // **************************************************************************
705 }
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
A concrete implementation of geoMeshBase representing a mesh in a vtkUnstructuredGrid.
Definition: vtkGeoMesh.H:42
const Foam::fvMesh & getFoamMesh() const
Copy the mesh.
Definition: foamGeoMesh.H:105

◆ createPatchDict()

void MeshManipulationFoam::createPatchDict ( const int &  dirStat,
const bool &  write 
)
private
Parameters
dirStatdomain number to skip (output from splitMshRegions)
writeWrite boolean

Definition at line 187 of file MeshManipulationFoam.C.

References _mshMnipPrms, cpDict_, MeshManipulationFoamParams::createPatchParams, and MeshManipulationFoamParams::CreatePatch::pathSurrounding.

Referenced by createPtch().

188  {
189  const auto &createPatchParams = _mshMnipPrms->createPatchParams;
190 
191  // creating a base system directory
192  std::string dir_path = "./system/" + createPatchParams.pathSurrounding;
193 
194  if (write) {
195  boost::filesystem::path dir(dir_path);
196  try {
197  boost::filesystem::create_directory(dir);
198  } catch (boost::filesystem::filesystem_error &e) {
199  std::cerr << "Problem in creating system directory for the snappyHexMesh"
200  << "\n";
201  std::cerr << e.what() << std::endl;
202  throw;
203  }
204  }
205 
206  // header
207  std::string contText =
208  "\
209 /*--------------------------------*- C++ -*----------------------------------*\n\
210 | ========= | |\n\
211 | \\\\ / F ield | NEMoSys: snappyHexMesh interface |\n\
212 | \\\\ / O peration | |\n\
213 | \\\\ / A nd | |\n\
214 | \\\\/ M anipulation | |\n\
215 \\*---------------------------------------------------------------------------*/\n\
216 \n\
217 FoamFile\n\
218 {\n\
219  version 2.0;\n\
220  format ascii;\n\
221  class dictionary;\n\
222  location \"system\";\n\
223  object createPatchDict;\n\
224 }\n\n";
225 
226  contText =
227  contText +
228  "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
229 
230  contText = contText + "\n\npointSync true;\n";
231  contText = contText + "\n\npatches\n";
232  contText = contText + "(\n";
233  contText = contText + "\t{\n";
234  contText =
235  contText + "\t\tname " + (createPatchParams.surroundingName) + ";\n";
236  contText = contText + "\n\t\tpatchInfo\n";
237  contText = contText + "\t\t{\n";
238  contText =
239  contText + "\t\t\ttype " + (createPatchParams.srrndngPatchType) + ";\n";
240  contText = contText + "\t\t}\n";
241  contText = contText + "\n\t\tconstructFrom patches;\n";
242  contText = contText + "\n\t\tpatches (\"domain0_to_domain.*\");";
243  contText = contText + "\n\t}\n";
244  contText = contText + ");\n";
245 
246  contText = contText +
247  "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "
248  "*//\n\n";
249 
250  // creating mesh dictionary file
251  std::ofstream contDict;
252  if (write) {
253  contDict.open(std::string(dir_path) + "/createPatchDict");
254  contDict << contText;
255  contDict.close();
256  }
257 
258  // Keep this dictionary in memory
259  Foam::dictionary tmptmpDuc =
260  new Foam::dictionary(Foam::IStringStream(contText)(), true);
261  cpDict_ = std::unique_ptr<Foam::dictionary>(
262  new Foam::dictionary("createPatchDict"));
263  cpDict_->merge(tmptmpDuc);
264 
265  if (dirStat == 1) {
266  const char dir_path2[] = "./system/domain2";
267 
268  if (write) {
269  boost::filesystem::path dir2(dir_path2);
270  try {
271  boost::filesystem::create_directory(dir2);
272  } catch (boost::filesystem::filesystem_error &e) {
273  std::cerr << "Problem in creating system directory for createPatch"
274  << "\n";
275  std::cerr << e.what() << std::endl;
276  throw;
277  }
278  }
279 
280  // header
281  std::string contText2 =
282  "\
283 /*--------------------------------*- C++ -*----------------------------------*\n\
284 | ========= | |\n\
285 | \\\\ / F ield | NEMoSys: snappyHexMesh interface |\n\
286 | \\\\ / O peration | |\n\
287 | \\\\ / A nd | |\n\
288 | \\\\/ M anipulation | |\n\
289 \\*---------------------------------------------------------------------------*/\n\
290 \n\
291 FoamFile\n\
292 {\n\
293  version 2.0;\n\
294  format ascii;\n\
295  class dictionary;\n\
296  location \"system\";\n\
297  object createPatchDict;\n\
298 }\n\n";
299 
300  contText2 = contText2 +
301  "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "
302  "* * //\n\n";
303 
304  contText2 = contText2 + "\n\npointSync true;\n";
305  contText2 = contText2 + "\n\npatches\n";
306  contText2 = contText2 + "(\n";
307  contText2 = contText2 + "\t{\n";
308  contText2 = contText2 + "\t\tname " + (createPatchParams.packsName) + ";\n";
309  contText2 = contText2 + "\n\t\tpatchInfo\n";
310  contText2 = contText2 + "\t\t{\n";
311  contText2 =
312  contText2 + "\t\t\ttype " + (createPatchParams.packsPatchType) + ";\n";
313  contText2 = contText2 + "\t\t}\n";
314  contText2 = contText2 + "\n\t\tconstructFrom patches;\n";
315  contText2 = contText2 + "\n\t\tpatches (\"domain.*_to_domain0\");";
316  contText2 = contText2 + "\n\t}\n";
317  contText2 = contText2 + ");\n";
318 
319  contText2 = contText2 +
320  "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "
321  "* * //\n\n";
322 
323  // creating mesh dictionary file
324  std::ofstream contDict2;
325  if (write) {
326  contDict2.open(std::string(dir_path2) + "/createPatchDict");
327  contDict2 << contText2;
328  contDict2.close();
329  }
330 
331  // Keep this dictionary in memory
332  cpDict_.reset();
333  Foam::dictionary tmptmpDuc2 =
334  new Foam::dictionary(Foam::IStringStream(contText2)(), true);
335  cpDict_ = std::unique_ptr<Foam::dictionary>(
336  new Foam::dictionary("createPatchDict"));
337  cpDict_->merge(tmptmpDuc2);
338  } else {
339  const char dir_path2[] = "./system/domain1";
340  if (write) {
341  boost::filesystem::path dir2(dir_path2);
342  try {
343  boost::filesystem::create_directory(dir2);
344  } catch (boost::filesystem::filesystem_error &e) {
345  std::cerr << "Problem in creating system directory for createPatch"
346  << "\n";
347  std::cerr << e.what() << std::endl;
348  throw;
349  }
350  }
351 
352  // header
353  std::string contText2 =
354  "\
355 /*--------------------------------*- C++ -*----------------------------------*\n\
356 | ========= | |\n\
357 | \\\\ / F ield | NEMoSys: snappyHexMesh interface |\n\
358 | \\\\ / O peration | |\n\
359 | \\\\ / A nd | |\n\
360 | \\\\/ M anipulation | |\n\
361 \\*---------------------------------------------------------------------------*/\n\
362 \n\
363 FoamFile\n\
364 {\n\
365  version 2.0;\n\
366  format ascii;\n\
367  class dictionary;\n\
368  location \"system\";\n\
369  object createPatchDict;\n\
370 }\n\n";
371 
372  contText2 = contText2 +
373  "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "
374  "* * //\n\n";
375 
376  contText2 = contText2 + "\n\npointSync true;\n";
377  contText2 = contText2 + "\n\npatches\n";
378  contText2 = contText2 + "(\n";
379  contText2 = contText2 + "\t{\n";
380  contText2 = contText2 + "\t\tname " + (createPatchParams.packsName) + ";\n";
381  contText2 = contText2 + "\n\t\tpatchInfo\n";
382  contText2 = contText2 + "\t\t{\n";
383  contText2 =
384  contText2 + "\t\t\ttype " + (createPatchParams.packsPatchType) + ";\n";
385  contText2 = contText2 + "\t\t}\n";
386  contText2 = contText2 + "\n\t\tconstructFrom patches;\n";
387  contText2 = contText2 + "\n\t\tpatches (\"domain.*_to_domain0\");";
388  contText2 = contText2 + "\n\t}\n";
389  contText2 = contText2 + ");\n";
390 
391  contText2 = contText2 +
392  "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "
393  "* * //\n\n";
394 
395  // creating mesh dictionary file
396  std::ofstream contDict2;
397  if (write) {
398  contDict2.open(std::string(dir_path2) + "/createPatchDict");
399  contDict2 << contText2;
400  contDict2.close();
401  }
402 
403  // Keep this dictionary in memory
404  Foam::dictionary tmptmpDuc2 =
405  new Foam::dictionary(Foam::IStringStream(contText2)(), true);
406  cpDict_.reset();
407  cpDict_ = std::unique_ptr<Foam::dictionary>(
408  new Foam::dictionary("createPatchDict"));
409  cpDict_->merge(tmptmpDuc2);
410  }
411 }
std::unique_ptr< Foam::dictionary > cpDict_
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.
std::string pathSurrounding
Defines surrounding mesh path from main directory.

◆ createPtch()

void MeshManipulationFoam::createPtch ( int  dirStat)

User input is usually createPatchDict.

Parameters
dirStatdomain number to skip (output from splitMshRegions)

Definition at line 149 of file MeshManipulationFoam.C.

References _mshMnipPrms, cpDict_, createPatchDict(), and MeshManipulationFoamParams::createPatchParams.

149  {
150  const auto &createPatchParams = _mshMnipPrms->createPatchParams;
151  auto cpObj = createPatch();
152  createPatchDict(dirStat, true);
153  cpObj.execute(dirStat, createPatchParams.pathSurrounding, cpDict_);
154 }
std::unique_ptr< Foam::dictionary > cpDict_
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.
void createPatchDict(const int &dirStat, const bool &write)
createPatchDict utility creates a dictionary needed for createPatch method.

◆ foamToSurf()

void MeshManipulationFoam::foamToSurf ( )

Definition at line 160 of file MeshManipulationFoam.C.

References _mshMnipPrms, and MeshManipulationFoamParams::foamToSurfParams.

160  {
161  const auto &foamToSurfaceParams = _mshMnipPrms->foamToSurfParams;
162  auto ftsObj = foamToSurface();
163  ftsObj.execute(foamToSurfaceParams.outSurfName);
164 }
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.

◆ mergeMesh()

void MeshManipulationFoam::mergeMesh ( int  dirStat,
int  nDomains 
)
Parameters
dirStatdomain number to skip (output from splitMshRegions)
nDomainsNumber of meshes to merge

Definition at line 120 of file MeshManipulationFoam.C.

References _mshMnipPrms, and MeshManipulationFoamParams::mergeMeshesParams.

120  {
121  auto mmObj = mergeMeshes();
122  const auto &mergeMeshesParams = _mshMnipPrms->mergeMeshesParams;
123 
124  std::vector<std::string> addCases;
125 
126  // Collecting all domain names for automatic merging of all mesh regions.
127  // Directory number obtained from splitMeshRegions is used here. Also
128  // number of packs are passed through this function for use in loop.
129 
130  if (nDomains == 2) {
131  addCases.push_back(mergeMeshesParams.addCase);
132  } else {
133  for (int i = 2; i < (nDomains + 1); i++) {
134  if (i == dirStat) i++;
135  addCases.push_back("domain" + (std::to_string(i)));
136  }
137  addCases.push_back(mergeMeshesParams.addCase);
138  }
139  mmObj.execute(mergeMeshesParams.masterCasePath, mergeMeshesParams.addCasePath,
140  addCases, nDomains, dirStat);
141 }
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.

◆ periodicMeshMapper()

void MeshManipulationFoam::periodicMeshMapper ( std::string &  patch1,
std::string &  patch2 
)
Parameters
patch1First boundary for mapping.
patch2Second boundary for mapping.

Definition at line 1076 of file MeshManipulationFoam.C.

References NEM::MSH::New(), points, and NEM::MSH::Read().

1077  {
1078  bool writeDicts = false;
1079  std::unique_ptr<getDicts> initFoam;
1080  initFoam = std::unique_ptr<getDicts>(new getDicts());
1081  auto controlDict_ = initFoam->createControlDict(writeDicts);
1082 
1083  Foam::fileName one = ".";
1084  Foam::fileName two = ".";
1085  Foam::Time runTime(controlDict_.get(), one, two);
1086 
1087  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
1088 
1089  // Foam::word regionName = Foam::polyMesh::defaultRegion;
1090 
1091  // auto _fmeshPacks = new Foam::polyMesh(Foam::IOobject(
1092  // regionName, runTime.timeName(), runTime, Foam::IOobject::MUST_READ));
1093 
1094  auto fm = std::unique_ptr<NEM::MSH::foamGeoMesh>(
1095  NEM::MSH::foamGeoMesh::Read(".foam"));
1096 
1097  const auto &_fmeshPacks = fm->getFoamMesh();
1098 
1099  // Creating patch objects for periodic boundary patches
1100  int patchIDIn = _fmeshPacks.boundaryMesh().findPatchID(patch1);
1101  int patchIDOut = _fmeshPacks.boundaryMesh().findPatchID(patch2);
1102 
1103  const Foam::polyPatch &InPolyPatch = _fmeshPacks.boundaryMesh()[patchIDIn];
1104  const Foam::polyPatch &OutPolyPatch = _fmeshPacks.boundaryMesh()[patchIDOut];
1105 
1106  // Point IDs from periodic patches.
1107  Foam::labelList inPts(InPolyPatch.meshPoints());
1108  Foam::labelList outPts(OutPolyPatch.meshPoints());
1109 
1110  if (inPts.size() != outPts.size()) {
1111  std::cerr << "Selected boundaries are not periodic!"
1112  << "\nExiting!" << std::endl;
1113  throw;
1114  }
1115 
1116  Foam::pointField packsPF = _fmeshPacks.points();
1117 
1118  // Creating map of IDs on both patches
1119  std::map<int, int> periodicMap;
1120 
1121  for (int i = 0; i < inPts.size(); i++) { periodicMap[inPts[i]] = outPts[i]; }
1122 
1123  ofstream myfile;
1124  myfile.open("PeriodicMap.csv");
1125  for (int i = 0; i < inPts.size(); i++) {
1126  myfile << inPts[i] << "," << outPts[i] << std::endl;
1127  }
1128  myfile.close();
1129 
1130  // Method test using VTK unstructured writer
1131  // Very useful for extracting face node orders. Might use this in
1132  // cohesive elements. Also, Foam::facePointPatch::pointNormals()
1133  // can be useful for artificial thickness elements
1134  vtkSmartPointer<vtkUnstructuredGrid> dataSetTest =
1136  vtkSmartPointer<vtkPoints> pointsMesh = vtkSmartPointer<vtkPoints>::New();
1137 
1138  for (int i = 0; i < packsPF.size(); i++) {
1139  pointsMesh->InsertNextPoint(packsPF[i].x(), packsPF[i].y(), packsPF[i].z());
1140  }
1141 
1142  dataSetTest->SetPoints(pointsMesh);
1143 
1144  forAll (_fmeshPacks.boundaryMesh()[patchIDIn], facei) {
1145  const Foam::label &faceID =
1146  _fmeshPacks.boundaryMesh()[patchIDIn].start() + facei;
1147  std::vector<int> pntIds;
1148  pntIds.resize(4, -1);
1149  int g = 0;
1150  forAll (_fmeshPacks.faces()[faceID], nodei) {
1151  const Foam::label &nodeID = _fmeshPacks.faces()[faceID][nodei];
1152  pntIds[g] = nodeID;
1153  g++;
1154  }
1155  vtkSmartPointer<vtkIdList> vtkCellIds = vtkSmartPointer<vtkIdList>::New();
1156  vtkCellIds->SetNumberOfIds(pntIds.size());
1157  for (auto pit = pntIds.begin(); pit != pntIds.end(); pit++)
1158  vtkCellIds->SetId(pit - pntIds.begin(), *pit);
1159  dataSetTest->InsertNextCell(9, vtkCellIds);
1160  }
1161 
1162  forAll (_fmeshPacks.boundaryMesh()[patchIDOut], facei) {
1163  const Foam::label &faceID =
1164  _fmeshPacks.boundaryMesh()[patchIDOut].start() + facei;
1165  std::vector<int> pntIds;
1166  pntIds.resize(4, -1);
1167  int g = 0;
1168  forAll (_fmeshPacks.faces()[faceID], nodei) {
1169  const Foam::label &nodeID = _fmeshPacks.faces()[faceID][nodei];
1170  pntIds[g] = nodeID;
1171  g++;
1172  }
1173  vtkSmartPointer<vtkIdList> vtkCellIds = vtkSmartPointer<vtkIdList>::New();
1174  vtkCellIds->SetNumberOfIds(pntIds.size());
1175  for (auto pit = pntIds.begin(); pit != pntIds.end(); pit++)
1176  vtkCellIds->SetId(pit - pntIds.begin(), *pit);
1177  dataSetTest->InsertNextCell(9, vtkCellIds);
1178  }
1179 
1180  auto vm = std::unique_ptr<NEM::MSH::vtkGeoMesh>(
1181  new NEM::MSH::vtkGeoMesh(dataSetTest));
1182  vm->write("PeriodicMesh.vtu");
1183 }
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
A concrete implementation of geoMeshBase representing a mesh in a vtkUnstructuredGrid.
Definition: vtkGeoMesh.H:42
std::vector< vtkIdType > points
points given by id in .inp file
Definition: inpGeoMesh.C:133

◆ splitMshRegions()

std::pair< std::vector< int >, std::vector< std::string > > MeshManipulationFoam::splitMshRegions ( )

Writes these regions in separate Foam meshes.

Parameters

Definition at line 109 of file MeshManipulationFoam.C.

References _mshMnipPrms, and MeshManipulationFoamParams::splitMeshRegParams.

109  {
110  const auto &spltMshRegions = _mshMnipPrms->splitMeshRegParams;
111  const bool useCellZones = (spltMshRegions.cellZones);
112  auto smrObj = splitMeshRegions();
113  return smrObj.execute(useCellZones);
114 }
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.

◆ surfLambdaMuSmooth()

void MeshManipulationFoam::surfLambdaMuSmooth ( )

This utility supports .ofs, .obj, .inp, .stl, .tri, .off, .stlb, .nas, .bdf, .gts, .vtk, .ac extensions for input and output surface files.

Definition at line 86 of file MeshManipulationFoam.C.

References _mshMnipPrms, and MeshManipulationFoamParams::surfLMSmoothParams.

86  {
87  const auto &surfLMSmoothParams = _mshMnipPrms->surfLMSmoothParams;
88  const Foam::fileName surfFileName = (surfLMSmoothParams.slmssurfaceFile);
89  const Foam::fileName outFileName = (surfLMSmoothParams.slmsoutputFile);
90  const Foam::scalar lambda = (surfLMSmoothParams.lambda_);
91  const Foam::scalar mu = (surfLMSmoothParams.mu);
92  const Foam::label iters = (surfLMSmoothParams.slmsIterations);
93  const bool addFtrFl = (surfLMSmoothParams.addFeatureFile);
94  auto slmsObj = surfaceLambdaMuSmooth();
95  slmsObj.execute(surfFileName, outFileName, lambda, mu, iters, addFtrFl);
96 }
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.
SurfaceLambdaMuSmooth surfLMSmoothParams

◆ surfSpltByTopology()

int MeshManipulationFoam::surfSpltByTopology ( )

writes a surface file with separated patches as well as multiple surface files for separate patches.

Definition at line 172 of file MeshManipulationFoam.C.

References _mshMnipPrms, and MeshManipulationFoamParams::surfSplitParams.

172  {
173  const auto &surfSplitParams = _mshMnipPrms->surfSplitParams;
174  Foam::fileName surfFileName(surfSplitParams.surfFile);
175  Foam::Info << "Reading surface from " << surfFileName << Foam::endl;
176  Foam::fileName outFileName(surfSplitParams.outSurfFile);
177  auto ssbtObj = surfaceSplitByTopology();
178  return ssbtObj.execute(surfFileName, outFileName);
179 }
MeshManipulationFoamParams * _mshMnipPrms
MeshManipulationFoam object.
SurfaceSplitByManifold surfSplitParams

Member Data Documentation

◆ _mshMnipPrms

MeshManipulationFoamParams* MeshManipulationFoam::_mshMnipPrms
private

◆ cpDict_

std::unique_ptr<Foam::dictionary> MeshManipulationFoam::cpDict_
private

Definition at line 172 of file MeshManipulationFoam.H.

Referenced by createPatchDict(), and createPtch().


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