Commit b7659d53 authored by ghweber's avatar ghweber
Browse files

Removed obsolete file.

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@12388 18c085ea-50e0-402c-830e-de6fd14e8384
parent 87f486e9
/*****************************************************************************
*
* Copyright (c) 2000 - 2010, Lawrence Livermore National Security, LLC
* Produced at the Lawrence Livermore National Laboratory
* LLNL-CODE-400124
* All rights reserved.
*
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the disclaimer (as noted below) in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/
// ************************************************************************* //
// File: avtAMRStitchCellFilter.C
// ************************************************************************* //
//#define ENABLE_UNGHOST_CELL_OPTIMIZATION
#include <avtAMRStitchCellFilter.h>
#include <DebugStream.h>
#include <avtDataTree.h>
#include <avtGhostData.h>
#include <avtIntervalTree.h>
#include <avtMetaData.h>
#include <avtStructuredDomainBoundaries.h>
#include <avtStructuredDomainNesting.h>
#include <vtkCellData.h>
#include <vtkCellType.h>
#include <vtkFieldData.h>
#include <vtkFloatArray.h>
#include <vtkIntArray.h>
#include <vtkObjectFactory.h>
#include <vtkPoints.h>
#include <vtkPointData.h>
#include <vtkRectilinearGrid.h>
#include <vtkUnsignedCharArray.h>
#include <vtkUnstructuredGrid.h>
// ****************************************************************************
// Method: avtAMRStitchCellFilter constructor
//
// Programmer: ghweber -- generated by xml2avt
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// ****************************************************************************
avtAMRStitchCellFilter::avtAMRStitchCellFilter()
{
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter destructor
//
// Programmer: ghweber -- generated by xml2avt
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// Modifications:
//
// ****************************************************************************
avtAMRStitchCellFilter::~avtAMRStitchCellFilter()
{
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::Create
//
// Programmer: ghweber -- generated by xml2avt
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// ****************************************************************************
avtFilter *
avtAMRStitchCellFilter::Create()
{
return new avtAMRStitchCellFilter();
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::SetAtts
//
// Purpose:
// Sets the state of the filter based on the attribute object.
//
// Arguments:
// a The attributes to use.
//
// Programmer: ghweber -- generated by xml2avt
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// ****************************************************************************
void
avtAMRStitchCellFilter::SetAtts(const AttributeGroup *a)
{
atts = *(const AMRStitchCellAttributes*)a;
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::Equivalent
//
// Purpose:
// Returns true if creating a new avtAMRStitchCellFilter with the given
// parameters would result in an equivalent avtAMRStitchCellFilter.
//
// Programmer: ghweber -- generated by xml2avt
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// ****************************************************************************
bool
avtAMRStitchCellFilter::Equivalent(const AttributeGroup *a)
{
return (atts == *(AMRStitchCellAttributes*)a);
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::ModifyContract
//
// Purpose:
// Request creation of ghost zones
//
// Arguments:
// in_contract The input contract.
//
// Programmer: Hank Childs
// Creation: June 6, 2001
//
// Modifications:
//
// ****************************************************************************
avtContract_p
avtAMRStitchCellFilter::ModifyContract(avtContract_p in_contract)
{
avtContract_p contract = new avtContract(in_contract);
// FIXME: Ensure that data is node centered
contract->GetDataRequest()->SetDesiredGhostDataType(GHOST_ZONE_DATA);
return contract;
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::PreExecute
//
// Purpose:
// Compute extents to obtain origin of all boxes/patches.
//
// Programmer: Gunther H. Weber
// Creation: August 5, 2010
//
// Modifications:
//
// ****************************************************************************
void
avtAMRStitchCellFilter::PreExecute(void)
{
// Get dimension of data set
avtDataAttributes &inAtts = GetInput()->GetInfo().GetAttributes();
topologicalDimension = inAtts.GetTopologicalDimension();
if (topologicalDimension < 2 || topologicalDimension > 3)
EXCEPTION1(ImproperUseException,
"Need 2D or 3D data set to generate dual mesh and stitch cells.");
// Obtian data set origin via spatial extents
avtIntervalTree *iTree = GetMetaData()->GetSpatialExtents();
if (!iTree)
EXCEPTION1(ImproperUseException,
"Cannot determine spatial extents of data set.");
iTree->GetExtents(domainBoundingBox);
// Set domainOrigin
for (int i=0; i<topologicalDimension; ++i)
domainOrigin[i] = domainBoundingBox[2*i];
for (int i=topologicalDimension; i<3; ++i)
domainOrigin[i] = 0.0;
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::ExecuteDataTree
//
// Purpose:
// Create dual grid and stitch cell data sets and add them to a data tree
//
// Arguments:
// in_ds The input dataset.
// domain The domain number.
// <unused> The label.
//
// Returns: The output dataset.
//
// Programmer: Gunther H. Weber
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// ****************************************************************************
avtDataTree_p
avtAMRStitchCellFilter::ExecuteDataTree(vtkDataSet *in_ds, int domain, string str)
{
vtkRectilinearGrid *rgrid = dynamic_cast<vtkRectilinearGrid*>(in_ds);
if (!rgrid)
EXCEPTION1(ImproperUseException,
"Can only create dual mesh and stitch cells for a rectilinear grid.");
// Dimensions of data set
int dims[3];
rgrid->GetDimensions(dims);
// We want number of cells as grid dimension, not number of cells
for (int d=0; d<topologicalDimension; ++d)
dims[d]--;
debug5 << "avtAMRStitchCellFilter::ExecuteDataTree(): Grid is regular and has ";
debug5 << "extents " << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
// Get base_index (measured in number of cells of current level (i.e.,
// same level as patch) form origin)
vtkIntArray *baseIdxArray =
(vtkIntArray*) rgrid->GetFieldData()->GetArray("base_index");
if (!baseIdxArray)
EXCEPTION1(ImproperUseException,
"Need base_index data to generate dual mesh and stitch cells.");
int baseIdx[3];
for (int d = 0; d < topologicalDimension; ++d)
baseIdx[d] = baseIdxArray->GetValue(d);
for (int d = topologicalDimension; d < 3; ++d)
baseIdx[d] =0;
debug5 << "avtAMRStitchCellFilter::ExecuteData Tree(): base_index is ";
debug5 << baseIdx[0] << ", " << baseIdx[1] << ", " << baseIdx[2] << std::endl;
// Consistency check: layer of ghost cells needs to have a width of one
vtkIntArray *realDimsArray =
dynamic_cast<vtkIntArray*>(rgrid->GetFieldData()->GetArray("avtRealDims"));
if (!realDimsArray)
EXCEPTION1(ImproperUseException, "Need avtRealDims to generate stitch cells.");
int realIMin = realDimsArray->GetValue(0);
int realIMax = realDimsArray->GetValue(1);
int realJMin = realDimsArray->GetValue(2);
int realJMax = realDimsArray->GetValue(3);
debug5 << "avtAMRStitchCellFilter::CreateStitchCells2D(): Real dims are ";
debug5 << realIMin << " " << realIMax << " " << realJMin << " " << realJMax << std::endl;
if (realIMin != 1 || dims[0] - realIMax != 1 ||
realJMin != 1 || dims[1] - realJMax != 1)
{
EXCEPTION1(ImproperUseException,
"Need exactly one layer of ghost cells to create stitch cells.");
}
if (topologicalDimension == 3)
{
int realKMin = realDimsArray->GetValue(4);
int realKMax = realDimsArray->GetValue(5);
if (realKMin != ! 1 || dims[2] - realKMax != 1)
{
EXCEPTION1(ImproperUseException,
"Need exactly one layer of ghost cells to create stitch cells.");
}
}
// We need structured domain nesting to figure out extents of neighboring
// boxes/patches, our level and our refinement ratio wrt. to the parent level
avtStructuredDomainNesting *sdn =
dynamic_cast<avtStructuredDomainNesting*>(GetMetaData()->GetDomainNesting());
if (!sdn)
EXCEPTION1(ImproperUseException,
"Need structured domain nesting information to compute dual "
"mesh and stitch cells.");
vtkIdType *refinedInSameLevelDomain;
if (topologicalDimension == 2)
{
refinedInSameLevelDomain = new vtkIdType[dims[0]*dims[1]]; // FIXME: More memory efficient storage
for (int i=0; i < dims[0]*dims[1]; ++i)
{
// Fill with pre-set value of -1 to mark cells without neighboring grid
refinedInSameLevelDomain[i] = -1;
}
// Initialize refineInDameLevelId array -> For all ghost cells surrounding the grid,
// this array contains -1 if that cell does not have a neighboring grid in the same
// level. If there is a neighboring grid in the same level, this array contains the
// domain number of that grid.
avtStructuredDomainBoundaries *db =
dynamic_cast<avtStructuredDomainBoundaries*>(GetMetaData()->GetDomainBoundaries());
if (!db)
EXCEPTION1(ImproperUseException, "Need structured domain boundaries to compute stitch cells.");
std::vector<Neighbor> neighbors = db->GetNeighbors(domain);
std::vector<int> le;
for (std::vector<Neighbor>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
{
switch(it->type)
{
case Boundary::IMIN:
le = sdn->GetDomainLogicalExtents(it->domain);
for (int j=std::max(0, le[1]-baseIdx[1]+1); j<std::min(dims[1], le[4]-baseIdx[1]+2); ++j)
refinedInSameLevelDomain[j*dims[0]] = it->domain;
break;
case Boundary::IMAX:
le = sdn->GetDomainLogicalExtents(it->domain);
for (int j=std::max(0, le[1]-baseIdx[1]+1); j<std::min(dims[1], le[4]-baseIdx[1]+2); ++j)
refinedInSameLevelDomain[j*dims[0]+dims[0]-1] = it->domain;
break;
case Boundary::JMIN:
le = sdn->GetDomainLogicalExtents(it->domain);
for (int i=std::max(0, le[0]-baseIdx[0]+1); i<std::min(dims[0], le[3]-baseIdx[0]+2); ++i)
refinedInSameLevelDomain[i] = it->domain;
break;
case Boundary::JMAX:
le = sdn->GetDomainLogicalExtents(it->domain);
for (int i=std::max(0, le[0]-baseIdx[0]+1); i<std::min(dims[0], le[3]-baseIdx[0]+2); ++i)
refinedInSameLevelDomain[(dims[1]-1)*dims[0]+i] = it->domain;
break;
case Boundary::IMIN | Boundary::JMIN:
refinedInSameLevelDomain[0] = it->domain;
break;
case Boundary::IMIN | Boundary::JMAX:
refinedInSameLevelDomain[(dims[1]-1)*dims[0]] = it->domain;
break;
case Boundary::IMAX | Boundary::JMIN:
refinedInSameLevelDomain[dims[0]-1] = it->domain;
break;
case Boundary::IMAX | Boundary::JMAX:
refinedInSameLevelDomain[(dims[1]-1)*dims[0]+dims[0]-1] = it->domain;
break;
default:
EXCEPTION1(ImproperUseException, "Encountered invalid boundary.");
}
}
}
else
{
EXCEPTION1(VisItException, "3D case not implemented, yet.");
}
vtkDataSet *out_ds[2];
// FIXME:out_ds[0] = CreateDualGrid(rgrid, domain, dims, refinedInSameLevelDomain);
// Obtain level
int level = sdn->GetDomainLevel(domain);
debug5 << "avtAMRStitchCellFilter::ExecuteDataTree(): Patch is in level ";
debug5 << level << std::endl;
std::cout << std::endl;
std::cout << "********************************************************************************" << std::endl;
std::cout << "Handling patch " << domain << " level " << level << " baseIdx " << baseIdx[0] << " " << baseIdx[1] << std::endl;
out_ds[0] = CreateDualGrid(rgrid, domain, dims, refinedInSameLevelDomain);
if (level != 0)
{
// We are not in the root level and thus need to generate stich cells.
// Obtain refinement ratio wrt. to parent level needed to translate indices
// between levels.
std::vector<int> refinementRatio = sdn->GetRatiosForLevel(level-1, domain);
debug5 << "avtAMRStitchCellFilter::ExecuteDataTree(): Refinement ratio ";
debug5<< " wrt. parent level is " << refinementRatio[0] << " ";
debug5 << refinementRatio[1] << std::endl;
// Consitency check, patch must start at the boundaries of a coarse level cell
if ((baseIdx[0] % refinementRatio[0]) || (baseIdx[1] % refinementRatio[1]))
EXCEPTION1(ImproperUseException,
"base_index must be divisible by refinement_ratio, i.e. "
"fine box/patch must start at coarse cell boundaries.");
out_ds[1] = CreateStitchCells2D(rgrid, domain, level, dims,
baseIdx, refinementRatio, refinedInSameLevelDomain);
}
else
{
// We are in the root level. There is no lower level to connect to.
// Connection to boxes/patches in the same level is handled by CreateDualGrid
out_ds[1] = 0;
debug5 << "Skipping stitch cell generation for patch in root level.";
debug5 << std::endl;
}
// Clean-up no longer needed information
delete[] refinedInSameLevelDomain;
// Create data tree
avtDataTree_p rv = new avtDataTree(2, out_ds, domain, str);
// Clean-up intermediate results
for (int dsNo=0; dsNo<2; ++dsNo)
if (out_ds[dsNo]) out_ds[dsNo]->Delete();
// Return result
return rv;
}
// ****************************************************************************
// Method: avtAMRStitchCellFilter::CreateStitchCells2D
//
// Purpose:
// Create stitch cells connecting the dual grid to its surroundings
//
// Arguments:
// in_ds The input dataset.
// domain The domain number.
//
// Returns: The output dataset.
//
// Programmer: Gunther H. Weber
// Creation: Thu Jul 8 15:14:01 PST 2010
//
// ****************************************************************************
vtkDataSet *
avtAMRStitchCellFilter::CreateStitchCells2D(vtkRectilinearGrid *rgrid,
int domain, int level, int dims[3], int baseIdx[3],
const vector<int> &refinementRatio,
const vtkIdType* refinedInSameLevelDomain)
{
// Compute cell size for current level
// NOTE: This step assumes constant spacing within a patch
// FIXME: Curvilinear grid? Varying cell spacing?
double cellSize[3];
if (rgrid->GetXCoordinates()->GetNumberOfTuples() > 0)
cellSize[0] = rgrid->GetXCoordinates()->GetTuple1(1) -
rgrid->GetXCoordinates()->GetTuple1(0);
else
EXCEPTION1(ImproperUseException,
"Data set must have at least two X coordinates.");
if (rgrid->GetYCoordinates()->GetNumberOfTuples() > 0)
cellSize[1] = rgrid->GetYCoordinates()->GetTuple1(1) -
rgrid->GetYCoordinates()->GetTuple1(0);
else
EXCEPTION1(ImproperUseException,
"Data set must have at least two Y coordinates.");
if (topologicalDimension == 3)
{
if (rgrid->GetZCoordinates()->GetNumberOfTuples() > 0)
cellSize[2] = rgrid->GetZCoordinates()->GetTuple1(1) -
rgrid->GetZCoordinates()->GetTuple1(0);
else
EXCEPTION1(ImproperUseException,
"Data set must have at least two Z coordinates.");
}
else
cellSize[2] = 0.0;
debug5 << "avtAMRStitchCellFilter::CreateStitchCells2D(): Cell size is ";
debug5 << cellSize[0] << " " << cellSize[1] << " " << cellSize[2] << std::endl;
// Parent cell size is current cell size multiploed by refinement ratio
double parentCellSize[3];
for (int d = 0; d < topologicalDimension; ++d)
parentCellSize[d] = refinementRatio[d] * cellSize[d];
for (int d = topologicalDimension; d < 3; ++ d)
parentCellSize[d] = 0.0;
// Data structures for stitch cells
vtkPoints *stitchCellPts = vtkPoints::New();
// FIXME: Multiple scalars, vectors, tensors etc.
vtkDataArray *inputData = rgrid->GetCellData()->GetScalars();
vtkDataArray *outputData = 0;
if (inputData)
{
//outputData = (vtkDataArray*)vtkObjectFactory::CreateInstance(inputData->GetClassName());
// FIXME: Make depedent on input type
outputData = vtkFloatArray::New();
outputData->SetName(inputData->GetName());
}
vtkUnstructuredGrid *stitchCellGrid = vtkUnstructuredGrid::New();
vtkUnsignedCharArray *inputGhostZones =
(vtkUnsignedCharArray *) rgrid->GetCellData()->GetArray("avtGhostZones");
vtkIdType *pointIds = new vtkIdType[dims[0]*dims[1]]; // FIXME: More memory efficient storage
for (int i=0; i < dims[0]*dims[1]; ++i)
{
// Fill with specified invalid value for debugging purposes
pointIds[i] = -2;
}
/*
std::cout << "VisIt ghost information:" << std::endl;
for (int i=0; i<dims[0]*dims[1]; ++i)
{
std::cout << std::setw(4) << int(inputGhostZones->GetValue(i));
if (i%dims[0]==dims[0]-1) std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "IDs of neighboring domains:" << std::endl;
for (int i=0; i<dims[0]*dims[1]; ++i)
{
std::cout << std::setw(3) << refinedInSameLevelDomain[i];
if (i%dims[0]==dims[0]-1) std::cout << std::endl; else std::cout << " ";;
}
std::cout << std::endl;
*/
#ifdef LOC
#undef LOC
#endif
#define LOC(i,j) ((j+1)*dims[0]+(i+1))
for (int j=-1; j<dims[1]-1; ++j)
for (int i=-1; i<dims[0]-1; i += (((j==-1) || (j==dims[1]-2)) ? 1 : dims[0]-1))
{
if (avtGhostData::IsGhostZoneType(inputGhostZones->GetValue(LOC(i,j)),
REFINED_ZONE_IN_AMR_GRID))
// If there is data available at a finer level, do not create a point since the
// data at the finer level supercedes the data at the current level.
pointIds[LOC(i,j)] = -1;
else
{
if(refinedInSameLevelDomain[LOC(i,j)] != -1)
{
if (refinedInSameLevelDomain[LOC(i,j)] > domain)
{
pointIds[LOC(i,j)] = stitchCellPts->InsertNextPoint(
domainOrigin[0] + (baseIdx[0] + i + 0.5) * cellSize[0],
domainOrigin[1] + (baseIdx[1] + j + 0.5) * cellSize[1],
0
);
if (inputData)
outputData->InsertNextTuple1(inputData->GetTuple1(vtkIdType(LOC(i,j))));
}
else
{
pointIds[LOC(i,j)] = -1; // Cell belongs to grid with smaller domain index
}
}
else
{
if (((j == -1) || (j==dims[1]-2)) && (i != -1) && (i % refinementRatio[0]))
{
pointIds[LOC(i,j)] = pointIds[LOC(i-1,j)];
}
else if ((j != -1) && (j != dims[1]-2) && (j % refinementRatio[1]))
{
pointIds[LOC(i,j)] = pointIds[LOC(i, j-1)];
}
else
{
int globalI = baseIdx[0] + i;
int globalJ = baseIdx[1] + j;
int maxGlobalI = (domainBoundingBox[1] - domainBoundingBox[0]) /
cellSize[0] - 1;
int maxGlobalJ = (domainBoundingBox[3] - domainBoundingBox[2]) /
cellSize[1] - 1;
if (0<= globalI && globalI <= maxGlobalI &&
0<= globalJ && globalJ <= maxGlobalJ)
{
int parentI = globalI / refinementRatio[0];
int parentJ = globalJ / refinementRatio[1];
pointIds[LOC(i,j)] = stitchCellPts->InsertNextPoint(
domainOrigin[0] + (parentI + 0.5) * parentCellSize[0],
domainOrigin[1] + (parentJ + 0.5) * parentCellSize[1],
0
);
if (inputData)
outputData->InsertNextTuple1(inputData->GetTuple1(vtkIdType(LOC(i,j))));
}
else
{
pointIds[LOC(i,j)] = -1;
}
}
}
}
}
#if 0
std::cout << "IDs of computed vertices (A):" << std::endl;
for (int i=0; i<dims[0]*dims[1]; ++i)
{
std::cout << std::setw(4) << pointIds[i];
if (i%dims[0]==dims[0]-1) std::cout << std::endl; else std::cout << " ";;
}
std::cout << std::endl;
#endif
for (int j=0; j<dims[1]-2; ++j)
for (int i=0; i<dims[0]-2; i+=(((j==0) || (j==dims[1]-3)) ? 1 : dims[0]-3))
{
if (avtGhostData::IsGhostZoneType(inputGhostZones->GetValue(LOC(i,j)),
REFINED_ZONE_IN_AMR_GRID))