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.
vtkGeoMesh.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/vtkGeoMesh.H"
34 
35 #include <iostream>
36 #include <set>
37 #include <utility>
38 
39 #include <vtkGenericDataObjectReader.h>
40 #include <vtkGenericDataObjectWriter.h>
41 #include <vtkSTLReader.h>
42 #include <vtkXMLDataSetWriter.h>
43 #include <vtkXMLGenericDataObjectReader.h>
44 
45 #include "AuxiliaryFunctions.H"
46 
47 #ifdef HAVE_GMSH
48 #include <gmsh.h>
49 #endif
50 
51 namespace NEM {
52 namespace MSH {
53 
55 
56 vtkGeoMesh *vtkGeoMesh::Read(const std::string &fileName,
57  const std::string &geoArrayName) {
58  vtkSmartPointer<vtkUnstructuredGrid> inUnstructuredGrid;
59 
60  std::string fileExt = nemAux::find_ext(fileName);
61  if (fileExt == ".vtk") { // Legacy type
62  vtkSmartPointer<vtkGenericDataObjectReader> reader =
64  reader->SetFileName(fileName.c_str());
65  reader->Update();
66 
67  inUnstructuredGrid = vtkUnstructuredGrid::SafeDownCast(reader->GetOutput());
68  } else if (fileExt.substr(0, 3) == ".vt") { // XML type
69  vtkSmartPointer<vtkXMLGenericDataObjectReader> reader =
71  reader->SetFileName(fileName.c_str());
72  reader->Update();
73 
74  inUnstructuredGrid = vtkUnstructuredGrid::SafeDownCast(reader->GetOutput());
75  /*
76  } else if (fileExt == ".stl") { // Allow STLs
77  vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
78  reader->SetFileName(fileName.c_str());
79  reader->Update();
80 
81  // TODO: This cast fails. STL reader outputs vtkPolyData!
82  inUnstructuredGrid = vtkUnstructuredGrid::SafeDownCast(reader->GetOutput());
83  */
84  } else { // Not a VTK type
85  std::cerr << "ERROR: File extension " << fileExt
86  << " is not supported by vtkGeoMesh." << std::endl;
87  exit(1);
88  }
89 
90  if (!inUnstructuredGrid) { // Not a mesh
91  std::cerr << "ERROR: Only VTK Unstructured Grid (vtu) is supported."
92  << std::endl;
93  exit(1);
94  }
95 
96  return new vtkGeoMesh(inUnstructuredGrid, geoArrayName);
97 }
98 
100  : vtkGeoMesh(vtkSmartPointer<vtkUnstructuredGrid>::New()) {}
101 
102 vtkGeoMesh::vtkGeoMesh(vtkUnstructuredGrid *inUnstructuredGrid,
103  const std::string &geoArrayName)
104  : geoMeshBase(vtk2GM(inUnstructuredGrid, geoArrayName)) {
105  std::cout << "vtkGeoMesh constructed" << std::endl;
106 }
107 
108 // vtkGeoMesh::vtkGeoMesh(geoMeshBase *inGmb) : geoMeshBase(inGmb),
109 // _vtkMesh() {
110 //}
111 
112 vtkGeoMesh::~vtkGeoMesh() { std::cout << "vtkGeoMesh destructed" << std::endl; }
113 
114 void vtkGeoMesh::write(const std::string &fileName) {
115  auto mesh = getGeoMesh().mesh;
116 
117  std::string fileExt = nemAux::find_ext(fileName);
118  if (fileExt == ".vtk") { // Legacy type
119  vtkSmartPointer<vtkGenericDataObjectWriter> writer =
121  writer->SetFileName(fileName.c_str());
122  writer->SetInputData(mesh);
123  writer->Write();
124  } else { // XML type
125  vtkSmartPointer<vtkXMLDataSetWriter> writer =
127  writer->SetFileName(fileName.c_str());
128  writer->SetInputData(mesh);
129  writer->Write();
130  }
131 }
132 
133 void vtkGeoMesh::report(std::ostream &out) const { geoMeshBase::report(out); }
134 
135 void vtkGeoMesh::getVtkMesh(vtkUnstructuredGrid *dest) {
136  dest->DeepCopy(getGeoMesh().mesh);
137 }
138 
139 void vtkGeoMesh::setVtkMesh(vtkUnstructuredGrid *vtkMesh) {
140  setGeoMesh(vtk2GM(vtkMesh));
141 }
142 
144  const std::string &phyGrpArrayName) {
145  std::string gmshMesh = "vtkGeoMesh_" + nemAux::getRandomString(6);
146 #ifdef HAVE_GMSH
148  gmsh::model::add(gmshMesh);
149  gmsh::model::setCurrent(gmshMesh);
150 #endif
151 
152  if (!vtkMesh || // No mesh
153  vtkMesh->GetNumberOfPoints() == 0 || // No points
154  !vtkMesh->GetCellData()->HasArray(phyGrpArrayName.c_str()) // No geometry
155  )
156  return {vtkMesh, "", "", {}};
157 
158  { // Add geometric entities and physical groups
159  std::set<std::pair<int, int>> dim_phyGrp;
160  auto phyGrpArray = vtkArrayDownCast<vtkDataArray>(
161  vtkMesh->GetCellData()->GetArray(phyGrpArrayName.c_str()));
162  vtkSmartPointer<vtkGenericCell> vtkGC =
164 
165  // First sort
166  for (vtkIdType i = 0; i < vtkMesh->GetNumberOfCells(); ++i) {
167  vtkGC->SetCellType(vtkMesh->GetCellType(i));
168  int dim = vtkGC->GetCellDimension();
169  int phyGrp = static_cast<int>(phyGrpArray->GetComponent(i, 0));
170 
171  dim_phyGrp.insert({dim, phyGrp});
172  }
173 
174 #ifdef HAVE_GMSH
175  // then add. Each phyGrp gets its own geoEnt
176  for (const auto &dp : dim_phyGrp) {
177  gmsh::model::addDiscreteEntity(dp.first, dp.second);
178  gmsh::model::addPhysicalGroup(dp.first, {dp.second}, dp.second);
179  }
180 #endif
181  }
182 
183  /*
184  { // DEBUG
185  gmsh::vectorpair dimTags;
186  gmsh::model::getEntities(dimTags);
187  for (const auto &dimTag : dimTags) {
188  std::cout << "geoEnt dim: " << dimTag.first
189  << " tag: " << dimTag.second << std::endl;
190  }
191 
192  gmsh::model::getPhysicalGroups(dimTags);
193  for (const auto &dimTag : dimTags) {
194  std::cout << "phyGrp dim: " << dimTag.first
195  << " tag: " << dimTag.second << std::endl;
196  }
197  }
198  */
199 
200  return {vtkMesh, gmshMesh, phyGrpArrayName, {}};
201 }
202 
204 
205 } // namespace MSH
206 } // namespace NEM
virtual void report(std::ostream &out) const =0
Print a report about the mesh.
Definition: geoMeshBase.C:97
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.
void setGeoMesh(const geoMeshBase::GeoMesh &geoMesh)
Set the underlying geometry object.
Definition: geoMeshBase.H:538
static void Initialize()
Initialize Gmsh.
Definition: geoMeshBase.C:67
std::string find_ext(const std::string &fname)
A concrete implementation of geoMeshBase representing a mesh in a vtkUnstructuredGrid.
Definition: vtkGeoMesh.H:42
void getVtkMesh(vtkUnstructuredGrid *dest)
Copy the mesh.
Definition: vtkGeoMesh.C:135
vtkGeoMesh()
Create a vtkGeoMesh from a vtkUnstructuredGrid file.
Definition: vtkGeoMesh.C:99
std::string getRandomString(int length)
~vtkGeoMesh() override
Definition: vtkGeoMesh.C:112
std::shared_ptr< meshBase > mesh
vtkStandardNewMacro(exoGeoMesh)
Definition: exoGeoMesh.C:247
void resetNative() override
Definition: vtkGeoMesh.C:203
static vtkGeoMesh * New()
static GeoMesh vtk2GM(vtkUnstructuredGrid *vtkMesh, const std::string &phyGrpArrayName=std::string())
Create a GeoMesh from a vtkUnstructuredGrid.
Definition: vtkGeoMesh.C:143
void report(std::ostream &out) const override
Print a report about the mesh.
Definition: vtkGeoMesh.C:133
void write(const std::string &fileName) override
Write mesh to file.
Definition: vtkGeoMesh.C:114
abstract class to specify geometry and mesh data
Definition: geoMeshBase.H:102
const GeoMesh & getGeoMesh() const
Get the underlying geometry object.
Definition: geoMeshBase.H:533
void setVtkMesh(vtkUnstructuredGrid *vtkMesh)
Set the vtkGeoMesh&#39;s mesh to vtkMesh.
Definition: vtkGeoMesh.C:139