Commit ddd68974 authored by miller86's avatar miller86

adding support for exterior boundary ghosts

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@31513 18c085ea-50e0-402c-830e-de6fd14e8384
parent d8668a8f
......@@ -46,6 +46,8 @@
#include <vtkDataSet.h>
#include <vtkDataSetRemoveGhostCells.h>
#include <vtkPointData.h>
#include <vtkRectilinearGrid.h>
#include <vtkStructuredGrid.h>
#include <vtkUnsignedCharArray.h>
#include <DebugStream.h>
......@@ -77,8 +79,8 @@
avtGhostZoneFilter::avtGhostZoneFilter()
{
ghostDataMustBeRemoved = false;
ghostNodeTypesToRemove = 255;
ghostZoneTypesToRemove = 255;
ghostNodeTypesToRemove = 0xFF; // remove all types if must be removed
ghostZoneTypesToRemove = 0xFF; // remove all types if must be removed
}
......@@ -99,6 +101,105 @@ avtGhostZoneFilter::~avtGhostZoneFilter()
;
}
// ****************************************************************************
// Function: ExamineGhostArray
//
// Purpose: Efficiently examine ghost array data for whether all entities are
// ghost and/or whether all entities on exterior boundary are ghost.
//
// Programmer: Mark C. Miller
// Creation: Thu Sep 14 11:17:39 PDT 2017
//
// ****************************************************************************
static void
ExamineGhostArray(vtkDataSet *in_ds, bool zones, bool haveGhost,
unsigned char typesToRemove, bool *_allGhost, bool *_allLogBndGhost)
{
if (!haveGhost)
{
if (_allGhost) *_allGhost = false;
if (_allLogBndGhost) *_allLogBndGhost = false;
return;
}
vtkUnsignedCharArray *ghostArray = zones ?
(vtkUnsignedCharArray *) in_ds->GetCellData()->GetArray("avtGhostZones") :
(vtkUnsignedCharArray *) in_ds->GetPointData()->GetArray("avtGhostNodes");
const int nVals = zones ? in_ds->GetNumberOfCells() : in_ds->GetNumberOfPoints();
unsigned char const *ghostVals = ghostArray->GetPointer(0);
bool allGhost = true;
for (int i = 0 ; i < nVals && allGhost; i++)
{
if ((ghostVals[i] & typesToRemove) == 0x00)
allGhost = false;
}
if (_allGhost) *_allGhost = allGhost;
bool allLogBndGhost = true;
if (in_ds->GetDataObjectType() == VTK_RECTILINEAR_GRID ||
in_ds->GetDataObjectType() == VTK_STRUCTURED_GRID)
{
int dims[3];
if (in_ds->GetDataObjectType() == VTK_RECTILINEAR_GRID)
{
vtkRectilinearGrid *rg = vtkRectilinearGrid::SafeDownCast(in_ds);
rg->GetDimensions(dims);
}
else
{
vtkStructuredGrid *sg = vtkStructuredGrid::SafeDownCast(in_ds);
sg->GetDimensions(dims);
}
// If were here for cells instead of nodes, reduce dims by 1
if (zones)
{
for (int i = 0; i < 3; i++)
{
if (dims[i] > 1)
dims[i]--;
}
}
//
// This nesting of loops looks bad but has plenty of
// opportunities to terminate early.
//
for (int k = 0; k < dims[2] && allLogBndGhost; k++)
{
for (int j = 0; j < dims[1] && allLogBndGhost; j++)
{
for (int i = 0; i < dims[0] && allLogBndGhost; i++)
{
if (i==0 || i==(dims[0]-1))
{
int idx = k*dims[1]*dims[0] + j*dims[0] + i;
if ((ghostVals[idx] & typesToRemove) == 0x00)
allLogBndGhost = false;
}
else if (j==0 || j==(dims[1]-1))
{
int idx = k*dims[1]*dims[0] + j*dims[0] + i;
if ((ghostVals[idx] & typesToRemove) == 0x00)
allLogBndGhost = false;
}
else if (k==0 || k==(dims[2]-1))
{
int idx = k*dims[1]*dims[0] + j*dims[0] + i;
if ((ghostVals[idx] & typesToRemove) == 0x00)
allLogBndGhost = false;
}
}
}
}
}
else
{
allLogBndGhost = false;
}
if (_allLogBndGhost) *_allLogBndGhost = allLogBndGhost;
}
// ****************************************************************************
// Method: avtGhostZoneFilter::ExecuteData
......@@ -161,6 +262,9 @@ avtGhostZoneFilter::~avtGhostZoneFilter()
// I modified the routine to return a NULL in the case where it previously
// returned an avtDataRepresentation with a NULL vtkDataSet.
//
// Mark C. Miller, Thu Sep 14 11:18:52 PDT 2017
// Refactored code to check for all ghost nodes and zones and added checks
// for all logical boundary ghost.
// ****************************************************************************
avtDataRepresentation *
......@@ -191,59 +295,30 @@ avtGhostZoneFilter::ExecuteData(avtDataRepresentation *in_dr)
return in_dr;
}
//
// Check to see if the data is all ghost. If so, then we don't need
// to go any further.
//
if (haveGhostZones)
bool const zones = true;
bool allGhost = true;
bool allLogBndZonesGhost = false;
ExamineGhostArray(in_ds, zones, haveGhostZones, ghostZoneTypesToRemove,
&allGhost, &allLogBndZonesGhost);
if (allGhost)
{
vtkUnsignedCharArray *ghost_zones = (vtkUnsignedCharArray *)
in_ds->GetCellData()->GetArray("avtGhostZones");
unsigned char *gz = ghost_zones->GetPointer(0);
bool allGhost = true;
const int nCells = in_ds->GetNumberOfCells();
for (int i = 0 ; i < nCells ; i++)
{
if ((gz[i] & ghostZoneTypesToRemove) == '\0')
{
allGhost = false;
break;
}
}
if (allGhost)
{
debug5 << "Domain " << domain << " contains only ghosts. Removing"
<< endl;
return NULL;
}
debug5 << "Domain " << domain << " contains only ghost zones. Removing" << endl;
return NULL;
}
if (haveGhostNodes)
{
vtkUnsignedCharArray *ghost_nodes = (vtkUnsignedCharArray *)
in_ds->GetPointData()->GetArray("avtGhostNodes");
unsigned char *gn = ghost_nodes->GetPointer(0);
bool allGhost = true;
const int nNodes = in_ds->GetNumberOfPoints();
for (int i = 0 ; i < nNodes ; i++)
{
if ((gn[i] & ghostNodeTypesToRemove) == '\0')
{
allGhost = false;
break;
}
}
if (allGhost)
{
debug5 << "Domain " << domain << " contains only ghosts. Removing"
<< endl;
return NULL;
}
allGhost = true;
bool allLogBndNodesGhost = false;
ExamineGhostArray(in_ds, !zones, haveGhostNodes, ghostNodeTypesToRemove,
&allGhost, &allLogBndNodesGhost);
if (allGhost)
{
debug5 << "Domain " << domain << " contains only ghost nodes. Removing" << endl;
return NULL;
}
bool allLogBndGhost = allLogBndZonesGhost || allLogBndNodesGhost;
if (in_ds->GetDataObjectType() == VTK_RECTILINEAR_GRID &&
!ghostDataMustBeRemoved)
!ghostDataMustBeRemoved && !allLogBndGhost)
{
debug5 << "Allow rectilinear grid to travel through with ghost data;"
<< " depending on mapper to remove ghost data during render."
......@@ -252,7 +327,7 @@ avtGhostZoneFilter::ExecuteData(avtDataRepresentation *in_dr)
}
if (in_ds->GetDataObjectType() == VTK_STRUCTURED_GRID &&
!ghostDataMustBeRemoved)
!ghostDataMustBeRemoved && !allLogBndGhost)
{
debug5 << "Allow structured grid to travel through with ghost data;"
<< " depending on mapper to remove ghost data during render."
......@@ -317,7 +392,7 @@ avtGhostZoneFilter::UpdateDataObjectInfo(void)
{
GetOutput()->GetInfo().GetValidity().InvalidateZones();
GetOutput()->GetInfo().GetValidity().InvalidateSpatialMetaData();
if (ghostZoneTypesToRemove == 255)
if (ghostZoneTypesToRemove == 0xFF)
GetOutput()->GetInfo().GetAttributes().
SetContainsGhostZones(AVT_NO_GHOSTS);
}
......
......@@ -65,9 +65,11 @@
#include <vtkCellData.h>
#include <vtkFloatArray.h>
#include <vtkInformation.h>
#include <vtkIntArray.h>
#include <vtkPoints.h>
#include <vtkRectilinearGrid.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vtkStructuredGrid.h>
#include <vtkUnsignedCharArray.h>
......@@ -210,6 +212,7 @@ avtSAMRAIFileFormat::avtSAMRAIFileFormat(const char *fname)
ratios_coarser_levels = NULL;
var_cell_centered = NULL;
patch_extents = NULL;
patch_bdry_type = NULL;
var_extents = NULL;
var_names = NULL;
var_num_components = NULL;
......@@ -304,6 +307,7 @@ avtSAMRAIFileFormat::~avtSAMRAIFileFormat()
SAFE_DELETE(num_patches_level);
SAFE_DELETE(ratios_coarser_levels)
SAFE_DELETE(patch_extents);
SAFE_DELETE(patch_bdry_type);
if (var_extents != NULL) {
for(v=0; v<num_vars; v++) {
......@@ -712,6 +716,9 @@ avtSAMRAIFileFormat::GetMesh(int patch, const char *)
// Cyrus Harrison, Mon May 23 14:16:47 PDT 2011
// Added Nathan Masters' fix for ghost data w/ 'levels' and 'patches'.
//
// Mark C. Miller, Thu Sep 14 11:11:10 PDT 2017
// Add logic to support boundary ghosts vs. internal duplicate ghosts
// provided patch_bdry_type array is populated.
// ****************************************************************************
vtkDataSet *
avtSAMRAIFileFormat::ReadMesh(int patch)
......@@ -847,6 +854,8 @@ avtSAMRAIFileFormat::ReadMesh(int patch)
int nghost = 0;
int ncells = 1;
int i;
int const *bdry_type = patch_bdry_type ? &patch_bdry_type[patch*6] : 0;
for (i = 0; i < dim; i++)
ncells *= (dimensions[i]-1);
......@@ -854,10 +863,14 @@ avtSAMRAIFileFormat::ReadMesh(int patch)
ghostCells->SetName("avtGhostZones");
ghostCells->Allocate(ncells);
// fill in ghost value (0/1) for each cell
// fill in appropriate ghost value for each cell
unsigned char realVal=0, internalGhost=0, externalGhost=0;
avtGhostData::AddGhostZoneType(internalGhost, DUPLICATED_ZONE_INTERNAL_TO_PROBLEM);
avtGhostData::AddGhostZoneType(externalGhost, ZONE_EXTERIOR_TO_PROBLEM);
for (i = 0; i < ncells; i++)
{
bool in_ghost_layers = false;
unsigned char ghostVal;
// determine if cell is in ghost layers
int cell_idx = i;
......@@ -866,29 +879,50 @@ avtSAMRAIFileFormat::ReadMesh(int patch)
int nj = dimensions[j] - 1;
int jidx = cell_idx % nj;
if ((jidx < num_ghosts[j]) || (jidx >= nj - num_ghosts[j]))
if (jidx < num_ghosts[j])
{
in_ghost_layers = true;
break;
if (j == 0 && bdry_type && bdry_type[0]) { // xlo
ghostVal = externalGhost; break;
} else if (j == 1 && bdry_type && bdry_type[2]) { // ylo
ghostVal = externalGhost; break;
} else if (j == 2 && bdry_type && bdry_type[4]) { // zlo
ghostVal = externalGhost; break;
} else {
ghostVal = internalGhost; break;
}
}
else if (jidx >= nj - num_ghosts[j])
{
in_ghost_layers = true;
if (j == 0 && bdry_type && bdry_type[1]) { // xhi
ghostVal = externalGhost; break;
} else if (j == 1 && bdry_type && bdry_type[3]) { // yhi
ghostVal = externalGhost; break;
} else if (j == 2 && bdry_type && bdry_type[5]) { // zhi
ghostVal = externalGhost; break;
} else {
ghostVal = internalGhost; break;
}
}
cell_idx = cell_idx / nj;
}
if (in_ghost_layers)
{
unsigned char v = 0;
avtGhostData::AddGhostZoneType(v,
DUPLICATED_ZONE_INTERNAL_TO_PROBLEM);
ghostCells->InsertNextValue(v);
ghostCells->InsertNextValue(ghostVal);
nghost++;
}
else
ghostCells->InsertNextValue((unsigned char)0);
{
ghostCells->InsertNextValue(realVal);
}
}
// now, attach the ghost data to the grid
retval->GetCellData()->AddArray(ghostCells);
retval->GetInformation()->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
ghostCells->Delete();
debug5 << "avtSAMRAIFileFormat::ReadMesh ghosted " <<
......@@ -1006,7 +1040,7 @@ avtSAMRAIFileFormat::ReadVar(int patch,
{
debug5 << "avtSAMRAIFileFormat::ReadVar for variable " << visit_var_name
<< "on patch " << patch << endl;
<< " on patch " << patch << endl;
string var_name = visit_var_name;
......@@ -1074,7 +1108,7 @@ avtSAMRAIFileFormat::ReadVar(int patch,
}
if (num_alloc_comps == 0)
{
EXCEPTION2(UnexpectedValueException, "a value other than zero", num_alloc_comps);
EXCEPTION2(UnexpectedValueException, "a value greater than zero", num_alloc_comps);
}
// allocate VTK data array for this variable
......@@ -2584,6 +2618,8 @@ avtSAMRAIFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData *md)
blockPieceNames[i] = tmpName;
}
mesh->blockNames = blockPieceNames;
if (has_ghost && (grid_type == "ALE" || grid_type == "DEFORMED"))
mesh->containsExteriorBoundaryGhosts = true;
md->Add(mesh);
md->AddGroupInformation(num_levels, num_patches, groupIds);
......@@ -2842,6 +2878,7 @@ avtSAMRAIFileFormat::ReadMetaDataFile()
ReadVarExtents(h5_file);
ReadPatchExtents(h5_file);
ReadPatchBoundaryType(h5_file);
ReadPatchMap(h5_file);
ReadChildArrayLength(h5_file);
......@@ -2918,9 +2955,6 @@ avtSAMRAIFileFormat::ReadTime(hid_t &h5_file)
void
avtSAMRAIFileFormat::ReadAndCheckVDRVersion(hid_t &h5_file)
{
// cerr << "WARNING, SAMRAI VERSION CHECK DISABLED" << endl;
// return;
hid_t h5_dataset = H5Dopen(h5_file,"/BASIC_INFO/VDR_version_number");
if (h5_dataset < 0) {
char str[1024];
......@@ -3666,6 +3700,31 @@ avtSAMRAIFileFormat::ReadPatchExtents(hid_t &h5_file)
}
}
// ****************************************************************************
// Method: ReadPatchMap
//
// Purpose: Read information needed to handle boundary ghost vs internal
// dup ghost. Each patch has 6 ints for the kind of ghost along the patch's
// boundary for xlo,xhi,ylo,yhi,zlo,zhi. Always 6 no matter actual mesh
// dimension. non-zero indicates the ghost is a boundary. Otherwise its an
// internal dup. If data is available, it just leaves patch_bdry_type null.
//
// Mark C. Miller, Thu Sep 14 11:14:34 PDT 2017
//
// ****************************************************************************
void
avtSAMRAIFileFormat::ReadPatchBoundaryType(hid_t &h5_file)
{
hid_t h5_dataset = H5Dopen(h5_file, "/extents/bdry_type");
if (h5_dataset < 0)
return; // silently ignore if not available
patch_bdry_type = new int[num_patches*6];
H5Dread(h5_dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
patch_bdry_type);
H5Dclose(h5_dataset);
}
// ****************************************************************************
// Method: ReadPatchMap
......
......@@ -240,6 +240,7 @@ class avtSAMRAIFileFormat : public avtSTMDFileFormat
var_extents_t **var_extents;
patch_extents_t *patch_extents;
int *patch_bdry_type;
patch_map_t *patch_map;
int *child_array;
......@@ -299,6 +300,7 @@ class avtSAMRAIFileFormat : public avtSTMDFileFormat
void ReadVarExtents(hid_t &h5_file);
void ReadPatchExtents(hid_t &h5_file);
void ReadPatchBoundaryType(hid_t &h5_file);
void ReadPatchMap(hid_t &h5_file);
void ReadChildArrayLength(hid_t &h5_file);
......
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