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::VtkToPntConversionDriver Class Reference

Detailed Description

Definition at line 40 of file VtkToPntConversionDriver.H.

Classes

struct  Opts
 

Public Types

using Files = DriverInOutFiles
 

Public Member Functions

 VtkToPntConversionDriver (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 void genExo (std::vector< meshBase *> meshes, const std::string &fname)
 
static std::unique_ptr< NemDriverreadJSON (const jsoncons::json &inputjson)
 Factory method for all drivers. More...
 

Static Protected Member Functions

static void genExo (meshBase *mb, NEM::MSH::EXOMesh::exoMesh *em, const int &ndeIdOffset, const int &elmIdOffset, int &ins, int &ieb, int &iss, std::string mshName, const bool &usePhys, int &ndeIdOffset_local, int &elmIdOffset_local, const bool &makeFreeSurfSS, const bool &splitTopBotSS, std::vector< std::string > sideSetNames)
 
static void procExo (const jsoncons::json &ppJson, const std::string &fname, NEM::MSH::EXOMesh::exoMesh *em)
 
static void freeSurfaceSideSet (const meshBase *mb, NEM::MSH::EXOMesh::exoMesh *em, int elmIdOffset, std::map< int, int > v2e_elemID_map, bool splitTopBotSS, std::vector< std::string > sideSetNames)
 Creates side set(s) for the free surface, exterior surface, during conversion. More...
 

Private Member Functions

 VtkToPntConversionDriver ()
 

Private Attributes

Files files_
 
Opts opts_
 

Inherits NEM::DRV::ConversionDriver.

Member Typedef Documentation

◆ Files

Constructor & Destructor Documentation

◆ VtkToPntConversionDriver() [1/2]

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

Definition at line 37 of file VtkToPntConversionDriver.C.

◆ VtkToPntConversionDriver() [2/2]

NEM::DRV::VtkToPntConversionDriver::VtkToPntConversionDriver ( )
private

Definition at line 40 of file VtkToPntConversionDriver.C.

Member Function Documentation

◆ execute()

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

Implements NEM::DRV::NemDriver.

Definition at line 61 of file VtkToPntConversionDriver.C.

References meshBase::Create(), NEM::DRV::VtkToPntConversionDriver::Opts::dim, NEM::DRV::VtkToPntConversionDriver::Opts::elemBlockMap, files_, NEM::DRV::DriverInOutFiles::inputMeshFile, opts_, NEM::DRV::DriverInOutFiles::outputMeshFile, and PNTMesh::pntMesh::write().

61  {
62  auto source = meshBase::Create(files_.inputMeshFile);
63  std::cout << "Number of Blocks : " << opts_.elemBlockMap.size() << std::endl;
64  auto *pm = new PNTMesh::pntMesh(source, opts_.dim, opts_.elemBlockMap.size(),
67  delete pm;
68 }
std::string outputMeshFile
Definition: NemDriver.H:91
static meshBase * Create(const std::string &fname)
Construct vtkMesh from filename.
Definition: meshBase.C:78
std::string inputMeshFile
Definition: NemDriver.H:90
void write(const std::string &fname) const
Definition: pntMesh.C:609

◆ freeSurfaceSideSet()

void NEM::DRV::ConversionDriver::freeSurfaceSideSet ( const meshBase mb,
NEM::MSH::EXOMesh::exoMesh em,
int  elmIdOffset,
std::map< int, int >  v2e_elemID_map,
bool  splitTopBotSS,
std::vector< std::string >  sideSetNames 
)
staticprotectedinherited
Parameters
mbMeshbase object
emExoMesh object
elmIdOffsetExodus element ID offset
v2e_elemID_mapVTK to EXO element ID map
splitTopBotSSBoolean to split the side set into three side sets
sideSetNamesThe list of name(s) for the side set(s)

Definition at line 287 of file ConversionDriver.C.

References NEM::MSH::EXOMesh::exoMesh::addSdeSet(), NEM::MSH::EXOMesh::sdeSetType::elmIdOffset, NEM::MSH::EXOMesh::sdeSetType::elmIds, meshBase::getDataSet(), NEM::MSH::EXOMesh::exoMesh::getDimension(), NEM::MSH::EXOMesh::sdeSetType::id, NEM::MSH::EXOMesh::sdeSetType::name, NEM::MSH::New(), NEM::MSH::EXOMesh::sdeSetType::nSde, and NEM::MSH::EXOMesh::sdeSetType::sdeIds.

Referenced by NEM::DRV::ConversionDriver::genExo().

290  {
291  std::cout << "Creating side set from free surface." << std::endl;
292 
293  std::vector<std::pair<int, int>> freeSurfCellEdge;
294  std::vector<std::pair<int, int>> hexFreeSurfCellFace;
295  std::vector<std::pair<int, int>> wedgeFreeSurfCellFace;
296  std::vector<std::pair<int, int>> tetraFreeSurfCellFace;
297  std::vector<int> elementIds1, elementIds2, elementIds3, sideIds1, sideIds2,
298  sideIds3;
299  std::vector<std::vector<int>> splitElemIds, splitSideIds;
300 
301  // Maps for VTK to EXO face id conversion for hex and wedge
302  std::map<int, int> v2e_hexFace_map = {{1, 4}, {2, 2}, {3, 1},
303  {4, 3}, {5, 5}, {6, 6}};
304  std::map<int, int> v2e_wedgeFace_map = {
305  {1, 4}, {2, 5}, {3, 1}, {4, 2}, {5, 3}};
306  std::map<int, int> v2e_tetraFace_map = {{1, 1}, {2, 2}, {3, 3}, {4, 4}};
307 
308  // acquiring dataset
309  vtkSmartPointer<vtkDataSet> ds = mb->getDataSet();
310  if (!ds) {
311  std::cerr << "No dataset is associated to the meshbase." << std::endl;
312  throw;
313  }
314  bool tetWarning = false;
315  // loop through cells and obtain different quantities needed
316  int nCl = ds->GetNumberOfCells();
317  for (int cell_i = 0; cell_i < nCl; cell_i++) {
318  vtkCell *vc = ds->GetCell(cell_i);
319  if (vc->GetCellDimension() == 2) {
320  // for 2D cells
321  int ne = vc->GetNumberOfEdges();
322  for (int edge_i = 0; edge_i < ne; edge_i++) {
323  vtkCell *ve = vc->GetEdge(edge_i);
324  vtkIdList *pidl = ve->GetPointIds();
325 
326  std::pair<int, int> adjPair;
327 
328  // getting neighbour list
329  vtkSmartPointer<vtkIdList> cidl = vtkSmartPointer<vtkIdList>::New();
330  ds->GetCellNeighbors(cell_i, pidl, cidl);
331  if (cidl->GetNumberOfIds() == 0) {
332  adjPair.first = cell_i;
333  adjPair.second = edge_i + 1;
334  freeSurfCellEdge.push_back(adjPair);
335  }
336  }
337  } else if (vc->GetCellDimension() == 3) {
338  // for 3D cells
339  int nfc = vc->GetNumberOfFaces();
340  for (int face_i = 0; face_i < nfc; face_i++) {
341  vtkCell *vf = vc->GetFace(face_i);
342  vtkIdList *facePoints = vf->GetPointIds();
343 
344  std::pair<int, int> adjPair;
345 
346  // getting neighbour list
347  vtkSmartPointer<vtkIdList> cidl = vtkSmartPointer<vtkIdList>::New();
348  ds->GetCellNeighbors(cell_i, facePoints, cidl);
349  if (cidl->GetNumberOfIds() == 0) {
350  adjPair.first = cell_i;
351  adjPair.second = face_i + 1;
352  if (nfc == 6) hexFreeSurfCellFace.push_back(adjPair);
353  if (nfc == 5) wedgeFreeSurfCellFace.push_back(adjPair);
354  if (nfc == 4) {
355  tetraFreeSurfCellFace.push_back(adjPair);
356  if (splitTopBotSS && tetWarning == false) {
357  std::cerr
358  << "Warning: Tetrahedral element found on free surface.\n"
359  << " Cannot split top and bottom into separate side "
360  "sets.\n"
361  << " Creating single side set." << std::endl;
362  splitTopBotSS = false;
363  tetWarning = true;
364  }
365  }
366  }
367  }
368  }
369  }
370 
371  if (em->getDimension() == 3) {
372  // Iterate through *freeSurfCellFace to make lists of elements/faces
373  // Hexahedra
374  for (int i = 0; i < hexFreeSurfCellFace.size(); i++) {
375  int exoId = v2e_elemID_map[hexFreeSurfCellFace[i].first];
376  int sId = v2e_hexFace_map[hexFreeSurfCellFace[i].second];
377 
378  if (splitTopBotSS) {
379  if (sId == 5) {
380  // Top
381  elementIds2.push_back(exoId);
382  sideIds2.push_back(sId);
383  } else if (sId == 6) {
384  // Bottom
385  elementIds3.push_back(exoId);
386  sideIds3.push_back(sId);
387  } else {
388  elementIds1.push_back(exoId);
389  sideIds1.push_back(sId);
390  }
391  } else {
392  elementIds1.push_back(exoId);
393  sideIds1.push_back(sId);
394  }
395  }
396  // Wedges
397  for (int i = 0; i < wedgeFreeSurfCellFace.size(); i++) {
398  int exoId = v2e_elemID_map[wedgeFreeSurfCellFace[i].first];
399  int sId = v2e_wedgeFace_map[wedgeFreeSurfCellFace[i].second];
400 
401  if (splitTopBotSS) {
402  if (sId == 4) {
403  // Top
404  elementIds2.push_back(exoId);
405  sideIds2.push_back(sId);
406  } else if (sId == 5) {
407  // Bottom
408  elementIds3.push_back(exoId);
409  sideIds3.push_back(sId);
410  } else {
411  elementIds1.push_back(exoId);
412  sideIds1.push_back(sId);
413  }
414  } else {
415  elementIds1.push_back(exoId);
416  sideIds1.push_back(sId);
417  }
418  }
419  // Tetrahedra
420  for (int i = 0; i < tetraFreeSurfCellFace.size(); i++) {
421  int exoId = v2e_elemID_map[tetraFreeSurfCellFace[i].first];
422  int sId = v2e_tetraFace_map[tetraFreeSurfCellFace[i].second];
423  elementIds1.push_back(exoId);
424  sideIds1.push_back(sId);
425  }
426  }
427 
428  if (em->getDimension() == 2) {
429  // Iterate through freeSurfCellEdge to make lists of elements/faces
430  for (int i = 0; i < freeSurfCellEdge.size(); i++) {
431  // map from VTK element id to EXO element id
432  int exoId = v2e_elemID_map[freeSurfCellEdge[i].first];
433  elementIds1.push_back(exoId);
434  sideIds1.push_back(freeSurfCellEdge[i].second);
435  }
436  }
437 
438  if (splitTopBotSS && em->getDimension() == 3) {
439  splitElemIds = {elementIds1, elementIds2, elementIds3};
440  splitSideIds = {sideIds1, sideIds2, sideIds3};
441  } else {
442  splitElemIds = {elementIds1};
443  splitSideIds = {sideIds1};
444  }
445 
446  for (int i = 0; i < splitElemIds.size(); ++i) {
448 
449  // TODO: fix names, still not working correctly
450  if (sideSetNames.size() == 1 && splitElemIds.size() == 1) {
451  ss.name = sideSetNames[i];
452  }
453  if (sideSetNames.size() == 0) {
454  std::cout << "side set names size is zero" << std::endl;
455  ss.name = "side_set_000000" + std::to_string(i + 1);
456  }
457  if (sideSetNames.size() > 0 && sideSetNames.size() < 3 && splitTopBotSS) {
458  std::cerr << "Error: Expected 3 'Side Set Names', found "
459  << sideSetNames.size() << std::endl;
460  exit(1);
461  }
462  if (sideSetNames.size() == 3) {
463  ss.name = sideSetNames[i];
464  }
465 
466  // ss.id = ++iss;
467  ss.id = i + 1;
468  ss.nSde = (int)splitSideIds[i].size();
469  ss.elmIds = splitElemIds[i];
470  ss.sdeIds = splitSideIds[i];
471  ss.elmIdOffset = elmIdOffset;
472  em->addSdeSet(ss);
473  }
474 }
int getDimension() const
Returns problem dimension.
Definition: exoMesh.H:412
std::vector< int > sdeIds
Definition: exoMesh.H:102
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
std::vector< int > elmIds
Definition: exoMesh.H:101
Stores side set information.
Definition: exoMesh.H:97
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
void addSdeSet(const sdeSetType &ss)
Add side set to the database.
Definition: exoMesh.H:520

◆ genExo() [1/2]

void NEM::DRV::ConversionDriver::genExo ( std::vector< meshBase *>  meshes,
const std::string &  fname 
)
staticinherited

Definition at line 236 of file ConversionDriver.C.

Referenced by NEM::DRV::GmshToExoConversionDriver::execute(), and proteusHdf5::proteusHdf5().

237  {
238  bool usePhys = false;
239  bool makeFreeSurfSS = false;
240  bool splitTopBotSS = false;
241  std::vector<std::string> sideSetNames;
242 
243  std::cout << "Warning: this method does not support physical groups."
244  << std::endl;
245  std::cout << "Warning: this method does not support post-processing."
246  << std::endl;
247 
248  int nMsh = meshes.size();
249 
250  // sanity check
251  if (nMsh == 0) {
252  std::cerr << "Error: At least one mesh should be provided!\n";
253  exit(-1);
254  }
255 
256  // starting conversion operation
257  auto em = new NEM::MSH::EXOMesh::exoMesh(fname);
258 
259  // reading meshes
260  int ndeIdOffset = 0;
261  int elmIdOffset = 0;
262  int ins = 0;
263  int ieb = 0;
264  int iss = 0;
265  int ndeIdOffset_local = 0;
266  int elmIdOffset_local = 0;
267 
268  std::string mshName;
269 
270  for (auto itrMsh = meshes.begin(); itrMsh != meshes.end(); itrMsh++) {
271  mshName = (*itrMsh)->getFileName();
272  genExo(*itrMsh, em, ndeIdOffset, elmIdOffset, ins, ieb, iss, mshName,
273  usePhys, ndeIdOffset_local, elmIdOffset_local, makeFreeSurfSS,
274  splitTopBotSS, sideSetNames);
275  }
276 
277  // writing the file
278  em->write();
279  em->report();
280 
281  em->mergeNodes();
282 
283  // clean up
284  delete em;
285 }
A complete I/O class for EXODUS II file format.
Definition: exoMesh.H:172
static void genExo(std::vector< meshBase *> meshes, const std::string &fname)

◆ genExo() [2/2]

void NEM::DRV::ConversionDriver::genExo ( meshBase mb,
NEM::MSH::EXOMesh::exoMesh em,
const int &  ndeIdOffset,
const int &  elmIdOffset,
int &  ins,
int &  ieb,
int &  iss,
std::string  mshName,
const bool &  usePhys,
int &  ndeIdOffset_local,
int &  elmIdOffset_local,
const bool &  makeFreeSurfSS,
const bool &  splitTopBotSS,
std::vector< std::string >  sideSetNames 
)
staticprotectedinherited

Definition at line 54 of file ConversionDriver.C.

References NEM::MSH::EXOMesh::exoMesh::addElmBlk(), NEM::MSH::EXOMesh::exoMesh::addNde(), NEM::MSH::EXOMesh::exoMesh::addNdeSet(), NEM::MSH::EXOMesh::exoMesh::addSdeSet(), NEM::MSH::EXOMesh::elmBlkType::conn, NEM::MSH::EXOMesh::sdeSetType::elmIdOffset, NEM::MSH::EXOMesh::sdeSetType::elmIds, NEM::MSH::EXOMesh::elmBlkType::eTpe, NEM::DRV::ConversionDriver::freeSurfaceSideSet(), meshBase::getCellDataArray(), meshBase::getDataSet(), meshBase::getMetadata(), meshBase::getNumberOfCells(), meshBase::getNumberOfPoints(), meshBase::getPoint(), HEX, NEM::MSH::EXOMesh::ndeSetType::id, NEM::MSH::EXOMesh::elmBlkType::id, NEM::MSH::EXOMesh::sdeSetType::id, NEM::MSH::EXOMesh::ndeSetType::name, NEM::MSH::EXOMesh::elmBlkType::name, NEM::MSH::EXOMesh::sdeSetType::name, NEM::MSH::EXOMesh::ndeSetType::ndeIdOffset, NEM::MSH::EXOMesh::elmBlkType::ndeIdOffset, NEM::MSH::EXOMesh::ndeSetType::ndeIds, NEM::MSH::EXOMesh::elmBlkType::ndePerElm, NEM::MSH::EXOMesh::elmBlkType::nElm, NEM::MSH::New(), NEM::MSH::EXOMesh::ndeSetType::nNde, NEM::MSH::EXOMesh::sdeSetType::nSde, QUAD, NEM::MSH::EXOMesh::sdeSetType::sdeIds, NEM::MSH::EXOMesh::exoMesh::setDimension(), TETRA, TRIANGLE, NEM::MSH::EXOMesh::v2eEMap(), and WEDGE.

61  {
62  // add nodes to database
63  for (nemId_t iNde = 0; iNde < mb->getNumberOfPoints(); ++iNde)
64  em->addNde(mb->getPoint(iNde));
65 
66  // node coordinate to one nodeSet
68  ns.id = ++ins;
69  ns.nNde = mb->getNumberOfPoints();
70  ns.name = mshName;
71  ns.ndeIdOffset = ndeIdOffset;
72  for (int iNde = 0; iNde < ns.nNde; iNde++) {
73  ns.ndeIds.emplace_back(iNde + 1);
74  }
75  em->addNdeSet(ns);
76  ndeIdOffset_local += ns.nNde;
77 
78  // add element blocks
79 
80  // Element bucket where they will be sorted.
81  // Outer layer: Specifies grouping, such as physical groups. The 0th index
82  // is reserved for elements without a group.
83  // Inner layer: Sorted by element type. The 0th index is reserved for
84  // unsupported elements. The current support respects the ordering of the
85  // NEM::MSH::EXOMesh::elementType enum:
86  // OTHER, TRIANGLE, QUAD, TETRA, HEX
87  std::map<int, std::map<NEM::MSH::EXOMesh::elementType, std::vector<int>>>
88  elmBucket;
89  // map for VTK to EXO element ids
90  std::map<int, int> v2e_elemID_map;
91 
92  std::vector<double> grpIds(mb->getNumberOfCells(), 0.0);
93  if (usePhys) mb->getCellDataArray("PhysGrpId", grpIds);
94 
95  bool is3D = false;
96  // Loop through all elements
97  for (int iElm = 0; iElm < mb->getNumberOfCells(); iElm++) {
98  VTKCellType vtkType =
99  static_cast<VTKCellType>(mb->getDataSet()->GetCellType(iElm));
102 
103  // set the dimension of Exo database based on present elements
104  if (!is3D) {
105  if (exoType == NEM::MSH::EXOMesh::elementType::TETRA ||
108  is3D = true;
109  em->setDimension(3);
110  }
111  }
112 
113  elmBucket[static_cast<int>(grpIds[iElm])][exoType].emplace_back(iElm);
114  }
115 
116  // sanity check
117  int numUnsupported = 0;
118  for (const auto &elmGroup : elmBucket)
119  if (elmGroup.second.count(NEM::MSH::EXOMesh::elementType::OTHER) != 0)
120  numUnsupported +=
121  elmGroup.second.at(NEM::MSH::EXOMesh::elementType::OTHER).size();
122  if (numUnsupported > 0) {
123  std::cerr << "WARNING: Detected " << numUnsupported
124  << " unsupported elements.\n";
125  throw;
126  }
127 
128  // for each group and supported type, if existent, add an element block
129  for (const auto &elmGroup : elmBucket) {
130  for (const auto &elmIds : elmGroup.second) {
131  if (elmIds.second.empty()) continue; // skip if empty
132 
134  eb.id = ++ieb;
135  eb.ndeIdOffset = ndeIdOffset;
136  eb.nElm = elmIds.second.size();
137 
138  // populate VTK to EXO element id map for side set implementation
139  for (int i = 0; i < elmIds.second.size(); ++i) {
140  int vtkId = elmIds.second[i];
141  int exoId = i + elmIdOffset_local + 1;
142  v2e_elemID_map.insert(std::pair<int, int>(vtkId, exoId));
143  }
144 
145  if (usePhys)
146  eb.name = mshName + "_PhysGrp_" + std::to_string(ieb);
147  else
148  eb.name = mshName + "_" + std::to_string(ieb);
149 
150  switch (elmIds.first) {
152  std::cout << "Number of triangular elements = " << eb.nElm << "\n";
153  eb.ndePerElm = 3;
155  break;
157  std::cout << "Number of quadrilateral elements = " << eb.nElm << "\n";
158  eb.ndePerElm = 4;
160  break;
162  std::cout << "Number of tetrahedral elements = " << eb.nElm << "\n";
163  eb.ndePerElm = 4;
165  break;
167  std::cout << "Number of hexahedral elements = " << eb.nElm << "\n";
168  eb.ndePerElm = 8;
170  break;
172  std::cout << "Number of wedge elements = " << eb.nElm << "\n";
173  eb.ndePerElm = 6;
175  break;
176  case NEM::MSH::EXOMesh::elementType::OTHER:
177  default:
178  std::cerr << "WARNING: Processing unsupported element. Previous "
179  "sanity check failed!\n";
180  throw;
181  }
182 
183  eb.conn.reserve(eb.nElm * eb.ndePerElm);
184  vtkIdList *nids = vtkIdList::New();
185  for (const auto &iElm : elmIds.second) {
186  mb->getDataSet()->GetCellPoints(iElm, nids);
187  for (int in = 0; in < eb.ndePerElm; ++in) {
188  // offset node ids by 1
189  eb.conn.emplace_back(nids->GetId(in) + 1);
190  }
191  }
192 
193  // DEBUG
194  // std::cout << "Min node index = "
195  // << *min_element(eb.conn.begin(), eb.conn.end()) << "\n"
196  // << "Max node index = "
197  // << *max_element(eb.conn.begin(), eb.conn.end()) << "\n";
198  // std::cout << "Starting node offset = " << ndeIdOffset << std::endl;
199 
200  em->addElmBlk(eb);
201  elmIdOffset_local += eb.nElm;
202  }
203  }
204 
205  // add side set of the external surface(s) (free surface)
206  if (makeFreeSurfSS) {
207  freeSurfaceSideSet(mb, em, elmIdOffset, v2e_elemID_map, splitTopBotSS,
208  sideSetNames);
209  }
210 
211  // add side sets
212  if (mb->getMetadata()) {
213  // get side set metadata
214  vtkSmartPointer<vtkModelMetadata> metadata = mb->getMetadata();
215  vtkSmartPointer<vtkStringArray> sdeSetNames = metadata->GetSideSetNames();
216  int *sdeSetElmLst = metadata->GetSideSetElementList();
217  int *sdeSetSdeLst = metadata->GetSideSetSideList();
218  int *sdeSetSze = metadata->GetSideSetSize();
219 
220  for (int iSS = 0; iSS < metadata->GetNumberOfSideSets(); iSS++) {
222  ss.id = ++iss;
223  ss.name = sdeSetNames->GetValue(iSS);
224  ss.nSde = sdeSetSze[iSS];
225  ss.elmIds.assign(sdeSetElmLst, sdeSetElmLst + sdeSetSze[iSS]);
226  ss.sdeIds.assign(sdeSetSdeLst, sdeSetSdeLst + sdeSetSze[iSS]);
227  ss.elmIdOffset = elmIdOffset;
228  em->addSdeSet(ss);
229 
230  // Advance pointer for reading next side set.
231  sdeSetElmLst += sdeSetSze[iSS];
232  sdeSetSdeLst += sdeSetSze[iSS];
233  }
234  }
235 }
elementType v2eEMap(VTKCellType vt)
Convert VTK cell type to EXODUS element type.
Definition: exoMesh.C:61
std::vector< int > sdeIds
Definition: exoMesh.H:102
std::size_t nemId_t
Definition: meshBase.H:51
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
static void freeSurfaceSideSet(const meshBase *mb, NEM::MSH::EXOMesh::exoMesh *em, int elmIdOffset, std::map< int, int > v2e_elemID_map, bool splitTopBotSS, std::vector< std::string > sideSetNames)
Creates side set(s) for the free surface, exterior surface, during conversion.
void addNde(double x, double y, double z)
Add nodes to the database.
Definition: exoMesh.H:487
std::vector< int > elmIds
Definition: exoMesh.H:101
WEDGE
Definition: exoMesh.H:55
QUAD
Definition: exoMesh.H:55
HEX
Definition: exoMesh.H:55
vtkSmartPointer< vtkModelMetadata > getMetadata()
Definition: meshBase.H:443
Stores side set information.
Definition: exoMesh.H:97
TETRA
Definition: exoMesh.H:55
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
nemId_t getNumberOfPoints() const
return the number of points
Definition: meshBase.H:545
Stores element block information.
Definition: exoMesh.H:82
void addSdeSet(const sdeSetType &ss)
Add side set to the database.
Definition: exoMesh.H:520
void addElmBlk(const elmBlkType &eb)
Add element block to the database.
Definition: exoMesh.H:504
void addNdeSet(const ndeSetType &ns)
Add node set to the database.
Definition: exoMesh.H:512
elementType
Definition: pntMesh.H:47
void setDimension(int dim)
Sets/changes the problem dimensionality.
Definition: exoMesh.H:477
TRIANGLE
Definition: exoMesh.H:55
Stores node set information.
Definition: exoMesh.H:71
std::vector< int > ndeIds
Definition: exoMesh.H:75
virtual void getCellDataArray(const std::string &name, std::vector< double > &data)
<>
Definition: meshBase.H:369
nemId_t getNumberOfCells() const
return the number of cells
Definition: meshBase.H:550
virtual std::vector< double > getPoint(nemId_t id) const =0
get point with id
std::vector< int > conn
Definition: exoMesh.H:88

◆ getFiles()

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

Definition at line 43 of file VtkToPntConversionDriver.C.

References files_.

44  {
45  return files_;
46 }

◆ getOpts()

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

Definition at line 52 of file VtkToPntConversionDriver.C.

References opts_.

53  {
54  return opts_;
55 }

◆ procExo()

void NEM::DRV::ConversionDriver::procExo ( const jsoncons::json &  ppJson,
const std::string &  fname,
NEM::MSH::EXOMesh::exoMesh em 
)
staticprotectedinherited

Definition at line 476 of file ConversionDriver.C.

References NEM::MSH::EXOMesh::exoMesh::addElmBlkByElmIdLst(), NEM::MSH::EXOMesh::exoMesh::addNdeSetByNdeIdLst(), meshSrch::chkDuplElm(), meshSrch::Create(), meshBase::Create(), meshSrch::FindCellsInSphere(), meshSrch::FindCellsInTriSrf(), meshSrch::FindCellsWithinBounds(), meshSrch::FindPntsOnEdge(), meshSrch::FindPntsOnTriSrf(), NEM::MSH::EXOMesh::exoMesh::getElmBlkNames(), NEM::MSH::EXOMesh::exoMesh::lstElmInBlk(), NEM::MSH::EXOMesh::exoMesh::mergeNodes(), NEM::MSH::EXOMesh::exoMesh::removeElmBlkByName(), NEM::MSH::EXOMesh::exoMesh::scaleNodes(), and NEM::MSH::EXOMesh::exoMesh::snapNdeCrdsZero().

Referenced by NEM::DRV::GmshToExoConversionDriver::execute().

478  {
479  // converting to mesh base for geometric inquiry
480  meshBase *mb = meshBase::Create(fname);
481 
482  // performing requested operation
483  std::string opr = ppJson.get_with_default("Operation", "");
484  if (opr == "Material Assignment") {
485  meshSrch *ms = meshSrch::Create(mb);
486  // gathering information about all zones
487  // if densities are defined, materials with higher density will be
488  // prioritized
489  bool appDen = ppJson.get_with_default("Apply Density", false);
490 
491  std::map<std::pair<double, std::string>, std::set<int>> zoneGeom;
492 
493  // loop over all zones
494  for (const auto &zone : ppJson["Zones"].array_range()) {
495  // assuming first element is zone information keyed by zone name
496  // that we do not care about yet
497  std::string matName = zone[0].get_with_default("Material Name", "N/A");
498  std::string shape = zone[0].get_with_default("Shape", "N/A");
499  std::cout << "Processing zone: " << zone.object_range().begin()->key()
500  << " Material: " << matName << " Shape: " << shape;
501 
502  double density = 1.0; // Default density is 1.0
503  if (appDen) {
504  density = zone[0].get_with_default("Density", 1.0);
505  std::cout << " Density: " << density;
506  }
507  std::cout << std::endl;
508 
509  std::vector<nemId_t> lst;
510  if (shape == "Box") {
511  // Box shape. Requires 3-vector of Min and Max in x, y, and z, resp.
512  std::vector<double> bb;
513  bb.push_back(zone[0]["Params"]["Min"][0].as<double>());
514  bb.push_back(zone[0]["Params"]["Max"][0].as<double>());
515  bb.push_back(zone[0]["Params"]["Min"][1].as<double>());
516  bb.push_back(zone[0]["Params"]["Max"][1].as<double>());
517  bb.push_back(zone[0]["Params"]["Min"][2].as<double>());
518  bb.push_back(zone[0]["Params"]["Max"][2].as<double>());
519 
520  ms->FindCellsWithinBounds(bb, lst, true);
521  } else if (shape == "STL") {
522  // STL shape. Only supports Tri surface.
523  // Node Coordinates are given as 3-vector in an array.
524  // Connectivities are given as 3-vectors in an array.
525  // Tris are 0-indexed.
526  std::vector<std::vector<double>> crds;
527  std::vector<std::vector<vtkIdType>> conns;
528  for (const auto &crd :
529  zone[0]["Params"]["Node Coordinates"].array_range())
530  crds.push_back(crd.as<std::vector<double>>());
531  for (const auto &conn :
532  zone[0]["Params"]["Connectivities"].array_range())
533  conns.push_back(conn.as<std::vector<vtkIdType>>());
534 
535  ms->FindCellsInTriSrf(crds, conns, lst);
536  } else if (shape == "Sphere") {
537  // Sphere shape.
538  // Center is a 3-vector in an array.
539  // Radius is a double.
540  std::vector<double> center =
541  zone[0]["Params"]["Center"].as<std::vector<double>>();
542  auto radius = zone[0]["Params"]["Radius"].as<double>();
543 
544  ms->FindCellsInSphere(center, radius, lst);
545  } else {
546  std::cerr << "WARNING: Skipping unknown zone shape: " << shape
547  << std::endl;
548  continue;
549  }
550 
551  if (zone[0].contains("Only From Block")) {
552  std::string blkName = zone[0]["Only From Block"].as<std::string>();
553 
554  std::vector<std::string> elmBlkNames = em->getElmBlkNames();
555  auto elmBlkName =
556  std::find(elmBlkNames.begin(), elmBlkNames.end(), blkName);
557  if (elmBlkName == elmBlkNames.end()) {
558  std::cerr << "WARNING: Only From Block " << blkName
559  << " matches no available blocks. Continuing with no "
560  "restriction.\n";
561  } else {
562  std::vector<int> lst_int(lst.begin(), lst.end());
563  bool allIn = false;
564  lst_int = em->lstElmInBlk(
565  std::distance(elmBlkNames.begin(), elmBlkName), lst_int, allIn);
566  lst.assign(lst_int.begin(), lst_int.end());
567  }
568  }
569  zoneGeom[{1.0 / density, matName}].insert(lst.begin(), lst.end());
570  }
571 
572  if (appDen)
573  std::cout << "Applying material zones based on density ordering"
574  << std::endl;
575 
576  // adjusting exodus database accordingly
577  for (const auto &zone : zoneGeom) {
578  // zone is ((density, material name), ids)
579  std::vector<int> elmLst;
580  std::cout << "Manipulating ExodusDB for " << zone.first.second
581  << std::endl;
582  elmLst.insert(elmLst.end(), zone.second.begin(), zone.second.end());
583  em->addElmBlkByElmIdLst(zone.first.second, elmLst);
584  }
585  } else if (opr == "Check Duplicate Elements") {
586  std::cout << "Checking for existence of duplicate elements ... ";
587  meshSrch *ms = meshSrch::Create(mb);
588  bool ret = ms->chkDuplElm();
589  if (ret) {
590  std::cerr << " The exodus database contains duplicate elements."
591  << std::endl;
592  exit(-1);
593  } else {
594  std::cout << "False" << std::endl;
595  }
596  } else if (opr == "Remove Block") {
597  std::string blkName = ppJson.get_with_default("Block Name", "");
598  std::cout << "Removing Block " << blkName << std::endl;
599  em->removeElmBlkByName(blkName);
600  } else if (opr == "Snap Node Coords To Zero") {
601  double tol = ppJson.get_with_default("Tolerance", 0.0);
602  std::cout << "Snapping nodal coordinates to zero using tolerance: " << tol
603  << std::endl;
604  em->snapNdeCrdsZero(tol);
605  } else if (opr == "Boundary Condition Assignment") {
606  // For EP16 boundary conditions are simply translated to node sets. Node
607  // sets may have shared nodes. In that case a node the order of nodeset
608  // matter. A later node set supersedes an earlier one.
609  meshSrch *ms = meshSrch::Create(mb);
610 
611  // gathering information about all boundary node sets
612  jsoncons::json bcs = ppJson["Condition"];
613  for (const auto &bc : bcs.array_range()) {
614  std::set<nemId_t> pntIds;
615 
616  // identify node ids on each boundary
617  std::string bcName = bc["Name"].as<std::string>();
618  std::string bcTyp = bc["Boundary Type"].as<std::string>();
619  if (bcTyp == "Faces") {
620  std::vector<double> srfCrd;
621  std::vector<nemId_t> srfConn;
622  jsoncons::json nc = bc["Params"]["Node Coordinates"];
623  for (const auto &crds : nc.array_range())
624  for (const auto &cmp : crds.array_range())
625  srfCrd.push_back(cmp.as<double>());
626  jsoncons::json conn = bc["Params"]["Connectivities"];
627  for (const auto &tri : conn.array_range())
628  for (const auto &idx : tri.array_range())
629  srfConn.push_back(idx.as<nemId_t>());
630  ms->FindPntsOnTriSrf(srfCrd, srfConn, pntIds);
631  std::cout << "Number of points residing on the boundary " << bcName
632  << " is " << pntIds.size() << std::endl;
633  } else if (bcTyp == "Edges") {
634  std::vector<double> edgeCrd;
635  jsoncons::json ncs = bc["Params"]["Start"];
636  for (const auto &crds : ncs.array_range())
637  for (const auto &cmp : crds.array_range())
638  edgeCrd.push_back(cmp.as<double>());
639  jsoncons::json nce = bc["Params"]["End"];
640  for (const auto &crds : nce.array_range())
641  for (const auto &cmp : crds.array_range())
642  edgeCrd.push_back(cmp.as<double>());
643  ms->FindPntsOnEdge(edgeCrd, pntIds);
644  std::cout << "Number of points residing on the boundary " << bcName
645  << " is " << pntIds.size() << std::endl;
646  } else {
647  std::cerr << "Warning: unsupported boundary type " << bcTyp
648  << std::endl;
649  }
650 
651  // register node set in Exodus II database
652  if (!pntIds.empty()) {
653  std::vector<int> nv;
654  std::copy(pntIds.begin(), pntIds.end(), std::back_inserter(nv));
655  em->addNdeSetByNdeIdLst(bcName, nv);
656  }
657  }
658  } else if (opr == "Merge Nodes") {
659  em->mergeNodes();
660  } else if (opr == "Mesh Scaling") {
661  em->scaleNodes(ppJson["Scale"].as<double>());
662  } else {
663  std::cerr << "Unknown operation requested: " << opr << std::endl;
664  }
665 }
void addElmBlkByElmIdLst(const std::string &name, std::vector< int > &idLst)
Creates a new element block and augments previous owners.
Definition: exoMesh.C:807
const std::vector< std::string > & getElmBlkNames() const
Returns the names of registered element blocks.
Definition: exoMesh.H:391
A brief description of meshBase.
Definition: meshBase.H:64
std::size_t nemId_t
Definition: meshBase.H:51
bool chkDuplElm() const
Definition: meshSrch.C:212
static meshBase * Create(const std::string &fname)
Construct vtkMesh from filename.
Definition: meshBase.C:78
void snapNdeCrdsZero(double tol=1e-5)
Filter nodal coordinates and snap to zero.
Definition: exoMesh.C:876
void FindCellsInTriSrf(const std::vector< std::vector< double >> &crds, const std::vector< std::vector< vtkIdType >> &conns, std::vector< nemId_t > &ids, bool query3Donly=true, double tol=0.1e-15) const
Definition: meshSrch.C:256
void FindPntsOnTriSrf(const std::vector< double > &crds, const std::vector< nemId_t > &conn, std::set< nemId_t > &ids, double tol=0.1e-15) const
Definition: meshSrch.C:119
void addNdeSetByNdeIdLst(const std::string &name, const std::vector< int > &idLst)
Creates a new node set and augments previous ones if needed.
Definition: exoMesh.C:857
std::vector< int > lstElmInBlk(int blkIdx, const std::vector< int > &elmIds, bool &allIn) const
Finds all elements that are within the block and generates a list of them.
Definition: exoMesh.C:967
void FindCellsWithinBounds(std::vector< double > &bb, std::vector< nemId_t > &ids, bool fulImrsd=true)
Definition: meshSrch.C:93
static meshSrch * Create(meshBase *mb)
Definition: meshSrch.H:45
void FindCellsInSphere(const std::vector< double > &center, double radius, std::vector< nemId_t > &ids, bool query3Donly=true, double tol=0.1e-15) const
Definition: meshSrch.C:280
void scaleNodes(double sc=1.0)
scales the nodal coordinates
Definition: exoMesh.C:1357
void FindPntsOnEdge(std::vector< double > &crds, std::set< nemId_t > &ids, double tol=0.1e-15) const
Definition: meshSrch.C:167
void mergeNodes(double tol=1e-15)
Merges duplicated and nodes within given proximity.
Definition: exoMesh.C:1232
void removeElmBlkByName(const std::string &blkName)
Remove an element block by name.
Definition: exoMesh.C:901

◆ 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::VtkToPntConversionDriver::setFiles ( Files  files)

Definition at line 48 of file VtkToPntConversionDriver.C.

References files_.

48  {
49  this->files_ = std::move(files);
50 }

◆ setOpts()

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

Definition at line 57 of file VtkToPntConversionDriver.C.

References opts_.

57  {
58  this->opts_ = std::move(opts);
59 }

Member Data Documentation

◆ files_

Files NEM::DRV::VtkToPntConversionDriver::files_
private

Definition at line 68 of file VtkToPntConversionDriver.H.

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

◆ opts_

Opts NEM::DRV::VtkToPntConversionDriver::opts_
private

Definition at line 69 of file VtkToPntConversionDriver.H.

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


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