7 #include <vtkCellData.h>
8 #include <vtkFloatArray.h>
10 #include <vtkIdTypeArray.h>
11 #include <vtkInformation.h>
12 #include <vtkInformationVector.h>
13 #include <vtkMultiBlockDataSet.h>
14 #include <vtkMultiProcessController.h>
15 #include <vtkObjectFactory.h>
16 #include <vtkPointData.h>
17 #include <vtkPolyhedron.h>
18 #include <vtkStreamingDemandDrivenPipeline.h>
19 #include <vtkUnstructuredGrid.h>
21 #include <vtkSmartPointer.h>
22 #define VTK_CREATE(type, name) vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
23 #define VTK_NEW(type, name) name = vtkSmartPointer<type>::New()
29 this->SetNumberOfInputPorts(1);
30 this->SetNumberOfOutputPorts(1);
32 this->Controller =
NULL;
33 this->SetController(vtkMultiProcessController::GetGlobalController());
38 this->SetController(
nullptr);
43 this->Superclass::PrintSelf(os, indent);
44 os << indent <<
"vtkPMergeConnected filter"
48 void vtkPMergeConnected::SetController(vtkMultiProcessController* c)
50 if ((c ==
NULL) || (c->GetNumberOfProcesses() == 0))
52 this->NumProcesses = 1;
56 if (this->Controller == c)
63 if (this->Controller !=
NULL)
65 this->Controller->UnRegister(
this);
66 this->Controller =
NULL;
77 this->NumProcesses = c->GetNumberOfProcesses();
78 this->MyId = c->GetLocalProcessId();
82 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
85 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
86 vtkInformation* outInfo = outputVector->GetInformationObject(0);
89 vtkMultiBlockDataSet* input =
90 vtkMultiBlockDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
91 vtkMultiBlockDataSet* output =
92 vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
95 piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
96 numPieces = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
99 vtkMultiProcessController* contr = this->Controller;
102 int oops = ((piece != this->MyId) || (numPieces != this->NumProcesses));
104 for (
unsigned int i = piece; i < input->GetNumberOfBlocks(); i += numPieces)
106 vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast(input->GetBlock(i));
109 vtkErrorMacro(
"Blocks in the input data are not vtkUnstructuredGrid");
114 vtkCellData* cd = ugrid->GetCellData();
115 vtkPointData* pd = ugrid->GetPointData();
116 vtkIdTypeArray* prid_array = vtkIdTypeArray::SafeDownCast(pd->GetArray(
"RegionId"));
117 vtkIdTypeArray* crid_array = vtkIdTypeArray::SafeDownCast(cd->GetArray(
"RegionId"));
118 vtkFloatArray* vol_array = vtkFloatArray::SafeDownCast(cd->GetArray(
"Volumes"));
120 if (!prid_array || !crid_array || !vol_array)
123 "Input data does not have expected arrays. vtkPMergeConnected expects input data"
124 " to have 'RegionId' arrays on points and cells and a 'Volumes' array on the cells.");
130 contr->Reduce(&oops, &sum, 1, vtkCommunicator::SUM_OP, 0);
131 contr->Broadcast(&sum, 1, 0);
139 output->CopyStructure(input);
142 tb = input->GetNumberOfBlocks();
143 for (i = piece; i < tb; i += numPieces)
145 vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast(input->GetBlock(i));
148 ugrid_out->SetPoints(ugrid->GetPoints());
150 vtkCellData* cd = ugrid->GetCellData();
151 vtkPointData* pd = ugrid->GetPointData();
152 vtkCellData* ocd = ugrid_out->GetCellData();
153 vtkPointData* opd = ugrid_out->GetPointData();
155 vtkIdTypeArray* prid_array = vtkIdTypeArray::SafeDownCast(pd->GetArray(
"RegionId"));
156 vtkIdTypeArray* crid_array = vtkIdTypeArray::SafeDownCast(cd->GetArray(
"RegionId"));
157 vtkFloatArray* vol_array = vtkFloatArray::SafeDownCast(cd->GetArray(
"Volumes"));
164 oprid_array->DeepCopy(prid_array);
165 oprid_array->SetName(
"RegionId");
169 crid_array->GetRange(rid_range, 0);
172 ocrid_array->SetName(
"RegionId");
173 ovol_array->SetName(
"Volumes");
175 ocrid_array->SetNumberOfComponents(1);
176 ovol_array->SetNumberOfComponents(1);
179 for (j = rid_range[0]; j <= rid_range[1]; j++)
183 MergeCellsOnRegionId(ugrid, j, mcell);
184 ugrid_out->InsertNextCell(VTK_POLYHEDRON, mcell);
187 ocrid_array->InsertNextValue(j);
190 float vol = MergeCellDataOnRegionId(vol_array, crid_array, j);
191 ovol_array->InsertNextValue(vol);
195 opd->AddArray(oprid_array);
196 ocd->AddArray(ocrid_array);
197 ocd->AddArray(ovol_array);
199 output->SetBlock(i, ugrid_out);
203 LocalToGlobalRegionId(contr, output);
209 void vtkPMergeConnected::LocalToGlobalRegionId(
210 vtkMultiProcessController* contr, vtkMultiBlockDataSet*
data)
214 num_p = contr->GetNumberOfProcesses();
215 rank = contr->GetLocalProcessId();
216 tb =
data->GetNumberOfBlocks();
219 std::vector<int> all_num_regions_local;
220 all_num_regions_local.resize(tb);
222 memset(all_num_regions_local.data(), 0,
sizeof(
int) * tb);
223 for (i = rank; i < tb; i += num_p)
225 vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast(
data->GetBlock(i));
226 vtkIdTypeArray* crid_array =
227 vtkIdTypeArray::SafeDownCast(ugrid->GetCellData()->GetArray(
"RegionId"));
230 crid_array->GetRange(rid_range, 0);
231 all_num_regions_local[i] = rid_range[1] - rid_range[0] + 1;
234 std::vector<int> all_num_regions;
235 all_num_regions.resize(tb);
236 contr->AllReduce(all_num_regions_local.data(), all_num_regions.data(), tb, vtkCommunicator::SUM_OP);
239 for (i = rank; i < tb; i += num_p)
241 vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast(
data->GetBlock(i));
242 vtkIdTypeArray* crid_array =
243 vtkIdTypeArray::SafeDownCast(ugrid->GetCellData()->GetArray(
"RegionId"));
244 vtkIdTypeArray* prid_array =
245 vtkIdTypeArray::SafeDownCast(ugrid->GetPointData()->GetArray(
"RegionId"));
247 int num_cells = crid_array->GetNumberOfTuples();
248 int num_points = prid_array->GetNumberOfTuples();
253 ocrid_array->SetNumberOfComponents(1);
254 oprid_array->SetNumberOfComponents(1);
255 ocrid_array->SetNumberOfTuples(num_cells);
256 oprid_array->SetNumberOfTuples(num_points);
257 ocrid_array->SetName(
"RegionId");
258 oprid_array->SetName(
"RegionId");
261 for (j = 0; j < i; j++)
262 offset += all_num_regions[j];
265 for (j = 0; j < num_cells; j++)
266 ocrid_array->InsertValue(j,
offset + crid_array->GetValue(j));
267 for (j = 0; j < num_points; j++)
268 oprid_array->InsertValue(j,
offset + prid_array->GetValue(j));
270 ugrid->GetCellData()->RemoveArray(
"RegionId");
271 ugrid->GetCellData()->AddArray(ocrid_array);
273 ugrid->GetPointData()->RemoveArray(
"Regionid");
274 ugrid->GetPointData()->AddArray(oprid_array);
281 vtkIdType A = *(
static_cast<const vtkIdType*
>(
a));
282 vtkIdType B = *(
static_cast<const vtkIdType*
>(b));
283 return (
static_cast<int>(A - B));
289 FaceWithKey* facekey =
new FaceWithKey[1];
291 int num_pts = ids->GetNumberOfIds();
292 vtkIdType* key =
new vtkIdType[num_pts];
293 vtkIdType* orig =
new vtkIdType[num_pts];
296 for (i = 0; i < num_pts; i++)
297 orig[i] = ids->GetId(i);
298 memcpy(key, orig,
sizeof(vtkIdType) * num_pts);
299 qsort(key, num_pts,
sizeof(vtkIdType),
compare_ids);
301 facekey->num_pts = num_pts;
303 facekey->orig = orig;
317 for (i = 0; i <
a->num_pts; i++)
319 if (
a->key[i] != b->
key[i])
321 ret =
a->key[i] - b->
key[i];
334 void vtkPMergeConnected::delete_key(FaceWithKey* key)
343 void vtkPMergeConnected::MergeCellsOnRegionId(
344 vtkUnstructuredGrid* ugrid,
int target, vtkIdList* facestream)
348 vtkIdTypeArray* rids = vtkIdTypeArray::SafeDownCast(ugrid->GetCellData()->GetArray(
"RegionId"));
351 facestream->InsertNextId(-1);
353 std::map<FaceWithKey*, int, cmp_ids> face_map;
354 std::map<FaceWithKey*, int, cmp_ids>::iterator it;
357 for (i = 0; i < rids->GetNumberOfTuples(); i++)
359 if (rids->GetTuple1(i) == target)
361 vtkPolyhedron* cell = vtkPolyhedron::SafeDownCast(ugrid->GetCell(i));
362 for (j = 0; j < cell->GetNumberOfFaces(); j++)
364 vtkCell*
face = cell->GetFace(j);
365 vtkIdList* pts =
face->GetPointIds();
366 FaceWithKey* key = IdsToKey(pts);
368 it = face_map.find(key);
369 if (it == face_map.end())
379 for (it = face_map.begin(); it != face_map.end(); ++it)
381 FaceWithKey* key = (*it).first;
382 int count = (*it).second;
385 std::cerr <<
"error in building up face map" <<
std::endl;
388 facestream->InsertNextId(key->num_pts);
389 for (i = 0; i < key->num_pts; i++)
390 facestream->InsertNextId(key->orig[i]);
395 facestream->SetId(0, face_count);
399 float vtkPMergeConnected::MergeCellDataOnRegionId(
400 vtkFloatArray*
data_array, vtkIdTypeArray* rid_array, vtkIdType target)
405 for (i = 0; i < rid_array->GetNumberOfTuples(); i++)
406 if (rid_array->GetTuple1(i) == target)
416 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkMultiBlockDataSet");
vtkDataArray * data_array
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *)
void PrintSelf(ostream &os, vtkIndent indent)
int FillOutputPortInformation(int port, vtkInformation *info)
std::vector< unsigned int > face
QTextStream & endl(QTextStream &stream)
bool operator()(FaceWithKey const *a, FaceWithKey const *b) const
vtkStandardNewMacro(vtkPMergeConnected)
#define VTK_CREATE(type, name)
int compare_ids(const void *a, const void *b)