29 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) 30 # define _USE_MATH_DEFINES 43 #include <vtkAppendFilter.h> 51 gmsh::option::setNumber(
"General.Terminal", 1.0);
52 gmsh::option::setNumber(
"Mesh.SaveAll", 1);
53 std::cout <<
"Gmsh initialized" << std::endl;
60 std::cout <<
"Gmsh finalized" << std::endl;
82 InitializeObjectBase();
86 std::cout <<
"geoMeshBase constructed" << std::endl;
90 this->ReferenceCount--;
94 std::cout <<
"geoMeshBase destructed" << std::endl;
98 out << this->GetClassName() <<
":\n";
100 out <<
"Nodes:\t" <<
mesh->GetNumberOfPoints() <<
'\n';
101 out <<
"Elements:\t" <<
mesh->GetNumberOfCells() <<
'\n';
114 vtkSmartPointer<vtkAppendFilter> appendFilter =
117 appendFilter->AddInputData(otherGeoMesh->
_geoMesh.
mesh);
118 appendFilter->MergePointsOn();
119 appendFilter->Update();
129 vtkSmartPointer<vtkAbstractArray> copyOrCreateCopy(
130 vtkAbstractArray *orig, vtkAbstractArray *copy =
nullptr) {
132 copy->DeepCopy(orig);
135 auto newCopy = vtkSmartPointer<vtkAbstractArray>::Take(orig->NewInstance());
136 newCopy->DeepCopy(orig);
143 vtkSmartPointer<vtkAbstractArray> getArrCopy(
144 vtkFieldData *field,
const std::string &arrayName,
int *arrayIdx,
145 vtkAbstractArray *array =
nullptr) {
146 auto orig = arrayIdx ? field->GetAbstractArray(arrayName.c_str(), *arrayIdx)
147 : field->GetAbstractArray(arrayName.c_str());
148 return copyOrCreateCopy(orig, array);
151 vtkSmartPointer<vtkAbstractArray> getArrCopy(
152 vtkFieldData *field,
int arrayIdx, vtkAbstractArray *array =
nullptr) {
153 auto orig = field->GetAbstractArray(arrayIdx);
154 return copyOrCreateCopy(orig, array);
160 vtkAbstractArray *array,
161 int *arrayIdx)
const {
162 getArrCopy(
_geoMesh.
mesh->GetPointData(), arrayName, arrayIdx, array);
166 const std::string &arrayName,
int *arrayIdx)
const {
167 return getArrCopy(
_geoMesh.
mesh->GetPointData(), arrayName, arrayIdx);
171 vtkAbstractArray *array)
const {
172 getArrCopy(
_geoMesh.
mesh->GetPointData(), arrayIdx, array);
176 int arrayIdx)
const {
177 return getArrCopy(
_geoMesh.
mesh->GetPointData(), arrayIdx);
181 vtkAbstractArray *array,
182 int *arrayIdx)
const {
183 getArrCopy(
_geoMesh.
mesh->GetCellData(), arrayName, arrayIdx, array);
187 const std::string &arrayName,
int *arrayIdx)
const {
188 return getArrCopy(
_geoMesh.
mesh->GetCellData(), arrayName, arrayIdx);
192 vtkAbstractArray *array)
const {
193 getArrCopy(
_geoMesh.
mesh->GetCellData(), arrayIdx, array);
197 int arrayIdx)
const {
198 return getArrCopy(
_geoMesh.
mesh->GetCellData(), arrayIdx);
202 vtkAbstractArray *array,
203 int *arrayIdx)
const {
204 getArrCopy(
_geoMesh.
mesh->GetFieldData(), arrayName, arrayIdx, array);
208 const std::string &arrayName,
int *arrayIdx)
const {
209 return getArrCopy(
_geoMesh.
mesh->GetFieldData(), arrayName, arrayIdx);
213 vtkAbstractArray *array)
const {
214 getArrCopy(
_geoMesh.
mesh->GetFieldData(), arrayIdx, array);
218 int arrayIdx)
const {
219 return getArrCopy(
_geoMesh.
mesh->GetFieldData(), arrayIdx);
240 vtkIdTypeArray *origCell, vtkIntArray *cellFace,
241 vtkStringArray *setNames)
243 assert(geoEnt || sideSet->GetCellData()->HasArray(
GEO_ENT_NAME));
253 return sides ? vtkIntArray::FastDownCast(
261 sides->GetCellData()->AddArray(arr);
265 return sides ? vtkIdTypeArray::FastDownCast(
272 assert(arr->GetNumberOfTuples() ==
sides->GetNumberOfCells() &&
273 arr->GetNumberOfComponents() == 2);
275 sides->GetCellData()->AddArray(arr);
282 return sides ? vtkIntArray::FastDownCast(
289 assert(arr->GetNumberOfTuples() ==
sides->GetNumberOfCells() &&
290 arr->GetNumberOfComponents() == 2);
292 sides->GetCellData()->AddArray(arr);
299 return sides ? vtkStringArray::SafeDownCast(
306 assert(arr->GetNumberOfComponents() == 1);
308 sides->GetFieldData()->AddArray(arr);
315 if (sideSet.sides && !sideSet.getOrigCellArr() && !sideSet.getCellFaceArr()) {
316 vtkIdType numSides = sideSet.sides->GetNumberOfCells();
317 auto entArr = sideSet.getGeoEntArr();
318 vtkNew<vtkIdTypeArray> origCellArr;
319 origCellArr->SetNumberOfComponents(2);
320 origCellArr->SetNumberOfTuples(numSides);
321 origCellArr->FillTypedComponent(0, -1);
322 origCellArr->FillTypedComponent(1, -1);
323 vtkNew<vtkIntArray> cellFaceArr;
324 cellFaceArr->SetNumberOfComponents(2);
325 cellFaceArr->SetNumberOfTuples(numSides);
326 cellFaceArr->FillTypedComponent(0, -1);
327 cellFaceArr->FillTypedComponent(1, -1);
331 auto pt2Cell =
mesh->GetCellLinks();
332 for (vtkIdType i = 0; i < sideSet.sides->GetNumberOfCells(); ++i) {
333 auto sidePoints = sideSet.sides->GetCell(i)->GetPointIds();
334 auto cellList = pt2Cell->GetLink(sidePoints->GetId(0));
335 std::vector<vtkIdType> candidates{cellList.cells,
336 cellList.cells + cellList.ncells};
337 std::sort(candidates.begin(), candidates.end());
338 for (
auto j = 1; j < sidePoints->GetNumberOfIds(); ++j) {
339 std::vector<vtkIdType> newCandidates{};
340 cellList = pt2Cell->GetLink(sidePoints->GetId(j));
341 for (
auto iterCell = cellList.cells;
342 iterCell < cellList.cells + cellList.ncells; ++iterCell) {
344 std::lower_bound(candidates.begin(), candidates.end(), *iterCell);
345 if (findIter != candidates.end() && *iterCell == *findIter) {
346 newCandidates.emplace_back(*iterCell);
349 candidates = std::move(newCandidates);
350 std::sort(candidates.begin(), candidates.end());
353 bool foundMatch =
false;
354 if (candidates.size() == 1) {
357 std::vector<vtkIdType> sortedSidePoints(sidePoints->GetNumberOfIds());
358 auto pointsBegin = sidePoints->GetPointer(0);
359 std::partial_sort_copy(
360 pointsBegin, pointsBegin + sidePoints->GetNumberOfIds(),
361 sortedSidePoints.begin(), sortedSidePoints.end());
362 auto candOrigCell =
mesh->GetCell(candidates.at(0));
363 auto dim = candOrigCell->GetCellDimension();
364 for (
int j = 0; j < (dim == 3 ? candOrigCell->GetNumberOfFaces()
365 : candOrigCell->GetNumberOfEdges());
368 dim == 3 ? candOrigCell->GetFace(j) : candOrigCell->GetEdge(j);
369 std::vector<vtkIdType> sortedCandPoints(sortedSidePoints.size());
370 auto candPointsBegin = candSide->GetPointIds()->GetPointer(0);
373 auto candPointsEnd = candPointsBegin + sidePoints->GetNumberOfIds();
374 std::partial_sort_copy(candPointsBegin, candPointsEnd,
375 sortedCandPoints.begin(),
376 sortedCandPoints.end());
377 if (sortedSidePoints == sortedCandPoints) {
379 origCellArr->SetTypedComponent(i, 0, candidates.at(0));
380 cellFaceArr->SetTypedComponent(i, 0, j);
386 assert(candidates.size() == 2);
387 for (
const auto &candIdx : candidates) {
388 auto candOrigCell =
mesh->GetCell(candIdx);
389 auto dim = candOrigCell->GetCellDimension();
390 bool foundSide =
false;
391 for (
int j = 0; j < (dim == 3 ? candOrigCell->GetNumberOfFaces()
392 : candOrigCell->GetNumberOfEdges()) &&
396 dim == 3 ? candOrigCell->GetFace(j) : candOrigCell->GetEdge(j);
397 auto candPointsBegin = candSide->GetPointIds()->GetPointer(0);
400 auto candPointsEnd = candPointsBegin + sidePoints->GetNumberOfIds();
401 auto findFirstPoint =
402 std::find(candPointsBegin, candPointsEnd, sidePoints->GetId(0));
403 if (findFirstPoint != candPointsEnd) {
404 std::vector<vtkIdType> rotatedCandPoints(
405 sidePoints->GetNumberOfIds());
406 std::rotate_copy(candPointsBegin, findFirstPoint, candPointsEnd,
407 rotatedCandPoints.begin());
408 if (std::equal(rotatedCandPoints.begin(), rotatedCandPoints.end(),
409 sidePoints->GetPointer(0))) {
412 origCellArr->SetTypedComponent(i, 0, candIdx);
413 cellFaceArr->SetTypedComponent(i, 0, j);
414 }
else if (std::equal(rotatedCandPoints.rbegin(),
415 rotatedCandPoints.rend(),
416 sidePoints->GetPointer(0))) {
418 origCellArr->SetTypedComponent(i, 1, candIdx);
419 cellFaceArr->SetTypedComponent(i, 1, j);
423 if (foundMatch) {
break; }
427 std::cerr <<
"No cell in mesh found to correspond to side set cell " 431 sideSet.setOrigCellArr(origCellArr);
432 sideSet.setCellFaceArr(cellFaceArr);
437 if (this->
mesh->GetNumberOfCells() > 0) {
438 return this->
mesh->GetCell(0)->GetCellDimension();
virtual void report(std::ostream &out) const =0
Print a report about the mesh.
void getPointDataArrayCopy(const std::string &arrayName, vtkAbstractArray *array, int *arrayIdx=nullptr) const
Get copy of point data array by name.
static constexpr auto CELL_FACE_NAME
vtkSmartPointer< vtkUnstructuredGrid > mesh
vtkSmartPointer< vtkIntArray > getCellFaceArr() const
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
static void Finalize()
Finalize Gmsh.
vtkSmartPointer< vtkIdTypeArray > getOrigCellArr() const
void findSide2OrigCell()
For each edge/polygon in sideSet, find the corresponding mesh element in mesh.
static void Initialize()
Initialize Gmsh.
void setCellFaceArr(vtkIntArray *arr)
static constexpr auto NAME_ARR_NAME
void setOrigCellArr(vtkIdTypeArray *arr)
void setGeoEntArr(vtkIntArray *arr)
virtual void mergeGeoMesh(geoMeshBase *otherGeoMesh)
Merge mesh data from a new geoMesh to an existing geoMesh.
vtkSmartPointer< vtkPolyData > sides
Cells represent edges/faces of some GeoMesh.
std::shared_ptr< meshBase > mesh
void getFieldDataArrayCopy(const std::string &arrayName, vtkAbstractArray *array, int *arrayIdx=nullptr) const
Get copy of field data array by name.
std::array< int, 2 > sides
vtkSmartPointer< vtkIntArray > getGeoEntArr() const
double _angleThreshold
Dihedral angle threshold (in radians) to classify surfaces (Default: 30 degrees)
void setSideSetNamesArr(vtkStringArray *arr)
geoMeshBase()
Query for conversion from vtk to gmsh.
static constexpr auto GEO_ENT_NAME
static std::shared_ptr< GmshInterface > instance
virtual void resetNative()=0
void getCellDataArrayCopy(const std::string &arrayName, vtkAbstractArray *array, int *arrayIdx=nullptr) const
Get copy of cell data array by name.
abstract class to specify geometry and mesh data
vtkSmartPointer< vtkStringArray > getSideSetNames() const
int getDimension() const
Get dimension of mesh.
const GeoMesh & getGeoMesh() const
Get the underlying geometry object.
static constexpr auto ORIG_CELL_NAME
virtual void takeGeoMesh(geoMeshBase *otherGeoMesh)
Take the GeoMesh of another geoMeshBase.