Commit 524ba39d authored by Chuck Atkins's avatar Chuck Atkins Committed by Kitware Robot
Browse files

Merge topic 'multiple-ghostcell-layers'

e8c9e0af

 Updated vtkPUnstructuredGridGhostCellsGenerator
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Reviewed-by: default avatarJoachim Pouderoux <joachim.pouderoux@kitware.com>
Merge-request: !1107
parents ffd7a24f e8c9e0af
...@@ -145,83 +145,94 @@ int TestPUnstructuredGridGhostCellsGenerator(int argc, char* argv[]) ...@@ -145,83 +145,94 @@ int TestPUnstructuredGridGhostCellsGenerator(int argc, char* argv[])
ghostGenerator->Modified(); ghostGenerator->Modified();
// Check ghost cells generated with and without the global point ids // Check ghost cells generated with and without the global point ids
// for several ghost layer levels
int maxGhostLevel = 2;
vtkUnstructuredGrid* outGrids[2]; vtkUnstructuredGrid* outGrids[2];
for(int step = 0; step < 2; ++step) for(int ghostLevel = 1; ghostLevel <= maxGhostLevel; ++ghostLevel)
{ {
ghostGenerator->SetUseGlobalPointIds(step == 0 ? 1 : 0); for(int step = 0; step < 2; ++step)
vtkNew<vtkTimerLog> timer;
timer->StartTimer();
ghostGenerator->UpdatePiece(rankId, nbRanks, 1);
timer->StopTimer();
// Save the grid for further analyze
outGrids[step] = ghostGenerator->GetOutput();
outGrids[step]->Register(0);
double ellapsed = timer->GetElapsedTime();
// get some performance statistics
double minGhostUpdateTime = 0.0;
double maxGhostUpdateTime = 0.0;
double avgGhostUpdateTime = 0.0;
controller->Reduce(&ellapsed, &minGhostUpdateTime, 1, vtkCommunicator::MIN_OP, 0);
controller->Reduce(&ellapsed, &maxGhostUpdateTime, 1, vtkCommunicator::MAX_OP, 0);
controller->Reduce(&ellapsed, &avgGhostUpdateTime, 1, vtkCommunicator::SUM_OP, 0);
avgGhostUpdateTime /= static_cast<double>(nbRanks);
vtkMPIUtilities::Printf(controller.Get(),
"-- Ellapsed Time: min=%f, avg=%f, max=%f\n",
minGhostUpdateTime, avgGhostUpdateTime, maxGhostUpdateTime);
}
vtkIdType initialNbOfCells = initialGrid->GetNumberOfCells();
if (outGrids[0]->GetNumberOfCells() != outGrids[1]->GetNumberOfCells())
{
vtkMPIUtilities::Printf(controller.Get(),
"Grids obtained with and without global ids do not have the same number of cells!\n");
ret = EXIT_FAILURE;
}
for (int step = 0; step < 2; ++step)
{
vtkUnsignedCharArray* ghosts = vtkUnsignedCharArray::SafeDownCast(
outGrids[step]->GetCellGhostArray());
if (initialNbOfCells >= outGrids[step]->GetNumberOfCells())
{ {
ghostGenerator->SetUseGlobalPointIds(step == 0 ? 1 : 0);
vtkNew<vtkTimerLog> timer;
timer->StartTimer();
ghostGenerator->UpdatePiece(rankId, nbRanks, ghostLevel);
timer->StopTimer();
// Save the grid for further analysis
outGrids[step] = ghostGenerator->GetOutput();
outGrids[step]->Register(0);
double elapsed = timer->GetElapsedTime();
// get some performance statistics
double minGhostUpdateTime = 0.0;
double maxGhostUpdateTime = 0.0;
double avgGhostUpdateTime = 0.0;
controller->Reduce(&elapsed, &minGhostUpdateTime, 1, vtkCommunicator::MIN_OP, 0);
controller->Reduce(&elapsed, &maxGhostUpdateTime, 1, vtkCommunicator::MAX_OP, 0);
controller->Reduce(&elapsed, &avgGhostUpdateTime, 1, vtkCommunicator::SUM_OP, 0);
avgGhostUpdateTime /= static_cast<double>(nbRanks);
vtkMPIUtilities::Printf(controller.Get(), vtkMPIUtilities::Printf(controller.Get(),
"Obtained grids has less or as many cells as the input grid!\n"); "-- Ghost Level: %i Elapsed Time: min=%f, avg=%f, max=%f\n",
ret = EXIT_FAILURE; ghostLevel, minGhostUpdateTime, avgGhostUpdateTime, maxGhostUpdateTime);
} }
if (!ghosts)
vtkIdType initialNbOfCells = initialGrid->GetNumberOfCells();
if (outGrids[0]->GetNumberOfCells() != outGrids[1]->GetNumberOfCells())
{ {
vtkMPIUtilities::Printf(controller.Get(), vtkMPIUtilities::Printf(controller.Get(),
"Ghost cells array not found at step %d!\n", step); "Grids obtained with and without global ids for ghost level %i do not have the same number of cells!\n",
ghostLevel);
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
continue;
} }
for (vtkIdType i = 0; i < ghosts->GetNumberOfTuples(); ++i) for (int step = 0; step < 2; ++step)
{ {
unsigned char val = ghosts->GetValue(i); vtkUnsignedCharArray* ghosts = vtkUnsignedCharArray::SafeDownCast(
if (i < initialNbOfCells && val != 0) outGrids[step]->GetCellGhostArray());
if (initialNbOfCells >= outGrids[step]->GetNumberOfCells())
{ {
vtkMPIUtilities::Printf(controller.Get(), vtkMPIUtilities::Printf(controller.Get(),
"Cell %d is not supposed to be a ghost cell but it is!\n", i); "Obtained grids for ghost level %i has less or as many cells as the input grid!\n",
ghostLevel);
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
break;
} }
if (i >= initialNbOfCells && val != 1) if (!ghosts)
{ {
vtkMPIUtilities::Printf(controller.Get(), vtkMPIUtilities::Printf(controller.Get(),
"Cell %d is supposed to be a ghost cell but it's not!\n", i); "Ghost cells array not found at ghost level %i, step %d!\n",
ghostLevel, step);
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
break; continue;
}
for (vtkIdType i = 0; i < ghosts->GetNumberOfTuples(); ++i)
{
unsigned char val = ghosts->GetValue(i);
if (i < initialNbOfCells && val != 0)
{
vtkMPIUtilities::Printf(controller.Get(),
"Ghost Level %i Cell %d is not supposed to be a ghost cell but it is!\n",
ghostLevel, i);
ret = EXIT_FAILURE;
break;
}
if (i >= initialNbOfCells && val != 1)
{
vtkMPIUtilities::Printf(controller.Get(),
"Ghost Level %i Cell %d is supposed to be a ghost cell but it's not!\n",
ghostLevel, i);
ret = EXIT_FAILURE;
break;
}
} }
} }
outGrids[0]->Delete();
outGrids[1]->Delete();
} }
outGrids[0]->Delete();
outGrids[1]->Delete();
controller->Finalize(); controller->Finalize();
return ret; return ret;
......
...@@ -34,6 +34,33 @@ ...@@ -34,6 +34,33 @@
// //
// .SECTION Thanks // .SECTION Thanks
// This filter has been developed by Joachim Pouderoux, Kitware SAS 2015. // This filter has been developed by Joachim Pouderoux, Kitware SAS 2015.
//
// This filter was expanded to compute multiple ghost layers by Boonthanome
// Nouanesengsy and John Patchett, Los Alamos National Laboratory 2016.
//
// ************************************************
//
// This filter uses different algorithms when obtaining the first layer of
// ghost cells and getting subsequent layers.
//
// First ghost cell layer algorithm:
// - each proc obtains surface points using the surface filter
// - perform an all-to-all to share surface points with each other
// - for each other proc, look at their points, and see if any points
// match any of your local points
// - for each matching point, find all local cells which use those points,
// and send those cells to that proc. mark the cells that were sent
// (used for later ghost layers)
// - receive all cells sent to you, and merge everything together
//
// Subsequent ghost layers
// - for each cell that was sent last round, find all other local cells
// which border these cells. 'local cells' also includes all ghost cells
// which i have. send these cells to the same proc, and mark them as sent
// last round
// - receive all cells sent to you, and merge everything together
// - if another layer is needed, repeat
//
#ifndef vtkPUnstructuredGridGhostCellsGenerator_h #ifndef vtkPUnstructuredGridGhostCellsGenerator_h
#define vtkPUnstructuredGridGhostCellsGenerator_h #define vtkPUnstructuredGridGhostCellsGenerator_h
...@@ -43,6 +70,7 @@ ...@@ -43,6 +70,7 @@
class vtkMultiProcessController; class vtkMultiProcessController;
class vtkUnstructuredGrid; class vtkUnstructuredGrid;
class vtkUnstructuredGridBase;
class VTKFILTERSPARALLELGEOMETRY_EXPORT vtkPUnstructuredGridGhostCellsGenerator: class VTKFILTERSPARALLELGEOMETRY_EXPORT vtkPUnstructuredGridGhostCellsGenerator:
public vtkUnstructuredGridAlgorithm public vtkUnstructuredGridAlgorithm
...@@ -72,6 +100,23 @@ public: ...@@ -72,6 +100,23 @@ public:
vtkSetStringMacro(GlobalPointIdsArrayName); vtkSetStringMacro(GlobalPointIdsArrayName);
vtkGetStringMacro(GlobalPointIdsArrayName); vtkGetStringMacro(GlobalPointIdsArrayName);
// Description:
// Specify if the data has global cell ids.
// If more than one layer of ghost cells is needed, global cell ids are
// necessary. If global cell ids are not provided, they will be computed
// internally.
// If false, global cell ids will be computed, then deleted afterwards.
// Default is FALSE.
vtkSetMacro(HasGlobalCellIds, bool);
vtkGetMacro(HasGlobalCellIds, bool);
vtkBooleanMacro(HasGlobalCellIds, bool);
// Description:
// Specify the name of the global cell ids data array if the GlobalIds
// attribute array is not set. Default is "GlobalNodeIds".
vtkSetStringMacro(GlobalCellIdsArrayName);
vtkGetStringMacro(GlobalCellIdsArrayName);
// Description: // Description:
// Specify if the filter must generate the ghost cells only if required by // Specify if the filter must generate the ghost cells only if required by
// the pipeline. // the pipeline.
...@@ -88,25 +133,39 @@ protected: ...@@ -88,25 +133,39 @@ protected:
virtual int RequestData(vtkInformation *, vtkInformationVector **, virtual int RequestData(vtkInformation *, vtkInformationVector **,
vtkInformationVector *); vtkInformationVector *);
void GetFirstGhostLayer(int, vtkUnstructuredGrid *);
void ExtractAndReduceSurfacePoints(); void ExtractAndReduceSurfacePoints();
void ComputeSharedPoints(); void ComputeSharedPoints();
void ExtractAndSendGhostCells(); void ExtractAndSendGhostCells(vtkUnstructuredGridBase *);
void ReceiveAndMergeGhostCells(int, vtkUnstructuredGridBase *,
vtkUnstructuredGrid *);
void AddGhostLayer(int ghostLevel, int maxGhostLevel);
void FindGhostCells();
void AddGlobalCellIds();
void RemoveGlobalCellIds();
void ReceiveAndMergeGhostCells(vtkUnstructuredGrid*);
vtkMultiProcessController *Controller; vtkMultiProcessController *Controller;
int NumRanks; int NumRanks;
int RankId; int RankId;
char* GlobalPointIdsArrayName; char *GlobalPointIdsArrayName;
bool UseGlobalPointIds; bool UseGlobalPointIds;
char *GlobalCellIdsArrayName;
bool HasGlobalCellIds;
bool BuildIfRequired; bool BuildIfRequired;
private: private:
struct vtkInternals; struct vtkInternals;
vtkInternals* Internals; vtkInternals *Internals;
vtkPUnstructuredGridGhostCellsGenerator(const vtkPUnstructuredGridGhostCellsGenerator&); // Not implemented vtkPUnstructuredGridGhostCellsGenerator(const vtkPUnstructuredGridGhostCellsGenerator&); // Not implemented
void operator=(const vtkPUnstructuredGridGhostCellsGenerator&); // Not implemented void operator=(const vtkPUnstructuredGridGhostCellsGenerator&); // Not implemented
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment