aboutsummaryrefslogtreecommitdiff
path: root/src/AMRHierLib
diff options
context:
space:
mode:
Diffstat (limited to 'src/AMRHierLib')
-rw-r--r--src/AMRHierLib/AMRGrid.cc612
-rw-r--r--src/AMRHierLib/AMRGrid.hh327
-rw-r--r--src/AMRHierLib/AMRGrid.icc194
-rw-r--r--src/AMRHierLib/AMRGridCell.cc32
-rw-r--r--src/AMRHierLib/AMRGridCell.hh130
-rw-r--r--src/AMRHierLib/AMRGridCell.icc47
-rw-r--r--src/AMRHierLib/AMRGridStitcher.cc1936
-rw-r--r--src/AMRHierLib/AMRGridStitcher.hh141
-rw-r--r--src/AMRHierLib/AMRHierarchy.cc189
-rw-r--r--src/AMRHierLib/AMRHierarchy.hh127
-rw-r--r--src/AMRHierLib/AMRHierarchy.icc93
-rw-r--r--src/AMRHierLib/AMRLevel.cc152
-rw-r--r--src/AMRHierLib/AMRLevel.hh169
-rw-r--r--src/AMRHierLib/AMRLevel.icc78
-rw-r--r--src/AMRHierLib/COPYRIGHT42
-rw-r--r--src/AMRHierLib/Makefile138
-rw-r--r--src/AMRHierLib/PrintAMRHier.cc24
-rw-r--r--src/AMRHierLib/README28
-rw-r--r--src/AMRHierLib/StitchCellWriter.cc188
-rw-r--r--src/AMRHierLib/StitchCellWriter.hh111
-rw-r--r--src/AMRHierLib/StitchCellWriter.icc26
-rw-r--r--src/AMRHierLib/Vol2IEEEIO.cc66
-rw-r--r--src/AMRHierLib/VtxOrder.fig137
-rw-r--r--src/AMRHierLib/VtxOrder.pdfbin0 -> 3069 bytes
-rw-r--r--src/AMRHierLib/WriteStitchCells.cc53
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
new file mode 100644
index 0000000..a2584cc
--- /dev/null
+++ b/src/AMRHierLib/VtxOrder.pdf
Binary files differ
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();
+ }
+ }
+}