6#ifndef PResolveHangingNodesTestUtilities_h
7#define PResolveHangingNodesTestUtilities_h
44constexpr double EPSILON = 1e-6;
50 const std::array<int, 3>& numCells,
double spacing)
53 block->SetOrigin(origin.data());
54 block->SetSpacing(spacing, spacing, spacing);
55 block->SetDimensions(numCells[0] + 1, numCells[1] + 1, numCells[2] + 1);
57 values->SetName(
"Values");
59 levels->SetName(
"Levels");
60 for (
vtkIdType i = 0; i < block->GetNumberOfPoints(); ++i)
62 const double* p = block->GetPoint(i);
63 values->InsertNextValue(p[0] + 10.0 * p[1] + 100.0 * p[2]);
64 levels->InsertNextValue(level);
66 block->GetPointData()->AddArray(values);
67 block->GetPointData()->AddArray(levels);
80const std::array<std::array<double, 4>, 8> QUADS = { {
99 values->SetName(
"Values");
100 auto add = [&](
double x,
double y)
102 values->InsertNextValue(x + 10.0 * y + 100.0 * partition);
103 return points->InsertNextPoint(x, y, 0.0);
105 const auto& [x0, y0, x1, y1] = QUADS[partition];
107 const vtkIdType quad[4] = { add(x0, y0), add(x1, y0), add(x1, y1), add(x0, y1) };
108 polys->InsertNextCell(4, quad);
111 pd->SetPoints(points);
113 pd->GetPointData()->AddArray(values);
136 values->SetName(
"Values");
138 auto point = [&](
int x,
int y,
int z)
140 auto it =
pointIds.find({ x, y, z });
145 values->InsertNextValue(x + 10.0 * y + 100.0 * z + 1000.0 * partition);
152 ug->AllocateExact(8, 64);
153 auto hex = [&](
int x,
int y,
int z,
int size)
156 point(x, y + size, z),
point(x, y, z + size),
point(x + size, y, z + size),
157 point(x + size, y + size, z + size),
point(x, y + size, z + size) };
165 else if (partition == 2)
169 else if (partition == 3)
173 else if (partition >= 6)
175 hex(partition - 4, 1, 1, 1);
179 const int j = partition == 4 ? 1 : 0;
180 const int k = partition == 5 ? 1 : 0;
181 for (
int i = 0; i < 2; ++i)
186 ug->SetPoints(points);
187 ug->GetPointData()->AddArray(values);
210 geometry->SetInputData(ds);
213 if constexpr (Dim == 2)
216 edges->SetInputData(boundary);
217 edges->BoundaryEdgesOn();
218 edges->FeatureEdgesOff();
219 edges->NonManifoldEdgesOff();
220 edges->ManifoldEdgesOff();
222 boundary =
edges->GetOutput();
224 double measure = 0.0;
226 for (
vtkIdType c = 0; c < boundary->GetNumberOfCells(); ++c)
228 boundary->GetCellPoints(c, ids);
229 if constexpr (Dim == 2)
232 boundary->GetPoint(ids->GetId(0), p0);
233 boundary->GetPoint(ids->GetId(1), p1);
240 boundary->GetPoints(), ids->GetNumberOfIds(), ids->
GetPointer(0), normal);
251 vtkDataObject* output,
double expectedMeasure,
double expectedBoundaryMeasure)
257 if (!partitions.empty())
262 localAppend->AddInputData(partition);
264 localAppend->Update();
265 local = localAppend->GetOutput();
267 std::vector<vtkSmartPointer<vtkDataObject>> outputs;
268 controller->
Gather(local, outputs, 0);
274 append->MergePointsOn();
275 for (
const auto& partition : outputs)
277 append->AddInputData(partition);
282 const double boundaryMeasure = BoundaryMeasure<Dim>(mesh);
283 if (std::abs(boundaryMeasure - expectedBoundaryMeasure) > EPSILON)
285 std::cerr <<
name <<
": the boundary " << (Dim == 2 ?
"length" :
"area") <<
" is "
286 << boundaryMeasure <<
" instead of " << expectedBoundaryMeasure
287 <<
", the output is not conforming\n";
294 validator->SetInputData(mesh);
300 if (states->
GetTuple1(c) !=
static_cast<short>(vtkCellValidator::State::Valid))
302 std::cerr <<
name <<
": cell " << c <<
" of type " << mesh->
GetCellType(c)
303 <<
" is not valid\n";
311 double measure = 0.0;
314 measure += 1.0 / inverseMeasure->
GetTuple1(c);
316 if (std::abs(measure - expectedMeasure) > EPSILON)
318 std::cerr <<
name <<
": the cells cover " << (Dim == 2 ?
"an area" :
"a volume") <<
" of "
319 << measure <<
" instead of " << expectedMeasure <<
"\n";
332 vtkTypeMacro(vtkPLevelsTestFilter, vtkPResolveHangingNodes);
334 std::vector<int> PartitionedDataSetIds;
335 bool ReceivedOnlyOtherLevels =
true;
338 std::vector<vtkSmartPointer<vtkPolyData>> GetRemotePoints(
339 const std::vector<vtkPolyData*>& boundaries,
340 const std::vector<int>& partitionedDataSetIds)
override
342 this->PartitionedDataSetIds = partitionedDataSetIds;
343 std::vector<vtkSmartPointer<vtkPolyData>> remotePoints =
345 for (std::size_t p = 0; p < remotePoints.size(); ++p)
348 remotePoints[p] ? remotePoints[p]->GetPointData()->GetArray(
"Levels") :
nullptr;
351 if (levels->
GetTuple1(i) == partitionedDataSetIds[p])
353 this->ReceivedOnlyOtherLevels =
false;
vtkIdType GetNumberOfTuples() const
Get the number of complete tuples (a component group) in the array.
static std::vector< DataSetT * > GetDataSets(vtkDataObject *dobj, bool preserveNull=false)
Extract datasets from the given data object.
double GetTuple1(vtkIdType tupleIdx)
These methods are included as convenience for the wrappers.
general representation of visualization data
abstract class to specify dataset behavior
static vtkDataSet * SafeDownCast(vtkObjectBase *o)
virtual vtkIdType GetNumberOfPoints()=0
Determine the number of points composing the dataset.
virtual double * GetPoint(vtkIdType ptId)=0
Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints.
vtkCellData * GetCellData()
Return a pointer to this dataset's cell data.
vtkDataArray * GetArray(int i)
Not recommended for use.
static ReturnTypeT Distance2BetweenPoints(const TupleRangeT1 &p1, const TupleRangeT2 &p2)
Compute distance squared between two points p1 and p2.
Multiprocessing communication superclass.
int Gather(const int *sendBuffer, int *recvBuffer, vtkIdType length, int destProcessId)
Gather collects arrays in the process with id destProcessId.
int GetLocalProcessId()
Tells you which process [0, NumProcess) you are in.
Allocate and hold a VTK object.
T * GetPointer() const noexcept
Get a raw pointer to the contained object.
resolve the hanging nodes of a 2D or 3D multi-resolution mesh distributed over several processes
std::vector< vtkSmartPointer< vtkPolyData > > GetRemotePoints(const std::vector< vtkPolyData * > &boundaries, const std::vector< int > &partitionedDataSetIds) override
Exchange the points of the boundary of the partitions with their neighbors, on this process or on oth...
double ComputeArea()
Compute the area of a polygon.
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
dataset represents arbitrary combinations of all possible cell types
vtkIdType GetNumberOfCells() override
Standard vtkDataSet methods; see vtkDataSet.h for documentation.
int GetCellType(vtkIdType cellId) override
Get the type of the cell with the given cellId.
const std::string pointIds
std::pair< boost::graph_traits< vtkGraph * >::edge_iterator, boost::graph_traits< vtkGraph * >::edge_iterator > edges(vtkGraph *g)
#define VTK_STANDARD_NEW_BODY(thisClass)