HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_MGOperator.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_MGOperator.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  * This class encapsulates a tiled discrete Laplacian operator that
10  * is algebraically coarsened, allowing for a sparse Poisson solve.
11  */
12 
13 #ifndef __UT_MGOperator__
14 #define __UT_MGOperator__
15 
16 #include "UT_API.h"
17 #include "UT_MatrixSolver.h"
18 #include "UT_VoxelArray.h"
19 #include "UT_FixedVector.h"
20 
21 /// This function returns true if the given tile has at least one voxel whose
22 /// value exceeds 0.5.
23 template<typename S> UT_API
24 bool ut_tileHasActiveVoxel(const UT_VoxelTile<S>* tile);
25 
26 template<typename T>
28 {
29 public:
30  /// Once initialized, this operator is algebraically coarsened until the number
31  /// of degrees of freedom does not exceed the provided threshold.
32  UT_MGOperatorT(int threshold = 100) : myVoxelCountThreshold(threshold),
33  mySmoothingPasses(2),
34  myDiffusionPasses(1),
35  myAmplificationFactor(1.8),
36  myJacobiOmega(2.0 / 3),
37  myGSOmega(4.0 / 3) {}
38 
39  /// Initializes this operator to the Laplacian matrix with the given spacing and
40  /// boundary conditions. This method also takes care of setting up the coarser
41  /// operators. Tiles in the operator corresponds to tiles of the reference array.
42  /// Active tiles are non-constant or different from inactive.
43  /// All dimensions of the reference array must be divisible by 16.
44  template<typename S>
45  void init(const UT_VoxelArray<S>& ref, S inactive,
46  const UT_Vector3T<T>& spacing,
47  const UT_Vector3I& boundariesNeg,
48  const UT_Vector3I& boundariesPos);
49  /// This version of initialization takes a validity map (whose resolution should
50  /// match that of the finest tile map) and performs the necessary setup. Active
51  /// tiles have a non-zero value in the reference voxel array.
52  /// Resolution of this operator will be 16 times the resolution of the reference
53  /// array.
54  template<typename S>
55  void init(const UT_VoxelArray<S>& ref,
56  const UT_Vector3T<T>& spacing,
57  const UT_Vector3I& boundariesNeg,
58  const UT_Vector3I& boundariesPos);
59  /// This version of initialization accepts a stencil array. Tiles in the operator
60  /// are activated if the corresponding tile in the stencil array has at least one
61  /// voxel whose value exceeds 0.5.
62  /// All dimension of the reference array must be divisible by 16.
63  template<typename S>
64  void initFromStencil(const UT_VoxelArray<S>& stencil,
65  const UT_Vector3T<T>& spacing,
66  const UT_Vector3I& boundariesNeg,
67  const UT_Vector3I& boundariesPos);
68 
69  /// Applies the restriction operator from level l to level l+1.
70  void mgRestrict(const UT_VectorT<T>& src, UT_VectorT<T>& dst, int l) const;
71  /// Applies the prolongation operator from level l+1 to level l.
72  void mgProlong(const UT_VectorT<T>& src, UT_VectorT<T>& dst, int l) const;
73 
74  /// Flattens contents of the given voxel array into the vector.
75  void copyFromVoxels(const UT_VoxelArray<T>& src, UT_VectorT<T>& dst) const;
76  /// Copies the contents of the flattened vector into the voxel array. If topad
77  /// is true, then destination array will have an extra layer of voxels
78  /// compared to the internal tile map, whose entries will be set to 0.
79  void copyToVoxels(const UT_VectorT<T>& src, UT_VoxelArray<T>& dst,
80  bool topad) const;
81 
82  /// Solves the linear system using multigrid.
83  /// The solution is stored in x, which will be initialized to the appropriate
84  /// size. If b has incomplete tiles, x will be padded with an extra layer of
85  /// voxels along every dimension.
86  /// If startFMG is true, the first iteration will be full-multigrid;
87  /// otherwise, only v-cycles are used.
88  int solvePoisson(fpreal64 abstol, fpreal64 reltol, int maxiter,
90  UT_ValArray<fpreal64>* resnorminf,
91  UT_ValArray<fpreal64>* resnorm2,
92  bool startFMG = true);
93 
94  /// Calculates b-Lx at the given level and puts the answer in d (note that b
95  /// and d can be the same vector).
96  void subtractApplyLaplacian(const UT_VectorT<T>& x, const UT_VectorT<T>& b,
97  UT_VectorT<T>& d, int level) const;
98  /// Calculates Lx at the given level and puts the answer in b.
99  void applyLaplacian(const UT_VectorT<T>& x, UT_VectorT<T>& b, int level) const;
100 
101  /// Does a full multigrid solve to get an approximation for the solution to
102  /// the equation Lx=b at the given level. Note that x must be pre-initialized,
103  /// but its incoming contents are irrelevant.
104  /// t0 and t1 are used to perform intermediate work and must be pre-allocated.
105  void fullMultigrid(UT_VectorT<T>& x, const UT_VectorT<T>& b, UT_VectorT<T>& t0,
106  UT_VectorT<T>& t1, int level);
107  /// Approximates a solution for the equation Lx=b using a single V-cycle. Note
108  /// that x will be re-initialized, so its incoming contents are irrelevant.
109  /// t is a temporary vector that must be allocated to the same size as x.
110  void vcycle(UT_VectorT<T>& x, UT_VectorT<T>& t, const UT_VectorT<T>& b,
111  int level);
112  /// Does a single iteration of relaxation on the solution vector at the given
113  /// level. For positive levels, uses Jacobi relaxation; for negative levels,
114  /// performs red-black Gauss-Seidel, with redFirst indicating which color to
115  /// smooth first.
116  /// For Jacobi smoothing (non-negative levels) x0 is the vector to relax, x
117  /// will hold the result. These vectors must be distinct! For Gauss-Seidel
118  /// smoothing (negative levels), x holds the input and output solutions, so x0
119  /// is unused.
120  /// If ZERO_GUESS is true, it is assumed that the incoming vector is zero.
121  template<bool ZERO_GUESS = false>
122  void smoothLaplacian(UT_VectorT<T>& x, const UT_VectorT<T>& x0,
123  const UT_VectorT<T>& b, T omega, int level,
124  bool redFirst) const;
125  /// Does a single iteration of homogeneous relaxation (smoothing for the system
126  /// Lx=0). Uses Jacobi relaxation without damping.
127  /// x0 is the vector to relax, x will hold the results; these vectors must be
128  /// distinct!
129  void smoothLaplacianHomogeneous(UT_VectorT<T>& x, const UT_VectorT<T>& x0,
130  int level) const;
131  /// Performs a direct solve at the coarsest level.
132  void directSolve(UT_VectorT<T>& x, const UT_VectorT<T>& b) const;
133 
134  /// Returns the tile map's resolution at the given level.
135  UT_Vector3i getTileMapResolution(int level) const;
136  /// Returns the number of voxels at the given level.
137  exint getNumVoxels(int level) const;
138  /// Returns the number of active tiles at the given level.
139  int getNumTiles(int level) const;
140  /// Returns the number of tile map levels (depth of the operator).
141  int getNumLevels() const;
142 
143  /// Build the tile Laplacian matrix at the specified level. Only works for non-
144  /// negative levels. Returns the number of rows/columns.
145  int buildMatrix(UT_MatrixT<T>& M, int level) const;
146 
147 protected:
148  /// Helper function to create the finest level tile map from the given reference
149  /// voxel array. If tileMap is false, tiles of the array are considered active
150  /// if they are not constant and equal to the inactive argument. If tileMap is
151  /// true, ref is assumed to be the same resolution as the finest tile map, and
152  /// a tile is active if its value in ref is non-zero.
153  /// Spacing and boundary conditions must be set prior to calling this function.
154  template<typename S>
155  void initTileMap0(const UT_VoxelArray<S>& ref, S inactive, bool tileMap);
156  /// Adds a tile map one level coarser than the coarsest in the atlas.
157  void addTileMapLevel();
158 
159  /// Builds the coefficient matrix for the linear system at the last level. Also
160  /// factors it to allow for fast linear solves.
161  void factorFinalLevel();
162  /// Helper function to for initialization. Coarsens the map until the degrees of
163  /// freedom are sufficiently reduced, factors the final level, and allocates the
164  /// scratchpad.
165  void finishInit();
166 
167  /// Returns the off-diagonal value in the matrix between the node at the given
168  /// location and the next one along the supplied axis; works at the provided
169  /// level. Note that axis must be in [0, 5], coresponding to -X, +X, -Y, +Y, -Z,
170  /// +Z.
171  inline T getEdgeWeight(int x, int y, int z, int level, int axis) const;
172  /// Returns the diagonal value in the matrix at the given voxel and level.
173  inline T getDiagonalWeight(int x, int y, int z, int level) const;
174 
175  /// Helper function for mgRestrict() and mgProlong(), for negative levels.
176  /// If RESTRICT is true, src is restricted to a coarser level and stored in dst.
177  /// If RESTRICT is false, src is prolongated to a finer level and stored in dst.
178  /// LEVEL must be pre-negated (so it is positive).
179  template<bool RESTRICT, int LEVEL>
180  inline void mgRestrictProlongN(const UT_VectorT<T>& src, UT_VectorT<T>& dst)
181  const;
182  /// Helper function for mgRestrict(), for non-negative levels.
183  /// If RESTRICT is true, src is restricted to a coarser level and stored in dst.
184  /// If RESTRICT is false, src is prolongated to a finer level and stored in dst.
185  template<bool RESTRICT>
186  inline void mgRestrictProlongP(const UT_VectorT<T>& src, UT_VectorT<T>& dst,
187  int level) const;
188 
189  /// Helper function for applying the Laplacian operator. LEVEL must be pre-negated
190  /// (so it is positive). If SUBTRACT is true computes b-Lx, otherwise calculates
191  /// Lx.
192  template<int LEVEL, bool SUBTRACT>
193  inline void applyLaplacianInternalN(const UT_VectorT<T>& x, const UT_VectorT<T>& b,
194  UT_VectorT<T>& d) const;
195  /// Helper function for subtractApplyLaplacian(), for non-negative levels. If
196  /// SUBTRACT is true, computes b-Lx, otherwise calculates Lx.
197  template<bool SUBTRACT>
198  inline void applyLaplacianInternalP(const UT_VectorT<T>& x, const UT_VectorT<T>& b,
199  UT_VectorT<T>& d, int level) const;
200 
201  /// Performs a single step of red-black Gauss-Seidel relaxation for voxels of the
202  /// given parity. Note that this helper function is intended for negative levels
203  /// (multiple voxels per tile). The template parameter must be pre-negated (so it
204  /// is positive).
205  /// If ZERO_GUESS is true, FIRST_PASS signals whether or not one of the colors has
206  /// already been processed. The difference is that on the second pass, values of
207  /// the previous color must be used, but colors of the current color are still
208  /// assumed to be zero.
209  /// This generic function implements the relaxation for all types and negative
210  /// levels.
211  template<int LEVEL, bool ZERO_GUESS, bool FIRST_PASS>
212  inline void smoothLaplacianInternalGS(UT_VectorT<T>& x, const UT_VectorT<T>& b,
213  T omega, int parity) const;
214  /// Performs a single step of red-black Gauss-Seidel relaxation for voxels of the
215  /// given parity at level -1. This is a specialized method that either calls the
216  /// generic function or does the work itself using SIMD.
217  template<bool ZERO_GUESS, bool FIRST_PASS>
218  inline void smoothLaplacianInternalGS_V1(UT_VectorT<T>& x, const UT_VectorT<T>& b,
219  T omega, int parity) const;
220  /// Performs a single step of red-black Gauss-Seidel relaxation for voxels of the
221  /// given parity at level -2. This is a specialized method that either calls the
222  /// generic function or does the work itself using SIMD.
223  template<bool ZERO_GUESS, bool FIRST_PASS>
224  inline void smoothLaplacianInternalGS_V2(UT_VectorT<T>& x, const UT_VectorT<T>& b,
225  T omega, int parity) const;
226  /// Performs a single step of red-black Gauss-Seidel relaxation for voxels of the
227  /// given parity at level -3 or -4. This is a specialized method that either calls
228  /// the generic function or does the work itself using SIMD.
229  template<int LEVEL, bool ZERO_GUESS, bool FIRST_PASS>
230  inline void smoothLaplacianInternalGS_V34(UT_VectorT<T>& x, const UT_VectorT<T>& b,
231  T omega, int parity) const;
232  /// Performs a single step of Jacobi relaxation. This helper function is intended
233  /// for negative levels (the template parameter must be pre-negated so it is
234  /// positive.
235  /// CAUTION: x and x0 must be distinct!
236  /// b vector is unused if relaxation is homogeneous. Likewise, omega is unused (no
237  /// damping).
238  /// This generic function implements the relaxation for all types and negative
239  /// levels.
240  template<int LEVEL, bool HOMOGENEOUS>
241  inline void smoothLaplacianInternalJN(UT_VectorT<T>& x, const UT_VectorT<T>& x0,
242  const UT_VectorT<T>& b, T omega) const;
243  /// Performs a single step of Jacobi relaxation at level -1. This is a specialized
244  /// method that either calls the generic function or does the work itself using SIMD.
245  template<bool HOMOGENEOUS>
246  inline void smoothLaplacianInternalJN_V1(UT_VectorT<T>& x, const UT_VectorT<T>& x0,
247  const UT_VectorT<T>& b, T omega) const;
248  /// Performs a single step of Jacobi relaxation at levels -2, -3, or -4. This is a
249  /// specialized method that either calls the generic function or does the work itself
250  /// using SIMD.
251  template<int LEVEL, bool HOMOGENEOUS>
252  inline void smoothLaplacianInternalJN_V234(UT_VectorT<T>& x, const UT_VectorT<T>& x0,
253  const UT_VectorT<T>& b, T omega) const;
254  /// Performs a single step of Jacobi relaxation. This helper function is intended
255  /// for non-negative levels.
256  /// CAUTION: x and x0 must be distinct!
257  /// b vector is unused if relaxation is homogeneous. Likewise, omega is unused (no
258  /// damping).
259  template<bool HOMOGENEOUS, bool ZERO_GUESS>
260  inline void smoothLaplacianInternalJP(UT_VectorT<T>& x, const UT_VectorT<T>& x0,
261  const UT_VectorT<T>& b, T omega,
262  int level) const;
263 
264  /// Puts pointers to the blocks from the given vector into the data array.
265  /// Border compensations for adjusting the diagonal value are also placed in the
266  /// border array.
267  template<int LEVEL>
268  void getTilePointers(int tile, const UT_VectorT<T>& b, T* data[7], T border[6])
269  const;
270 
271  /// Multithreaded helper for copyToVoxels. dst should be set to the correct size
272  /// before calling this.
273  THREADED_METHOD3_CONST(UT_MGOperatorT, dst.numTiles() > 500,
274  copyToVoxelsHelper,
275  const UT_VectorT<T>&, src,
277  bool, topad);
278  void copyToVoxelsHelperPartial(const UT_VectorT<T>& src, UT_VoxelArray<T>& dst,
279  bool toPad, const UT_JobInfo& info) const;
280 
281 
282 public:
283  /// This struct contains the coordinates of the current tile, as well as its
284  /// Laplacian coefficients.
285  /// Coefficient order convention: -X, +X, -Y, +Y, -Z, +Z, diagonal.
287  {
290  };
291 
292  /// This struct holds the tile map (which gives the linear tile number for each
293  /// tile location), its inverse map (which produces location of a tile from its
294  /// linear index), and the coefficients for the row corresponding to the tile.
295  struct utMGTileMap
296  {
299  };
300 
301 protected:
302  /// Internal coefficients for the Laplacian operator; first three hold the
303  /// weights along each axis, followed by the diagonal weight.
305  /// Conditions at the lower/left/back boundaries of the map.
307  /// Conditions at the upper/right/front boundaries of the map.
309 
310  /// Array of tile map levels.
312 
313  /// The factored coefficient matrix for the linear system at the coarsest tile
314  /// level.
317 
318  /// The tile map is coarsened until its number of voxels is smaller than this
319  /// value.
321 
322  /// Array of pre-allocated temporary vectors for use in the Poisson solve (2 per
323  /// level).
325 
326 public:
327  /// Number of pre- and post-smoothing passes to perform in a V-cycle.
329  /// Number of homogeneous smoothing passes to perform after prolongation in a
330  /// V- and full multigrid cycles.
332  /// Amplification factor after prolongation (for V- and full multigrid cycles).
334  /// Damping parameter for Jacobi smoothing passes.
336  /// Overrelaxation parameter for Gauss-Seidel smoothing passes.
338 };
339 
343 
346 
347 #endif
348 
UT_MGOperatorT(int threshold=100)
Definition: UT_MGOperator.h:32
UT_FixedVector< T, 7 > coeff
UT_Array< utMGTileMap > myAtlas
Array of tile map levels.
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
int64 exint
Definition: SYS_Types.h:125
GLint level
Definition: glcorearb.h:108
#define UT_API
Definition: UT_API.h:14
UT_Vector3I myBoundariesPos
Conditions at the upper/right/front boundaries of the map.
GLint y
Definition: glcorearb.h:103
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:174
UT_API bool ut_tileHasActiveVoxel(const UT_VoxelTile< S > *tile)
double fpreal64
Definition: SYS_Types.h:201
int mySmoothingPasses
Number of pre- and post-smoothing passes to perform in a V-cycle.
UT_MGOperatorT< fpreal32 > UT_MGOperatorF
GLint ref
Definition: glcorearb.h:124
UT_VectorT< T > myCoarseCholeskyD
UT_VoxelArray< int > tileMap
const int myVoxelCountThreshold
T myAmplificationFactor
Amplification factor after prolongation (for V- and full multigrid cycles).
UT_Vector4T< T > myInternalCoeff
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
UT_MatrixT< T > myCoarseCholeskyL
GLdouble t
Definition: glad.h:2397
UT_Vector3I myBoundariesNeg
Conditions at the lower/left/back boundaries of the map.
UT_Array< utMGCoordAndCoeff > invTileMapMat
UT_EXTERN_TEMPLATE(UT_MGOperatorT< fpreal32 >)
GLenum GLenum dst
Definition: glcorearb.h:1793
GLint GLint GLsizei GLint border
Definition: glcorearb.h:108
UT_Array< UT_VectorT< T > > myScratchpad
UT_MGOperatorT< fpreal64 > UT_MGOperatorD
T myGSOmega
Overrelaxation parameter for Gauss-Seidel smoothing passes.
GLint GLfloat GLint stencil
Definition: glcorearb.h:1278
#define THREADED_METHOD3_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3)
UT_MGOperatorT< fpreal > UT_MGOperatorR
Definition: format.h:895
T myJacobiOmega
Damping parameter for Jacobi smoothing passes.
GLenum src
Definition: glcorearb.h:1793