aboutsummaryrefslogtreecommitdiff
path: root/src/AMRHierLib/AMRGrid.hh
blob: f4b799c341eab11123f7ff0c59d06d6d41091797 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
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