29 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) 30 # define _USE_MATH_DEFINES 41 #include <vtkCellIterator.h> 42 #include <vtkCellType.h> 43 #include <vtkIntArray.h> 49 void addGmshEntitiesToDataSet(
50 const gmsh::vectorpair &entityTags,
51 const std::map<std::size_t, vtkIdType> &gmshNodeNum2vtkId,
52 vtkSmartPointer<T> dataSet, vtkIntArray *vtkEntities =
nullptr) {
54 for (
const auto &dimTag : entityTags) {
56 std::vector<int> elementTypes;
57 std::vector<std::vector<std::size_t>> elementTags;
58 std::vector<std::vector<std::size_t>> nodeTags;
59 gmsh::model::mesh::getElements(elementTypes, elementTags, nodeTags,
60 dimTag.first, dimTag.second);
63 for (std::size_t iety = 0; iety < elementTypes.size(); ++iety) {
65 std::string elementName;
66 int dim, order, numNodes, numPrimaryNodes;
67 std::vector<double> nodeCoord;
68 gmsh::model::mesh::getElementProperties(elementTypes[iety], elementName,
69 dim, order, numNodes, nodeCoord,
75 for (std::size_t ietg = 0; ietg < elementTags[iety].size(); ++ietg) {
77 vtkNew<vtkIdList> ptIds{};
78 ptIds->Allocate(numNodes);
79 for (
int nn = 0; nn < numNodes; ++nn) {
81 gmshNodeNum2vtkId.at(nodeTags[iety][ietg * numNodes + nn]));
85 dataSet->InsertNextCell(ct, ptIds);
88 if (vtkEntities) vtkEntities->InsertNextValue(dimTag.second);
103 gmsh::open(fileName);
106 gmsh::model::getCurrent(gmshMesh);
115 std::cout <<
"gmshGeoMesh constructed" << std::endl;
120 std::cout <<
"gmshGeoMesh destructed" << std::endl;
125 gmsh::write(fileName);
126 gmsh::model::mesh::clear();
134 if (name ==
"Point") {
140 if (name ==
"Point") {
142 }
else if (name ==
"Line") {
144 case 3:
return VTK_QUADRATIC_EDGE;
145 default:
return VTK_LINE;
147 }
else if (name ==
"Triangle") {
149 case 6:
return VTK_QUADRATIC_TRIANGLE;
150 default:
return VTK_TRIANGLE;
152 }
else if (name ==
"Quadrilateral") {
154 case 8:
return VTK_QUADRATIC_QUAD;
155 case 9:
return VTK_BIQUADRATIC_QUAD;
156 default:
return VTK_QUAD;
158 }
else if (name ==
"Polygon") {
160 }
else if (name ==
"Tetrahedron") {
162 case 10:
return VTK_QUADRATIC_TETRA;
163 default:
return VTK_TETRA;
165 }
else if (name ==
"Hexahedron") {
167 case 20:
return VTK_QUADRATIC_HEXAHEDRON;
168 case 27:
return VTK_TRIQUADRATIC_HEXAHEDRON;
169 default:
return VTK_HEXAHEDRON;
171 }
else if (name ==
"Prism") {
173 }
else if (name ==
"Pyramid") {
175 }
else if (name ==
"Trihedron" ||
176 name ==
"Polyhedron")
178 std::cerr <<
"ERROR in Gmsh to VTK element conversion: Gmsh element \"" 179 << name <<
"\" is not supported by VTK." << std::endl;
181 std::cerr <<
"ERROR in Gmsh to VTK element conversion: Gmsh element \"" 182 << name <<
"\" is not recognized." << std::endl;
190 if (gmshMesh.empty())
return {
vtkMesh, gmshMesh,
"", {}};
194 gmsh::model::setCurrent(gmshMesh);
197 std::map<std::size_t, vtkIdType> gmshNodeNum2vtkId;
200 vtkSmartPointer<vtkPoints>
points =
204 std::vector<std::size_t> nodeTags;
205 std::vector<double> coord;
206 std::vector<double> parametricCoord;
207 gmsh::model::mesh::getNodes(nodeTags, coord, parametricCoord);
210 points->Allocate(nodeTags.size());
213 for (std::size_t i = 0; i < nodeTags.size(); ++i) {
214 gmshNodeNum2vtkId[nodeTags[i]] = points->GetNumberOfPoints();
215 points->InsertNextPoint(coord[i * 3 + 0], coord[i * 3 + 1],
226 gmsh::vectorpair dimTags;
227 gmsh::model::getEntities(dimTags, gmsh::model::getDimension());
230 vtkSmartPointer<vtkIntArray> vtkEntities =
232 vtkEntities->Initialize();
233 vtkEntities->SetName(geoEntArrayName.c_str());
235 addGmshEntitiesToDataSet(dimTags, gmshNodeNum2vtkId,
vtkMesh, vtkEntities);
238 vtkMesh->GetCellData()->AddArray(vtkEntities);
246 gmsh::vectorpair dimTags;
247 gmsh::model::getEntities(dimTags, gmsh::model::getDimension() - 1);
248 if (!dimTags.empty()) {
250 sideSetPD->SetPoints(
vtkMesh->GetPoints());
251 sideSetPD->Allocate();
252 vtkNew<vtkIntArray> vtkEntities{};
254 addGmshEntitiesToDataSet(dimTags, gmshNodeNum2vtkId, sideSetPD,
256 if (sideSetPD->GetNumberOfCells() > 0) {
257 sideSetPD->Squeeze();
258 sideSet =
SideSet(sideSetPD, vtkEntities);
266 gmsh::model::mesh::clear();
268 return {
vtkMesh, gmshMesh, geoEntArrayName, sideSet};
272 gmsh::model::setCurrent(geoMesh.
geo);
274 if (geoMesh.
mesh->GetNumberOfPoints() > 0) {
275 std::vector<std::size_t> nodeTags;
276 std::vector<double> coord;
278 vtkSmartPointer<vtkPoints> dataSetPoints = geoMesh.
mesh->GetPoints();
279 coord.resize(3 * dataSetPoints->GetNumberOfPoints());
280 nodeTags.resize(dataSetPoints->GetNumberOfPoints());
281 for (vtkIdType ptId = 0; ptId < dataSetPoints->GetNumberOfPoints();
283 nodeTags[ptId] = ptId + 1;
284 dataSetPoints->GetPoint(ptId, &coord[3 * ptId]);
287 gmsh::vectorpair dimTags;
288 gmsh::model::getEntities(dimTags);
289 gmsh::model::mesh::addNodes(dimTags[0].first, dimTags[0].second, nodeTags,
293 if (geoMesh.
mesh->GetNumberOfCells() > 0) {
296 vtkSmartPointer<vtkCellIterator>::Take(geoMesh.
mesh->NewCellIterator());
297 vtkSmartPointer<vtkIntArray> geoEntArray = vtkIntArray::FastDownCast(
298 geoMesh.
mesh->GetCellData()->GetArray(geoMesh.
link.c_str()));
299 for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextCell()) {
300 int geoEnt = geoEntArray->GetTypedComponent(it->GetCellId(), 0);
302 vtkSmartPointer<vtkIdList> ptIds = it->GetPointIds();
303 std::vector<std::size_t> nodeTag;
304 for (vtkIdType pt = 0; pt < it->GetNumberOfPoints(); ++pt) {
305 nodeTag.emplace_back(ptIds->GetId(pt) + 1);
308 gmsh::model::mesh::addElementsByType(
309 geoEnt, getGmshTypeFromVTKType(it->GetCellType()),
310 {
static_cast<std::size_t
>(it->GetCellId() + 1)}, nodeTag);
315 auto it = vtkSmartPointer<vtkCellIterator>::Take(
318 for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextCell()) {
319 int geoEnt = geoEntArray->GetTypedComponent(it->GetCellId(), 0);
321 vtkSmartPointer<vtkIdList> ptIds = it->GetPointIds();
322 std::vector<std::size_t> nodeTag;
323 for (vtkIdType pt = 0; pt < it->GetNumberOfPoints(); ++pt) {
324 nodeTag.emplace_back(ptIds->GetId(pt) + 1);
327 gmsh::model::mesh::addElementsByType(
328 geoEnt, getGmshTypeFromVTKType(it->GetCellType()),
329 {
static_cast<std::size_t
>(it->GetCellId() + 1)}, nodeTag);
333 gmsh::model::mesh::reclassifyNodes();
340 if (gm.geo.empty()) {
342 gmsh::model::add(gm.geo);
344 if (gm.link.empty()) {
347 linkArr->SetName(gm.link.c_str());
348 linkArr->SetNumberOfTuples(
getGeoMesh().
mesh->GetNumberOfCells());
349 linkArr->FillComponent(0, 1);
virtual void report(std::ostream &out) const =0
Print a report about the mesh.
vtkSmartPointer< vtkUnstructuredGrid > mesh
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
void report(std::ostream &out) const override
Print a report about the mesh.
static vtkTypeMacro(gmshGeoMesh, geoMeshBase) public VTKCellType getVTKTypeFromGmshType(const std::string &gmshType)
Create a gmshGeoMesh from a file.
static constexpr auto GEO_ENT_DEFAULT_NAME
gmshGeoMesh()
Construct a gmshGeoMesh with an empty mesh.
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
static void Finalize()
Finalize Gmsh.
static GeoMesh gmsh2GM(const std::string &gmshMesh)
Convert gmshMesh (name of a gmsh model) to GeoMesh.
void setGeoMesh(const geoMeshBase::GeoMesh &geoMesh)
Set the underlying geometry object.
static void Initialize()
Initialize Gmsh.
std::string findToStr(const std::string &str, const std::string &ptrn)
std::string findFromStr(const std::string &str, const std::string &ptrn)
A concrete implementation of geoMeshBase representing a Gmsh mesh.
std::string getRandomString(int length)
vtkSmartPointer< vtkPolyData > sides
Cells represent edges/faces of some GeoMesh.
std::shared_ptr< meshBase > mesh
void resetNative() override
std::vector< vtkIdType > points
points given by id in .inp file
vtkSmartPointer< vtkIntArray > getGeoEntArr() const
vtkStandardNewMacro(exoGeoMesh)
static std::string GM2gmsh(const GeoMesh &geoMesh)
Add the mesh from geoMesh to the gmsh model in geoMesh.
abstract class to specify geometry and mesh data
void write(const std::string &fileName) override
Write mesh to file.
const GeoMesh & getGeoMesh() const
Get the underlying geometry object.