Commit e2d2f7f3 authored by hrchilds's avatar hrchilds

Update from January 20, 2004

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@161 18c085ea-50e0-402c-830e-de6fd14e8384
parent 35013a0c
......@@ -10,11 +10,11 @@
<Field name="axisType" type="int">1</Field>
</Object>
<Object name="PluginManagerAttributes" childObjects="0">
<Field name="name" type="stringVector">Streamline </Field>
<Field name="type" type="stringVector">plot </Field>
<Field name="version" type="stringVector">1.0 </Field>
<Field name="id" type="stringVector">Streamline_1.0 </Field>
<Field name="enabled" type="intVector">0 </Field>
<Field name="name" type="stringVector">Streamline InverseGhostZone </Field>
<Field name="type" type="stringVector">plot operator </Field>
<Field name="version" type="stringVector">1.0 1.0 </Field>
<Field name="id" type="stringVector">Streamline_1.0 InverseGhostZone_1.0 </Field>
<Field name="enabled" type="intVector">0 0 </Field>
</Object>
<Object name="HostProfileList" childObjects="31">
<Object name="HostProfile" childObjects="0">
......
......@@ -10,11 +10,11 @@
<Field name="axisType" type="int">1</Field>
</Object>
<Object name="PluginManagerAttributes" childObjects="0">
<Field name="name" type="stringVector">Streamline </Field>
<Field name="type" type="stringVector">plot </Field>
<Field name="version" type="stringVector">1.0 </Field>
<Field name="id" type="stringVector">Streamline_1.0 </Field>
<Field name="enabled" type="intVector">0 </Field>
<Field name="name" type="stringVector">Streamline InverseGhostZone </Field>
<Field name="type" type="stringVector">plot operator </Field>
<Field name="version" type="stringVector">1.0 1.0 </Field>
<Field name="id" type="stringVector">Streamline_1.0 InverseGhostZone_1.0 </Field>
<Field name="enabled" type="intVector">0 0 </Field>
</Object>
<Object name="HostProfileList" childObjects="21">
<Object name="HostProfile" childObjects="0">
......
......@@ -20,6 +20,9 @@
# files. It also puts the core header files into a single include directory
# so you don't have to add tons of include directories in MSVC.
#
# Brad Whitlock, Thu Jan 8 11:15:13 PDT 2004
# I added BUILD_NOTES.txt.
#
#------------------------------------------------------------------------------
if(`pwd` != "/data_vobs/VisIt") then
......@@ -62,6 +65,7 @@ rm -rf $VISITSRC/include/visit
# Copy windowsbuild/VisItBuildInstructionsOnWindows.doc to $VisItDev
cp $TOPDIR/windowsbuild/VisItBuildInstructionsOnWindows.doc .
cp $TOPDIR/windowsbuild/BUILD_NOTES.txt .
# Move windowsbuild/include to $VisItDev/include.
cp -R $TOPDIR/windowsbuild/include .
......
......@@ -33,6 +33,7 @@
#include <avtCallback.h>
#include <avtDatabaseMetaData.h>
#include <avtDatasetCollection.h>
#include <avtDatasetVerifier.h>
#include <avtDomainBoundaries.h>
#include <avtDomainNesting.h>
#include <avtFileFormatInterface.h>
......@@ -230,6 +231,9 @@ avtGenericDatabase::SetDatabaseMetaData(avtDatabaseMetaData *md, int timeState)
// is difficult to do them in the opposite order (nesting must be on orig
// indices), but fairly straight-forward to do them in new order.
//
// Hank Childs, Fri Jan 9 13:46:43 PST 2004
// Use a dataset verifier before passing data into routines like the MIR.
//
// ****************************************************************************
avtDataTree_p
......@@ -262,6 +266,19 @@ avtGenericDatabase::GetOutput(avtDataSpecification_p spec,
//
ReadDataset(datasetCollection, domains, spec, src);
//
// Now that we have read things in from disk, verify that the dataset
// is valid, since routines like the MIR downstream will assume they are.
//
avtDatasetVerifier verifier;
vtkDataSet **ds_list = new vtkDataSet*[nDomains];
for (int i = 0 ; i < nDomains ; i++)
{
ds_list[i] = datasetCollection.GetDataset(i, 0);
}
verifier.VerifyDatasets(nDomains, ds_list, domains);
delete [] ds_list;
//
// Do species selection if appropriate.
//
......
......@@ -2395,17 +2395,15 @@ avtStructuredDomainBoundaries::SetIndicesForRectGrid(int domain, int e[6])
// Added code to disallow operation if shouldComputeNeighborsFromExtents is
// not true.
//
// Kathleen Bonnell, Tue Jan 20 17:26:40 PST 2004
// Reversed order of Exceptions, per Mark Miller's request.
//
// ****************************************************************************
void
avtStructuredDomainBoundaries::SetIndicesForAMRPatch(int domain,
int level, int e[6])
{
if (domain >= levels.size())
EXCEPTION1(VisItException,
"avtStructuredDomainBoundaries: "
"targetted domain more than number of domains");
if (!shouldComputeNeighborsFromExtents)
{
EXCEPTION1(VisItException,
......@@ -2414,6 +2412,12 @@ avtStructuredDomainBoundaries::SetIndicesForAMRPatch(int domain,
"computation of neighbors from index extents");
}
if (domain >= levels.size())
EXCEPTION1(VisItException,
"avtStructuredDomainBoundaries: "
"targetted domain more than number of domains");
levels[domain] = level;
extents[6*domain+0] = e[0];
extents[6*domain+1] = e[1];
......
#include <avtStructuredDomainNesting.h>
#include <BadIndexException.h>
#include <UnexpectedValueException.h>
#include <VisItException.h>
#include <vtkCellData.h>
#include <vtkFloatArray.h>
#include <vtkIntArray.h>
#include <vtkStructuredGrid.h>
#define MAX_GHOST_LAYERS 2
#define NESTING_GHOST_MASK 0x01
// ****************************************************************************
// Destructor: avtStructuredDomainNesting::Destruct
//
// Programmer: Hank Childs
// Creation: September 25, 2002
// Programmer: Mark C. Miller
// Creation: October 13, 2003
//
// Modifications:
//
......@@ -24,6 +29,136 @@ avtStructuredDomainNesting::Destruct(void *p)
delete sdn;
}
// ****************************************************************************
// Function: DetectBoundaryGhostLayers
//
// Purpose: Detects number of ghost layers in each dimension given
// knowledge of the dimension, non-ghosted size of the patch in each
// dimension and the pre-existing vtkGhostLevels data
//
// To perform the detection, basically we try all reasonable combinations
// of ghost layers and probe the ghostData array around the extreme high
// and low ijk corners of the patch to see if we get something thats
// consistent. The loop looks daunting but it completes very quickly.
//
// Programmer: Mark C. Miller
// Creation: January 8, 2004
//
// ****************************************************************************
void
DetectBoundaryGhostLayers(int numDims, unsigned char *ghostData, int numCells,
vector<int> extents, int *ghostLayers)
{
int Ni = 0, Nj = 0, Nk = 0;
// compute size of NON-ghosted patch
switch (numDims) // note: exploits fall-through
{
case 3: Nk = extents[5] - extents[2] + 1;
case 2: Nj = extents[4] - extents[1] + 1;
case 1: Ni = extents[3] - extents[0] + 1;
}
// vector to populate with valid ghost cases
vector<int> ghostCases;
// loop over all possible combinations of ghost layer widths
int gi, gj, gk;
for (gi = 0; gi <= (Ni==0 ? 0 : MAX_GHOST_LAYERS); gi++)
{
for (gj = 0; gj <= (Nj==0 ? 0 : MAX_GHOST_LAYERS); gj++)
{
for (gk = 0; gk <= (Nk==0 ? 0 : MAX_GHOST_LAYERS); gk++)
{
// we always skip the all 0 case
if ((gi == 0) && (gj == 0) && (gk == 0))
continue;
// compute size of ghosted patch given this layering
int Mk = Nk + 2 * gk;
int Mj = Nj + 2 * gj;
int Mi = Ni + 2 * gi;
// can ignore this case immediately if it doesn't equate the
// the number of cells we know the ghost data has
if (Mk * Mj * Mi != numCells)
continue;
// probe ghost data array round 2 extreme corners
int mult;
bool impossibleGhostCase = false;
for (mult = -1; (mult <= 1) && !impossibleGhostCase; mult += 2)
{
int i0, j0, k0;
// set which corner to look at
if (mult == -1)
{
// the extreme lowest corner
// in the
i0 = 0 + gi;
j0 = 0 + gj;
k0 = 0 + gk;
}
else
{
// the extreme highest corner
i0 = Ni - 1 + gi;
j0 = Nj - 1 + gj;
k0 = Nk - 1 + gk;
}
// examine all cells around the corner for ghost values
int i,j,k;
for (i = 0; (i <= gi) && !impossibleGhostCase; i++)
{
for (j = 0; (j <= gj) && !impossibleGhostCase; j++)
{
for (k = 0; (k <= gk) && !impossibleGhostCase; k++)
{
// we always skip the all 0 case
if ((i == 0) && (j == 0) && (k == 0))
continue;
// compute index within ghosted patch
int a = i0 + i * mult;
int b = j0 + j * mult;
int c = k0 + k * mult;
int idx = c*Mi*Mj + b*Mi + a;
if ((idx < 0) || (idx >= numCells) ||
(ghostData[idx] == 0))
{
impossibleGhostCase = true;
}
}
}
}
}
if (!impossibleGhostCase)
{
ghostCases.push_back(gi);
ghostCases.push_back(gj);
ghostCases.push_back(gk);
}
}
}
}
if (ghostCases.size() != 3)
{
EXCEPTION2(UnexpectedValueException, 3, ghostCases.size());
}
ghostLayers[0] = ghostCases[0];
ghostLayers[1] = ghostCases[1];
ghostLayers[2] = ghostCases[2];
}
// ****************************************************************************
// Method: avtStructuredDomainNesting::ApplyGhost
//
......@@ -38,6 +173,15 @@ avtStructuredDomainNesting::Destruct(void *p)
// Hank Childs, Tue Nov 18 22:56:02 PST 2003
// Clean up memory leak.
//
// Mark C. Miller, Thu Jan 8 10:08:18 PST 2004
// Modified to account for fact that incomming meshes may already have ghost
// zones from the file AND to accomodate possible avariation in number of
// ghost layers for different variables (SAMRAI does this). Also, I modifed
// it so that it will or the NESTING_GHOST_MASK value into the ghost data
// array. That way, when we go to using a bitfield for vtkGhostLevels, it can
// be easily modified to set the right bit. I also replaced cerr statements
// with bonified exceptions.
//
// ****************************************************************************
bool
avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
......@@ -49,14 +193,37 @@ avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
for (int i = 0; i < domainList.size(); i++)
{
int parentDom = domainList[i];
unsigned char *ghostData = 0;
vtkUnsignedCharArray *ghostArray = vtkUnsignedCharArray::SafeDownCast(
meshes[i]->GetCellData()->GetArray("vtkGhostLevels"));
vtkUnsignedCharArray *ghostArray = vtkUnsignedCharArray::New();
int parentDom = domainList[i];
int numCells = meshes[i]->GetNumberOfCells();
ghostArray->SetNumberOfTuples(numCells);
bool parentHasBoundaryGhosts = (ghostArray != 0);
int ghostLayers[3] = {0, 0, 0};
if (parentHasBoundaryGhosts)
{
ghostData = (unsigned char *) ghostArray->GetVoidPointer(0);
unsigned char *ghostData = (unsigned char *) ghostArray->GetVoidPointer(0);
memset(ghostData, 0x0, numCells);
//
// because number of ghost layers may vary from one variable to the next,
// we have a strange problem here in that we know we have ghost layers but
// don't know precisely how many in each dimension. So, we detect it from
// knowledge of the non-ghosted size (in the nesting info's logical extents
// of the parent) of the patch and the actual ghost data array
//
DetectBoundaryGhostLayers(numDimensions, ghostData, numCells,
domainNesting[parentDom].logicalExtents, ghostLayers);
}
else
{
ghostArray = vtkUnsignedCharArray::New();
ghostArray->SetNumberOfTuples(numCells);
ghostData = (unsigned char *) ghostArray->GetVoidPointer(0);
memset(ghostData, 0x0, numCells);
}
//
// Look at each of the children of this domain.
......@@ -81,11 +248,14 @@ avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
int childDom = domainNesting[parentDom].childDomains[j];
int childLevel = domainNesting[childDom].level;
int Ni = domainNesting[parentDom].logicalExtents[3] -
domainNesting[parentDom].logicalExtents[0] + 1;
domainNesting[parentDom].logicalExtents[0] +
1 + 2 * ghostLayers[0];
int Nj = domainNesting[parentDom].logicalExtents[4] -
domainNesting[parentDom].logicalExtents[1] + 1;
domainNesting[parentDom].logicalExtents[1] +
1 + 2 * ghostLayers[1];
int Nk = domainNesting[parentDom].logicalExtents[5] -
domainNesting[parentDom].logicalExtents[2] + 1;
domainNesting[parentDom].logicalExtents[2] +
1 + 2 * ghostLayers[2];
int I0 = domainNesting[parentDom].logicalExtents[0];
int I1 = domainNesting[parentDom].logicalExtents[3] + 1;
int J0 = domainNesting[parentDom].logicalExtents[1];
......@@ -104,7 +274,7 @@ avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
//
// Often a child domain spans multiple parents. So, we need to
// clip the bounds computed above to the parent's upper bounds
// clip the bounds computed above to THIS parent's upper bounds
//
if (i1 > I1) i1 = I1;
if (j1 > J1) j1 = J1;
......@@ -121,26 +291,17 @@ avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
for (int jj = j0; jj < j1; jj++)
for (int kk = k0; kk < k1; kk++)
{
int a = ii - I0;
int b = jj - J0;
int c = kk - K0;
if ((c*Ni*Nj + b*Ni + a >= numCells) ||
(c*Ni*Nj + b*Ni + a < 0))
int a = ii - I0 + ghostLayers[0];
int b = jj - J0 + ghostLayers[1];
int c = kk - K0 + ghostLayers[2];
int idx = c*Ni*Nj + b*Ni + a;
if ((idx >= numCells) || (idx < 0))
{
cerr << "bad index value in avtStructuredDomainNesting "
<< c << ", " << b << ", " << a << endl;
cerr << "parent = " << i << ", child = " << childDom << endl;
cerr << "I0 = " << I0 << ", I1 = " << I1 << endl;
cerr << "i0 = " << i0 << ", i1 = " << i1 << endl;
cerr << "J0 = " << J0 << ", J1 = " << J1 << endl;
cerr << "j0 = " << j0 << ", j1 = " << j1 << endl;
cerr << "K0 = " << K0 << ", K1 = " << K1 << endl;
cerr << "k0 = " << k0 << ", k1 = " << k1 << endl;
cerr << "numCells = " << numCells << ", index = " << c*Ni*Nj + b*Ni + a << endl;
EXCEPTION2(BadIndexException,idx,numCells);
}
else
{
ghostData[c*Ni*Nj + b*Ni + a] = 0x1;
ghostData[idx] |= NESTING_GHOST_MASK;
}
}
}
......@@ -149,17 +310,16 @@ avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
for (int ii = i0; ii < i1; ii++)
for (int jj = j0; jj < j1; jj++)
{
int a = ii - I0;
int b = jj - J0;
if ((b*Ni + a >= numCells) ||
(b*Ni + a < 0))
int a = ii - I0 + ghostLayers[0];
int b = jj - J0 + ghostLayers[1];
int idx = b*Ni + a;
if ((idx >= numCells) || (idx < 0))
{
cerr << "bad index value in avtStructuredDomainNesting "
<< b << ", " << a << endl;
EXCEPTION2(BadIndexException,idx,numCells);
}
else
{
ghostData[b*Ni + a] = 0x1;
ghostData[idx] |= NESTING_GHOST_MASK;
}
}
}
......@@ -167,25 +327,27 @@ avtStructuredDomainNesting::ApplyGhost(vector<int> domainList,
{
for (int ii = i0; ii < i1; ii++)
{
int a = ii - I0;
int a = ii - I0 + ghostLayers[0];
if ((a >= numCells) ||
(a < 0))
{
cerr << "bad index value in avtStructuredDomainNesting "
<< a << endl;
EXCEPTION2(BadIndexException,a,numCells);
}
else
{
ghostData[a] = 0x1;
ghostData[a] |= NESTING_GHOST_MASK;
}
}
}
}
}
ghostArray->SetName("vtkGhostLevels");
meshes[i]->GetCellData()->AddArray(ghostArray);
ghostArray->Delete();
if (!parentHasBoundaryGhosts)
{
ghostArray->SetName("vtkGhostLevels");
meshes[i]->GetCellData()->AddArray(ghostArray);
ghostArray->Delete();
}
}
return didGhost;
......
......@@ -1305,6 +1305,38 @@ avtDataTree::GetAllLabels(vector<string> &labels)
}
}
// ****************************************************************************
// Method: avtDataTree::GetAllDomainIds
//
// Purpose:
// Recursive method to retrieve domain ids.
//
// Arguments:
// doms A place to store the retrieved domains.
//
// Programmer: Hank Childs
// Creation: January 9, 2004
//
// ****************************************************************************
void
avtDataTree::GetAllDomainIds(vector<int> &doms)
{
if (nChildren > 0)
{
for (int i = 0; i < nChildren; i++)
{
if (*children[i] != NULL)
children[i]->GetAllDomainIds(doms);
}
}
else if (dataRep != NULL)
{
doms.push_back(dataRep->GetDomain());
}
}
// ****************************************************************************
// Method: avtDataTree::IsEmpty
//
......
......@@ -4,6 +4,7 @@
#ifndef AVT_DATA_TREE_H
#define AVT_DATA_TREE_H
#include <pipeline_exports.h>
#include <vector>
......@@ -72,6 +73,9 @@ typedef void (*TraverseFunc)(avtDataRepresentation &, void *, bool &);
// Kathleen Bonnell, Mon Apr 29 17:49:25 PDT 2002
// Added GetAllUniqueLabels and GetUniqueLabels.
//
// Hank Childs, Fri Jan 9 10:04:22 PST 2004
// Added GetAllDomainIds.
//
// ****************************************************************************
class PIPELINE_API avtDataTree
......@@ -113,6 +117,7 @@ class PIPELINE_API avtDataTree
void Traverse(TraverseFunc, void *, bool &);
vtkDataSet **GetAllLeaves(int &);
void GetAllDomainIds(vector<int> &);
void GetAllLabels(vector<string> &);
void GetAllUniqueLabels(vector<string> &);
avtDataTree_p PruneTree(const vector<int> &);
......
......@@ -8,9 +8,12 @@
#include <vtkDataSet.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkUnsignedCharArray.h>
#include <avtCallback.h>
#include <DebugStream.h>
// ****************************************************************************
// Method: avtDatasetVerifier constructor
......@@ -27,32 +30,39 @@ avtDatasetVerifier::avtDatasetVerifier()
// ****************************************************************************
// Method: avtDatasetVerifier::VerifyDataTree
// Method: avtDatasetVerifier::VerifyDatasets
//
// Purpose:
// Verifies that every VTK dataset in the tree is valid (like the number
// Verifies that every VTK dataset in the list is valid (like the number
// of elements in the variable makes sense for the mesh, etc).
//
// Arguments:
// tree The tree to verify.
// nlist The number of elements in the list.
// list The list of datasets.
// domains The domain number of each dataset.
//
// Programmer: Hank Childs
// Creation: October 18, 2001
//
// Modifications:
//
// Hank Childs, Fri Jan 9 09:40:32 PST 2004
// Renamed function and added arguments; made routine easily usable by
// the database as well the terminating dataset source.
//
// ****************************************************************************
void
avtDatasetVerifier::VerifyDataTree(avtDataTree_p &tree)
avtDatasetVerifier::VerifyDatasets(int nlist, vtkDataSet **list,
std::vector<int> &domains)
{
int nLeaves;
vtkDataSet **ds = tree->GetAllLeaves(nLeaves);
for (int i = 0 ; i < nLeaves ; i++)
for (int i = 0 ; i < nlist ; i++)
{
VerifyDataset(ds[i]);
if (list[i] != NULL)
{
VerifyDataset(list[i], domains[i]);
}
}
delete [] ds;
}
......@@ -64,42 +74,73 @@ avtDatasetVerifier::VerifyDataTree(avtDataTree_p &tree)
//
// Arguments:
// ds A single vtk dataset.
// dom The domain number.
//
// Programmer: Hank Childs
// Creation: October 18, 2001
//
// Modifications:
//
// Kathleen Bonnell, Fri Feb 8 11:03:49 PST 2002
// vtkScalars has been deprecated in VTK 4.0, use vtkDataArray instead.
//
// Hank Childs, Fri Jan 9 09:43:13 PST 2004
// Iterate over all variables. Added an argument for the domain number.
// Also do not issue a warning if the missing values are for ghost zones.
//
// ****************************************************************************
void
avtDatasetVerifier::VerifyDataset(vtkDataSet *ds)
avtDatasetVerifier::VerifyDataset(vtkDataSet *ds, int dom)
{
int i, j;
int nPts = ds->GetNumberOfPoints();
int nCells = ds->GetNumberOfCells();
vtkDataArray *pt_var = ds->GetPointData()->GetScalars();
vtkDataArray *cell_var = ds->GetCellData()->GetScalars();
if (pt_var != NULL)
int nPtVars = ds->GetPointData()->GetNumberOfArrays();
for (i = 0 ; i < nPtVars ; i++)
{
int nScalars = pt_var->GetNumberOfTuples();
if (nScalars != nPts)
vtkDataArray *pt_var = ds->GetPointData()->GetArray(i);
int nscalars = pt_var->GetNumberOfTuples();
if (nscalars != nPts)
{
CorrectVarMismatch(ds, pt_var, true);
IssueVarMismatchWarning(nScalars, nPts, true);
IssueVarMismatchWarning(nscalars, nPts, true, dom);
}
}
if (cell_var != NULL)
int nCellVars = ds->GetCellData()->GetNumberOfArrays();
for (i = 0 ; i < nCellVars ; i++)
{
int nScalars = cell_var->GetNumberOfTuples();
if (nScalars != nCells)
vtkDataArray *cell_var = ds->GetCellData()->GetArray(i);
int nscalars = cell_var->GetNumberOfTuples();
if (nscalars != nCells)
{
CorrectVarMismatch(ds, cell_var, false);
IssueVarMismatchWarning(nScalars, nCells, false);
bool issueWarning = true;
vtkUnsignedCharArray *gz = (vtkUnsignedCharArray *)
ds->GetCellData()->GetArray("vtkGhostLevels");
if (gz != NULL)
{
int ntuples = gz->GetNumberOfTuples();
int num_real = 0;
for (j = 0 ; j < ntuples ; j++)
{
if (gz->GetValue(j) == '\0')
num_real++;
}
if (num_real == nscalars)
{
issueWarning = false;
debug1 << "The input file has an invalid number of "
<< "entries in a zonal variable. Since the number"
<< " of entries corresponds to the number of real "
<< "zones, no warning is being issued." << endl;
}
}
if (issueWarning)
IssueVarMismatchWarning(nscalars, nCells, false, dom);
}
}
}
......@@ -115,6 +156,7 @@ avtDatasetVerifier::VerifyDataset(vtkDataSet *ds)
// nVars The number of values we got.
// nUnits The number we should have gotten.
// isPoint true if it is a ptvar, false otherwise.
// dom The domain number.
//
// Programmer: Hank Childs
// Creation: October 18, 2001
......@@ -124,10 +166,14 @@ avtDatasetVerifier::VerifyDataset(vtkDataSet *ds)
// Hank Childs, Tue Dec 16 10:02:10 PST 2003
// Improve clarity of warning.
//