diff options
Diffstat (limited to 'src/AMRHierLib')
25 files changed, 5040 insertions, 0 deletions
diff --git a/src/AMRHierLib/AMRGrid.cc b/src/AMRHierLib/AMRGrid.cc new file mode 100644 index 0000000..8e429b9 --- /dev/null +++ b/src/AMRHierLib/AMRGrid.cc @@ -0,0 +1,612 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +#include "AMRGrid.hh" + +// Standard C/C++ Includes +#include <list> +#include <algorithm> + +// Own basic includes +#include <assume.hh> +#include <interval.h> + +// AMR related includes +#include <AmrGridReader.hh> +#include <AMRLevel.hh> + +namespace AMRGridAuxFct { + inline char *dataTypeToStr(IObase::DataType dt) { + switch (dt) { + case 0: + return "Byte/Int8"; break; + case 1: + return "Int16"; break; + case 2: + return "Int32"; break; + case 3: + return "Int64"; break; + case 4: + return "Float32"; break; + case 5: + return "Float64"; break; + case 6: + return "uInt8/uChar"; break; + case 7: + return "uInt16"; break; + case 8: + return "uInt32"; break; + case 9: + return "uInt64"; break; + case 10: + return "Char/Char8/String"; break; + case 11: + return "Unicode/Char16"; break; + default: + return "UNKNOWN/ERROR"; break; + } + } + + inline int ceilDiv(int divident, int divisor) + { + return (divident / divisor) + ((divident % divisor) == 0 ? 0 : 1); + } + + std::ostream& operator<<(std::ostream &os, const int v[3]) + { + os << "(" << v[0] << ", " << v[1] << ", " << v[2] << ")"; + return os; + } + std::ostream& operator<<(std::ostream &os, const double v[3]) + { + os << "(" << v[0] << ", " << v[1] << ", " << v[2] << ")"; + return os; + } +} + +AMRGrid::GridProperty::~GridProperty() +{ +} + +AMRGrid::IntersectionMap::IntersectionMap(int iRes, int jRes, int kRes, int subCellIRes, int subCellJRes, int subCellKRes, MapType mapType) : mMapType(mapType), mIRes(iRes), mJRes(jRes), mKRes(kRes), mIntersectingGridIndices(new int[mIRes*mJRes*mKRes]), mSubCellIRes(subCellIRes), mSubCellJRes(subCellJRes), mSubCellKRes(subCellKRes), mRefinementMaps(new IntersectionMap*[mIRes*mJRes*mKRes]) +{ + init(); +} + +AMRGrid::IntersectionMap::~IntersectionMap() +{ + delete[] mIntersectingGridIndices; + for (int i=0; i<mIRes*mJRes*mKRes; ++i) + delete mRefinementMaps[i]; + delete[] mRefinementMaps; +} + +void AMRGrid::IntersectionMap::init() +{ + for(int i=0; i<mIRes*mJRes*mKRes; ++i) { + mIntersectingGridIndices[i] = NoGrid; + mRefinementMaps[i] = NULL; + } +} + +AMRGrid::IntersectionMap& AMRGrid::IntersectionMap::refineCell(int i, int j, int k) +{ + assert(0<=i && i<mIRes && 0<=j && j<mJRes && 0<=k && k<mKRes); + int idx = idxForTriple(i, j, k); + if (mRefinementMaps[idx]) return *mRefinementMaps[idx]; + else return *(mRefinementMaps[idx] = new IntersectionMap(mSubCellIRes, mSubCellJRes, mSubCellKRes, 1, 1, 1, RefinementMap)); +} + +void AMRGrid::IntersectionMap::createBlockRefined(int i, int j, int k, int subIMin, int subIMax, int subJMin, int subJMax, int subKMin, int subKMax, AMRHierarchy::GridId gridIdx) +{ + IntersectionMap &refinedCell = refineCell(i, j, k); + for (int currI=subIMin; currI<=subIMax; ++currI) { + for (int currJ=subJMin; currJ<=subJMax; ++currJ) { + for (int currK=subKMin; currK<=subKMax; ++currK) { + refinedCell(currI, currJ, currK) = gridIdx; + } + } + } +} + +AMRGrid::AMRGrid(AMRHierarchy::GridId index, AMRHierarchy *aMRHierarchy, AmrGridReader *amrGridReader) : mGridIndex(index), mAMRHierarchy(aMRHierarchy), mRefiningGrids(), mRefinedGrids(), mNextGridInLevel(0), mPrevGridInLevel(0), mAmrGridReader(amrGridReader), mValueRange(0.0,0.0) +{ + level = -1; + data = NULL; +} + +AMRGrid::~AMRGrid() +{ + unloadCells(); + for (std_ext::hash_map<const char*, GridProperty*>::iterator it = mGridProperties.begin(); it != mGridProperties.end(); ++it) + delete it->second; +} + +bool AMRGrid::loadCells() +{ + if (datatype!=IObase::Float32) { + std::cerr << "Error: Grid data is in " << AMRGridAuxFct::dataTypeToStr(IObase::DataType(datatype)) << " format. Currently only Float32 datasets are supported" << std::endl; + return false; + } + if (data==NULL) + mAmrGridReader->getGridData(*this, mGridIndex); + return true; +} + +void AMRGrid::loadCellsForAllRefiningGrids() +{ + for (AMRRefiningGridIterator refGridIt=refiningGridsBegin(); refGridIt!=refiningGridsEnd(); ++refGridIt) + (*refGridIt)->loadCells(); +} + +bool AMRGrid::overlaps(const AMRGrid &otherGrid) const +{ + for (int i=0; i<rank; ++i) { + int sr1 = spatialrefinement[i]; + int pr1 = gridplacementrefinement[i]; + int sr2 = otherGrid.spatialrefinement[i]; + int pr2 = otherGrid.gridplacementrefinement[i]; + // Increase refinement to sr1*pr1*sr2*pr2 + int min1 = iorigin[i]*sr1*pr2*sr2; // Already refined by pr1 + int min2 = otherGrid.iorigin[i]*pr1*sr1*sr2; // Already refined by pr2 + int ext1 = dims[i]*pr1*pr2*sr2; // Already refined by sr1 + int ext2 = otherGrid.dims[i]*sr1*pr1*pr2; // Already refined by sr2 + if (!intervalsOverlap(min1, min1+ext1-1, min2, min2+ext2-1)) return false; + } + return true; +} + +void AMRGrid::printInfo(std::ostream &os) const +{ + using namespace AMRGridAuxFct; + os << "Grid at level " << level << "; origin " << origin << "; dims: " << dims << std::endl; + os << "Extend: " << minext << " - " << maxext << std::endl; + os << "Gridspacing: " << delta << std::endl; + os << "Refinement: " << timerefinement << "; " << spatialrefinement << std::endl; + os << "IOrigin: " << iorigin << " with a placement refinement of " << gridplacementrefinement << std::endl; + os << "NBytes: " << nbytes << " Datatype: " << dataTypeToStr(IObase::Int2DataType(datatype)) << "; Itemsize: " << IObase::sizeOf(IObase::Int2DataType(datatype)) << std::endl; +} + +void AMRGrid::printInfo() const +{ + printInfo(std::cout); +} + +AMRGrid::IntersectionMap* AMRGrid::computeIntersectionMap(IntersectionMap::MapType mapType, const PrimitiveBitSet& gridsOfInterest, bool considerAllGrids) const +{ + if (!refinementAvailable() || (!considerAllGrids && gridsOfInterest.empty())) return new IntersectionMap(dims[0], dims[1], dims[2], 1, 1, 1, mapType); + if (mapType == IntersectionMap::RefinementMap) { + std::cerr << "Error: Illegal mapType (RefinementMap) in AMRGrid::computeIntersectionMap()" << std::endl; + return NULL; + } + std::list<AMRGrid*> refiningGridsOfInterest; + int calculationRefinement[3] = { 1, 1, 1 }; + for (AMRRefiningGridConstIterator refiningCandIter=refiningGridsBegin(); + refiningCandIter!=refiningGridsEnd(); + ++refiningCandIter) { + if (considerAllGrids || gridsOfInterest.getBitValue((*refiningCandIter)->index())) { + refiningGridsOfInterest.push_back(*refiningCandIter); + // <ATTENTION> The following choice of calculationRefinement assumes, + // that spatial refinement and grid placement refinement of all + // refining grids are integer multiples of each other and of spatial + // and grid placment refinement of the current grid. + calculationRefinement[0] = std::max(calculationRefinement[0], + std::max((*refiningCandIter)->gridplacementrefinement[0], (*refiningCandIter)->spatialrefinement[0])); + calculationRefinement[1] = std::max(calculationRefinement[1], + std::max((*refiningCandIter)->gridplacementrefinement[1], (*refiningCandIter)->spatialrefinement[1])); + calculationRefinement[2] = std::max(calculationRefinement[2], + std::max((*refiningCandIter)->gridplacementrefinement[2], (*refiningCandIter)->spatialrefinement[2])); + // </ATTENTION> + } + } + + int thisSpatialFactor [3]; + thisSpatialFactor[0] = calculationRefinement[0]/spatialrefinement[0]; + thisSpatialFactor[1] = calculationRefinement[1]/spatialrefinement[1]; + thisSpatialFactor[2] = calculationRefinement[2]/spatialrefinement[2]; + assert(calculationRefinement[0]%spatialrefinement[0]==0); + assert(calculationRefinement[1]%spatialrefinement[1]==0); + assert(calculationRefinement[2]%spatialrefinement[2]==0); + + int thisPlacementFactor[3]; + thisPlacementFactor[0] = calculationRefinement[0]/gridplacementrefinement[0]; + thisPlacementFactor[1] = calculationRefinement[1]/gridplacementrefinement[1]; + thisPlacementFactor[2] = calculationRefinement[2]/gridplacementrefinement[2]; + assert(calculationRefinement[0]%gridplacementrefinement[0]==0); + assert(calculationRefinement[1]%gridplacementrefinement[1]==0); + assert(calculationRefinement[2]%gridplacementrefinement[2]==0); + + IntersectionMap* theIntersectionMap = new IntersectionMap(dims[0], dims[1], dims[2], + thisSpatialFactor[0], thisSpatialFactor[1], thisSpatialFactor[2], mapType); + + for (std::list<AMRGrid*>::iterator refiningIter=refiningGridsOfInterest.begin(); + refiningIter!=refiningGridsOfInterest.end(); + ++refiningIter) { + int otherSpatialFactor [3]; + otherSpatialFactor[0] = calculationRefinement[0]/(*refiningIter)->spatialrefinement[0]; + otherSpatialFactor[1] = calculationRefinement[1]/(*refiningIter)->spatialrefinement[1]; + otherSpatialFactor[2] = calculationRefinement[2]/(*refiningIter)->spatialrefinement[2]; + assert(calculationRefinement[0]%(*refiningIter)->spatialrefinement[0]==0); + assert(calculationRefinement[1]%(*refiningIter)->spatialrefinement[1]==0); + assert(calculationRefinement[2]%(*refiningIter)->spatialrefinement[2]==0); + int otherPlacementFactor[3]; + otherPlacementFactor[0] = calculationRefinement[0]/(*refiningIter)->gridplacementrefinement[0]; + otherPlacementFactor[1] = calculationRefinement[1]/(*refiningIter)->gridplacementrefinement[1]; + otherPlacementFactor[2] = calculationRefinement[2]/(*refiningIter)->gridplacementrefinement[2]; + assert(calculationRefinement[0]%(*refiningIter)->gridplacementrefinement[0]==0); + assert(calculationRefinement[1]%(*refiningIter)->gridplacementrefinement[1]==0); + assert(calculationRefinement[2]%(*refiningIter)->gridplacementrefinement[2]==0); + + int minExt[3]; + minExt[0] = (*refiningIter)->iorigin[0]*otherPlacementFactor[0] - iorigin[0]*thisPlacementFactor[0]; + minExt[1] = (*refiningIter)->iorigin[1]*otherPlacementFactor[1] - iorigin[1]*thisPlacementFactor[1]; + minExt[2] = (*refiningIter)->iorigin[2]*otherPlacementFactor[2] - iorigin[2]*thisPlacementFactor[2]; + // Clip + if (minExt[0] < 0) minExt[0]=0; + if (minExt[1] < 0) minExt[1]=0; + if (minExt[2] < 0) minExt[2]=0; + + int maxExt[3]; + maxExt[0] = minExt[0] + (*refiningIter)->dims[0]*otherSpatialFactor[0] - 1; + maxExt[1] = minExt[1] + (*refiningIter)->dims[1]*otherSpatialFactor[1] - 1; + maxExt[2] = minExt[2] + (*refiningIter)->dims[2]*otherSpatialFactor[2] - 1; + // Clip + if (maxExt[0] > dims[0] * thisSpatialFactor[0] - 1) maxExt[0] = dims[0] * thisSpatialFactor[0] - 1; + if (maxExt[1] > dims[1] * thisSpatialFactor[1] - 1) maxExt[1] = dims[1] * thisSpatialFactor[1] - 1; + if (maxExt[2] > dims[2] * thisSpatialFactor[2] - 1) maxExt[2] = dims[2] * thisSpatialFactor[2] - 1; + + if (mapType == IntersectionMap::RefinedInnerCells) { + minExt[0]++; + minExt[1]++; + minExt[2]++; + maxExt[0]--; + maxExt[1]--; + maxExt[2]--; + if (!(maxExt[0]>minExt[0] && maxExt[1]>minExt[1] && maxExt[2]>minExt[2])) + // Skip this grid, no inner cells! + continue; + } + + int minExtCell[3]; + minExtCell[0] = minExt[0] / thisSpatialFactor[0]; // "Rounds" to floor(x), because >=0 !!! + minExtCell[1] = minExt[1] / thisSpatialFactor[1]; // "Rounds" to floor(x), because >=0 !!! + minExtCell[2] = minExt[2] / thisSpatialFactor[2]; // "Rounds" to floor(x), because >=0 !!! + int minExtSubCell[3]; + minExtSubCell[0] = minExt[0] % thisSpatialFactor[0]; + minExtSubCell[1] = minExt[1] % thisSpatialFactor[1]; + minExtSubCell[2] = minExt[2] % thisSpatialFactor[2]; + int maxExtCell[3]; + maxExtCell[0] = maxExt[0] / thisSpatialFactor[0]; + maxExtCell[1] = maxExt[1] / thisSpatialFactor[1]; + maxExtCell[2] = maxExt[2] / thisSpatialFactor[2]; + int maxExtSubCell[3]; + maxExtSubCell[0] = maxExt[0] % thisSpatialFactor[0]; + maxExtSubCell[1] = maxExt[1] % thisSpatialFactor[1]; + maxExtSubCell[2] = maxExt[2] % thisSpatialFactor[2]; + // Create the low-res intersection information + if (mapType == IntersectionMap::BorderCells) { + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + (*theIntersectionMap)(i,j,minExtCell[2]) = (*refiningIter)->mGridIndex; + (*theIntersectionMap)(i,j,maxExtCell[2]) = (*refiningIter)->mGridIndex; + } + } + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + (*theIntersectionMap)(i,minExtCell[1],k) = (*refiningIter)->mGridIndex; + (*theIntersectionMap)(i,maxExtCell[1],k) = (*refiningIter)->mGridIndex; + } + } + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + (*theIntersectionMap)(minExtCell[0],j,k) = (*refiningIter)->mGridIndex; + (*theIntersectionMap)(maxExtCell[0],j,k) = (*refiningIter)->mGridIndex; + } + } + } + else if (mapType == IntersectionMap::RefinedCells || mapType == IntersectionMap::RefinedInnerCells) { + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + (*theIntersectionMap)(i,j,k) = (*refiningIter)->mGridIndex; + } + } + } + } + /* + // Assumption: Each grid covers at least two cells in each extend + assume(minExtCell[0]!=maxExtCell[0]); + assume(minExtCell[1]!=maxExtCell[1]); + assume(minExtCell[2]!=maxExtCell[2]); + */ + + // Create subcells, where necessary + int subCellIRes = thisSpatialFactor[0]; + int subCellJRes = thisSpatialFactor[1]; + int subCellKRes = thisSpatialFactor[2]; + + if (minExtSubCell[2]) { + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + // <HACK> + // This isn't nice but avoids checking for serveral special cases + int subIMin = (i==minExtCell[0] ? minExtSubCell[0] : 0); + int subIMax = (i==maxExtCell[0] ? maxExtSubCell[0] : subCellIRes-1); + int subJMin = (j==minExtCell[1] ? minExtSubCell[1] : 0); + int subJMax = (j==maxExtCell[1] ? maxExtSubCell[1] : subCellJRes-1); + // </HACK> + theIntersectionMap->createBlockRefined(i, j, minExtCell[2], subIMin, subIMax, subJMin, subJMax, minExtSubCell[2], subCellKRes-1, (*refiningIter)->mGridIndex); + } + } + } + if (maxExtSubCell[2]!=subCellKRes-1) { + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + // <HACK> + // This isn't nice but avoids checking for serveral special cases + int subIMin = (i==minExtCell[0] ? minExtSubCell[0] : 0); + int subIMax = (i==maxExtCell[0] ? maxExtSubCell[0] : subCellIRes-1); + int subJMin = (j==minExtCell[1] ? minExtSubCell[1] : 0); + int subJMax = (j==maxExtCell[1] ? maxExtSubCell[1] : subCellJRes-1); + // </HACK> + theIntersectionMap->createBlockRefined(i, j, maxExtCell[2], subIMin, subIMax, subJMin, subJMax, 0, maxExtSubCell[2], (*refiningIter)->mGridIndex); + } + } + } + if (minExtSubCell[1]) { + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + // <HACK> + // This isn't nice but avoids checking for serveral special cases + int subIMin = (i==minExtCell[0] ? minExtSubCell[0] : 0); + int subIMax = (i==maxExtCell[0] ? maxExtSubCell[0] : subCellIRes-1); + int subKMin = (k==minExtCell[2] ? minExtSubCell[2] : 0); + int subKMax = (k==maxExtCell[2] ? maxExtSubCell[2] : subCellKRes-1); + // </HACK> + theIntersectionMap->createBlockRefined(i, minExtCell[1], k, subIMin, subIMax, minExtSubCell[1], subCellJRes-1, subKMin, subKMax, (*refiningIter)->mGridIndex); + } + } + } + if (maxExtSubCell[1]!=subCellJRes-1) { + for (int i=minExtCell[0]; i<=maxExtCell[0]; ++i) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + // <HACK> + // This isn't nice but avoids checking for serveral special cases + int subIMin = (i==minExtCell[0] ? minExtSubCell[0] : 0); + int subIMax = (i==maxExtCell[0] ? maxExtSubCell[0] : subCellIRes-1); + int subKMin = (k==minExtCell[2] ? minExtSubCell[2] : 0); + int subKMax = (k==maxExtCell[2] ? maxExtSubCell[2] : subCellKRes-1); + // </HACK> + theIntersectionMap->createBlockRefined(i, maxExtCell[1], k, subIMin, subIMax, 0, maxExtSubCell[1], subKMin, subKMax, (*refiningIter)->mGridIndex); + } + } + } + if (minExtSubCell[0]) { + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + // <HACK> + // This isn't nice but avoids checking for serveral special cases + int subJMin = (j==minExtCell[1] ? minExtSubCell[1] : 0); + int subJMax = (j==maxExtCell[1] ? maxExtSubCell[1] : subCellJRes-1); + int subKMin = (k==minExtCell[2] ? minExtSubCell[2] : 0); + int subKMax = (k==maxExtCell[2] ? maxExtSubCell[2] : subCellKRes-1); + // </HACK> + theIntersectionMap->createBlockRefined(minExtCell[0], j, k, minExtSubCell[0], subCellIRes-1, subJMin, subJMax, subKMin, subKMax, (*refiningIter)->mGridIndex); + } + } + } + if (maxExtSubCell[0]!=subCellIRes-1) { + for (int j=minExtCell[1]; j<=maxExtCell[1]; ++j) { + for (int k=minExtCell[2]; k<=maxExtCell[2]; ++k) { + // <HACK> + // This isn't nice but avoids checking for serveral special cases + int subJMin = (j==minExtCell[1] ? minExtSubCell[1] : 0); + int subJMax = (j==maxExtCell[1] ? maxExtSubCell[1] : subCellJRes-1); + int subKMin = (k==minExtCell[2] ? minExtSubCell[2] : 0); + int subKMax = (k==maxExtCell[2] ? maxExtSubCell[2] : subCellKRes-1); + // </HACK> + theIntersectionMap->createBlockRefined(maxExtCell[0], j, k, 0, maxExtSubCell[0], subJMin, subJMax, subKMin, subKMax, (*refiningIter)->mGridIndex); + } + } + } + } + return theIntersectionMap; +} + +AMRGrid::AMRRefinementInfo *AMRGrid::getRefinementInfo(const AMRGrid *refiningGrid) const +{ + if(level != refiningGrid->level-1) return 0; + + int calculationRefinement[3]; + calculationRefinement[0] = std::min(refiningGrid->spatialrefinement[0], refiningGrid->gridplacementrefinement[0]); + calculationRefinement[1] = std::min(refiningGrid->spatialrefinement[1], refiningGrid->gridplacementrefinement[1]); + calculationRefinement[2] = std::min(refiningGrid->spatialrefinement[2], refiningGrid->gridplacementrefinement[2]); + + // Assume that gridplacementrefinement and spatialrefinement can be expressed + // as integer ratios with respect to each other and the factors of the parent level + assume(calculationRefinement[0] % refiningGrid->spatialrefinement[0] == 0); + assume(calculationRefinement[1] % refiningGrid->spatialrefinement[1] == 0); + assume(calculationRefinement[2] % refiningGrid->spatialrefinement[2] == 0); + assume(calculationRefinement[0] % refiningGrid->gridplacementrefinement[0] == 0); + assume(calculationRefinement[1] % refiningGrid->gridplacementrefinement[1] == 0); + assume(calculationRefinement[2] % refiningGrid->gridplacementrefinement[2] == 0); + assume(calculationRefinement[0] % spatialrefinement[0] == 0); + assume(calculationRefinement[1] % spatialrefinement[1] == 0); + assume(calculationRefinement[2] % spatialrefinement[2] == 0); + assume(calculationRefinement[0] % gridplacementrefinement[0] == 0); + assume(calculationRefinement[1] % gridplacementrefinement[1] == 0); + assume(calculationRefinement[2] % gridplacementrefinement[2] == 0); + + int refiningPlacementFactor[3]; + refiningPlacementFactor[0] = calculationRefinement[0] / refiningGrid->gridplacementrefinement[0]; + refiningPlacementFactor[1] = calculationRefinement[1] / refiningGrid->gridplacementrefinement[1]; + refiningPlacementFactor[2] = calculationRefinement[2] / refiningGrid->gridplacementrefinement[2]; + int refiningSpatialFactor[3]; + refiningSpatialFactor[0] = calculationRefinement[0] / refiningGrid->spatialrefinement[0]; + refiningSpatialFactor[1] = calculationRefinement[1] / refiningGrid->spatialrefinement[1]; + refiningSpatialFactor[2] = calculationRefinement[2] / refiningGrid->spatialrefinement[2]; + int refinedPlacementFactor[3]; + refinedPlacementFactor[0] = calculationRefinement[0] / gridplacementrefinement[0]; + refinedPlacementFactor[1] = calculationRefinement[1] / gridplacementrefinement[1]; + refinedPlacementFactor[2] = calculationRefinement[2] / gridplacementrefinement[2]; + int refinedSpatialFactor[3]; + refinedSpatialFactor[0] = calculationRefinement[0] / spatialrefinement[0]; + refinedSpatialFactor[1] = calculationRefinement[1] / spatialrefinement[1]; + refinedSpatialFactor[2] = calculationRefinement[2] / spatialrefinement[2]; + int minExt[3]; + minExt[0] = refiningGrid->iorigin[0]*refiningPlacementFactor[0] - iorigin[0]*refinedPlacementFactor[0]; + minExt[1] = refiningGrid->iorigin[1]*refiningPlacementFactor[1] - iorigin[1]*refinedPlacementFactor[1]; + minExt[2] = refiningGrid->iorigin[2]*refiningPlacementFactor[2] - iorigin[2]*refinedPlacementFactor[2]; + int maxExt[3]; + maxExt[0] = minExt[0]+(refiningGrid->dims[0]-1)*refiningSpatialFactor[0]; + maxExt[1] = minExt[1]+(refiningGrid->dims[1]-1)*refiningSpatialFactor[1]; + maxExt[2] = minExt[2]+(refiningGrid->dims[2]-1)*refiningSpatialFactor[2]; + + int refinedCellsMin[3]; + refinedCellsMin[0] = minExt[0] / refinedSpatialFactor[0]; + refinedCellsMin[1] = minExt[1] / refinedSpatialFactor[1]; + refinedCellsMin[2] = minExt[2] / refinedSpatialFactor[2]; + int refinedCellsSubMin[3]; + refinedCellsSubMin[0] = minExt[0] % refinedSpatialFactor[0]; + refinedCellsSubMin[1] = minExt[1] % refinedSpatialFactor[1]; + refinedCellsSubMin[2] = minExt[2] % refinedSpatialFactor[2]; + int refinedCellsMax[3]; + refinedCellsMax[0] = maxExt[0] / refinedSpatialFactor[0]; + refinedCellsMax[1] = maxExt[1] / refinedSpatialFactor[1]; + refinedCellsMax[2] = maxExt[2] / refinedSpatialFactor[2]; + int refinedCellsSubMax[3]; + refinedCellsSubMax[0] = maxExt[0] % refinedSpatialFactor[0]; + refinedCellsSubMax[1] = maxExt[1] % refinedSpatialFactor[1]; + refinedCellsSubMax[2] = maxExt[2] % refinedSpatialFactor[2]; + + int completelyRefinedCellsMin[3]; + completelyRefinedCellsMin[0] = refinedCellsMin[0] + (refinedCellsSubMin[0] == 0 ? 0 : 1); + completelyRefinedCellsMin[1] = refinedCellsMin[1] + (refinedCellsSubMin[1] == 0 ? 0 : 1); + completelyRefinedCellsMin[2] = refinedCellsMin[2] + (refinedCellsSubMin[2] == 0 ? 0 : 1); + int completelyRefinedCellsMax[3]; + completelyRefinedCellsMax[0] = refinedCellsMax[0] - (refinedCellsSubMax[0] != refinedSpatialFactor[0]-1 ? 1 : 0); + completelyRefinedCellsMax[1] = refinedCellsMax[1] - (refinedCellsSubMax[1] != refinedSpatialFactor[1]-1 ? 1 : 0); + completelyRefinedCellsMax[2] = refinedCellsMax[2] - (refinedCellsSubMax[2] != refinedSpatialFactor[2]-1 ? 1 : 0); + + int refiningCellsMin[3]; + refiningCellsMin[0] = (completelyRefinedCellsMin[0] * refinedSpatialFactor[0] - minExt[0]) / refiningSpatialFactor[0]; + refiningCellsMin[1] = (completelyRefinedCellsMin[1] * refinedSpatialFactor[1] - minExt[1]) / refiningSpatialFactor[1]; + refiningCellsMin[2] = (completelyRefinedCellsMin[2] * refinedSpatialFactor[2] - minExt[2]) / refiningSpatialFactor[2]; + assume((completelyRefinedCellsMin[0] * refinedSpatialFactor[0] - minExt[0]) % refiningSpatialFactor[0] == 0); + assume((completelyRefinedCellsMin[1] * refinedSpatialFactor[1] - minExt[1]) % refiningSpatialFactor[1] == 0); + assume((completelyRefinedCellsMin[2] * refinedSpatialFactor[2] - minExt[2]) % refiningSpatialFactor[2] == 0); + int refiningCellsMax[3]; + refiningCellsMax[0] = ((completelyRefinedCellsMax[0]+1)*refinedSpatialFactor[0]-minExt[0]) / refiningSpatialFactor[0] - 1; + refiningCellsMax[1] = ((completelyRefinedCellsMax[1]+1)*refinedSpatialFactor[1]-minExt[1]) / refiningSpatialFactor[1] - 1; + refiningCellsMax[2] = ((completelyRefinedCellsMax[2]+1)*refinedSpatialFactor[2]-minExt[2]) / refiningSpatialFactor[2] - 1; + assume((completelyRefinedCellsMax[0]*refinedSpatialFactor[0] - minExt[0] + 1) % refiningSpatialFactor[0] == 0); + assume((completelyRefinedCellsMax[1]*refinedSpatialFactor[1] - minExt[1] + 1) % refiningSpatialFactor[1] == 0); + assume((completelyRefinedCellsMax[2]*refinedSpatialFactor[2] - minExt[2] + 1) % refiningSpatialFactor[2] == 0); + + int mSpatialRefinementWRTParent[3]; + mSpatialRefinementWRTParent[0] = refiningGrid->spatialrefinement[0]/spatialrefinement[0]; + mSpatialRefinementWRTParent[1] = refiningGrid->spatialrefinement[1]/spatialrefinement[1]; + mSpatialRefinementWRTParent[2] = refiningGrid->spatialrefinement[2]/spatialrefinement[2]; + assume(refiningGrid->spatialrefinement[0]%spatialrefinement[0]==0); + assume(refiningGrid->spatialrefinement[1]%spatialrefinement[1]==0); + assume(refiningGrid->spatialrefinement[2]%spatialrefinement[2]==0); + + return new AMRRefinementInfo( + AxisAlignedBox<int>(completelyRefinedCellsMin, completelyRefinedCellsMax), + AxisAlignedBox<int>(refiningCellsMin, refiningCellsMax), + AxisAlignedBox<int>(refinedCellsMin, refinedCellsMax), + AxisAlignedBox<int>(refinedCellsSubMin, refinedCellsSubMax), + mSpatialRefinementWRTParent + ); +} + +AxisAlignedBox<int> AMRGrid::getRefiningCells(const AMRGrid *otherGrid, int i, int j, int k) const +{ + if (otherGrid->level > level) return otherGrid->getRefiningCells(this, i, j, k); + assume(spatialrefinement[0] == gridplacementrefinement[0]); + assume(spatialrefinement[1] == gridplacementrefinement[1]); + assume(spatialrefinement[2] == gridplacementrefinement[2]); + int relativeRefinement[3]; + relativeRefinement[0] = spatialrefinement[0] / otherGrid->spatialrefinement[0]; + relativeRefinement[1] = spatialrefinement[1] / otherGrid->spatialrefinement[1]; + relativeRefinement[2] = spatialrefinement[2] / otherGrid->spatialrefinement[2]; + assume(spatialrefinement[0] % otherGrid->spatialrefinement[0] == 0); + assume(spatialrefinement[1] % otherGrid->spatialrefinement[1] == 0); + assume(spatialrefinement[2] % otherGrid->spatialrefinement[2] == 0); + int start[3]; + start[0] = (otherGrid->iorigin[0]+i) * relativeRefinement[0] - iorigin[0]; + start[1] = (otherGrid->iorigin[1]+j) * relativeRefinement[1] - iorigin[1]; + start[2] = (otherGrid->iorigin[2]+k) * relativeRefinement[2] - iorigin[2]; + int end[3]; + end[0] = start[0] + relativeRefinement[0] - 1; + end[1] = start[1] + relativeRefinement[1] - 1; + end[2] = start[2] + relativeRefinement[2] - 1; + return AxisAlignedBox<int>(start, end); +} + +AMRHierarchy::GridId AMRGrid::getCellRefiningGridId(int i, int j, int k) const +{ + // Get handle for next level + AMRLevel *nextLevel = mAMRHierarchy->getLevel(level+1); + + if (nextLevel) { + // Convert into absoulte level coordinates of next level + // <ATTENTION> This assumes spatialrefinment == gridplacementrefinment </ATTENTION> + int absIdxInNextLevel[3]; + absIdxInNextLevel[xAxis] = (i + iorigin[xAxis])*(nextLevel->getSpatialRefinement(xAxis)/spatialrefinement[xAxis]); + absIdxInNextLevel[yAxis] = (j + iorigin[yAxis])*(nextLevel->getSpatialRefinement(yAxis)/spatialrefinement[yAxis]); + absIdxInNextLevel[zAxis] = (k + iorigin[zAxis])*(nextLevel->getSpatialRefinement(zAxis)/spatialrefinement[zAxis]); + + return nextLevel->getGridId(absIdxInNextLevel); + } + else + return AMRGrid::NoGrid; +} + +void AMRGrid::addProperty(const char* name, AMRGrid::GridProperty* property) +{ + mGridProperties[name] = property; +} + +AMRGrid::GridProperty* AMRGrid::getProperty(const char *name) const +{ + std_ext::hash_map<const char*, GridProperty*>::const_iterator pos = mGridProperties.find(name); + if (pos == mGridProperties.end()) + return 0; + else + return pos->second; +} + +void AMRGrid::removeProperty(const char* name) +{ + mGridProperties.erase(name); +} + +void AMRGrid::computeValueRange() +{ + bool cellsAlreadyLoaded = (data != 0); + if (loadCells()) { + assert(data); + mValueRange.min = getValue(0); + mValueRange.max = mValueRange.min; + for (int i = 0; i < dims[0] * dims[1] * dims[2]; ++i) { + float val = getValue(i); + if ( val < mValueRange.min) + mValueRange.min = val; + else if (val > mValueRange.max) + mValueRange.max = val; + } + } + else { + std::cerr << "Error: Couldn't calculate value range. No data!" << std::endl; + } + if (!cellsAlreadyLoaded) unloadCells(); +} diff --git a/src/AMRHierLib/AMRGrid.hh b/src/AMRHierLib/AMRGrid.hh new file mode 100644 index 0000000..f4b799c --- /dev/null +++ b/src/AMRHierLib/AMRGrid.hh @@ -0,0 +1,327 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA and Germany" + * + */ + +#ifndef _GHW_AMRGRID_H_ +#define _GHW_AMRGRID_H_ + +// Standard C/C++-Includes +#include <iostream> +#include <list> +#if (__GNUC__< 3) +#include <hash_map> +#define std_ext std +#else +#include <ext/hash_map> +#define std_ext __gnu_cxx +#endif +#include <stdlib.h> +#include <math.h> + +// AMR related includes +#include <AmrGrid.h> +#include <AMRHierarchy.hh> + +// Own includes +#include <AxisAlignedBox.hh> +#include <PrimitiveBitSet.hh> +#include <Range.hh> + +class AmrGridReader; + +/** + * One grid of an AMR hierarchy + * Holds one grid of the AMRHierarchy together with inforamtion about how + * it is related to the other grids. + */ +class AMRGrid : public AmrGrid { + public: + /** + * Property attached to a grid + * Base class for 'properties' (additional information) that can be + * associated with a grid. + */ + class GridProperty { + public: + virtual ~GridProperty() = 0; + }; + static const int NoGrid = -1; /** Grid ID indicating 'no grid' */ + static const int Unknown = -2; /** Grid ID indicationg that no information about a grid ID is present */ + class AMRRefinementInfo { + public: + /** Information about relationship between a refining and a refined grid + * Class containing detailed information about how a given grid refines another + * grid. + */ + AMRRefinementInfo(const AxisAlignedBox<int>& complRefinedCells, + const AxisAlignedBox<int>& complRefiningCells, + const AxisAlignedBox<int>& refinedCells, + const AxisAlignedBox<int>& refinedSubCells, + int refiningSpatialRefinementWRTRefined[3]) : + mCompletelyRefinedCells(complRefinedCells), + mCompletelyRefiningCells(complRefiningCells), + mRefinedCells(refinedCells), + mRefinedSubCells(refinedSubCells) + { mRefiningSpatialRefinementWRTRefined[0] = refiningSpatialRefinementWRTRefined[0]; + mRefiningSpatialRefinementWRTRefined[1] = refiningSpatialRefinementWRTRefined[1]; + mRefiningSpatialRefinementWRTRefined[2] = refiningSpatialRefinementWRTRefined[2]; + } + const AxisAlignedBox<int>& completelyRefinedCells() { return mCompletelyRefinedCells; } + const AxisAlignedBox<int>& completelyRefiningCells() { return mCompletelyRefiningCells; } + const AxisAlignedBox<int>& refinedCells() { return mRefinedCells; } + const AxisAlignedBox<int>& refinedSubCells() { return mRefinedSubCells; } + int refiningSpatialRefinementWRTRefined(int dim) { assert(0<=dim && dim<3); return mRefiningSpatialRefinementWRTRefined[dim]; } + private: + AxisAlignedBox<int> mCompletelyRefinedCells; + AxisAlignedBox<int> mCompletelyRefiningCells; + AxisAlignedBox<int> mRefinedCells; + AxisAlignedBox<int> mRefinedSubCells; + int mRefiningSpatialRefinementWRTRefined[3]; + }; + /** Map from grid cells to IDs of grids refining them + * The intersection map is an array that contains an entry for each cell of a + * given grid specifying which grid (if there is any) refines it. + */ + class IntersectionMap { + public: + // The type of the map: + // BorderCells - only the on the border of the intersecting grids are marked + // RefinedCells - all cells overlapped by a grid in the next level are marked + + enum MapType { BorderCells, RefinedCells, RefinedInnerCells, RefinementMap }; + IntersectionMap(int iRes, int jRes, int kRes, int iSubCellRes, int jSubCellRes, int kSubCellRes, MapType mapType); + ~IntersectionMap(); + void init(); + const AMRHierarchy::GridId& operator()(int i, int j, int k) const { return mIntersectingGridIndices[idxForTriple(i,j,k)]; } + AMRHierarchy::GridId& operator()(int i, int j, int k) { return mIntersectingGridIndices[idxForTriple(i,j,k)]; } + const AMRHierarchy::GridId& operator()(int idx[3]) const { return mIntersectingGridIndices[idxForTriple(idx[0], idx[1], idx[2])]; } + AMRHierarchy::GridId& operator()(int idx[3]) { return mIntersectingGridIndices[idxForTriple(idx[0], idx[1], idx[2])]; } + IntersectionMap& refineCell(int i, int j, int k); + void createBlockRefined(int i, int j, int k, int iMin, int iMax, int jMin, int jMax, int kMin, int kMax, AMRHierarchy::GridId gridIdx); + MapType getMapType() const { return mMapType; } + const IntersectionMap* subCells(int i, int j, int k) const { return mRefinementMaps[idxForTriple(i, j, k)]; } + int getIRes() const { return mIRes; } + int getJRes() const { return mJRes; } + int getKRes() const { return mKRes; } + private: + MapType mMapType; + int mIRes, mJRes, mKRes; // Extends of this map + AMRHierarchy::GridId *mIntersectingGridIndices; // The actual map, each cell has an entry which in + int mSubCellIRes, mSubCellJRes, mSubCellKRes; + IntersectionMap **mRefinementMaps; + IntersectionMap(const IntersectionMap&); // Prevent copying + IntersectionMap& operator=(const IntersectionMap&); // Prevent copying + int idxForTriple(int i, int j, int k) const { assert (0<=i && i<mIRes && 0<=j && j<mJRes && 0<=k && k<mKRes); return (k*mJRes+j)*mIRes+i; }; + }; + + /** + * {\bf Description:}\\ + * Constructor for AMRGrid. Initializes some important member variables (esp. + * sets all pointers to NULL-pointers). + * \\{\bf Precondition:}\\ + * none + * \\{Postcondition}\\ + * Members indicating wether data is loaded are initialized. + * Level information is set to -1 to indicate that structure is not completely initialized + * @param + * amrHier - Reference to AMRHierachy (needed to access AmrGridReader for loading cell data) + * @return nothing + */ + AMRGrid(AMRHierarchy::GridId index, AMRHierarchy *aMRHierarchy, AmrGridReader *amrGridReader); + /** + * {\bf Description:}\\ + * Desctructor of AMRGrid. Frees cell data. + * \\{\bf Precondition:}\\ + * none + * \\{Postcondition}\\ + * Destroys AMRGrid object. Frees data-storage for grid-cells + * @param + * amrHier - Reference to AMRHierachy (needed to access AmrGridReader for loading cell data) + * @return nothing + */ + ~AMRGrid(); + /** + * {\bf Description:} + * Load the cell data array for this grid. If they are already loaded nothing + * is done. + * \\{\bf Precondition:}\\ + * mGridIndex ist correctly set + * \\{\bf Postcondition:}\\ + * Grid data is loaded + * @return nothing + */ + bool loadCells(); + /** {\bf Description:} + * Load cell data for all grids refining this grid + */ + void loadCellsForAllRefiningGrids(); + /** + * {\bf Description:} + * Free the cell data array. + * \\{\bf Precondition:}\\ + * none + * \\{\bf Postcondition:}\\ + * array containing cell data is freed + * data == NULL + * @return nothing + */ + void unloadCells(); + /** + * {\bf Description:} + * Check, if this grid and otherGrid overlap (i.e., have a non-empty intersection) + * \\{\bf Precondition:}\\ + * iorigin, dims, spatialrefinement and gridplacementrefinement of both grids are set properly. + * \\{\bf Postcondition:}\\ + * none + * @param + * otherGrid reference to the grid for which overlap shoud be checked + * @return true, if grids overlap; otherwise false. + */ + bool overlaps(const AMRGrid &otherGrid) const; + /** + * {\bf Description:} + * Print information about grid. + * \\{\bf Precondition:}\\ + * Member variables are set properly, i.e. are loaded from file. + * \\{\bf Postcondition:}\\ + * none + * @param + * os stream to which information is sent + * @return none + */ + void printInfo(std::ostream &os) const; + /** + * {\bf Description:} + * Print information about grid to standard output + * \\{\bf Precondition:}\\ + * Member variables are set properly, i.e. are loaded from file. + * \\{\bf Postcondition:}\\ + * none + * @return none + */ + void printInfo() const; + // Get next grid in this level (all grids of a level are stored as linked list + AMRGrid *getNextGridInLevel() const; + typedef std::list<AMRGrid *>::iterator AMRRefiningGridIterator; /** Iterator for iterating through refining grids */ + typedef std::list<AMRGrid *>::iterator AMRRefinedGridIterator; /** Iterator for iterating through refined grids */ + typedef std::list<AMRGrid *>::const_iterator AMRRefiningGridConstIterator; /** Constant iterator for iterating through refining grids */ + typedef std::list<AMRGrid *>::const_iterator AMRRefinedGridConstIterator; /** Constant iterator for iterating through refined grids */ + // Get iterator for iterating through refining and refined grids. A refining grid is a grid + // that overlaps the current grid on the next finer level and thus provides a more detailed + // description of a grid sub-region. A refined grid is a grid for which the current gird + // provides a more detailed description. + AMRRefiningGridIterator refiningGridsBegin(); + AMRRefiningGridIterator refiningGridsEnd(); + AMRRefinedGridIterator refinedGridsBegin(); + AMRRefinedGridIterator refinedGridsEnd(); + AMRRefiningGridConstIterator refiningGridsBegin() const; + AMRRefiningGridConstIterator refiningGridsEnd() const; + AMRRefinedGridConstIterator refinedGridsBegin() const; + AMRRefinedGridConstIterator refinedGridsEnd() const; + + // Get the index (unique grid identifier in AMR Hierarchy) of the grid + AMRHierarchy::GridId index() const; + // Get value for a cell specified by its index + float getValue(int i, int j, int k) const; + // Get an interpolated value for an arbitrary point covered by the grid + float getInterpolatedValue(double x, double y, double z) const; + // Get the range of all scalar values within the grid + const Range<float>& getValueRange() const; + // Compute the IntersectionMap (see above) + IntersectionMap* computeIntersectionMap(IntersectionMap::MapType mapType, const PrimitiveBitSet& gridsOfInterest, bool considerAllGrids=false) const; + IntersectionMap* computeIntersectionMap(IntersectionMap::MapType mapType) const; + // Is this grid refined by any grids? Are there grids in the next finer level that + // overlap the region covered by this grid + bool refinementAvailable() const; + // Is this grid refining any other grids (should only be false for grids in the root level) + bool isRefinement() const; + // Get information about how a given grid refines this grid + AMRRefinementInfo *getRefinementInfo(const AMRGrid *refiningGrid) const; + // Which cells of otherGrid overlap cell (i, j, k) of this grid + AxisAlignedBox<int> getRefiningCells(const AMRGrid *otherGrid, int i, int j, int k) const; + AMRHierarchy::GridId getCellRefiningGridId(int i, int j, int k) const; + AMRHierarchy::GridId getCellRefiningGridId(const int idx[3]) const; + // Manage grid properties (auxilliary information attached to a grid) + void addProperty(const char* name, GridProperty* property); + GridProperty* getProperty(const char* name) const; + void removeProperty(const char* name); + + private: + friend class AMRHierarchy; + AMRHierarchy::GridId mGridIndex; // Index of grid within hierarchy + AMRHierarchy *mAMRHierarchy; + // Relationship between grids + std::list<AMRGrid *> mRefiningGrids; // List of grids that refine this grid + std::list<AMRGrid *> mRefinedGrids; // List of grids that are refined by this grid + AMRGrid *mNextGridInLevel; // Next Grid in same level + AMRGrid *mPrevGridInLevel; // Previous grid in same level + AmrGridReader *mAmrGridReader; // Pointer to the AMRGridReader used to load cell data + Range<float> mValueRange; // Range of values in the grid + std_ext::hash_map<const char*, GridProperty*> mGridProperties; // Pointer to properties (additional information) attached to this grid + void computeValueRange(); + float getValue(int i) const; // Get data value at given array-idx + + // As seen in Scott Meyer's Effective C++: If you don't want to specify copy constructor + // and assignment operator, make them inaccessible to prevent them from being called accidently. + // NOTE: Even though declared here, they are not defined (causes link error when accidently needed + // within class). + AMRGrid(const AMRGrid&); // Prevent copying + AMRGrid& operator=(const AMRGrid&); // Prevent copying +}; + +#include "AMRGrid.icc" + +#endif diff --git a/src/AMRHierLib/AMRGrid.icc b/src/AMRHierLib/AMRGrid.icc new file mode 100644 index 0000000..c634f1e --- /dev/null +++ b/src/AMRHierLib/AMRGrid.icc @@ -0,0 +1,194 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* WARNING: This software is EXPERIMENTAL. The authors give no guaranty + * about stability or correctness of the provided source! + * + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA [and Germany :-)]" + * + */ + +inline float AMRGrid::getValue(int i) const +{ + // <NOTE> Maybe it is possible to integrate some type of conversion here, if the + // grid is not Float32.</NOTE> + // <NOTE> Maybe it is possible to switch here between logaritmic and normal grid rep. + // </NOTE> +#ifdef LOG_GETVALUE + return logf(static_cast<float*>(data)[i]); +#else + return static_cast<float*>(data)[i]; +#endif +} + +inline float AMRGrid::getValue(int i, int j, int k) const +{ + //if (0<=i && i<dims[0] && 0 <=j && j<dims[1] && 0<=k && k<dims[2]) + return getValue(i+dims[0]*(j+k*dims[1])); + //else + // return 0.0; +} + +inline float AMRGrid::getInterpolatedValue(double x, double y, double z) const +{ + // Compute (i, j, k) = index of cell containing position to interpolate value for + x -= origin[0]; + y -= origin[1]; + z -= origin[2]; + + int i = int(x/delta[0]+0.5)-1; + int j = int(y/delta[1]+0.5)-1; + int k = int(z/delta[2]+0.5)-1; + + float deltaX = (getValue(i+1, j, k) - getValue(i-1, j, k)) / delta[0]; + float deltaY = (getValue(i, j+1, k) - getValue(i, j-1, k)) / delta[1]; + float deltaZ = (getValue(i, j, k+1) - getValue(i, j, k-1)) / delta[2]; + + float xi = (float(i)+0.5)*delta[0]; + float yi = (float(j)+0.5)*delta[1]; + float zi = (float(k)+0.5)*delta[2]; + + float res = getValue(i, j, k) + deltaX*(x-xi) + deltaY*(y-yi) + deltaZ*(z-zi); + return res; +#if 0 + double tx = (x-xi)/delta[0]; + double ty = (y-yi)/delta[1]; + double tz = (z-zi)/delta[2]; + + return tz*(ty *(tx*getValue(i+1,j+1,k+1)*(1-tx)*getValue(i,j+1,k+1))+ + (1-ty)*(tx*getValue(i+1,j ,k+1)*(1-tx)*getValue(i,j, k+1))) + +(1-tz)*(ty *(tx*getValue(i+1,j+1,k )*(1-tx)*getValue(i,j+1,k ))+ + (1-ty)*(tx*getValue(i+1,j, k )*(1-tx)*getValue(i,j,k))); +#endif +} + +inline void AMRGrid::unloadCells() +{ + if (data) free(data); + data = NULL; +} + +inline AMRGrid* AMRGrid::getNextGridInLevel() const +{ + return mNextGridInLevel; +} + +inline AMRGrid::AMRRefiningGridIterator AMRGrid::refiningGridsBegin() +{ + return mRefiningGrids.begin(); +} + +inline AMRGrid::AMRRefiningGridIterator AMRGrid::refiningGridsEnd() +{ + return mRefiningGrids.end(); +} + +inline AMRGrid::AMRRefinedGridIterator AMRGrid::refinedGridsBegin() +{ + return mRefinedGrids.begin(); +} + +inline AMRGrid::AMRRefinedGridIterator AMRGrid::refinedGridsEnd() +{ + return mRefinedGrids.end(); +} + +inline AMRGrid::AMRRefiningGridConstIterator AMRGrid::refiningGridsBegin() const +{ + return mRefiningGrids.begin(); +} + +inline AMRGrid::AMRRefiningGridConstIterator AMRGrid::refiningGridsEnd() const +{ + return mRefiningGrids.end(); +} + +inline AMRGrid::AMRRefinedGridConstIterator AMRGrid::refinedGridsBegin() const +{ + return mRefinedGrids.begin(); +} + +inline AMRGrid::AMRRefinedGridConstIterator AMRGrid::refinedGridsEnd() const +{ + return mRefinedGrids.end(); +} + + +inline AMRHierarchy::GridId AMRGrid::index() const +{ + return mGridIndex; +} + +inline const Range<float>& AMRGrid::getValueRange() const +{ + return mValueRange; +} + +inline AMRGrid::IntersectionMap* AMRGrid::computeIntersectionMap(IntersectionMap::MapType mapType) const +{ + return computeIntersectionMap(mapType, PrimitiveBitSet(1), true); +} + +inline bool AMRGrid::refinementAvailable() const +{ + return !mRefiningGrids.empty(); +} + +inline bool AMRGrid::isRefinement() const +{ + return !mRefinedGrids.empty(); +} + +inline AMRHierarchy::GridId AMRGrid::getCellRefiningGridId(const int idx[3]) const +{ + return getCellRefiningGridId(idx[0], idx[1], idx[2]); +} diff --git a/src/AMRHierLib/AMRGridCell.cc b/src/AMRHierLib/AMRGridCell.cc new file mode 100644 index 0000000..6d6cdf1 --- /dev/null +++ b/src/AMRHierLib/AMRGridCell.cc @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +#include <AMRGridCell.hh> + +AMRGridCell::AMRGridCell(AMRGrid *g, int i, int j, int k, int id) : mGrid(g), mRefiningGridId(id) +{ + mIdx[0] = i; + mIdx[1] = j; + mIdx[2] = k; + assert(0<=i && i<mGrid->dims[0]); + assert(0<=j && j<mGrid->dims[1]); + assert(0<=k && k<mGrid->dims[2]); +} + +AMRGridCell::AMRGridCell(AMRGrid *g, int i[3], int id) : mGrid(g), mRefiningGridId(id) +{ + mIdx[0] = i[0]; + mIdx[1] = i[1]; + mIdx[2] = i[2]; + assert(0<=i[0] && i[0]<mGrid->dims[0]); + assert(0<=i[1] && i[1]<mGrid->dims[1]); + assert(0<=i[2] && i[2]<mGrid->dims[2]); +} diff --git a/src/AMRHierLib/AMRGridCell.hh b/src/AMRHierLib/AMRGridCell.hh new file mode 100644 index 0000000..8a09c58 --- /dev/null +++ b/src/AMRHierLib/AMRGridCell.hh @@ -0,0 +1,130 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA and Germany" + * + */ + +#ifndef _GHW_GRIDCELL_ +#define _GHW_GRIDCELL_ + +// Own Misc. Helper Includes +#include <AxisType.hh> +#include <Vertex.hh> + +// AMR Related Includes +#include <AMRGrid.hh> + +/** + * Describe a grid cell + * Describe a grid cell via pointer to grid containing it and its + * index within that grid. + */ +class AMRGridCell { + public: + /** + * Construct a GridCell + * Consturct a new GridCell + * \param g pointer to grid containing the cell + * \param i index of cell along x-Axis + * \param j index of cell along y-Axis + * \param k index of cell along z-Axis + * \param id ID of grid refining this cell, if known + */ + AMRGridCell(AMRGrid *g, int i, int j, int k, AMRHierarchy::GridId id=AMRGrid::Unknown); + /** + * Construct a GridCell + * Consturct a new GridCell + * \param g pointer to grid containing the cell + * \param i index of cell + * \param id ID of grid refining this cell, if known + */ + AMRGridCell(AMRGrid *g, int i[3], AMRHierarchy::GridId id=AMRGrid::Unknown); + /** + * Get absolute position of center of the grid cell + * Calaculate the absoulte position of the center of the grid cell, i.e. the + * location associated with the grid cell sample value. + */ + Vertex pos() const; + /** + * Get value associated with grid point + * Get the scalar value that is stored in the grid for the given grid point. + */ + double val() const; + /** + * Get index of grid containing the grid-cell + * Get the index/ID of the grid that contains this grid cell + */ + int containingId() const; + /** + * Get index of grid refining the grid-cell + * Get the index/ID of the grid that refines this grid cell + */ + int refiningId() const; + /** + * Get a pointer to the AMRGrid containing the cell + */ + AMRGrid *grid() const; + /** + * Get index in 'grid coordinates' + */ + int idx(AxisType axis) const; + private: + AMRGrid *mGrid; // Pointer to the grid containing the cell + int mIdx[3]; // Index of the cell + mutable int mRefiningGridId; // Index of the grid that refines this grid cell +}; + +#include <AMRGridCell.icc> + +#endif diff --git a/src/AMRHierLib/AMRGridCell.icc b/src/AMRHierLib/AMRGridCell.icc new file mode 100644 index 0000000..4365728 --- /dev/null +++ b/src/AMRHierLib/AMRGridCell.icc @@ -0,0 +1,47 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +inline Vertex AMRGridCell::pos() const +{ + return Vertex( + mGrid->origin[0] + (mIdx[0]+0.5) * mGrid->delta[0], + mGrid->origin[1] + (mIdx[1]+0.5) * mGrid->delta[1], + mGrid->origin[2] + (mIdx[2]+0.5) * mGrid->delta[2] + ); +} + +inline double AMRGridCell::val() const +{ + return mGrid->getValue(mIdx[0], mIdx[1], mIdx[2]); +} + +inline AMRHierarchy::GridId AMRGridCell::containingId() const +{ + return mGrid->index(); +} + +inline AMRHierarchy::GridId AMRGridCell::refiningId() const +{ + if (mRefiningGridId == AMRGrid::Unknown) { + mRefiningGridId = mGrid->getCellRefiningGridId(mIdx); + } + return mRefiningGridId; +} + +inline AMRGrid* AMRGridCell::grid() const +{ + return mGrid; +} + +inline int AMRGridCell::idx(AxisType axis) const +{ + return mIdx[axis]; +} diff --git a/src/AMRHierLib/AMRGridStitcher.cc b/src/AMRHierLib/AMRGridStitcher.cc new file mode 100644 index 0000000..61817e4 --- /dev/null +++ b/src/AMRHierLib/AMRGridStitcher.cc @@ -0,0 +1,1936 @@ +//------------------------------------------------------------------------------ +// +// Project: Crack-free Isosurfaces for AMR Data +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +#include "AMRGridStitcher.hh" + +// Own Helper Includes +#include <assume.hh> +#include <Vertex.hh> + +// AMR Specific Includes +#include <AMRGrid.hh> +#include <AMRLevel.hh> + +namespace AMRGridStitcherAuxFct +{ + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism045(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + stitchCellHandler.handleTetrahedronCell(p3, p2, p5, p0); + stitchCellHandler.handlePyramidCell(p1, p4, p5, p2, p0); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism145(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + stitchCellHandler.handleTetrahedronCell(p3, p2, p5, p1); + stitchCellHandler.handlePyramidCell(p0, p3, p5, p4, p1); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism245(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + generateCellsForDeformedTrianglePrism045(stitchCellHandler, p2, p3, p0, p1, p5, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism345(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + generateCellsForDeformedTrianglePrism145(stitchCellHandler, p2, p3, p0, p1, p5, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism0145(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + stitchCellHandler.handleTetrahedronCell(p0, p4, p1, p5); + stitchCellHandler.handlePyramidCell(p0, p1, p2, p3, p5); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism2345(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + generateCellsForDeformedTrianglePrism0145(stitchCellHandler, p2, p3, p0, p1, p5, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism12345(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + stitchCellHandler.handleTetrahedronCell(p0, p4, p1, p3); + stitchCellHandler.handlePyramidCell(p1, p4, p5, p2, p3); + } + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism02345(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + stitchCellHandler.handleTetrahedronCell(p0, p4, p1, p2); + stitchCellHandler.handlePyramidCell(p0, p3, p5, p4, p2); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism01345(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + generateCellsForDeformedTrianglePrism12345(stitchCellHandler, p2, p3, p0, p1, p5, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedTrianglePrism01245(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5) + { + generateCellsForDeformedTrianglePrism02345(stitchCellHandler, p2, p3, p0, p1, p5, p4); + } + template <class StitchCellHandler> + inline void generateCellsForDeformedPyramid04(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4) + { + stitchCellHandler.handleTetrahedronCell(p0, p1, p2, p4); + stitchCellHandler.handleTetrahedronCell(p0, p2, p3, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedPyramid023(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4) + { + stitchCellHandler.handleTetrahedronCell(p0, p1, p2, p4); + stitchCellHandler.handleTetrahedronCell(p0, p2, p3, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedPyramid024(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4) + { + stitchCellHandler.handleTetrahedronCell(p0, p1, p2, p4); + stitchCellHandler.handleTetrahedronCell(p0, p2, p3, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedPyramid1234(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4) + { + stitchCellHandler.handleTetrahedronCell(p0, p1, p3, p4); + stitchCellHandler.handleTetrahedronCell(p1, p2, p3, p4); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedCube024567(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5, const AMRGridCell& p6, const AMRGridCell& p7) + { + generateCellsForDeformedPyramid1234(stitchCellHandler, p3, p7, p4, p0, p2); + generateCellsForDeformedPyramid1234(stitchCellHandler, p1, p0, p4, p5, p2); + stitchCellHandler.handlePyramidCell(p4, p7, p6, p5, p2); + } + + Vertex centroid(const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex& v4, const Vertex& v5, const Vertex& v6) + { + return affineCombination(7, &v0, 1.0/7.0, &v1, 1.0/7.0, &v2, 1.0/7.0, &v3, 1.0/7.0, &v4, 1.0/7.0, &v5, 1.0/7.0, &v6, 1.0/7.0); + } + + template <class StitchCellHandler> + inline void generateCellsForDeformedCube1234567(StitchCellHandler& stitchCellHandler, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3, const AMRGridCell& p4, const AMRGridCell& p5, const AMRGridCell& p6, const AMRGridCell& p7) + { + stitchCellHandler.handleTetrahedronCell(p3, p1, p4, p0); + std::cout << "Inserting vertex to avoid illegal tesselation." << std::endl; + Vertex newPos = AMRGridStitcherAuxFct::centroid(p1.pos(), p2.pos(), p3.pos(), p4.pos(), p5.pos(), p6.pos(), p7.pos()); + double newVal = p1.val() + p2.val() + p3.val() + p4.val() + p5.val() + p6.val() + p7.val(); + newVal /= 7; + stitchCellHandler.handleTetrahedronCell(p3, p4, p1, newPos, newVal); + stitchCellHandler.handleTetrahedronCell(p4, p3, p7, newPos, newVal); + stitchCellHandler.handlePyramidCell(p4, p7, p6, p5, newPos, newVal); + stitchCellHandler.handlePyramidCell(p3, p2, p6, p7, newPos, newVal); + stitchCellHandler.handleTetrahedronCell(p1, p2, p3, newPos, newVal); + stitchCellHandler.handlePyramidCell(p1, p5, p6, p2, newPos, newVal); + stitchCellHandler.handleTetrahedronCell(p1, p4, p5, newPos, newVal); + } +} + +template <class StitchCellHandler> +AMRGridStitcher<StitchCellHandler>::AMRGridStitcher(StitchCellHandler& stitchCellHandler, AMRHierarchy& amrHier, AMRGrid *stitchGrid, bool considerNextLevel) +: mStitchCellHandler(stitchCellHandler), mAMRDataSet(amrHier), mStitchGrid(stitchGrid), mConsiderNextLevel(considerNextLevel), mParentLevel(mAMRDataSet.getLevel(stitchGrid->level-1)) +{ + assert(mParentLevel != 0); + // <ATTENTION> Assume spatialrefinement == gridplacementrefinement </ATTENTION> + // <ATTENTION> Assume spatialrefinement % parentLevel->getSpatialRefinemet == 0 </ATTENTION> + int refinementWRTParentLevel[3]; + refinementWRTParentLevel[xAxis] = mStitchGrid->spatialrefinement[xAxis] / mParentLevel->getSpatialRefinement(xAxis); + refinementWRTParentLevel[yAxis] = mStitchGrid->spatialrefinement[yAxis] / mParentLevel->getSpatialRefinement(yAxis); + refinementWRTParentLevel[zAxis] = mStitchGrid->spatialrefinement[zAxis] / mParentLevel->getSpatialRefinement(zAxis); + + mOriginInParentLevel[xAxis] = mStitchGrid->iorigin[xAxis] / refinementWRTParentLevel[xAxis]; + mOriginInParentLevel[yAxis] = mStitchGrid->iorigin[yAxis] / refinementWRTParentLevel[yAxis]; + mOriginInParentLevel[zAxis] = mStitchGrid->iorigin[zAxis] / refinementWRTParentLevel[zAxis]; + // <ATTENTION> Assume refined grid starts at cell boundaries of parent level </ATTENTION> + assume(mStitchGrid->iorigin[xAxis] % refinementWRTParentLevel[xAxis] == 0); + assume(mStitchGrid->iorigin[yAxis] % refinementWRTParentLevel[yAxis] == 0); + assume(mStitchGrid->iorigin[zAxis] % refinementWRTParentLevel[zAxis] == 0); + + mMaxExtInParentLevel[xAxis] = mOriginInParentLevel[xAxis] + (mStitchGrid->dims[xAxis] / refinementWRTParentLevel[xAxis]) -1; + mMaxExtInParentLevel[yAxis] = mOriginInParentLevel[yAxis] + (mStitchGrid->dims[yAxis] / refinementWRTParentLevel[yAxis]) -1; + mMaxExtInParentLevel[zAxis] = mOriginInParentLevel[zAxis] + (mStitchGrid->dims[zAxis] / refinementWRTParentLevel[zAxis]) -1; + // <ATTENTION> Assume refined grid ends at cell boundaries of parent level </ATTENTION> + assume(mStitchGrid->dims[xAxis] % refinementWRTParentLevel[xAxis] == 0); + assume(mStitchGrid->dims[yAxis] % refinementWRTParentLevel[yAxis] == 0); + assume(mStitchGrid->dims[zAxis] % refinementWRTParentLevel[zAxis] == 0); + + // Load all grids necessary + AMRLevel *thisLevel = mAMRDataSet.getLevel(mStitchGrid->level); + for (AMRGrid *currGridPtr = thisLevel->getFirstGrid(); currGridPtr != 0; currGridPtr = currGridPtr->getNextGridInLevel()) + currGridPtr->loadCells(); + + for (AMRGrid *currGridPtr = mParentLevel->getFirstGrid(); currGridPtr != 0; currGridPtr = currGridPtr->getNextGridInLevel()) + currGridPtr->loadCells(); +} + +template <class StitchCellHandler> +AMRGridStitcher<StitchCellHandler>::~AMRGridStitcher() +{ +} + +template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::generateStitchCells(bool xyMin, bool xyMax, bool yzMin, bool yzMax, bool xzMin, bool xzMax) +{ + if (xyMin) generateCellsForFace(xAxis, yAxis, zAxis, min); + if (xzMin) generateCellsForFace(zAxis, xAxis, yAxis, min); + if (yzMin) generateCellsForFace(yAxis, zAxis, xAxis, min); + if (xyMax) generateCellsForFace(yAxis, xAxis, zAxis, max); + if (xzMax) generateCellsForFace(xAxis, zAxis, yAxis, max); + if (yzMax) generateCellsForFace(zAxis, yAxis, xAxis, max); + if (xyMin || xzMin) generateCellsForEdge(xAxis, yAxis, min, zAxis, min); + if (xyMax || xzMin) generateCellsForEdge(xAxis, yAxis, min, zAxis, max); + if (xyMin || xzMax) generateCellsForEdge(xAxis, yAxis, max, zAxis, min); + if (xyMax || xzMax) generateCellsForEdge(xAxis, yAxis, max, zAxis, max); + if (xyMin || yzMin) generateCellsForEdge(yAxis, zAxis, min, xAxis, min); + if (xyMin || yzMax) generateCellsForEdge(yAxis, zAxis, min, xAxis, max); + if (xyMax || yzMin) generateCellsForEdge(yAxis, zAxis, max, xAxis, min); + if (xyMax || yzMax) generateCellsForEdge(yAxis, zAxis, max, xAxis, max); + if (xzMin || yzMin) generateCellsForEdge(zAxis, xAxis, min, yAxis, min); + if (xzMin || yzMax) generateCellsForEdge(zAxis, xAxis, min, yAxis, max); + if (xzMax || yzMin) generateCellsForEdge(zAxis, xAxis, max, yAxis, min); + if (xzMax || yzMax) generateCellsForEdge(zAxis, xAxis, max, yAxis, max); + generateCellsForVertex(xAxis, yAxis, zAxis, min, min, min); + generateCellsForVertex(zAxis, yAxis, xAxis, min, min, max); + generateCellsForVertex(xAxis, yAxis, zAxis, max, min, max); + generateCellsForVertex(zAxis, yAxis, xAxis, max, min, min); + generateCellsForVertex(zAxis, yAxis, xAxis, min, max, min); + generateCellsForVertex(xAxis, yAxis, zAxis, max, max, min); + generateCellsForVertex(zAxis, yAxis, xAxis, max, max, max); + generateCellsForVertex(xAxis, yAxis, zAxis, min, max, max); +} + +template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::connectQuadToVertex(const AMRGridCell& qp0, const AMRGridCell& qp1, const AMRGridCell& qp2, const AMRGridCell& qp3, const AMRGridCell& vp, AxisType axis0, AxisType axis1, AxisType axis2, MinMaxType faceType) +{ + // If the coarse grid points are from different grids, i.e. the quad results from several + // coarse grids rather than a single one, only generate stitch cells if we are stitching + // the grid with the smallest index. + if (qp0.containingId() < mStitchGrid->index() || qp1.containingId() < mStitchGrid->index() || + qp2.containingId() < mStitchGrid->index() || qp3.containingId() < mStitchGrid->index()) return; + + if (vp.refiningId() != AMRGrid::NoGrid) { + if (mStitchGrid->index() <= vp.refiningId()) { + // No cell bounadaries are crossed, check only one cell for refinement + AMRGrid *otherGrid = mAMRDataSet.getGridByIndex(vp.refiningId()); + AxisAlignedBox<int> refiningCells = otherGrid->getRefiningCells(vp.grid(), vp.idx(xAxis), vp.idx(yAxis), vp.idx(zAxis)); + int oIdx00[3]; + oIdx00[axis0] = refiningCells.min(axis0); + oIdx00[axis1] = refiningCells.min(axis1); + oIdx00[axis2] = faceType == min ? refiningCells.max(axis2) : refiningCells.min(axis2); + + int oIdx01[3]; + oIdx01[axis0] = oIdx00[axis0] + 1; + oIdx01[axis1] = oIdx00[axis1]; + oIdx01[axis2] = oIdx00[axis2]; + + int oIdx10[3]; + oIdx10[axis0] = oIdx00[axis0]; + oIdx10[axis1] = oIdx00[axis1] + 1; + oIdx10[axis2] = oIdx00[axis2]; + + int oIdx11[3]; + oIdx11[axis0] = oIdx00[axis0] + 1; + oIdx11[axis1] = oIdx00[axis1] + 1; + oIdx11[axis2] = oIdx00[axis2]; + + AMRGridCell vpRef0(otherGrid, oIdx00); + AMRGridCell vpRef1(otherGrid, oIdx10); + AMRGridCell vpRef2(otherGrid, oIdx11); + AMRGridCell vpRef3(otherGrid, oIdx01); + + if (!mConsiderNextLevel || + vpRef0.refiningId() == AMRGrid::NoGrid && + vpRef1.refiningId() == AMRGrid::NoGrid && + vpRef2.refiningId() == AMRGrid::NoGrid && + vpRef3.refiningId() == AMRGrid::NoGrid) + // Only add stitch cell when no stitch cells for next level are generated (i.e. + // one of the refining cells is refined itself by an even finer grid) + mStitchCellHandler.handleHexahedronCell(qp0, qp1, qp2, qp3, vpRef0, vpRef1, vpRef2, vpRef3); + } + // else Do nothing! + } + else { + mStitchCellHandler.handlePyramidCell(qp0, qp1, qp2, qp3, vp); + } +} + +template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::connectQuadToEdge(const AMRGridCell& qp0, const AMRGridCell& qp1, const AMRGridCell& qp2, const AMRGridCell& qp3, const AMRGridCell& ep0, const AMRGridCell& ep1, AxisType axis01, AxisType axis03, AxisType axisPerp0123, MinMaxType qp0Axis01Type, MinMaxType qp0Axis03Type, MinMaxType quadFaceType) +{ + // If the coarse grid points are from different grids, i.e. the quad results from several + // coarse grids rather than a single one, only generate stitch cells if we are stitching + // the grid with the smallest index. + if (qp0.containingId() < mStitchGrid->index() || qp1.containingId() < mStitchGrid->index() || + qp2.containingId() < mStitchGrid->index() || qp3.containingId() < mStitchGrid->index()) return; + + int connectCase = 0; + + AMRGridCell *epRef0 = 0; + AMRGridCell *epRef1 = 0; + if (ep0.refiningId() != AMRGrid::NoGrid) { + connectCase |= 1; + + AMRGrid *otherGrid0 = mAMRDataSet.getGridByIndex(ep0.refiningId()); + AxisAlignedBox<int> refiningCells0 = otherGrid0->getRefiningCells(ep0.grid(), ep0.idx(xAxis), ep0.idx(yAxis), ep0.idx(zAxis)); + + int oIdx0[3]; + oIdx0[axis01] = qp0Axis01Type == min ? refiningCells0.min(axis01) : refiningCells0.max(axis01); + oIdx0[axis03] = qp0Axis03Type == min ? refiningCells0.min(axis03) : refiningCells0.max(axis03); + oIdx0[axisPerp0123] = quadFaceType == min ? refiningCells0.max(axisPerp0123) : refiningCells0.min(axisPerp0123); + epRef0 = new AMRGridCell(otherGrid0, oIdx0); + + int oIdx1[3]; + oIdx1[axis01] = qp0Axis01Type == max ? refiningCells0.min(axis01) : refiningCells0.max(axis01); + oIdx1[axis03] = qp0Axis03Type == min ? refiningCells0.min(axis03) : refiningCells0.max(axis03); + oIdx1[axisPerp0123] = quadFaceType == min ? refiningCells0.max(axisPerp0123) : refiningCells0.min(axisPerp0123); + epRef1 = new AMRGridCell(otherGrid0, oIdx1); + } + + AMRGridCell *epRef2 = 0; + AMRGridCell *epRef3 = 0; + if (ep1.refiningId() != AMRGrid::NoGrid) { + connectCase |= 2; + + AMRGrid *otherGrid1 = mAMRDataSet.getGridByIndex(ep1.refiningId()); + AxisAlignedBox<int> refiningCells1 = otherGrid1->getRefiningCells(ep1.grid(), ep1.idx(xAxis), ep1.idx(yAxis), ep1.idx(zAxis)); + + int oIdx2[3]; + oIdx2[axis01] = qp0Axis01Type == max ? refiningCells1.min(axis01) : refiningCells1.max(axis01); + oIdx2[axis03] = qp0Axis03Type == max ? refiningCells1.min(axis03) : refiningCells1.max(axis03); + oIdx2[axisPerp0123] = quadFaceType == min ? refiningCells1.max(axisPerp0123) : refiningCells1.min(axisPerp0123); + epRef2 = new AMRGridCell(otherGrid1, oIdx2); + + int oIdx3[3]; + oIdx3[axis01] = qp0Axis01Type == min ? refiningCells1.min(axis01) : refiningCells1.max(axis01); + oIdx3[axis03] = qp0Axis03Type == max ? refiningCells1.min(axis03) : refiningCells1.max(axis03); + oIdx3[axisPerp0123] = quadFaceType == min ? refiningCells1.max(axisPerp0123) : refiningCells1.min(axisPerp0123); + epRef3 = new AMRGridCell(otherGrid1, oIdx3); + } + + switch (connectCase) { + case 0: + mStitchCellHandler.handleTrianglePrismCell(qp0, qp1, qp2, qp3, ep0, ep1); + break; + case 1: + assert(epRef0->refiningId() == AMRGrid::NoGrid && + epRef1->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= ep0.refiningId()) { + mStitchCellHandler.handlePyramidCell(*epRef0, *epRef1, qp2, qp3, ep1); + mStitchCellHandler.handleTrianglePrismCell(qp3, qp0, qp1, qp2, *epRef0, *epRef1); + } + break; + case 2: + assert(epRef2->refiningId() == AMRGrid::NoGrid && + epRef3->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= ep1.refiningId()) { + mStitchCellHandler.handlePyramidCell(qp0, qp1, *epRef2, *epRef3, ep0); + mStitchCellHandler.handleTrianglePrismCell(qp1, qp2, qp3, qp0, *epRef2, *epRef3); + } + break; + case 3: + if (!mConsiderNextLevel || + epRef0->refiningId() == AMRGrid::NoGrid && + epRef1->refiningId() == AMRGrid::NoGrid && + epRef2->refiningId() == AMRGrid::NoGrid && + epRef3->refiningId() == AMRGrid::NoGrid) + if (mStitchGrid->index() <= ep0.refiningId() && mStitchGrid->index() <= ep1.refiningId()) { + mStitchCellHandler.handleHexahedronCell(qp0, qp1, qp2, qp3, *epRef0, *epRef1, *epRef2, *epRef3); + } + break; + default: + assert(false); + break; + } + delete epRef0; + delete epRef1; + delete epRef2; + delete epRef3; +} + +template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::connectQuadToQuad(const AMRGridCell& qp0, const AMRGridCell& qp1, const AMRGridCell& qp2, const AMRGridCell& qp3, const AMRGridCell& oqp0, const AMRGridCell& oqp1, const AMRGridCell& oqp2, const AMRGridCell& oqp3, AxisType axis01, AxisType axis03, AxisType axisPerp0123, MinMaxType qp0Axis01Type, MinMaxType qp0Axis03Type, MinMaxType quadFaceType) +{ + // If the coarse grid points are from different grids, i.e. the quad results from several + // coarse grids rather than a single one, only generate stitch cells if we are stitching + // the grid with the smallest index. + if (qp0.containingId() < mStitchGrid->index() || qp1.containingId() < mStitchGrid->index() || + qp2.containingId() < mStitchGrid->index() || qp3.containingId() < mStitchGrid->index()) return; + + + int connectCase = 0; + + AMRGridCell *oqp0Ref = 0; + if (oqp0.refiningId() != AMRGrid::NoGrid) { + connectCase |= 1; + AMRGrid *otherGrid0 = mAMRDataSet.getGridByIndex(oqp0.refiningId()); + AxisAlignedBox<int> refiningCells0 = otherGrid0->getRefiningCells(oqp0.grid(), oqp0.idx(xAxis), oqp0.idx(yAxis), oqp0.idx(zAxis)); + int oIdx0[3]; + oIdx0[axis01] = qp0Axis01Type == max ? refiningCells0.max(axis01) : refiningCells0.min(axis01); + oIdx0[axis03] = qp0Axis03Type == max ? refiningCells0.max(axis03) : refiningCells0.min(axis03); + oIdx0[axisPerp0123] = quadFaceType == min ? refiningCells0.max(axisPerp0123) : refiningCells0.min(axisPerp0123); + oqp0Ref = new AMRGridCell(otherGrid0, oIdx0); + } + + AMRGridCell *oqp1Ref = 0; + if (oqp1.refiningId() != AMRGrid::NoGrid) { + connectCase |= 2; + AMRGrid *otherGrid1 = mAMRDataSet.getGridByIndex(oqp1.refiningId()); + AxisAlignedBox<int> refiningCells1 = otherGrid1->getRefiningCells(oqp1.grid(), oqp1.idx(xAxis), oqp1.idx(yAxis), oqp1.idx(zAxis)); + int oIdx1[3]; + oIdx1[axis01] = qp0Axis01Type == max ? refiningCells1.min(axis01) : refiningCells1.max(axis01); + oIdx1[axis03] = qp0Axis03Type == max ? refiningCells1.max(axis03) : refiningCells1.min(axis03); + oIdx1[axisPerp0123] = quadFaceType == min ? refiningCells1.max(axisPerp0123) : refiningCells1.min(axisPerp0123); + oqp1Ref = new AMRGridCell(otherGrid1, oIdx1); + } + + AMRGridCell *oqp2Ref = 0; + if (oqp2.refiningId() != AMRGrid::NoGrid) { + connectCase |= 4; + AMRGrid *otherGrid2 = mAMRDataSet.getGridByIndex(oqp2.refiningId()); + AxisAlignedBox<int> refiningCells2 = otherGrid2->getRefiningCells(oqp2.grid(), oqp2.idx(xAxis), oqp2.idx(yAxis), oqp2.idx(zAxis)); + int oIdx2[3]; + oIdx2[axis01] = qp0Axis01Type == max ? refiningCells2.min(axis01) : refiningCells2.max(axis01); + oIdx2[axis03] = qp0Axis03Type == max ? refiningCells2.min(axis03) : refiningCells2.max(axis03); + oIdx2[axisPerp0123] = quadFaceType == min ? refiningCells2.max(axisPerp0123) : refiningCells2.min(axisPerp0123); + oqp2Ref = new AMRGridCell(otherGrid2, oIdx2); + } + + AMRGridCell *oqp3Ref = 0; + if (oqp3.refiningId() != AMRGrid::NoGrid) { + connectCase |= 8; + AMRGrid *otherGrid3 = mAMRDataSet.getGridByIndex(oqp3.refiningId()); + AxisAlignedBox<int> refiningCells3 = otherGrid3->getRefiningCells(oqp3.grid(), oqp3.idx(xAxis), oqp3.idx(yAxis), oqp3.idx(zAxis)); + int oIdx3[3]; + oIdx3[axis01] = qp0Axis01Type == max ? refiningCells3.max(axis01) : refiningCells3.min(axis01); + oIdx3[axis03] = qp0Axis03Type == max ? refiningCells3.min(axis03) : refiningCells3.max(axis03); + oIdx3[axisPerp0123] = quadFaceType == min ? refiningCells3.max(axisPerp0123) : refiningCells3.min(axisPerp0123); + oqp3Ref = new AMRGridCell(otherGrid3, oIdx3); + } + + switch (connectCase) { + case 0: + mStitchCellHandler.handleHexahedronCell(qp0, qp1, qp2, qp3, oqp0, oqp1, oqp2, oqp3); + break; + case 1: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp0.refiningId()) { + mStitchCellHandler.handlePyramidCell(qp0, qp1, qp2, qp3, *oqp0Ref); + mStitchCellHandler.handlePyramidCell(qp3, qp2, oqp2, oqp3, *oqp0Ref); + mStitchCellHandler.handlePyramidCell(qp2, qp1, oqp1, oqp2, *oqp0Ref); + } + break; + case 2: + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp1.refiningId()) { + mStitchCellHandler.handlePyramidCell(qp0, qp1, qp2, qp3, *oqp1Ref); + mStitchCellHandler.handlePyramidCell(qp0, qp3, oqp3, oqp0, *oqp1Ref); + mStitchCellHandler.handlePyramidCell(qp3, qp2, oqp2, oqp3, *oqp1Ref); + } + break; + case 3: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp0.refiningId() && mStitchGrid->index() <= oqp1.refiningId()) { + mStitchCellHandler.handleTrianglePrismCell(qp1, qp2, qp3, qp0, *oqp1Ref, *oqp0Ref); + mStitchCellHandler.handleTrianglePrismCell(qp2, oqp2, oqp3, qp3,*oqp1Ref, *oqp0Ref); + } + break; + case 4: + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp2.refiningId()) { + mStitchCellHandler.handlePyramidCell(qp0, qp1, qp2, qp3, *oqp2Ref); + mStitchCellHandler.handlePyramidCell(qp1, qp0, oqp0, oqp1, *oqp2Ref); + mStitchCellHandler.handlePyramidCell(qp0, qp3, oqp3, oqp0, *oqp2Ref); + } + break; + case 5: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp0.refiningId() && mStitchGrid->index() <= oqp2.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedCube024567(mStitchCellHandler, *oqp0Ref, oqp3, *oqp2Ref, oqp1, qp0, qp3, qp2, qp1); + } + break; + case 6: + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp1.refiningId() && mStitchGrid->index() <= oqp2.refiningId()) { + mStitchCellHandler.handleTrianglePrismCell(qp0, qp1, qp2, qp3, *oqp1Ref, *oqp2Ref); + mStitchCellHandler.handleTrianglePrismCell(oqp0, qp0, qp3, oqp3, *oqp1Ref, *oqp2Ref); + } + break; + case 7: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp2.refiningId() && mStitchGrid->index() <= oqp1.refiningId() && mStitchGrid->index() <= oqp0.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedCube1234567(mStitchCellHandler, oqp3, *oqp2Ref, *oqp1Ref, *oqp0Ref, qp3, qp2, qp1, qp0); + } + break; + case 8: + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp3.refiningId()) { + mStitchCellHandler.handlePyramidCell(qp0, qp1, qp2, qp3, *oqp3Ref); + mStitchCellHandler.handlePyramidCell(qp1, qp0, oqp0, oqp1, *oqp3Ref); + mStitchCellHandler.handlePyramidCell(qp2, qp1, oqp1, oqp2, *oqp3Ref); + } + break; + case 9: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp0.refiningId() && mStitchGrid->index() <= oqp3.refiningId()) { + mStitchCellHandler.handleTrianglePrismCell(qp0, qp1, qp2, qp3, *oqp0Ref, *oqp3Ref); + mStitchCellHandler.handleTrianglePrismCell(qp1, oqp1, oqp2, qp2, *oqp0Ref, *oqp3Ref); + } + break; + case 10: + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp1.refiningId() && mStitchGrid->index() <= oqp3.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedCube024567(mStitchCellHandler, *oqp1Ref, oqp0, *oqp3Ref, oqp2, qp1, qp0, qp3, qp2); + } + break; + case 11: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp3.refiningId() && mStitchGrid->index() <= oqp1.refiningId() && mStitchGrid->index() <= oqp0.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedCube1234567(mStitchCellHandler, oqp2, *oqp1Ref, *oqp0Ref, *oqp3Ref, qp2, qp1, qp0, qp3); + } + break; + case 12: + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp2.refiningId() && mStitchGrid->index() <= oqp3.refiningId()) { + mStitchCellHandler.handleTrianglePrismCell(qp1, qp2, qp3, qp0, *oqp2Ref, *oqp3Ref); + mStitchCellHandler.handleTrianglePrismCell(oqp1, qp1, qp0, oqp0, *oqp2Ref, *oqp3Ref); + } + break; + case 13: + assert(oqp0Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp3.refiningId() && mStitchGrid->index() <= oqp2.refiningId() && mStitchGrid->index() <= oqp0.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedCube1234567(mStitchCellHandler, oqp1, *oqp0Ref, *oqp3Ref, *oqp2Ref, qp1, qp0, qp3, qp2); + } + break; + case 14: + assert(oqp1Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp2Ref->refiningId() == AMRGrid::NoGrid); + assert(oqp3Ref->refiningId() == AMRGrid::NoGrid); + if (mStitchGrid->index() <= oqp3.refiningId() && mStitchGrid->index() <= oqp2.refiningId() && mStitchGrid->index() <= oqp1.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedCube1234567(mStitchCellHandler, oqp0, *oqp3Ref, *oqp2Ref, *oqp1Ref, qp0, qp3, qp2, qp1); + } + break; + case 15: + if (!mConsiderNextLevel || + oqp0Ref->refiningId() == AMRGrid::NoGrid && + oqp1Ref->refiningId() == AMRGrid::NoGrid && + oqp2Ref->refiningId() == AMRGrid::NoGrid && + oqp3Ref->refiningId() == AMRGrid::NoGrid) + if (mStitchGrid->index() <= oqp0.refiningId() && mStitchGrid->index() <= oqp1.refiningId() && mStitchGrid->index() <= oqp2.refiningId() && mStitchGrid->index() <= oqp3.refiningId()) { + mStitchCellHandler.handleHexahedronCell(qp0, qp1, qp2, qp3, *oqp0Ref, *oqp1Ref, *oqp2Ref, *oqp3Ref); + } + break; + default: + assert(false); + } +} + +template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::connectEdgeSegmentToEdges(const AMRGridCell& ep0, const AMRGridCell& ep1, const AMRGridCell& cp0, const AMRGridCell& cp1, const AMRGridCell& cp2, AxisType edgeAxis, AxisType edgeAxis01, MinMaxType edgeAxis01Type, AxisType edgeAxis02, MinMaxType edgeAxis02Type) +{ + if (ep0.containingId() < mStitchGrid->index() || ep1.containingId() < mStitchGrid->index()) return; + + if (cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + mStitchCellHandler.handleTetrahedronCell(ep0, ep1, cp0, cp1); + mStitchCellHandler.handleTetrahedronCell(ep0, cp0, ep1, cp2); + } + else if (cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + if (mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0Ref0Idx[3]; + cp0Ref0Idx[edgeAxis] = cp0RefiningCells.min(edgeAxis); + cp0Ref0Idx[edgeAxis01] = edgeAxis01Type == min ? cp0RefiningCells.max(edgeAxis01) : cp0RefiningCells.min(edgeAxis01); + cp0Ref0Idx[edgeAxis02] = edgeAxis02Type == min ? cp0RefiningCells.max(edgeAxis01) : cp0RefiningCells.min(edgeAxis01); + AMRGridCell cp0Ref0(cp0RefiningGrid, cp0Ref0Idx[0], cp0Ref0Idx[1], cp0Ref0Idx[2]); + int cp0Ref1Idx[3]; + cp0Ref1Idx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0Ref1Idx[edgeAxis01] = cp0Ref0Idx[edgeAxis01]; + cp0Ref1Idx[edgeAxis02] = cp0Ref0Idx[edgeAxis02]; + AMRGridCell cp0Ref1(cp0RefiningGrid, cp0Ref1Idx[0], cp0Ref1Idx[1], cp0Ref1Idx[2]); + mStitchCellHandler.handlePyramidCell(ep0, ep1, cp0Ref1, cp0Ref0, cp1); + mStitchCellHandler.handlePyramidCell(ep0, cp0Ref0, cp0Ref1, ep1, cp2); + } + } + else if (cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1Ref0Idx[3]; + cp1Ref0Idx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1Ref0Idx[edgeAxis01] = edgeAxis01Type == min ? cp1RefiningCells.min(edgeAxis01) : cp1RefiningCells.max(edgeAxis01); + cp1Ref0Idx[edgeAxis02] = edgeAxis02Type == min ? cp1RefiningCells.max(edgeAxis02) : cp1RefiningCells.min(edgeAxis02); + AMRGridCell cp1Ref0(cp1RefiningGrid, cp1Ref0Idx[0], cp1Ref0Idx[1], cp1Ref0Idx[2]); + int cp1Ref1Idx[3]; + cp1Ref1Idx[edgeAxis] = cp1RefiningCells.max(edgeAxis); + cp1Ref1Idx[edgeAxis01] = cp1Ref0Idx[edgeAxis01]; + cp1Ref1Idx[edgeAxis02] = cp1Ref0Idx[edgeAxis02]; + AMRGridCell cp1Ref1(cp1RefiningGrid, cp1Ref1Idx[0], cp1Ref1Idx[1], cp1Ref1Idx[2]); + connectQuadToEdge(cp1Ref0, cp1Ref1, ep1, ep0, cp0, cp2, edgeAxis, edgeAxis02, edgeAxis01, min, edgeAxis02Type == min ? max : min, edgeAxis01Type); + } + else { + assert(cp2.refiningId() != AMRGrid::NoGrid); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2Ref0Idx[3]; + cp2Ref0Idx[edgeAxis] = cp2RefiningCells.min(edgeAxis); + cp2Ref0Idx[edgeAxis01] = edgeAxis01Type == min ? cp2RefiningCells.max(edgeAxis01) : cp2RefiningCells.min(edgeAxis01); + cp2Ref0Idx[edgeAxis02] = edgeAxis02Type == min ? cp2RefiningCells.min(edgeAxis02) : cp2RefiningCells.max(edgeAxis02); + AMRGridCell cp2Ref0(cp2RefiningGrid, cp2Ref0Idx[0], cp2Ref0Idx[1], cp2Ref0Idx[2]); + int cp2Ref1Idx[3]; + cp2Ref1Idx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2Ref1Idx[edgeAxis01] = cp2Ref0Idx[edgeAxis01]; + cp2Ref1Idx[edgeAxis02] = cp2Ref0Idx[edgeAxis02]; + AMRGridCell cp2Ref1(cp2RefiningGrid, cp2Ref1Idx[0], cp2Ref1Idx[1], cp2Ref1Idx[2]); + connectQuadToEdge(cp2Ref1, cp2Ref0, ep0, ep1, cp0, cp1, edgeAxis, edgeAxis01, edgeAxis02, max, edgeAxis01Type == min ? max : min, edgeAxis02Type); + } +} + +template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::connectEdgeSegmentToQuads(const AMRGridCell& ep0, const AMRGridCell& ep1, const AMRGridCell& cp0, const AMRGridCell& cp1, const AMRGridCell& cp2, const AMRGridCell& cp3, const AMRGridCell& cp4, const AMRGridCell& cp5, AxisType edgeAxis, AxisType addAxis0132, MinMaxType edgeAxis0132Type, AxisType addAxis0451, MinMaxType edgeAxis0451Type) +{ + if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 0 + mStitchCellHandler.handleTrianglePrismCell(cp2, cp0, cp1, cp3, ep0, ep1); + mStitchCellHandler.handleTrianglePrismCell(cp0, cp4, cp5, cp1, ep0, ep1); + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 1 + if (mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism145(mStitchCellHandler, cp2, cp0Ref, cp1, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism045(mStitchCellHandler, cp0Ref, cp4, cp5, cp1, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 2 + if (mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism245(mStitchCellHandler, cp2, cp0, cp1Ref, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism345(mStitchCellHandler, cp0, cp4, cp5, cp1Ref, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 3 + if (mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + mStitchCellHandler.handleTrianglePrismCell(cp0Ref, ep0, ep1, cp1Ref, cp2, cp3); + mStitchCellHandler.handleTrianglePrismCell(ep0, cp0Ref, cp1Ref, ep1, cp4, cp5); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 4 + if (mStitchGrid->index() <= cp2.refiningId()) { + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + mStitchCellHandler.handleTetrahedronCell(ep1, cp1, cp2Ref, cp3); + std::cout << "Inserting vertex to avoid illegal tesselation (Case 4)." << std::endl; + Vertex newPos = AMRGridStitcherAuxFct::centroid(ep0.pos(), ep1.pos(), cp0.pos(), cp1.pos(), cp2Ref.pos(), cp4.pos(), cp5.pos()); + double newVal = ep0.val() + ep1.val() + cp0.val() + cp1.val() + cp2Ref.val() + cp4.val() + cp5.val(); + newVal /= 7; + mStitchCellHandler.handlePyramidCell(ep0, cp4, cp0, cp2Ref, newPos, newVal); + mStitchCellHandler.handlePyramidCell(ep0, ep1, cp5, cp4, newPos, newVal); + mStitchCellHandler.handlePyramidCell(cp0, cp4, cp5, cp1, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep1, cp1, cp5, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep1, cp2Ref, cp1, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(cp0, cp1, cp2Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, cp2Ref, ep1, newPos, newVal); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 5 + if (mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism0145(mStitchCellHandler, cp2Ref, cp0Ref, cp1, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism045(mStitchCellHandler, cp0Ref, cp4, cp5, cp1, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 6 + if (mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + mStitchCellHandler.handlePyramidCell(ep0, cp4, cp0, cp2Ref, cp1Ref); + mStitchCellHandler.handlePyramidCell(ep0, ep1, cp5, cp4, cp1Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp3, ep1, ep0, cp2Ref, cp1Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 7 + if (mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism01245(mStitchCellHandler, cp2Ref, cp0Ref, cp1Ref, cp3, ep0, ep1); + mStitchCellHandler.handleTrianglePrismCell(cp0Ref, cp4, cp5, cp1Ref, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 8 + if (mStitchGrid->index() <= cp3.refiningId()) { + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + mStitchCellHandler.handleTetrahedronCell(ep0, cp3Ref, cp0, cp2); + std::cout << "Inserting vertex to avoid illegal tesselation (Case 8)." << std::endl; + Vertex newPos = AMRGridStitcherAuxFct::centroid(ep0.pos(), ep1.pos(), cp0.pos(), cp1.pos(), cp3Ref.pos(), cp4.pos(), cp5.pos()); + double newVal = ep0.val() + ep1.val() + cp0.val() + cp1.val() + cp3Ref.val() + cp4.val() + cp5.val(); + newVal /= 7; + mStitchCellHandler.handlePyramidCell(cp0, cp4, cp5, cp1, newPos, newVal); + mStitchCellHandler.handlePyramidCell(ep0, ep1, cp5, cp4, newPos, newVal); + mStitchCellHandler.handlePyramidCell(ep1, cp3Ref, cp1, cp5, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, cp4, cp0, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, cp0, cp3Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(cp0, cp1, cp3Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, cp3Ref, ep1, newPos, newVal); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 9 + if (mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + + mStitchCellHandler.handlePyramidCell(cp1, cp5, ep1, cp3Ref, cp0Ref); + mStitchCellHandler.handlePyramidCell(ep0, ep1, cp5, cp4, cp0Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp2, cp3Ref, ep1, ep0, cp0Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 10 + if (mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism2345(mStitchCellHandler, cp2, cp0, cp1Ref, cp3Ref, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism345(mStitchCellHandler, cp0, cp4, cp5, cp1Ref, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 11 + if (mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism12345(mStitchCellHandler, cp2, cp0Ref, cp1Ref, cp3Ref, ep0, ep1); + mStitchCellHandler.handleTrianglePrismCell(cp0Ref, cp4, cp5, cp1Ref, ep0, ep1); + } + } + else if (!(cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid) && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid) { + // Case 12 ... 15, Case 28 ... 31, Case 44 ... 47 + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + connectQuadToQuad(ep0, cp2Ref, cp3Ref, ep1, cp4, cp0, cp1, cp5, addAxis0451, edgeAxis, addAxis0132, edgeAxis0451Type, max, edgeAxis0132Type); + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 16 + if (mStitchGrid->index() <= cp4.refiningId()) { + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + mStitchCellHandler.handleTetrahedronCell(ep1, cp4Ref, cp1, cp5); + std::cout << "Inserting vertex to avoid illegal tesselation (Case 16)." << std::endl; + Vertex newPos = AMRGridStitcherAuxFct::centroid(ep0.pos(), ep1.pos(), cp0.pos(), cp1.pos(), cp2.pos(), cp3.pos(), cp4Ref.pos()); + double newVal = ep0.val() + ep1.val() + cp0.val() + cp1.val() + cp2.val() + cp3.val() + cp4Ref.val(); + newVal /= 7; + mStitchCellHandler.handlePyramidCell(ep0, cp4Ref, cp0, cp2, newPos, newVal); + mStitchCellHandler.handlePyramidCell(cp0, cp1, cp3, cp2, newPos, newVal); + mStitchCellHandler.handlePyramidCell(ep0, cp2, cp3, ep1, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, ep1, cp4Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep1, cp1, cp4Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep1, cp3, cp1, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(cp0, cp4Ref, cp1, newPos, newVal); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 17 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism145(mStitchCellHandler, cp2, cp0Ref, cp1, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism0145(mStitchCellHandler, cp0Ref, cp4Ref, cp5, cp1, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 18 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + + mStitchCellHandler.handlePyramidCell(ep0, cp2, cp3, ep1, cp1Ref); + mStitchCellHandler.handlePyramidCell(ep0, cp4Ref, cp0, cp2, cp1Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp5, cp4Ref, ep0, ep1, cp1Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 19 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <=cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + mStitchCellHandler.handleTrianglePrismCell(cp2, cp0Ref, cp1Ref, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism01345(mStitchCellHandler, cp0Ref, cp4Ref, cp5, cp1Ref, ep0, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 20 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp2.refiningId()) { + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp3, ep1, ep0, cp2Ref, cp4Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, cp2Ref, cp0, cp1, cp3, cp4Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, ep1, cp3, cp1, cp5, cp4Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 21 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + mStitchCellHandler.handlePyramidCell(ep0, cp4Ref, cp0Ref, cp2Ref, ep1); + mStitchCellHandler.handlePyramidCell(cp0Ref, cp4Ref, cp5, cp1, ep1); + mStitchCellHandler.handlePyramidCell(cp0Ref, cp1, cp3, cp2Ref, ep1); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 22 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid024(mStitchCellHandler, ep1, cp3, cp1Ref, cp5, cp4Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid024(mStitchCellHandler, cp1Ref, cp3, cp2Ref, cp0, cp4Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp3, ep1, ep0, cp2Ref, cp4Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 23 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + mStitchCellHandler.handlePyramidCell(cp0Ref, cp2Ref, ep0, cp4Ref, cp1Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp3, ep1, ep0, cp2Ref, cp1Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp5, cp4Ref, ep0, ep1, cp1Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 24 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index()) { + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + mStitchCellHandler.handlePyramidCell(cp0, cp2, ep0, cp4Ref, cp3Ref); + mStitchCellHandler.handleTetrahedronCell(cp0, cp4Ref, cp1, cp3Ref); + mStitchCellHandler.handlePyramidCell(ep1, cp3Ref, cp1, cp5, cp4Ref); + mStitchCellHandler.handleTetrahedronCell(ep0, cp3Ref, ep1, cp4Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 25 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() && cp0.refiningId() <= mStitchGrid->index()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + mStitchCellHandler.handleTrianglePrismCell(cp3Ref, cp1, cp5, ep1, cp0Ref, cp4Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism12345(mStitchCellHandler, cp2, cp3Ref, ep1, ep0, cp0Ref, cp4Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 26 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() && cp1.refiningId() <= mStitchGrid->index()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + + mStitchCellHandler.handleTrianglePrismCell(cp4Ref, cp0, cp2, ep0, cp1Ref, cp3Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism12345(mStitchCellHandler, cp5, cp4Ref, ep0, ep1, cp1Ref, cp3Ref); + } + } + else if (cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 27 + if (mStitchGrid->index() <= cp4.refiningId() && mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() && cp1.refiningId() <= mStitchGrid->index() && cp0.refiningId() <= mStitchGrid->index()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism12345(mStitchCellHandler, cp2, cp0Ref, cp1Ref, cp3Ref, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism01345(mStitchCellHandler, cp0Ref, cp4Ref, cp5, cp1Ref, ep0, ep1); + } + } + // Case 28 ... 31 see Case 12 ... 15 + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 32 + if (mStitchGrid->index() <= cp5.refiningId()) { + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + mStitchCellHandler.handleTetrahedronCell(ep0, cp0, cp5Ref, cp4); + std::cout << "Inserting vertex to avoid illegal tesselation (Case 32)." << std::endl; + Vertex newPos = AMRGridStitcherAuxFct::centroid(ep0.pos(), ep1.pos(), cp0.pos(), cp1.pos(), cp2.pos(), cp3.pos(), cp5Ref.pos()); + double newVal = ep0.val() + ep1.val() + cp0.val() + cp1.val() + cp2.val() + cp3.val() + cp5Ref.val(); + newVal /= 7; + mStitchCellHandler.handlePyramidCell(ep0, cp2, cp3, ep1, newPos, newVal); + mStitchCellHandler.handlePyramidCell(cp0, cp1, cp3, cp2, newPos, newVal); + mStitchCellHandler.handlePyramidCell(ep1, cp3, cp1, cp5Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, ep1, cp5Ref, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, cp5Ref, cp0, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(ep0, cp0, cp2, newPos, newVal); + mStitchCellHandler.handleTetrahedronCell(cp0, cp5Ref, cp1, newPos, newVal); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 33 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + mStitchCellHandler.handlePyramidCell(cp1, cp5Ref, ep1, cp3, cp0Ref); + mStitchCellHandler.handlePyramidCell(ep0, cp2, cp3, ep1, cp0Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp4, ep0, ep1, cp5Ref, cp0Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 34 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism245(mStitchCellHandler, cp2, cp0, cp1Ref, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism2345(mStitchCellHandler, cp0, cp4, cp5Ref, cp1Ref, ep0, ep1); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 35 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + mStitchCellHandler.handleTrianglePrismCell(cp2, cp0Ref, cp1Ref, cp3, ep0, ep1); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism02345(mStitchCellHandler, cp0Ref, cp4, cp5Ref, cp1Ref, ep0, ep1); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 36 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp2.refiningId()) { + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism145(mStitchCellHandler, cp3, cp2Ref, cp0, cp1, ep1, cp5Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism0145(mStitchCellHandler, cp2Ref, ep0, cp4, cp0, ep1, cp5Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 37 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + mStitchCellHandler.handleTrianglePrismCell(cp3, cp2Ref, cp0Ref, cp1, ep1, cp5Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism01345(mStitchCellHandler, cp2Ref, ep0, cp4, cp0Ref, ep1, cp5Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 38 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + mStitchCellHandler.handleTrianglePrismCell(ep0, cp4, cp0, cp2Ref, cp5Ref, cp1Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism01245(mStitchCellHandler, ep1, ep0, cp2Ref, cp3, cp5Ref, cp1Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() != AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 39 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp2.refiningId() && mStitchGrid->index() <= cp1.refiningId() && cp0.refiningId() <= mStitchGrid->index()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp2RefiningGrid = mAMRDataSet.getGridByIndex(cp2.refiningId()); + AxisAlignedBox<int> cp2RefiningCells = cp2RefiningGrid->getRefiningCells(cp2.grid(), cp2.idx(xAxis), cp2.idx(yAxis), cp2.idx(zAxis)); + int cp2RefIdx[3]; + cp2RefIdx[edgeAxis] = cp2RefiningCells.max(edgeAxis); + cp2RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp2RefiningCells.min(addAxis0132) : cp2RefiningCells.max(addAxis0132); + cp2RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp2RefiningCells.max(addAxis0451) : cp2RefiningCells.min(addAxis0451); + AMRGridCell cp2Ref(cp2RefiningGrid, cp2RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism02345(mStitchCellHandler, ep0, cp4, cp0Ref, cp2Ref, cp5Ref, cp1Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedTrianglePrism01245(mStitchCellHandler, ep1, ep0, cp2Ref, cp3, cp5Ref, cp1Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 40 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp3.refiningId()) { + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, ep0, cp4, cp0, cp2, cp5Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, cp3Ref, cp2, cp0, cp1, cp5Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp2, cp3Ref, ep1, ep0, cp5Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 41 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp3.refiningId() && cp0.refiningId() <= mStitchGrid->index()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid024(mStitchCellHandler, ep0, cp4, cp0Ref, cp2, cp5Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid024(mStitchCellHandler, cp3Ref, cp2, cp0Ref, cp1, cp5Ref); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp2, cp3Ref, ep1, ep0, cp5Ref); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + // Case 42 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() <= cp1.refiningId()) { + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + mStitchCellHandler.handlePyramidCell(ep1, cp3Ref, cp1Ref, cp5Ref, ep0); + mStitchCellHandler.handlePyramidCell(cp0, cp4, cp5Ref, cp1Ref, ep0); + mStitchCellHandler.handlePyramidCell(cp0, cp1Ref, cp3Ref, cp2, ep0); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() != AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() != AMRGrid::NoGrid && cp0.refiningId() != AMRGrid::NoGrid) { + // Case 43 + if (mStitchGrid->index() <= cp5.refiningId() && mStitchGrid->index() <= cp3.refiningId() && mStitchGrid->index() <= cp1.refiningId() && mStitchGrid->index() <= cp0.refiningId()) { + AMRGrid *cp0RefiningGrid = mAMRDataSet.getGridByIndex(cp0.refiningId()); + AxisAlignedBox<int> cp0RefiningCells = cp0RefiningGrid->getRefiningCells(cp0.grid(), cp0.idx(xAxis), cp0.idx(yAxis), cp0.idx(zAxis)); + int cp0RefIdx[3]; + cp0RefIdx[edgeAxis] = cp0RefiningCells.max(edgeAxis); + cp0RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp0RefiningCells.max(addAxis0132) : cp0RefiningCells.min(addAxis0132); + cp0RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp0RefiningCells.max(addAxis0451) : cp0RefiningCells.min(addAxis0451); + AMRGridCell cp0Ref(cp0RefiningGrid, cp0RefIdx); + AMRGrid *cp1RefiningGrid = mAMRDataSet.getGridByIndex(cp1.refiningId()); + AxisAlignedBox<int> cp1RefiningCells = cp1RefiningGrid->getRefiningCells(cp1.grid(), cp1.idx(xAxis), cp1.idx(yAxis), cp1.idx(zAxis)); + int cp1RefIdx[3]; + cp1RefIdx[edgeAxis] = cp1RefiningCells.min(edgeAxis); + cp1RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp1RefiningCells.max(addAxis0132) : cp1RefiningCells.min(addAxis0132); + cp1RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp1RefiningCells.max(addAxis0451) : cp1RefiningCells.min(addAxis0451); + AMRGridCell cp1Ref(cp1RefiningGrid, cp1RefIdx); + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[edgeAxis] = cp3RefiningCells.min(edgeAxis); + cp3RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp3RefiningCells.min(addAxis0132) : cp3RefiningCells.max(addAxis0132); + cp3RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp3RefiningCells.max(addAxis0451) : cp3RefiningCells.min(addAxis0451); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + mStitchCellHandler.handlePyramidCell(ep1, cp3Ref, cp1Ref, cp5Ref, ep0); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp4, cp5Ref, cp1Ref, cp0Ref, ep0); + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, cp2, cp0Ref, cp1Ref, cp3Ref, ep0); + } + } + else if (cp5.refiningId() != AMRGrid::NoGrid && cp4.refiningId() != AMRGrid::NoGrid) { + // Case 48 ... 63 + AMRGrid *cp4RefiningGrid = mAMRDataSet.getGridByIndex(cp4.refiningId()); + AxisAlignedBox<int> cp4RefiningCells = cp4RefiningGrid->getRefiningCells(cp4.grid(), cp4.idx(xAxis), cp4.idx(yAxis), cp4.idx(zAxis)); + int cp4RefIdx[3]; + cp4RefIdx[edgeAxis] = cp4RefiningCells.max(edgeAxis); + cp4RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp4RefiningCells.max(addAxis0132) : cp4RefiningCells.min(addAxis0132); + cp4RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp4RefiningCells.min(addAxis0451) : cp4RefiningCells.max(addAxis0451); + AMRGridCell cp4Ref(cp4RefiningGrid, cp4RefIdx); + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[edgeAxis] = cp5RefiningCells.min(edgeAxis); + cp5RefIdx[addAxis0132] = edgeAxis0132Type == min ? cp5RefiningCells.max(addAxis0132) : cp5RefiningCells.min(addAxis0132); + cp5RefIdx[addAxis0451] = edgeAxis0451Type == min ? cp5RefiningCells.min(addAxis0451) : cp5RefiningCells.max(addAxis0451); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + connectQuadToQuad(ep0, ep1, cp5Ref, cp4Ref, cp2, cp3, cp1, cp0, edgeAxis, addAxis0132, addAxis0451, max, edgeAxis0132Type, edgeAxis0451Type); + } + else { + assert(false); + } +} + + template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::connectVertexToQuad(const AMRGridCell& vtx, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3) +{ + assert(p0.refiningId() == AMRGrid::NoGrid); + if (p1.refiningId() == AMRGrid::NoGrid && p2.refiningId() == AMRGrid::NoGrid && p3.refiningId() == AMRGrid::NoGrid) { + mStitchCellHandler.handlePyramidCell(p0, p1, p2, p3, vtx); + } + else if (p1.refiningId() != AMRGrid::NoGrid && p2.refiningId() == AMRGrid::NoGrid && p3.refiningId() == AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p1.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, p1, p2, p3, p0, vtx); + } + } + else if (p1.refiningId() == AMRGrid::NoGrid && p2.refiningId() != AMRGrid::NoGrid && p3.refiningId() == AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p2.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, p2, p3, p0, p1, vtx); + } + } + else if (p1.refiningId() == AMRGrid::NoGrid && p2.refiningId() == AMRGrid::NoGrid && p3.refiningId() != AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p3.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid04(mStitchCellHandler, p3, p0, p1, p2, vtx); + } + } + else if (p1.refiningId() != AMRGrid::NoGrid && p2.refiningId() != AMRGrid::NoGrid && p3.refiningId() == AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p1.refiningId() && mStitchGrid->index() <= p2.refiningId()) { + mStitchCellHandler.handlePyramidCell(p0, p1, p2, p3, vtx); + } + } + else if (p1.refiningId() != AMRGrid::NoGrid && p2.refiningId() == AMRGrid::NoGrid && p3.refiningId() != AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p1.refiningId() && mStitchGrid->index() <= p3.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid024(mStitchCellHandler, p1, p2, p3, p0, vtx); + } + } + else if (p1.refiningId() == AMRGrid::NoGrid && p2.refiningId() != AMRGrid::NoGrid && p3.refiningId() != AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p1.refiningId() && mStitchGrid->index() <= p2.refiningId()) { + mStitchCellHandler.handlePyramidCell(p0, p1, p2, p3, vtx); + } + } + else if (p1.refiningId() != AMRGrid::NoGrid && p2.refiningId() != AMRGrid::NoGrid && p3.refiningId() != AMRGrid::NoGrid) { + if (mStitchGrid->index() <= p1.refiningId() && mStitchGrid->index() <= p2.refiningId() && mStitchGrid->index() <= p3.refiningId()) { + AMRGridStitcherAuxFct::generateCellsForDeformedPyramid1234(mStitchCellHandler, p0, p1, p2, p3, vtx); + } + } + else { + assert(false); + } + +} + + template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::generateCellsForFace(AxisType axis0, AxisType axis1, AxisType axis2, MinMaxType faceType) +{ + assert(axis0 != axis1 && axis0 != axis2 && axis1 != axis2); + + try { + // Here for k=0. k=refiningGrid->dims[2]-1 analogous + // In this step we connect the faces of the refining grid with points in the + // refined grid. + for (int fFaceIdx0=0; fFaceIdx0<mStitchGrid->dims[axis0]-1; ++fFaceIdx0) + for (int fFaceIdx1=0; fFaceIdx1<mStitchGrid->dims[axis1]-1; ++fFaceIdx1) { + int cIdx00[3]; + cIdx00[axis0] = mOriginInParentLevel[axis0] + fFaceIdx0/2; + cIdx00[axis1] = mOriginInParentLevel[axis1] + fFaceIdx1/2; + if (faceType == min) + cIdx00[axis2] = mOriginInParentLevel[axis2] - 1; + else + cIdx00[axis2] = mMaxExtInParentLevel[axis2] + 1; + AMRGridCell cp0 = mParentLevel->getGridCell(cIdx00); + + int cIdx01[3]; + cIdx01[axis0] = cIdx00[axis0] + 1; + cIdx01[axis1] = cIdx00[axis1]; + cIdx01[axis2] = cIdx00[axis2]; + AMRGridCell cp3 = mParentLevel->getGridCell(cIdx01); + + int cIdx10[3]; + cIdx10[axis0] = cIdx00[axis0]; + cIdx10[axis1] = cIdx00[axis1] + 1; + cIdx10[axis2] = cIdx00[axis2]; + AMRGridCell cp1 = mParentLevel->getGridCell(cIdx10); + + int cIdx11[3]; + cIdx11[axis0] = cIdx00[axis0] + 1; + cIdx11[axis1] = cIdx00[axis1] + 1; + cIdx11[axis2] = cIdx00[axis2]; + AMRGridCell cp2 = mParentLevel->getGridCell(cIdx11);; + + int fIdx00[3]; + fIdx00[axis0] = fFaceIdx0; + fIdx00[axis1] = fFaceIdx1; + if (faceType == min) + fIdx00[axis2] = 0; + else + fIdx00[axis2] = mStitchGrid->dims[axis2] - 1; + AMRGridCell fp0(mStitchGrid, fIdx00[0], fIdx00[1], fIdx00[2]); + + int fIdx01[3]; + fIdx01[axis0] = fIdx00[axis0] + 1; + fIdx01[axis1] = fIdx00[axis1]; + fIdx01[axis2] = fIdx00[axis2]; + AMRGridCell fp3(mStitchGrid, fIdx01[0], fIdx01[1], fIdx01[2]); + + int fIdx10[3]; + fIdx10[axis0] = fIdx00[axis0]; + fIdx10[axis1] = fIdx00[axis1] + 1; + fIdx10[axis2] = fIdx00[axis2]; + AMRGridCell fp1(mStitchGrid, fIdx10[0], fIdx10[1], fIdx10[2]); + + int fIdx11[3]; + fIdx11[axis0] = fIdx00[axis0] + 1; + fIdx11[axis1] = fIdx00[axis1] + 1; + fIdx11[axis2] = fIdx00[axis2]; + AMRGridCell fp2(mStitchGrid, fIdx11[0], fIdx11[1], fIdx11[2]); + + // Compute combination from 2D case. If i is even, we connect with the corresponding + // point, if it is odd, we connect with the corresponding edge. The same for j. + // The combination yields: + // Axis 1 Axis 0 Result + // ====================== + // point point point + // point edge edge 0 (parallel axis 0) + // edge point edge 1 (parallel to axis 1) + // edge edge quad + enum ConnectionTypeType { Point = 0, Edge0 = 1, Edge1 = 2, Quad = 3 }; + ConnectionTypeType connectionType = ConnectionTypeType((fFaceIdx1%2) << 1 | fFaceIdx0%2); + switch (connectionType) { + case Point: + connectQuadToVertex(fp0, fp1, fp2, fp3, cp0, axis0, axis1, axis2, faceType); + break; + case Edge0: + //connectQuadToAxis0Edge(fp0, fp1, fp2, fp3, cp0, cp3, axis0, axis1, axis2, faceType); + connectQuadToEdge(fp0, fp1, fp2, fp3, cp0, cp3, axis1, axis0, axis2, min, max, faceType); + break; + case Edge1: + //connectQuadToAxis1Edge(fp0, fp1, fp2, fp3, cp0, cp1, axis0, axis1, axis2, faceType); + connectQuadToEdge(fp3, fp0, fp1, fp2, cp0, cp1, axis0, axis1, axis2, max, max, faceType); + break; + case Quad: + connectQuadToQuad(fp0, fp1, fp2, fp3, cp0, cp1, cp2, cp3, axis1, axis0, axis2, max, max, faceType); + break; + default: + std::cerr << "Internal Error (generateCellsForFace(AxisType, AxisType, AxisType)): Invalid enum value." << std::endl; + abort(); + } + } + } + catch (AMRLevel::NoGrid ng) { + std::cerr << "Error (AMRGridStitcher::generateCellsForFace(AxisType, AxisType, AxisType, MinMaxType): " << ng << std::endl; + } +} + + template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::generateCellsForEdge(AxisType edgeAxis, AxisType nonEdgeAxis0, MinMaxType nonEdgeAxis0Type, AxisType nonEdgeAxis1, MinMaxType nonEdgeAxis1Type) +{ + AxisType addAxis0132; + AxisType addAxis0451; + MinMaxType addAxis0132Type; + MinMaxType addAxis0451Type; + if (nonEdgeAxis1Type == min && nonEdgeAxis0Type == min) { + addAxis0132 = nonEdgeAxis0; + addAxis0451 = nonEdgeAxis1; + addAxis0132Type = min; + addAxis0451Type = min; + } + else if (nonEdgeAxis1Type == min && nonEdgeAxis0Type == max) { + addAxis0132 = nonEdgeAxis1; + addAxis0451 = nonEdgeAxis0; + addAxis0132Type = min; + addAxis0451Type = max; + } + if (nonEdgeAxis1Type == max && nonEdgeAxis0Type == min) { + addAxis0132 = nonEdgeAxis1; + addAxis0451 = nonEdgeAxis0; + addAxis0132Type = max; + addAxis0451Type = min; + } + if (nonEdgeAxis1Type == max && nonEdgeAxis0Type == max) { + addAxis0132 = nonEdgeAxis0; + addAxis0451 = nonEdgeAxis1; + addAxis0132Type = max; + addAxis0451Type = max; + } + + try { + for (int edgeIdx=0; edgeIdx<mStitchGrid->dims[edgeAxis]-1; ++edgeIdx) { + int cIdx0[3]; + cIdx0[edgeAxis] = mOriginInParentLevel[edgeAxis] + edgeIdx/2; + if (nonEdgeAxis0Type == min) + cIdx0[nonEdgeAxis0] = mOriginInParentLevel[nonEdgeAxis0] - 1; + else + cIdx0[nonEdgeAxis0] = mMaxExtInParentLevel[nonEdgeAxis0] + 1; + if (nonEdgeAxis1Type == min) + cIdx0[nonEdgeAxis1] = mOriginInParentLevel[nonEdgeAxis1] - 1; + else + cIdx0[nonEdgeAxis1] = mMaxExtInParentLevel[nonEdgeAxis1] + 1; + AMRGridCell cp0 = mParentLevel->getGridCell(cIdx0); + + int cIdx1[3]; + cIdx1[edgeAxis] = cIdx0[edgeAxis] + 1; + cIdx1[nonEdgeAxis0] = cIdx0[nonEdgeAxis0]; + cIdx1[nonEdgeAxis1] = cIdx0[nonEdgeAxis1]; + AMRGridCell cp1 = mParentLevel->getGridCell(cIdx1); + + int cIdx2[3]; + cIdx2[edgeAxis] = cIdx0[edgeAxis]; + if (addAxis0132Type == min) + cIdx2[addAxis0132] = cIdx0[addAxis0132] + 1; + else + cIdx2[addAxis0132] = cIdx0[addAxis0132] - 1; + cIdx2[addAxis0451] = cIdx0[addAxis0451]; + AMRGridCell cp2 = mParentLevel->getGridCell(cIdx2); + + int cIdx3[3]; + cIdx3[edgeAxis] = cIdx2[edgeAxis] + 1; + cIdx3[addAxis0132] = cIdx2[addAxis0132]; + cIdx3[addAxis0451] = cIdx2[addAxis0451]; + AMRGridCell cp3 = mParentLevel->getGridCell(cIdx3); + + int cIdx4[3]; + cIdx4[edgeAxis] = cIdx0[edgeAxis]; + cIdx4[addAxis0132] = cIdx0[addAxis0132]; + if (addAxis0451Type == min) + cIdx4[addAxis0451] = cIdx0[addAxis0451] + 1; + else + cIdx4[addAxis0451] = cIdx0[addAxis0451] - 1; + AMRGridCell cp4 = mParentLevel->getGridCell(cIdx4); + + int cIdx5[3]; + cIdx5[edgeAxis] = cIdx4[edgeAxis] + 1; + cIdx5[addAxis0132] = cIdx4[addAxis0132]; + cIdx5[addAxis0451] = cIdx4[addAxis0451]; + AMRGridCell cp5 = mParentLevel->getGridCell(cIdx5); + + int eIdx0[3]; + eIdx0[edgeAxis] = edgeIdx; + if (nonEdgeAxis0Type == min) + eIdx0[nonEdgeAxis0] = 0; + else + eIdx0[nonEdgeAxis0] = mStitchGrid->dims[nonEdgeAxis0]-1; + if (nonEdgeAxis1Type == min) + eIdx0[nonEdgeAxis1] = 0; + else + eIdx0[nonEdgeAxis1] = mStitchGrid->dims[nonEdgeAxis1]-1; + AMRGridCell ep0(mStitchGrid, eIdx0[0], eIdx0[1], eIdx0[2]); + + int eIdx1[3]; + eIdx1[edgeAxis] = eIdx0[edgeAxis] + 1; + eIdx1[nonEdgeAxis0] = eIdx0[nonEdgeAxis0]; + eIdx1[nonEdgeAxis1] = eIdx0[nonEdgeAxis1]; + AMRGridCell ep1(mStitchGrid, eIdx1[0], eIdx1[1], eIdx1[2]); + + if (edgeIdx % 2) { + connectEdgeSegmentToQuads(ep0, ep1, cp0, cp1, cp2, cp3, cp4, cp5, edgeAxis, addAxis0132, addAxis0132Type, addAxis0451, addAxis0451Type); + } + else { + connectEdgeSegmentToEdges(ep0, ep1, cp0, cp2, cp4, edgeAxis, addAxis0132, addAxis0132Type, addAxis0451, addAxis0451Type); + } + } + } + catch (AMRLevel::NoGrid ng) { + std::cerr << "Error (AMRGridStitcher::generateCellsForEdge(AxisType, AxisType, MinMaxType, AxisType, MinMaxType): " << ng << std::endl; + } +} + + template<class StitchCellHandler> +void AMRGridStitcher<StitchCellHandler>::generateCellsForVertex(AxisType axis0, AxisType axis1, AxisType axis2, MinMaxType axis0VertexType, MinMaxType axis1VertexType, MinMaxType axis2VertexType) +{ + try { + int fIdx[3]; + fIdx[axis0] = axis0VertexType == min ? 0 : mStitchGrid->dims[axis0] - 1; + fIdx[axis1] = axis1VertexType == min ? 0 : mStitchGrid->dims[axis1] - 1; + fIdx[axis2] = axis2VertexType == min ? 0 : mStitchGrid->dims[axis2] - 1; + AMRGridCell fp(mStitchGrid, fIdx); + + int cp0Idx[3]; + cp0Idx[axis0] = axis0VertexType == min ? mOriginInParentLevel[axis0] - 1 : mMaxExtInParentLevel[axis0] + 1; + cp0Idx[axis1] = axis1VertexType == min ? mOriginInParentLevel[axis1] - 1 : mMaxExtInParentLevel[axis1] + 1; + cp0Idx[axis2] = axis2VertexType == min ? mOriginInParentLevel[axis2] - 1 : mMaxExtInParentLevel[axis2] + 1; + AMRGridCell cp0 = mParentLevel->getGridCell(cp0Idx); + + int cp1Idx[3]; + cp1Idx[axis0] = cp0Idx[axis0]; + cp1Idx[axis1] = axis1VertexType == min ? cp0Idx[axis1] + 1 : cp0Idx[axis1] - 1; + cp1Idx[axis2] = cp0Idx[axis2]; + AMRGridCell cp1 = mParentLevel->getGridCell(cp1Idx); + + int cp2Idx[3]; + cp2Idx[axis0] = axis0VertexType == min ? cp0Idx[axis0] + 1 : cp0Idx[axis0] - 1; + cp2Idx[axis1] = cp0Idx[axis1]; + cp2Idx[axis2] = cp0Idx[axis2]; + AMRGridCell cp2 = mParentLevel->getGridCell(cp2Idx); + + int cp3Idx[3]; + cp3Idx[axis0] = axis0VertexType == min ? cp1Idx[axis0] + 1 : cp1Idx[axis0] - 1; + cp3Idx[axis1] = cp1Idx[axis1]; + cp3Idx[axis2] = cp1Idx[axis2]; + AMRGridCell cp3 = mParentLevel->getGridCell(cp3Idx); + + int cp4Idx[3]; + cp4Idx[axis0] = cp0Idx[axis0]; + cp4Idx[axis1] = cp0Idx[axis1]; + cp4Idx[axis2] = axis2VertexType == min ? cp0Idx[axis2] + 1 : cp0Idx[axis2] - 1; + AMRGridCell cp4 = mParentLevel->getGridCell(cp4Idx); + + int cp5Idx[3]; + cp5Idx[axis0] = cp1Idx[axis0]; + cp5Idx[axis1] = cp1Idx[axis1]; + cp5Idx[axis2] = axis2VertexType == min ? cp1Idx[axis2] + 1 : cp1Idx[axis2] - 1; + AMRGridCell cp5 = mParentLevel->getGridCell(cp5Idx); + + int cp6Idx[3]; + cp6Idx[axis0] = cp2Idx[axis0]; + cp6Idx[axis1] = cp0Idx[axis1]; + cp6Idx[axis2] = cp4Idx[axis2]; + AMRGridCell cp6 = mParentLevel->getGridCell(cp6Idx); + + if (cp6.refiningId() == AMRGrid::NoGrid && cp5.refiningId() == AMRGrid::NoGrid && cp4.refiningId() == AMRGrid::NoGrid && cp3.refiningId() == AMRGrid::NoGrid && cp2.refiningId() == AMRGrid::NoGrid && cp1.refiningId() == AMRGrid::NoGrid && cp0.refiningId() == AMRGrid::NoGrid) { + mStitchCellHandler.handlePyramidCell(cp0, cp2, cp3, cp1, fp); + mStitchCellHandler.handlePyramidCell(cp0, cp1, cp5, cp4, fp); + mStitchCellHandler.handlePyramidCell(cp0, cp4, cp6, cp2, fp); + } + else if (!(cp3.refiningId() != AMRGrid::NoGrid || cp5.refiningId() != AMRGrid::NoGrid || cp6.refiningId() != AMRGrid::NoGrid)) { + connectVertexToQuad(fp, cp3, cp1, cp0, cp2); + connectVertexToQuad(fp, cp5, cp4, cp0, cp1); + connectVertexToQuad(fp, cp6, cp2, cp0, cp4); + } + else if (cp3.refiningId() != AMRGrid::NoGrid) { + AMRGrid *cp3RefiningGrid = mAMRDataSet.getGridByIndex(cp3.refiningId()); + AxisAlignedBox<int> cp3RefiningCells = cp3RefiningGrid->getRefiningCells(cp3.grid(), cp3.idx(xAxis), cp3.idx(yAxis), cp3.idx(zAxis)); + int cp3RefIdx[3]; + cp3RefIdx[axis0] = axis0VertexType == min ? cp3RefiningCells.min(axis0) : cp3RefiningCells.max(axis0); + cp3RefIdx[axis1] = axis1VertexType == min ? cp3RefiningCells.min(axis1) : cp3RefiningCells.max(axis1); + cp3RefIdx[axis2] = axis2VertexType == min ? cp3RefiningCells.max(axis2) : cp3RefiningCells.min(axis2); + AMRGridCell cp3Ref(cp3RefiningGrid, cp3RefIdx); + if (axis2VertexType == min) + connectEdgeSegmentToQuads(cp3Ref, fp, cp0, cp4, cp2, cp6, cp1, cp5, axis2, axis0, axis0VertexType, axis1, axis1VertexType); + else + connectEdgeSegmentToQuads(fp, cp3Ref, cp4, cp0, cp5, cp1, cp6, cp2, axis2, axis1, axis1VertexType, axis0, axis0VertexType); + } + else if (cp5.refiningId() != AMRGrid::NoGrid) { + AMRGrid *cp5RefiningGrid = mAMRDataSet.getGridByIndex(cp5.refiningId()); + AxisAlignedBox<int> cp5RefiningCells = cp5RefiningGrid->getRefiningCells(cp5.grid(), cp5.idx(xAxis), cp5.idx(yAxis), cp5.idx(zAxis)); + int cp5RefIdx[3]; + cp5RefIdx[axis0] = axis0VertexType == min ? cp5RefiningCells.max(axis0) : cp5RefiningCells.min(axis0); + cp5RefIdx[axis1] = axis1VertexType == min ? cp5RefiningCells.min(axis1) : cp5RefiningCells.max(axis1); + cp5RefIdx[axis2] = axis2VertexType == min ? cp5RefiningCells.min(axis2) : cp5RefiningCells.max(axis2); + AMRGridCell cp5Ref(cp5RefiningGrid, cp5RefIdx); + if (axis0VertexType == min) + connectEdgeSegmentToQuads(cp5Ref, fp, cp0, cp2, cp1, cp3, cp4, cp6, axis0, axis1, axis1VertexType, axis2, axis2VertexType); + else + connectEdgeSegmentToQuads(fp, cp5Ref, cp2, cp0, cp6, cp4, cp3, cp1, axis0, axis2, axis2VertexType, axis1, axis1VertexType); + } + else if (cp6.refiningId() != AMRGrid::NoGrid) { + AMRGrid *cp6RefiningGrid = mAMRDataSet.getGridByIndex(cp6.refiningId()); + AxisAlignedBox<int> cp6RefiningCells = cp6RefiningGrid->getRefiningCells(cp6.grid(), cp6.idx(xAxis), cp6.idx(yAxis), cp6.idx(zAxis)); + int cp6RefIdx[3]; + cp6RefIdx[axis0] = axis0VertexType == min ? cp6RefiningCells.min(axis0) : cp6RefiningCells.max(axis0); + cp6RefIdx[axis1] = axis1VertexType == min ? cp6RefiningCells.max(axis1) : cp6RefiningCells.min(axis1); + cp6RefIdx[axis2] = axis2VertexType == min ? cp6RefiningCells.min(axis2) : cp6RefiningCells.max(axis2); + AMRGridCell cp6Ref(cp6RefiningGrid, cp6RefIdx); + if (axis0VertexType == min) + connectEdgeSegmentToQuads(cp6Ref, fp, cp0, cp1, cp4, cp5, cp2, cp3, axis1, axis2, axis2VertexType, axis0, axis0VertexType); + else + connectEdgeSegmentToQuads(fp, cp6Ref, cp1, cp0, cp3, cp2, cp5, cp4, axis1, axis0, axis0VertexType, axis2, axis2VertexType); + } + } + catch (AMRLevel::NoGrid ng) { + std::cerr << "Error (AMRGridStitcher::generateCellsForVertex(AxisType, AxisType, AxisType, MinMaxType, MinMaxType, MinMaxType): " << ng << std::endl; + } +} diff --git a/src/AMRHierLib/AMRGridStitcher.hh b/src/AMRHierLib/AMRGridStitcher.hh new file mode 100644 index 0000000..a4c4e8f --- /dev/null +++ b/src/AMRHierLib/AMRGridStitcher.hh @@ -0,0 +1,141 @@ +//------------------------------------------------------------------------------ +// +// Project: Crackfree Isosurfaces for AMR data +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA and Germany" + * + */ + +#ifndef _GHW_AMRGRIDSTITCHER_HH_ +#define _GHW_AMRGRIDSTITCHER_HH_ + +// Standard C/C++ Includes +#include <algorithm> +#include <iterator> +#include <list> + +// Support Classes +#include <Vertex.hh> + +// AMR Specific Includes +#include <AMRHierarchy.hh> +#include <AMRGridCell.hh> + +class AMRGrid; + +// AMRGridStitcher: +// Connect Grids in AMR Hierarchy via stitch cells, +// see WriteStitchCells for an example +// AMRGridStitcher is a template of a class which is supposed to +// handle the stitch cells and do something with them, e.g. write them +// to a file (as StitchCellWriter in the WriteStitchCells example does) +// This class must implement the following methods: +// void handleTetrahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const Vertex& p3, double v3); +// --> Handle a tetrahedron cell with one Vertex that is not an original data value (computed as centroid of original data vertices) +// void handleTetrahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3); +// --> Handle a tetrahedron cell with vertices described by GridCells, i.e. one only using original data points +// void handlePyramidCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const Vertex& p4, double v4); +// --> Handle a pyramid cell with one Vertex that is not an original data value (computed as centroid of original data vertices) +// void handlePyramidCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4); +// --> Handle a pyramid cell with vertices described by GridCells, i.e. one only using original data points +// void handleTrianglePrismCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4, const AMRGridCell& c5); +// --> Handle a triangle prism cell with vertices described by GridCells, i.e. one only using original data points +// void handleHexahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4, const AMRGridCell& c5, const AMRGridCell& c6, const AMRGridCell& c7); +// --> Handle a hexahedron cell with vertices described by GridCells, i.e. one only using original data points +// Concerning the ordering scheme of vertices of the stitch-cells see VtxOrder.pdf or VtxOrder.png + +template<class StitchCellHandler> +class AMRGridStitcher { + public: + // Generate a grid stitcher: + // stitchCellHandler - object which uses the generated cells + // amrHier - the AMR hierarchy + // stitchGrid - Grid that should be stitched into the parent level + // considerNextLevel - if true: do not generate those stitch cells that would be covered by cells/stitch cells of a next level, + // i.e., when cells connecting two grids are generated and this is set to true, all cells that are overlaped by grids of + // the next level are ignored. If false: any effects a next level may have are ignored + AMRGridStitcher(StitchCellHandler& stitchCellHandler, AMRHierarchy& amrHier, AMRGrid *stitchGrid, bool considerNextLevel=false); + ~AMRGridStitcher(); + // Start the stitching process + void generateStitchCells(bool xyMin = true, bool xyMax = true, bool yzMin = true, bool yzMax = true, bool xzMin = true, bool xzMax = true); + + private: // Helper functions and data types + enum MinMaxType { min, max }; + + void connectQuadToVertex(const AMRGridCell& qp0, const AMRGridCell& qp1, const AMRGridCell& qp2, const AMRGridCell& qp3, const AMRGridCell& vp, AxisType axis0, AxisType axis1, AxisType axis2, MinMaxType faceType); + void connectQuadToEdge(const AMRGridCell& qp0, const AMRGridCell& qp1, const AMRGridCell& qp2, const AMRGridCell& qp3, const AMRGridCell& ep0, const AMRGridCell& ep1, AxisType axis01, AxisType axis03, AxisType axisPerp0123, MinMaxType qp0Axis01Type, MinMaxType qp0Axis03Type, MinMaxType quadFaceType); + void connectQuadToQuad(const AMRGridCell& qp0, const AMRGridCell& qp1, const AMRGridCell& qp2, const AMRGridCell& qp3, const AMRGridCell& oqp0, const AMRGridCell& oqp1, const AMRGridCell& oqp2, const AMRGridCell& oqp3, AxisType axis01, AxisType axis03, AxisType axisPerp0123, MinMaxType qp0Axis01Type, MinMaxType qp0Axis03Type, MinMaxType quadFaceType); + + void connectEdgeSegmentToEdges(const AMRGridCell& ep0, const AMRGridCell& ep1, const AMRGridCell& cp0, const AMRGridCell& cp1, const AMRGridCell& cp2, AxisType edgeAxis, AxisType edge01Axis, MinMaxType edgeAxis01Type, AxisType edge02Axis, MinMaxType edgeAxis02Type); + void connectEdgeSegmentToQuads(const AMRGridCell& ep0, const AMRGridCell& ep1, const AMRGridCell& cp0, const AMRGridCell& cp1, const AMRGridCell& cp2, const AMRGridCell& cp3, const AMRGridCell& cp4, const AMRGridCell& cp5, AxisType edgeAxis, AxisType addAxis0132, MinMaxType edgeAxis0132Type, AxisType addAxis0451, MinMaxType edgeAxis0451Type); + + void connectVertexToQuad(const AMRGridCell& vtx, const AMRGridCell& p0, const AMRGridCell& p1, const AMRGridCell& p2, const AMRGridCell& p3); + + void generateCellsForFace(AxisType axis1, AxisType axis2, AxisType axis3, MinMaxType faceType); + void generateCellsForEdge(AxisType edgeAxis, AxisType nonEdgeAxis1, MinMaxType nonEdgeAxis1Type, AxisType nonEdgeAxis2, MinMaxType nonEdgeAxis2Type); + void generateCellsForVertex(AxisType axis0, AxisType axis1, AxisType axis2, MinMaxType axis0VertexType, MinMaxType axis1VertexType, MinMaxType axis2VertexType); + + private: // Data members + StitchCellHandler &mStitchCellHandler; + AMRHierarchy &mAMRDataSet; + AMRGrid *mStitchGrid; + bool mConsiderNextLevel; + AMRLevel *mParentLevel; + int mOriginInParentLevel[3]; + int mMaxExtInParentLevel[3]; +}; + +#ifdef __GNUC__ +#include "AMRGridStitcher.cc" +#endif + +#endif diff --git a/src/AMRHierLib/AMRHierarchy.cc b/src/AMRHierLib/AMRHierarchy.cc new file mode 100644 index 0000000..aabf16b --- /dev/null +++ b/src/AMRHierLib/AMRHierarchy.cc @@ -0,0 +1,189 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* WARNING: This software is EXPERIMENTAL. The authors give no guaranty + * about stability or correctness of the provided source! + * + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA [and Germany :-)]" + * + */ + +#include "AMRHierarchy.hh" + +// Standard C/C++-Includes +#include <iostream> +#include <math.h> + +// AMR related includes +#include <IEEEIO.hh> +#include <AmrGridReader.hh> +#include <AMRGrid.hh> +#include <AMRLevel.hh> + +AMRHierarchy::AMRHierarchy() : mAmrFile(NULL), mAmrGridReader(NULL), mNoLevels(0), mNoGrids(0), mAMRLevel(NULL), mIndexToGridPtrMap(NULL), mValueRange(0.0,0.0) {} + +AMRHierarchy::~AMRHierarchy() +{ + clear(); +} + + +bool AMRHierarchy::readIEEEFile(const char *filename) +{ + // Create the object for file-access. This allows AmrGridReader to read different + // file formats. + IEEEIO *theAmrFile = new IEEEIO(filename, IObase::Read); + if (!(theAmrFile!=NULL && theAmrFile->isValid())) { + std::cerr << "Error in AMRHierarchy::readIEEEFile(char *): Couldn't open AMR-file" << filename << " for reading" << std::endl; + return false; + } + return readFromFile(theAmrFile); +} + +bool AMRHierarchy::readFromFile(IObase *theAmrFile) +{ + // Clear old grid data + clear(); + + mAmrFile = theAmrFile; + + // Create the object for reading the AMR Hierarchy + mAmrGridReader = new AmrGridReader(*mAmrFile); + + GridId currentGridIdx=0; // This is the index of the current grid within the AMR file + std::list<AMRGrid *>allGrids; // List of all AMR Grids + + AMRGrid *newGrid = new AMRGrid(currentGridIdx, this, mAmrGridReader); + while (mAmrGridReader->getGridInfo(*newGrid, currentGridIdx)) { + newGrid->computeValueRange(); + std::cout << "Read grid " << currentGridIdx << std::endl; + // <TEMPORARY> + // This is because the iorigin in the data set isn't always correct.... + newGrid->iorigin[0] = int(newGrid->origin[0]/(newGrid->delta[0])+0.5); + newGrid->iorigin[1] = int(newGrid->origin[1]/(newGrid->delta[1])+0.5); + newGrid->iorigin[2] = int(newGrid->origin[2]/(newGrid->delta[2])+0.5); + // </TEMPORARY> + if (newGrid->level+1>mNoLevels) mNoLevels=newGrid->level+1; + allGrids.push_back(newGrid); + ++currentGridIdx; + newGrid = new AMRGrid(currentGridIdx, this, mAmrGridReader); + } + delete newGrid; // Space allocated for a grid which couldn't be read + + // Create the list of levels + AMRGrid **firstGridInLevel = new AMRGrid*[mNoLevels]; + for (int currLevel=0; currLevel<mNoLevels; ++currLevel) firstGridInLevel[currLevel]=NULL; + std::list<AMRGrid*>::iterator gridIter; + for (gridIter=allGrids.begin(); gridIter!=allGrids.end(); ++gridIter) { + int level = (*gridIter)->level; + (*gridIter)->mNextGridInLevel = firstGridInLevel[level]; + firstGridInLevel[level] = (*gridIter); + } + + // Create tree/graph structure + for (int currLevel=0; currLevel<mNoLevels-1; ++currLevel) { + for (AMRGrid *currParent=firstGridInLevel[currLevel]; + currParent!=NULL; + currParent=currParent->mNextGridInLevel) { + for (AMRGrid *currPotentialChild=firstGridInLevel[currLevel+1]; + currPotentialChild!=NULL; + currPotentialChild=currPotentialChild->mNextGridInLevel) { + if (currPotentialChild->overlaps(*currParent)) { + currParent->mRefiningGrids.push_back(currPotentialChild); + currPotentialChild->mRefinedGrids.push_back(currParent); + } // if + } // for (currPotentialChild...) + } // for (currParent...) + } // for (currLevel...) + + // Create AMRLevel + mAMRLevel = new AMRLevel*[mNoLevels]; + for (int currLevel=0; currLevel<mNoLevels; ++currLevel) + mAMRLevel[currLevel] = new AMRLevel(firstGridInLevel[currLevel]); + delete[] firstGridInLevel; + + // Copy list of pointers to all grids to gridIndex, for direct access to grids via index + mNoGrids = allGrids.size(); + mIndexToGridPtrMap = new AMRGrid*[mNoGrids]; + for (gridIter = allGrids.begin(); gridIter != allGrids.end(); ++gridIter) { + assert((*gridIter)->index() < mNoGrids); + mIndexToGridPtrMap[(*gridIter)->index()] = *gridIter; + } + + mValueRange = mIndexToGridPtrMap[0]->getValueRange(); + for (GridId currGridIdx = 1; currGridIdx < mNoGrids; ++currGridIdx) { + mValueRange.combine(mIndexToGridPtrMap[currGridIdx]->getValueRange()); + } + std::cout << "Value range " << mValueRange.min << " to " << mValueRange.max << std::endl; + + return true; +} + +void AMRHierarchy::clear() +{ + delete mAmrFile; + mAmrFile = NULL; + delete mAmrGridReader; + mAmrGridReader = NULL; + + for (int currLevel=0; currLevel < mNoLevels; ++currLevel) + delete mAMRLevel[currLevel]; + delete[] mAMRLevel; + mAMRLevel = NULL; + mNoLevels = 0; + for (int i=0; i<mNoGrids; ++i) delete mIndexToGridPtrMap[i]; + mNoGrids = 0; + delete[] mIndexToGridPtrMap; + mIndexToGridPtrMap= NULL; + + mValueRange.setRange(0.0,0.0); +} diff --git a/src/AMRHierLib/AMRHierarchy.hh b/src/AMRHierLib/AMRHierarchy.hh new file mode 100644 index 0000000..c061252 --- /dev/null +++ b/src/AMRHierLib/AMRHierarchy.hh @@ -0,0 +1,127 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA and Germany" + * + */ + +#ifndef _GHW_AMRHIERARCHY_H_ +#define _GHW_AMRHIERARCHY_H_ + +// Misc. includes +#include <Range.hh> + +// AMR related includes +#include <IO.hh> + +class AMRLevel; +class AMRGrid; +class AmrGridReader; + +/* + * Access to the hierarchy of an AMR data set: + * This class is a wrapper to the AMR structures + */ +class AMRHierarchy { + public: + typedef int GridId; + // Read an AMR File in John's IEEE format from disk + bool readIEEEFile(const char *filename); + // Read arbitrary AMR file formats, if a reader is given. This is currently + // only used on readIEEEFile. See that function for details. + bool readFromFile(IObase *theAmrFile); + // Erase hierarchy + void clear(); + // How many levels are in the hierarchy? + int numLevels() const; + // How many grids? + int numGrids() const; + // Each grid in the hierachy has an index 0 <= gridIndex < numGrids(). This + // function allows to get a grid without any regard to its position in the hierarchy. + AMRGrid* getGridByIndex(GridId gridIndex) const; + // Get an AMRLevel object (see corresponding header). This gives access to a list of grids + // of that level. AMRLevel also provides some helper functions, e.g. translating a global + // level index to a pointer to a grid and an index within that grid. + AMRLevel* getLevel(int levelNo) const; + // Gets the value range in the entire hierarchy + const Range<float> &getValueRange() const; + // Create an empty hierarchy object + AMRHierarchy(); + // Clean up. + ~AMRHierarchy(); + private: + friend class AMRGrid; + // Accessing the data on disk: + IObase *mAmrFile; + AmrGridReader *mAmrGridReader; + + // Accessing the data in memory: + int mNoLevels; // Number of levels in hierarchy + int mNoGrids; // Number of grids in hierarchy (all levels!) + AMRLevel **mAMRLevel; // Array 0..mNumLevels-1 of pointers to AMRLevel objects + AMRGrid **mIndexToGridPtrMap; // Array that maps each grid index to a pointer to the corresponding grid + + // Additional Info about grid-data: + Range<float> mValueRange; // Range of values in all grids + + // As seen in Scott Meyer's Effective C++: If you don't want to specify copy constructor + // and assignment operator, make them inaccessible to prevent them from being called accidently. + // NOTE: Even though declared here, they are not defined (causes link error when accidently needed + // within class). + AMRHierarchy(const AMRHierarchy&); // Prevent copying + AMRHierarchy& operator=(const AMRHierarchy&); // Prevent assignment +}; + +#include "AMRHierarchy.icc" + +#endif diff --git a/src/AMRHierLib/AMRHierarchy.icc b/src/AMRHierLib/AMRHierarchy.icc new file mode 100644 index 0000000..0b2e9d8 --- /dev/null +++ b/src/AMRHierLib/AMRHierarchy.icc @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* WARNING: This software is EXPERIMENTAL. The authors give no guaranty + * about stability or correctness of the provided source! + * + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA [and Germany :-)]" + * + */ + +inline int AMRHierarchy::numLevels() const +{ + return mNoLevels; +} + +inline int AMRHierarchy::numGrids() const +{ + return mNoGrids; +} + +inline AMRGrid* AMRHierarchy::getGridByIndex(GridId index) const +{ + if (0 <= index && index < mNoGrids) { + return mIndexToGridPtrMap[index]; + } + else + return 0; +} + +inline AMRLevel* AMRHierarchy::getLevel(int levelNo) const +{ + if (0 <= levelNo && levelNo < mNoLevels) { + return mAMRLevel[levelNo]; + } + else { + return 0; + } +} + +inline const Range<float> &AMRHierarchy::getValueRange() const +{ + return mValueRange; +} + diff --git a/src/AMRHierLib/AMRLevel.cc b/src/AMRHierLib/AMRLevel.cc new file mode 100644 index 0000000..bec1631 --- /dev/null +++ b/src/AMRHierLib/AMRLevel.cc @@ -0,0 +1,152 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* WARNING: This software is EXPERIMENTAL. The authors give no guaranty + * about stability or correctness of the provided source! + * + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA [and Germany :-)]" + * + */ + +#include <AMRLevel.hh> + +// Standard C/C++ Includes +#include <assert.h> +#include <iostream> + +// Own Misc. Helper Includes +#include <assume.hh> + +// AMR Related Includes +#include <AMRGrid.hh> +#include <AMRGridCell.hh> + +AMRLevel::AMRLevel(AMRGrid *firstGridInLevel) : mFirstGridInLevel(firstGridInLevel), mLevelNo(mFirstGridInLevel->level) +{ + // All grids in any given level must have the same spatial- and placement-refinement + // Thus, take these values from the first grid. + mSpatialRefinement[0] = mFirstGridInLevel->spatialrefinement[0]; + mSpatialRefinement[1] = mFirstGridInLevel->spatialrefinement[1]; + mSpatialRefinement[2] = mFirstGridInLevel->spatialrefinement[2]; + mPlacementRefinement[0] = mFirstGridInLevel->gridplacementrefinement[0]; + mPlacementRefinement[1] = mFirstGridInLevel->gridplacementrefinement[1]; + mPlacementRefinement[2] = mFirstGridInLevel->gridplacementrefinement[2]; + +#ifndef NDEBUG + // Perform a sanity check, whether above condition (same refinement ratio + // for all grids in a level) is true. + for (AMRGrid *currGridPtr=mFirstGridInLevel; currGridPtr!=0; currGridPtr=currGridPtr->getNextGridInLevel()) { + assert(mSpatialRefinement[0] == currGridPtr->spatialrefinement[0]); + assert(mSpatialRefinement[1] == currGridPtr->spatialrefinement[1]); + assert(mSpatialRefinement[2] == currGridPtr->spatialrefinement[2]); + assert(mPlacementRefinement[0] == currGridPtr->gridplacementrefinement[0]); + assert(mPlacementRefinement[1] == currGridPtr->gridplacementrefinement[1]); + assert(mPlacementRefinement[2] == currGridPtr->gridplacementrefinement[2]); + } +#endif + + // Check if the assumpution spatialrefinement == gridplacementrefinement holds. We rely + // on this throughout further computations. + assume(mSpatialRefinement[0] == mPlacementRefinement[0]); + assume(mSpatialRefinement[1] == mPlacementRefinement[1]); + assume(mSpatialRefinement[2] == mPlacementRefinement[2]); + + // Build a data structure enabling efficient access to a grid containing a given location + // TODO: Finalize planing of acceleration structure and implement +} + +AMRGridCell AMRLevel::getGridCell(int i, int j, int k) const +{ + for (AMRGrid *currGridPtr=mFirstGridInLevel; currGridPtr!=0; currGridPtr=currGridPtr->getNextGridInLevel()) { + int idx[3]; + idx[0] = i - currGridPtr->iorigin[0]; + idx[1] = j - currGridPtr->iorigin[1]; + idx[2] = k - currGridPtr->iorigin[2]; + if (0 <= idx[0] && idx[0] < currGridPtr->dims[0] && + 0 <= idx[1] && idx[1] < currGridPtr->dims[1] && + 0 <= idx[2] && idx[2] < currGridPtr->dims[2]) { + return AMRGridCell(currGridPtr, idx, AMRGrid::Unknown); // Lazy evaluation + } + } + throw NoGrid(i, j, k); +} + +AMRHierarchy::GridId AMRLevel::getGridId(int i, int j, int k) const +{ + // TODO: Add spatial search structure and make grid lookup more efficient enabling the use + // for really large datasets. + for (AMRGrid *currGridPtr=mFirstGridInLevel; currGridPtr!=0; currGridPtr=currGridPtr->getNextGridInLevel()) { + int idx[3]; + idx[0] = i - currGridPtr->iorigin[0]; + idx[1] = j - currGridPtr->iorigin[1]; + idx[2] = k - currGridPtr->iorigin[2]; + if (0 <= idx[0] && idx[0] < currGridPtr->dims[0] && + 0 <= idx[1] && idx[1] < currGridPtr->dims[1] && + 0 <= idx[2] && idx[2] < currGridPtr->dims[2]) { + return currGridPtr->index(); + } + } + return AMRGrid::NoGrid; +} + +AMRLevel::NoGrid::NoGrid(int i, int j, int k) +{ + mPos[0] = i; + mPos[1] = j; + mPos[2] = k; +} + +std::ostream& operator<<(std::ostream& os, const AMRLevel::NoGrid &ng) +{ + os << "No grid present at (" << ng.mPos[0] << ", " << ng.mPos[1] << ", " << ng.mPos[2] << ")"; + return os; +} diff --git a/src/AMRHierLib/AMRLevel.hh b/src/AMRHierLib/AMRLevel.hh new file mode 100644 index 0000000..eaf7501 --- /dev/null +++ b/src/AMRHierLib/AMRLevel.hh @@ -0,0 +1,169 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA [and Germany :-)]" + * + */ + +#ifndef _GHW_AMRLEVEL_HH_ +#define _GHW_AMRLEVEL_HH_ + +// Standard C/C++ Includes +#include <iostream> + +// Own Misc. Helper Includes +#include <AxisType.hh> + +// AMR Related Includes +#include <AMRHierarchy.hh> +#include <AMRGridCell.hh> + +class AMRGrid; + +/** + * One level of an AMR hierarchy. + * Holds one level of the AMR hierarchy and enables queries over an entire + * level rather than single grids. + * + */ +class AMRLevel { + public: + /** + * Construct an AMR level + * Construct an AMR level from a linked list of grids. + * \param firstGridInLevel pointer to the first grid in this level. + * Each grid contains has method getNextGridInLevel() that returns + * the next grid in the level. The list must already be complete when + * this constructor is called. + */ + AMRLevel(AMRGrid *firstGridInLevel); + /** + * Get GridPoint for given position + * Get structure containing pointer to grid containing the given location + * and index of that location within that grid. + * \param i Index along x-Axis within <em>level</em> + * \param j Index along y-Axis within <em>level</em> + * \param k Index along z-Axis within <em>level</em> + * \return Pointer to \see{GridPoint} structure or NULL, if no grid contains + * the given location + */ + AMRGridCell getGridCell(int i, int j, int k) const; + /** + * Get GridPoint for given position + * Get structure containing pointer to grid containing the given location + * and index of that location within that grid. + * \param idx Array containing indices within <em>level</em> + * \return Pointer to \see{GridPoint} structure or NULL, if no grid contains + * the given location + */ + AMRGridCell getGridCell(int idx[3]) const; + /** + * Get index of grid containing absolutes position. + * Gets the index of a grid that contains the position given in level + * coordsinates. + * \param i Index along x-Axis within <em>level</em> + * \param j Index along y-Axis within <em>level</em> + * \param k Index along z-Axis within <em>level</em> + * \return GridId of grid containing that location in the level, or AMRGrid::NoGrid (-1) + * if no grid contains that location. + */ + AMRHierarchy::GridId getGridId(int i, int j, int k) const; + /** + * Get index of grid containing absolutes position. + * Gets the index of a grid that contains the position given in level + * coordsinates. + * \param idx Array containing indicrs within <em>level> + * \return GridId of grid containing that location in the level, or AMRGrid::NoGrid (-1) + * if no grid contains that location. + */ + AMRHierarchy::GridId getGridId(int idx[3]) const; + + /** + * Get pointer to first grid in this level + * Get pointer to first grid in this level. + * \return Pointer to first grid in that level. + */ + AMRGrid* getFirstGrid() const; + + /** + * Get spatial refinement along a given axis. + */ + int getSpatialRefinement(AxisType axis) const; + + /** + * Exception indicating no grid + */ + class NoGrid { + public: + NoGrid(int i, int j, int k); + private: + friend std::ostream& operator<<(std::ostream& os, const AMRLevel::NoGrid &ng); + int mPos[3]; + }; + + private: + // Pointer to the first grid of this level. All grids are + // stored in a linked list. The pointer to the next grid + // in this level is AMRGrid::mNextGridInLevel and can be + // accessed by AMRGrid::getNextGridInLevel. + AMRGrid* mFirstGridInLevel; + // This information is also found in the individual grids. + // It is also stored here for convinience. + int mLevelNo; + int mSpatialRefinement[3]; + int mPlacementRefinement[3]; +}; + +#include <AMRLevel.icc> + +#endif diff --git a/src/AMRHierLib/AMRLevel.icc b/src/AMRHierLib/AMRLevel.icc new file mode 100644 index 0000000..70951a8 --- /dev/null +++ b/src/AMRHierLib/AMRLevel.icc @@ -0,0 +1,78 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* WARNING: This software is EXPERIMENTAL. The authors give no guaranty + * about stability or correctness of the provided source! + * + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA [and Germany :-)]" + * + */ + +inline AMRGrid* AMRLevel::getFirstGrid() const +{ + return mFirstGridInLevel; +} + +inline AMRGridCell AMRLevel::getGridCell(int idx[3]) const +{ + return getGridCell(idx[0], idx[1], idx[2]); +} + +inline AMRHierarchy::GridId AMRLevel::getGridId(int idx[3]) const +{ + return getGridId(idx[0], idx[1], idx[2]); +} + +inline int AMRLevel::getSpatialRefinement(AxisType axis) const +{ + return mSpatialRefinement[axis]; +} diff --git a/src/AMRHierLib/COPYRIGHT b/src/AMRHierLib/COPYRIGHT new file mode 100644 index 0000000..700db96 --- /dev/null +++ b/src/AMRHierLib/COPYRIGHT @@ -0,0 +1,42 @@ +Copyright (C) 2001, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by the Visualization + Group at Lawrence Berkeley National Laboratory. +4. Neither the name of the University of California, Berkeley nor of the + Lawrence Berkeley National Laboratory may be used to endorse or + promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + + +This work is supported by the U. S. Department of Energy under contract +number DE-AC03-76SF00098 between the U. S. Department of Energy and the +University of California. + +Author: Gunther H Weber + Lawrence Berkeley National Laboratory + Berkeley, California + +"this software is 100% hand-crafted by a human being in the USA and Germany" diff --git a/src/AMRHierLib/Makefile b/src/AMRHierLib/Makefile new file mode 100644 index 0000000..ed7714d --- /dev/null +++ b/src/AMRHierLib/Makefile @@ -0,0 +1,138 @@ +#!gmake +# Include common defines + +#Change this to SHARED to build and install shared version +BUILDVERSION = STATIC + +# FlexIO +# Set this to your location of FlexIO +FLEXIO_INCPATH = -I.. +FLEXIO_LIBPATH = -L.. + +# Support Libs +# Set this to your location of the support libs (here: subdirectory Support) +ifneq ($(USE_INSTALLED_SUPPORT_LIBS), 1) +SUPPORT_INCPATH = -ISupport/include +SUPPORT_LIBPATH = -LSupport/lib +endif + +# If needed: System specific LIBPATH. Here: We need to include the lib dir of our custom gcc-3.1.1 installation +SYSTEM_LIBPATH = -Wl,--rpath,/usr/global/packages/languages/gcc-3.1.1/lib + +# Programs +CC = gcc3.1 +CXX = g++3.1 +AR = ar +INSTALL = install +RM = rm + +# Options +OPTFLAGS = -g +#OPTFLAGS = -O2 +SOPOSOPT = -Wl,--rpath -Wl, +AR_CREATEFLAGS = rv + +# Directories +OBJDIR = objLinux + +# Where to install +INSTALLPREFIX = $(HOME)/WorkCVS +INSTALLARCHDEPPREFIX = $(INSTALLPREFIX) +INSTALLBINPATH = $(INSTALLARCHDEPPREFIX)/bin +INSTALLLIBPATH = $(INSTALLARCHDEPPREFIX)/lib-g++3.1 +INSTALLINCPATH = $(INSTALLPREFIX)/include + +ifeq ($(USE_INSTALLED_SUPPORT_LIBS), 1) +INCPATH = -I. -I$(INSTALLINCPATH) $(FLEXIO_INCPATH) +LIBPATH = -L$(INSTALLLIBPATH) $(SOPOSOPT)$(INSTALLLIBPATH) $(FLEXIO_LIBPATH) $(SYSTEM_LIBPATH) +else +INCPATH = -I. $(FLEXIO_INCPATH) $(SUPPORT_INCPATH) -I$(INSTALLINCPATH) +LIBPATH = -L$(INSTALLLIBPATH) $(SOPOSOPT)$(INSTALLLIBPATH) $(FLEXIO_LIBPATH) $(SUPPORT_LIBPATH) $(SYSTEM_LIBPATH) +endif +CPPFLAGS = $(OPTFLAGS) $(INCPATH) -Wall +CXXFLAGS = $(PROJ_CXXFLAGS) + +GeometryLib = -lGeometry +MathLib = -lm +#FlexIOLibs = -lAMR -lieeeio -lhdfio -ldf +FlexIOLibs = -lAMR -lieeeio +AMRHierLib = -lAMRHier + +AMRHLIB_STATIC = libAMRHier.a +AMRHLIB_SHARED = libAMRHier.so +ifeq ($(BUILDVERSION), SHARED) +AMRHLIB = $(AMRHLIB_SHARED) +else +AMRHLIB = $(AMRHLIB_STATIC) +endif +AMRHLIB_SRC.CC = AMRHierarchy.cc AMRGrid.cc AMRLevel.cc AMRGridCell.cc +AMRHLIB_INC = AMRHierarchy.hh AMRHierarchy.icc AMRGrid.hh AMRGrid.icc AMRLevel.hh AMRLevel.icc AMRGridCell.hh AMRGridCell.icc AMRGridStitcher.hh AMRGridStitcher.cc +AMRHLIB_OBJ = $(addprefix $(OBJDIR)/, $(AMRHLIB_SRC.CC:.cc=.o)) + +PAMRH = PrintAMRHier +PAMRH_SRC.CC = PrintAMRHier.cc +PAMRH_OBJ = $(addprefix $(OBJDIR)/, $(PAMRH_SRC.CC:.cc=.o)) +PAMRH_LIBS = $(AMRHierLib) $(FlexIOLibs) $(MathLib) + +WSC = WriteStitchCells +WSC_SRC.CC = WriteStitchCells.cc StitchCellWriter.cc +WSC_OBJ = $(addprefix $(OBJDIR)/, $(WSC_SRC.CC:.cc=.o)) +ifeq ($(USE_INSTALLED_SUPPORT_LIBS), 1) +WSC_LIBS = $(AMRHierLib) $(FlexIOLibs) $(GeometryLib) $(MathLib) +else +WSC_LIBS = $(AMRHierLib) $(FlexIOLibs) $(MathLib) +endif + +VOL2IEEEIO = Vol2IEEEIO +VOL2IEEEIO_SRC.CC= Vol2IEEEIO.cc +VOL2IEEEIO_OBJ = $(addprefix $(OBJDIR)/, $(VOL2IEEEIO_SRC.CC:.cc=.o)) +VOL2IEEEIO_LIBS = $(FlexIOLibs) -lz + +DEPENDENCIES = $(AMRHLIB_OBJ:.o=.d) $(PAMRH_OBJ:.o=.d) $(WDPF_OBJ:.o=.c) + +PROJ_TARGETS = $(AMRHLIB) $(PAMRH) $(WSC) $(VOL2IEEEIO) + +all: $(PROJ_TARGETS) + +# Implicit Rules +$(OBJDIR)/%.o: %.cc + @rm -f $(OBJDIR)/$*.d + $(COMPILE.cc) -Wp,-MD,$(OBJDIR)/$*.P $(OUTPUT_OPTION) $< + @sed -e 's/$*\.o/$(OBJDIR)\/$*.o/g' -e 's/moc_[^.]*\.cc//g' <$(OBJDIR)/$*.P >$(OBJDIR)/$*.d + @rm -f $(OBJDIR)/$*.P + +# Project Rules +$(AMRHLIB_STATIC): $(AMRHLIB_OBJ) + $(AR) $(ARFLAGS) $@ $(AMRHLIB_OBJ) + +$(AMRHLIB_SHARED): $(AMRHLIB_OBJ) + $(CXX) $(OPTFLAGS) -shared $(AMRHLIB_OBJ) $(AMRLib) $(IEEEIOLib) $(MathLib) -o $@ + +$(PAMRH): $(PAMRH_OBJ) $(AMRHLIB) + $(CXX) $(CXXFLAGS) $(PAMRH_OBJ) -L. $(LIBPATH) -o $@ $(PAMRH_LIBS) + +$(WSC): $(WSC_OBJ) $(AMRHLIB) + $(CXX) $(CXXFLAGS) $(WSC_OBJ) -L. $(LIBPATH) -o $@ $(WSC_LIBS) + +$(VOL2IEEEIO): $(VOL2IEEEIO_OBJ) $(AMRHLIB) + $(CXX) $(CXXFLAGS) $(VOL2IEEEIO_OBJ) -L. $(LIBPATH) -o $@ $(VOL2IEEEIO_LIBS) + +install: $(TARGETS) + $(INSTALL) -d $(INSTALLINCPATH) $(INSTALLLIBPATH) + $(INSTALL) -m 644 $(AMRHLIB) $(INSTALLLIBPATH) + $(INSTALL) -m 644 $(AMRHLIB_INC) $(INSTALLINCPATH) + +clean: + $(RM) -rf $(OBJDIR) core Makedepend.$(TARGET_OS) tags + +setup: + mkdir $(OBJDIR) + +distclean: clean + $(RM) -f $(PROJ_TARGETS) + +ifeq ($(CXX), g++) +sinclude $(DEPENDENCIES) +else +sinclude Makedepend.$(TARGET_OS) +endif diff --git a/src/AMRHierLib/PrintAMRHier.cc b/src/AMRHierLib/PrintAMRHier.cc new file mode 100644 index 0000000..7201d05 --- /dev/null +++ b/src/AMRHierLib/PrintAMRHier.cc @@ -0,0 +1,24 @@ +#include <iostream> +#include "AMRHierarchy.hh" +#include "AMRLevel.hh" +#include "AMRGrid.hh" + +int main(int argc, char *argv[]) +{ + AMRHierarchy theAMRHier; + + if (argc!=2) { + std::cerr << "Usage: " << argv[0] << " <amrHierFile>" << std::endl; + return 27; + } + + if (!theAMRHier.readIEEEFile(argv[1])) { + std::cerr << "Could not read AMR file " << argv[1] << std::endl; + } + + for (int levelNo=0; levelNo<theAMRHier.numLevels(); ++levelNo) { + std::cout << "********** Level " << levelNo << " of " << theAMRHier.numLevels() << "**********" << std::endl; + for (AMRGrid *currGridPtr = theAMRHier.getLevel(levelNo)->getFirstGrid(); currGridPtr != 0; currGridPtr = currGridPtr->getNextGridInLevel()) + currGridPtr->printInfo(std::cout); + } +} diff --git a/src/AMRHierLib/README b/src/AMRHierLib/README new file mode 100644 index 0000000..011d37d --- /dev/null +++ b/src/AMRHierLib/README @@ -0,0 +1,28 @@ +These classes are intended to give a higher level access to AMR hierarchies in +FlexIO format. Unfortunately they grew as I just became accustomed to the AMR +format and still contain provisions due to some initial misconceptions on my +part (i.e. trying to handle incompletely refined grid cells being the severest +example). They were left in the library because they sometimes come in handy +when experimenting with AMR data (e.g. throwing away boundary cells for higher +order interpolation, etc.). Ultimately they should be discarded. + +All this is work in progress and still needs to be tweaked to work. It was +sufficient to generate the images in the papers I wrote, but I may have broken +one thing or the other when I made changes. So take these sources as they are +and expect some problems when using them. + +The grid stitching code can be found in AMRGridStitcher.hh and AMRGridStitcher.cc. +WriteStitchCells.cc and StitchCellWriter.hh, StitchCellWriter.cc is an example +for using it to write the stitch cells to a file. A description of the grid +stitching can be found in: + +Weber, G.H., Kreylos, O., Ligocki, T.J., Shalf, J.M., Hagen, H., Hamann, B. +and Joy, K.I. (2002), "Extraction of crack-free isosurfaces from adaptive +mesh refinement data," to appear in: Farin, G., Hagen, H. and Hamann, B., +eds., Hierarchical and Geometrical Methods in Scientific Visualization, +Springer-Verlag, Heidelberg, Germany. + +A pdf version of the paper is available at +http://graphics.cs.ucdavis.edu/~hamann/WeberKreylosLigockiShalfHagenHamannJoy2002.pdf + +Gunther H Weber (weber@informatik.uni-kl.de) diff --git a/src/AMRHierLib/StitchCellWriter.cc b/src/AMRHierLib/StitchCellWriter.cc new file mode 100644 index 0000000..3f86dae --- /dev/null +++ b/src/AMRHierLib/StitchCellWriter.cc @@ -0,0 +1,188 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +#include "StitchCellWriter.hh" + +// Standard C/C++ Includes +#include <string> + +// Own Misc. Helper Includes +#include <BinStream.hh> + +// AMR Includes +#include <AMRHierarchy.hh> +#include <AMRGrid.hh> +#include <AMRGridCell.hh> + +StitchCellWriter::StitchCellWriter(const AMRHierarchy& amrHier, const char* baseFilename, int maxLevel) + : mMaxLevel(maxLevel), + mGridStartPointIdx(new int[amrHier.numGrids()+1]), + mPositionStream((std::string(baseFilename) + std::string(".pts")).c_str()), + mValueStream((std::string(baseFilename) + std::string(".vals")).c_str()), + mNumPoints(0), + mTetStream((std::string(baseFilename) + std::string(".tets")).c_str()), + mNumTets(0), + mPyramidStream((std::string(baseFilename) + std::string(".pyramids")).c_str()), + mNumPyramids(0), + mTrianglePrismStream((std::string(baseFilename) + std::string(".triangleprisms")).c_str()), + mNumTrianglePrisms(0), + mHexahedronStream((std::string(baseFilename) + std::string(".hexahedra")).c_str()), + mNumHexahedra(0) +{ + // Write 0 as number of points, tets, ... + // Destructor seeks back and writes actual numbers when they are known (no more points, + // tets, ...) added + BinStream::binaryOut(mPositionStream, mNumPoints); + BinStream::binaryOut(mTetStream, mNumTets); + BinStream::binaryOut(mPyramidStream, mNumPyramids); + BinStream::binaryOut(mTrianglePrismStream, mNumTrianglePrisms); + BinStream::binaryOut(mHexahedronStream, mNumHexahedra); + + mGridStartPointIdx[0] = 0; + for (int currGridIdx=0; currGridIdx < amrHier.numGrids(); ++currGridIdx) { + AMRGrid *currGrid = amrHier.getGridByIndex(currGridIdx); + + if (currGrid->level > mMaxLevel) { + // Skip grid + std::cout << "Skipping grid " << currGrid->index() << ", level " << currGrid->level << " > " << mMaxLevel << std::endl; + mGridStartPointIdx[currGridIdx+1] = mGridStartPointIdx[currGridIdx]; + } + else { + currGrid->loadCells(); + // Write data points + Vertex pos; + int i, j, k; + OutputFPType out; + // (i, j, k) -> mGridStartPointIdx[gridIdx] + (k * dims[1] + j) * dims[0] + i + for (k=0, pos.z = currGrid->origin[2]+0.5*currGrid->delta[2]; k < currGrid->dims[2]; ++k, pos.z += currGrid->delta[2]) + for (j=0, pos.y = currGrid->origin[1]+0.5*currGrid->delta[1]; j < currGrid->dims[1]; ++j, pos.y += currGrid->delta[1]) + for (i=0, pos.x = currGrid->origin[0]+0.5*currGrid->delta[0]; i < currGrid->dims[0]; ++i, pos.x += currGrid->delta[0]) { + out = pos.x; BinStream::binaryOut(mPositionStream, out); + out = pos.y; BinStream::binaryOut(mPositionStream, out); + out = pos.z; BinStream::binaryOut(mPositionStream, out); + out = currGrid->getValue(i, j, k); BinStream::binaryOut(mValueStream, out); + } + int numPointsThisGrid = currGrid->dims[0]*currGrid->dims[1]*currGrid->dims[2]; + mGridStartPointIdx[currGridIdx+1] = mGridStartPointIdx[currGridIdx] + numPointsThisGrid; + mNumPoints += numPointsThisGrid; + + AMRGrid::IntersectionMap *intersectionMap = currGrid->computeIntersectionMap(AMRGrid::IntersectionMap::RefinedCells); + // Write dual grid + for (i=0; i<currGrid->dims[0]-1; ++i) + for (j=0; j<currGrid->dims[1]-1; ++j) + for (k=0; k<currGrid->dims[2]-1; ++k) + if (((*intersectionMap)(i , j , k ) == -1) && ((*intersectionMap)(i , j , k+1) == -1) && + ((*intersectionMap)(i , j+1, k ) == -1) && ((*intersectionMap)(i , j+1, k+1) == -1) && + ((*intersectionMap)(i+1, j , k ) == -1) && ((*intersectionMap)(i+1, j , k+1) == -1) && + ((*intersectionMap)(i+1, j+1, k ) == -1) && ((*intersectionMap)(i+1, j+1, k+1) == -1) + || currGrid->level == maxLevel) + handleHexahedronCell( + AMRGridCell(currGrid, i , j , k ), + AMRGridCell(currGrid, i+1, j , k ), + AMRGridCell(currGrid, i+1, j+1, k ), + AMRGridCell(currGrid, i , j+1, k ), + AMRGridCell(currGrid, i , j , k+1), + AMRGridCell(currGrid, i+1, j , k+1), + AMRGridCell(currGrid, i+1, j+1, k+1), + AMRGridCell(currGrid, i , j+1, k+1) + ); + delete intersectionMap; + } + } +} + +StitchCellWriter::~StitchCellWriter() +{ + // Write actual number of points, tets, ... + mPositionStream.seekp(0); + BinStream::binaryOut(mPositionStream, mNumPoints); + std::cout << "Wrote " << mNumPoints << " positions and values." << std::endl; + mTetStream.seekp(0); + BinStream::binaryOut(mTetStream, mNumTets); + std::cout << "Wrote " << mNumTets << " tetrahedra." << std::endl; + mPyramidStream.seekp(0); + BinStream::binaryOut(mPyramidStream, mNumPyramids); + std::cout << "Wrote " << mNumPyramids << " pyramids." << std::endl; + mTrianglePrismStream.seekp(0); + BinStream::binaryOut(mTrianglePrismStream, mNumTrianglePrisms); + std::cout << "Wrote " << mNumTrianglePrisms << " triangle prisms." << std::endl; + mHexahedronStream.seekp(0); + BinStream::binaryOut(mHexahedronStream, mNumHexahedra); + std::cout << "Wrote " << mNumHexahedra << " hexahedra." << std::endl; +} + +void StitchCellWriter::handleTetrahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const Vertex& p3, double v3) +{ + // Adapt vertex ordering to Nelson Max's ordering scheme + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c0)); + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c2)); + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c1)); + BinStream::binaryOut(mTetStream, addPoint(p3, v3)); + ++mNumTets; +} + +void StitchCellWriter::handleTetrahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3) +{ + // Adapt vertex ordering to Nelson Max's ordering scheme + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c0)); + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c2)); + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c1)); + BinStream::binaryOut(mTetStream, pointIdxForGridCell(c3)); + ++mNumTets; +} + +void StitchCellWriter::handlePyramidCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const Vertex& p4, double v4) +{ + // Adapt vertex ordering to Nelson Max's ordering scheme + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c0)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c1)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c2)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c3)); + BinStream::binaryOut(mPyramidStream, addPoint(p4, v4)); + ++mNumPyramids; +} + +void StitchCellWriter::handlePyramidCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4) +{ + // Adapt vertex ordering to Nelson Max's ordering scheme + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c0)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c1)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c2)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c3)); + BinStream::binaryOut(mPyramidStream, pointIdxForGridCell(c4)); + ++mNumPyramids; +} + +void StitchCellWriter::handleTrianglePrismCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4, const AMRGridCell& c5) +{ + // Adapt vertex ordering to Nelson Max's ordering scheme + BinStream::binaryOut(mTrianglePrismStream, pointIdxForGridCell(c1)); + BinStream::binaryOut(mTrianglePrismStream, pointIdxForGridCell(c2)); + BinStream::binaryOut(mTrianglePrismStream, pointIdxForGridCell(c3)); + BinStream::binaryOut(mTrianglePrismStream, pointIdxForGridCell(c0)); + BinStream::binaryOut(mTrianglePrismStream, pointIdxForGridCell(c4)); + BinStream::binaryOut(mTrianglePrismStream, pointIdxForGridCell(c5)); + ++mNumTrianglePrisms; +} + +void StitchCellWriter::handleHexahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4, const AMRGridCell& c5, const AMRGridCell& c6, const AMRGridCell& c7) +{ + // Adapt vertex ordering to Nelson Max's ordering scheme + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c7)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c6)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c2)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c1)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c4)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c5)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c3)); + BinStream::binaryOut(mHexahedronStream, pointIdxForGridCell(c0)); + ++mNumHexahedra; +} diff --git a/src/AMRHierLib/StitchCellWriter.hh b/src/AMRHierLib/StitchCellWriter.hh new file mode 100644 index 0000000..d19ce93 --- /dev/null +++ b/src/AMRHierLib/StitchCellWriter.hh @@ -0,0 +1,111 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +/* + * Copyright (C) 2001, The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Visualization + * Group at Lawrence Berkeley National Laboratory. + * 4. Neither the name of the University of California, Berkeley nor of the + * Lawrence Berkeley National Laboratory may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE 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 THE 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. + * + * + * This work is supported by the U. S. Department of Energy under contract + * number DE-AC03-76SF00098 between the U. S. Department of Energy and the + * University of California. + * + * Author: Gunther H Weber + * Lawrence Berkeley National Laboratory + * Berkeley, California + * + * "this software is 100% hand-crafted by a human being in the USA and Germany" + * + */ + +#ifndef _GHW_STITCHCELLWRITER_HH_ +#define _GHW_STITCHCELLWRITER_HH_ + +// Standard C/C++ Includes +#include <fstream> + +// Own Helper Includes +#include <BinStream.hh> + +// AMR Related Includes +#include <AMRGrid.hh> +#include <AMRGridCell.hh> + +// A StitchCellCollector that writes all stitch cells to files +class StitchCellWriter { + public: + // Construction/Destruction + StitchCellWriter(const AMRHierarchy& amrHier, const char* baseFilename, int maxLevel); + ~StitchCellWriter(); + + // Cell Types + void handleTetrahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const Vertex& p3, double v3); + void handleTetrahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3); + void handlePyramidCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const Vertex& p4, double v4); + void handlePyramidCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4); + void handleTrianglePrismCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4, const AMRGridCell& c5); + void handleHexahedronCell(const AMRGridCell& c0, const AMRGridCell& c1, const AMRGridCell& c2, const AMRGridCell& c3, const AMRGridCell& c4, const AMRGridCell& c5, const AMRGridCell& c6, const AMRGridCell& c7); + private: + // Private Types + typedef float OutputFPType; + + // Private Memeber Functions + int pointIdxForGridCell(const AMRGridCell& c); + int addPoint(const Vertex& p, double v); + + // Private Data Members + int mMaxLevel; + int *mGridStartPointIdx; + std::ofstream mPositionStream; + std::ofstream mValueStream; + int mNumPoints; + std::ofstream mTetStream; + int mNumTets; + std::ofstream mPyramidStream; + int mNumPyramids; + std::ofstream mTrianglePrismStream; + int mNumTrianglePrisms; + std::ofstream mHexahedronStream; + int mNumHexahedra; +}; + +#include "StitchCellWriter.icc" + +#endif diff --git a/src/AMRHierLib/StitchCellWriter.icc b/src/AMRHierLib/StitchCellWriter.icc new file mode 100644 index 0000000..d91ec06 --- /dev/null +++ b/src/AMRHierLib/StitchCellWriter.icc @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +inline int StitchCellWriter::pointIdxForGridCell(const AMRGridCell& gc) +{ + // (i, j, k) -> mGridStartPointIdx[gridIdx] + (k * dims[1] + j) * dims[0] + i + AMRGrid *g = gc.grid(); + return mGridStartPointIdx[g->index()] + (gc.idx(zAxis) * g->dims[1] + gc.idx(yAxis)) * g->dims[0] + gc.idx(xAxis); +} + +inline int StitchCellWriter::addPoint(const Vertex& p, double v) +{ + OutputFPType out = p.x; BinStream::binaryOut(mPositionStream, out); + out = p.y; BinStream::binaryOut(mPositionStream, out); + out = p.z; BinStream::binaryOut(mPositionStream, out); + out = v; BinStream::binaryOut(mValueStream, out); + return mNumPoints++; +} diff --git a/src/AMRHierLib/Vol2IEEEIO.cc b/src/AMRHierLib/Vol2IEEEIO.cc new file mode 100644 index 0000000..6247eb9 --- /dev/null +++ b/src/AMRHierLib/Vol2IEEEIO.cc @@ -0,0 +1,66 @@ +//------------------------------------------------------------------------------ +// +// Project: AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +#include <IO.hh> +#include <IEEEIO.hh> +#include <fstream> +#include <zlib.h> +#include <iostream> + +int main(int argc, char* argv[]) +{ + if (argc!=3) { + std::cerr << "Usage: " << argv[0] << " <volFilename> <ieeeioFilename>" << std::endl; + return 42; + } + + gzFile in; + if ((in = gzopen(argv[1], "rb"))) { + int dims[3]; + double delta[3]; + bool success = true; + success = success && gzread(in, &dims[0], sizeof(int)) == sizeof(int); + success = success && gzread(in, &dims[1], sizeof(int)) == sizeof(int); + success = success && gzread(in, &dims[2], sizeof(int)) == sizeof(int); + success = success && gzread(in, &delta[0], sizeof(double)) == sizeof(double); + success = success && gzread(in, &delta[1], sizeof(double)) == sizeof(double); + success = success && gzread(in, &delta[2], sizeof(double)) == sizeof(double); + if (success) { + unsigned char* bytedata = new unsigned char[dims[0]*dims[1]*dims[2]]; + if (gzread(in, bytedata, dims[0]*dims[1]*dims[2]*sizeof(unsigned char)) == dims[0]*dims[1]*dims[2]*sizeof(unsigned char)) { + float *data = new float[dims[0]*dims[1]*dims[2]]; + for (int i=0; i<dims[0]*dims[1]*dims[2]; ++i) { + data[i] = double(bytedata[i]); + } + IObase *writer = new IEEEIO(argv[2], IObase::Create); + int rank = 3; + writer->write(IObase::Float32, rank, dims, data); + double origin[3] = {0.0, 0.0, 0.0}; + writer->writeAttribute("origin", IObase::Float64,3,origin); + writer->writeAttribute("min_ext", IObase::Float64,3,origin); + double maxExt[3] = {(dims[0]+1)*delta[0],(dims[1]+1)*delta[1],(dims[2]+1)*delta[2]}; + writer->writeAttribute("max_ext", IObase::Float64,3,maxExt); + int level = 0; + writer->writeAttribute("level", IObase::Int32, 1, &level); + writer->writeAttribute("delta", IObase::Float64, 3, delta); + int refine[3] = { 1, 1, 1 }; + writer->writeAttribute("spatial_refinement", IObase::Int32, 3, refine); + writer->writeAttribute("grid_placement_refinement", IObase::Int32, 3, refine); + int iorigin[3] = { 0, 0, 0 }; + writer->writeAttribute("iorigin", IObase::Int32,3,iorigin); + delete data; + delete writer; + } + delete bytedata; + } + gzclose(in); + } +} diff --git a/src/AMRHierLib/VtxOrder.fig b/src/AMRHierLib/VtxOrder.fig new file mode 100644 index 0000000..e37d6e6 --- /dev/null +++ b/src/AMRHierLib/VtxOrder.fig @@ -0,0 +1,137 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 375 3225 3975 5850 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 1650 4950 75 75 1650 4950 1725 4950 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 450 5475 75 75 450 5475 525 5475 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 2550 5475 75 75 2550 5475 2625 5475 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 3750 4950 75 75 3750 4950 3825 4950 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 2400 3675 75 75 2400 3675 2475 3675 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 3752 4954 2552 5479 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 0 0 2 + 450 5475 2475 5475 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 0 0 2 + 450 5475 2400 3675 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 0 0 2 + 2400 3675 2550 5475 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 0 0 2 + 2400 3675 3750 4950 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 1650 4950 450 5475 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 1725 4950 3750 4950 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 2400 3675 1650 4950 +4 0 0 50 0 0 24 0.0000 4 255 180 1725 5250 0\001 +4 0 0 50 0 0 24 0.0000 4 255 180 450 5850 1\001 +4 0 0 50 0 0 24 0.0000 4 255 180 2550 5850 2\001 +4 0 0 50 0 0 24 0.0000 4 255 180 3750 5325 3\001 +4 0 0 50 0 0 24 0.0000 4 255 180 2325 3525 4\001 +-6 +6 4800 3075 7200 5700 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 6075 4800 75 75 6075 4800 6150 4800 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 4875 5325 75 75 4875 5325 4950 5325 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 6975 5325 75 75 6975 5325 7050 5325 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 5925 3525 75 75 5925 3525 6000 3525 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 0 0 2 + 4875 5325 6900 5325 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 0 0 2 + 4875 5325 5925 3525 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 0 0 2 + 5925 3525 6975 5325 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 6075 4800 4875 5325 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 5925 3525 6075 4800 +2 1 1 1 0 0 50 0 20 4.000 0 0 -1 0 0 2 + 6075 4800 6975 5325 +4 0 0 50 0 0 24 0.0000 4 255 180 4875 5700 1\001 +4 0 0 50 0 0 24 0.0000 4 255 180 6975 5700 2\001 +4 0 0 50 0 0 24 0.0000 4 255 180 5850 3375 3\001 +4 0 0 50 0 0 24 0.0000 4 255 180 6150 4725 0\001 +-6 +6 3750 3075 5025 4500 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4050 3975 4725 3975 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4125 4125 4125 3375 +2 1 0 1 0 0 50 0 20 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4200 3900 3900 4275 +4 0 0 50 0 0 24 0.0000 4 180 195 4800 4050 x\001 +4 0 0 50 0 0 24 0.0000 4 255 165 4125 3300 y\001 +4 0 0 50 0 0 24 0.0000 4 180 150 3750 4500 z\001 +-6 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 750 2550 75 75 750 2550 825 2550 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 2850 2550 75 75 2850 2550 2925 2550 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 3975 2025 75 75 3975 2025 4050 2025 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 1950 2025 75 75 1950 2025 2025 2025 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 750 675 75 75 750 675 825 675 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 1950 150 75 75 1950 150 2025 150 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 4050 150 75 75 4050 150 4125 150 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 2850 675 75 75 2850 675 2925 675 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 5475 525 75 75 5475 525 5550 525 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 7575 525 75 75 7575 525 7650 525 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 6075 1950 75 75 6075 1950 6150 1950 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 4875 2475 75 75 4875 2475 4950 2475 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 6975 2475 75 75 6975 2475 7050 2475 +1 3 0 1 0 0 50 0 20 4.000 1 0.0000 8175 1950 75 75 8175 1950 8250 1950 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 750 675 2850 675 2850 2550 750 2550 750 675 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 750 675 1950 150 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 2849 658 4049 133 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 2859 2541 4059 2016 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 4035 2025 4035 150 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 4020 150 1905 150 +2 1 1 1 0 7 50 0 -1 4.000 0 0 7 0 0 2 + 1950 2025 4035 2025 +2 1 1 1 0 7 50 0 -1 4.000 0 0 7 0 0 2 + 1920 135 1920 1995 +2 1 1 1 0 7 50 0 -1 4.000 0 0 7 0 0 2 + 744 2541 1944 2016 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 8177 1954 6977 2479 +2 1 0 1 0 7 50 0 -1 4.000 0 0 7 0 0 2 + 4875 2475 6900 2475 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 4875 2475 5475 525 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 6975 2475 7575 525 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 7578 524 8178 1949 +2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 + 5475 525 7575 525 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 6150 1950 8175 1950 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 6075 1950 4875 2475 +2 1 1 1 0 0 50 0 20 4.000 0 0 7 0 0 2 + 5475 525 6075 1950 +4 0 0 50 0 0 24 0.0000 4 255 180 1950 2400 0\001 +4 0 0 50 0 0 24 0.0000 4 255 180 3975 2400 1\001 +4 0 0 50 0 0 24 0.0000 4 255 180 4125 525 2\001 +4 0 0 50 0 0 24 0.0000 4 255 180 2025 525 3\001 +4 0 0 50 0 0 24 0.0000 4 255 180 525 2925 4\001 +4 0 0 50 0 0 24 0.0000 4 255 180 2700 2925 5\001 +4 0 0 50 0 0 24 0.0000 4 255 180 2925 1050 6\001 +4 0 0 50 0 0 24 0.0000 4 255 180 825 1050 7\001 +4 0 0 50 0 0 24 0.0000 4 255 180 6150 2250 0\001 +4 0 0 50 0 0 24 0.0000 4 255 180 4875 2850 1\001 +4 0 0 50 0 0 24 0.0000 4 255 180 6975 2850 2\001 +4 0 0 50 0 0 24 0.0000 4 255 180 8175 2325 3\001 +4 0 0 50 0 0 24 0.0000 4 255 180 7500 375 5\001 +4 0 0 50 0 0 24 0.0000 4 255 180 5400 375 4\001 diff --git a/src/AMRHierLib/VtxOrder.pdf b/src/AMRHierLib/VtxOrder.pdf Binary files differnew file mode 100644 index 0000000..a2584cc --- /dev/null +++ b/src/AMRHierLib/VtxOrder.pdf diff --git a/src/AMRHierLib/WriteStitchCells.cc b/src/AMRHierLib/WriteStitchCells.cc new file mode 100644 index 0000000..0becef4 --- /dev/null +++ b/src/AMRHierLib/WriteStitchCells.cc @@ -0,0 +1,53 @@ +//------------------------------------------------------------------------------ +// +// Project: Tools for AMR Visualization +// Module: $RCSfile$ +// Language: C++ +// Date: $Date$ +// Author: $Author$ +// Version: $Revision$ +// +//------------------------------------------------------------------------------ + +// Standard C/C++ Includes +#include <algorithm> +#include <iostream> + +// AMR Related Includes +#include <AMRHierarchy.hh> +#include <AMRLevel.hh> +#include <AMRGridStitcher.hh> + +// Project specific Includes +#include "StitchCellWriter.hh" + +int main(int argc, char* argv[]) +{ + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " <Input File> <Output Basename> <NumUsedLevels>" << std::endl; + return 42; + } + AMRHierarchy theAMRHier; + theAMRHier.readIEEEFile(argv[1]); + int maxLevel = std::min(atoi(argv[3]) - 1, theAMRHier.numLevels() - 1);; + StitchCellWriter writer(theAMRHier, argv[2], maxLevel); + + if (maxLevel > 0) { + for (int currLevelNo = 1; currLevelNo < maxLevel; ++currLevelNo) + { + std::cout << "Start level " << currLevelNo << std::endl; + AMRLevel *currLevel = theAMRHier.getLevel(currLevelNo); + for (AMRGrid *currGridPtr = currLevel->getFirstGrid(); currGridPtr != 0; currGridPtr = currGridPtr->getNextGridInLevel()) { + std::cout << "Stitching grid #" << currGridPtr->index() << std::endl; + AMRGridStitcher<StitchCellWriter> gridStitcher(writer, theAMRHier, currGridPtr, true); + gridStitcher.generateStitchCells(); + } + } + AMRLevel *lastLevel = theAMRHier.getLevel(maxLevel); + for (AMRGrid *currGridPtr = lastLevel->getFirstGrid(); currGridPtr != 0; currGridPtr = currGridPtr->getNextGridInLevel()) { + std::cout << "Stitching grid #" << currGridPtr->index() << std::endl; + AMRGridStitcher<StitchCellWriter> gridStitcher(writer, theAMRHier, currGridPtr, false); + gridStitcher.generateStitchCells(); + } + } +} |