Toast++  1.0.2 (r.539)
Forward and inverse modelling in optical tomography
mesh.h
1 // -*-C++-*-
2 // ==========================================================================
3 // Module libfe
4 // File mesh.h
5 // Declaration of class Mesh
6 // ==========================================================================
7 
8 #ifndef __MESH_H
9 #define __MESH_H
10 
11 #define MESH_DIRICHLET BND_DIRICHLET
12 #define MESH_ROBIN BND_ROBIN
13 #define MESH_EXTRAPOL BND_INTERNAL
14 #define MESH_ODD BND_NONE
15 
16 // system matrix assembly modes
17 #define ASSEMBLE_FF 0
18 #define ASSEMBLE_DD 1
19 #define ASSEMBLE_PFF 2
20 #define ASSEMBLE_PDD 3
21 #define ASSEMBLE_BNDPFF 4
22 #define ASSEMBLE_CFF 5
23 #define ASSEMBLE_CDD 6
24 #define ASSEMBLE_iCFF 7
25 #define ASSEMBLE_iCDD 8
26 #define ASSEMBLE_PFF_EL 9
27 #define ASSEMBLE_PDD_EL 10
28 #define ASSEMBLE_BNDPFF_EL 11
29 #define ASSEMBLE_BNDFF 12
30 #define ASSEMBLE_iPFF 13
31 
32 // rhs assembly modes
33 #define RHS_P 0
34 #define RHS_PF 1
35 #define RHS_BNDPF 2
36 
37 // ==========================================================================
38 // Prototypes
39 
40 FELIB void AddToElMatrix (const Mesh &mesh, int el,
41  RGenericSparseMatrix &M, const RVector *coeff, int mode);
42 
43 FELIB void AddToElMatrix (const Mesh &mesh, int el,
44  FGenericSparseMatrix &M, const RVector *coeff, int mode);
45 
46 FELIB void AddToElMatrix (const Mesh &mesh, int el,
47  SCGenericSparseMatrix &M, const RVector *coeff, int mode);
48 
49 FELIB void AddToElMatrix (const Mesh &mesh, int el,
50  CGenericSparseMatrix &M, const RVector *coeff, int mode);
51 
52 FELIB void AddToSysMatrix (const Mesh &mesh,
53  RGenericSparseMatrix &M, const RVector *coeff, int mode);
54 
55 FELIB void AddToSysMatrix (const Mesh &mesh,
56  FGenericSparseMatrix &M, const RVector *coeff, int mode);
57 
58 FELIB void AddToSysMatrix (const Mesh &mesh,
59  SCGenericSparseMatrix &M, const RVector *coeff, int mode);
60 
61 FELIB void AddToSysMatrix (const Mesh &mesh,
62  CGenericSparseMatrix &M, const RVector *coeff, int mode);
63 
64 FELIB void AddToSysMatrix (const Mesh &mesh,
65  CGenericSparseMatrix &M, const double coeff, int mode);
66 
67 FELIB void AddToSysMatrix (const Mesh &mesh,
68  SCGenericSparseMatrix &M, const double coeff, int mode);
69 
70 FELIB void AddToSysMatrix_elasticity (const Mesh &mesh,
71  RGenericSparseMatrix &M, const RVector &modulus,
72  const RVector &pratio);
73 
74 FELIB void AddToRHS_elasticity (const Mesh &mesh, RVector &rhs,
75  const RVector *coeff, int mode);
76 
77 FELIB void AddToRHS_thermal_expansion (const Mesh &mesh,
78  RVector &rhs, const RVector &modulus, const RVector &pratio,
79  const RVector &thermal_expansion, double deltaT);
80 
81 FELIB RGenericSparseMatrix *GridMapMatrix (const Mesh &mesh,
82  const IVector &gdim, const Point *bbmin, const Point *bbmax,
83  const int *elref);
84 
85 FELIB void AddElasticStrainDisplacementToSysMatrix (const Mesh &mesh,
86  RGenericSparseMatrix &M, double E, double nu, int *nf);
87 
88 FELIB RGenericSparseMatrix *NodeMapMatrix (const Mesh &mesh,
89  const IVector &gdim, const Point *bbmin, const Point *bbmax,
90  const int *elref);
91 
92 FELIB RGenericSparseMatrix *NodeMapMatrix2 (const Mesh &mesh,
93  const IVector &gdim, const Point *bbmin = 0, const Point *bbmax = 0,
94  const int *elref = 0);
95 
96 FELIB RGenericSparseMatrix *Grid2LinPixMatrix (const IVector &gdim,
97  const IVector &bdim, const int *elref = 0);
98 
99 FELIB RGenericSparseMatrix *LinPix2GridMatrix (const IVector &gdim,
100  const IVector &bdim, const int *elref = 0);
101 
102 FELIB RGenericSparseMatrix *CubicPix2GridMatrix (const IVector &bdim,
103  const IVector &gdim, const int *elref = 0);
104 
105 FELIB void GenerateVoxelPositions (const Mesh &mesh, const IVector &gdim,
106  const Point *bbmin, const Point *bbmax, RDenseMatrix &pos);
107 
108 FELIB void SubsampleLinPixel (const RVector &gf, RVector &bf,
109  const IVector &gdim, const IVector &bdim, const int *elref = 0);
110 
111 FELIB RGenericSparseMatrix *NodeMapMatrix (const Mesh &mesh,
112  const IVector &gdim, const Point *bbmin = 0, const Point *bbmax = 0,
113  const int *elref = 0);
114 
115 FELIB RGenericSparseMatrix *GridMapMatrix (const Mesh &mesh,
116  const IVector &gdim, const Point *bbmin = 0, const Point *bbmax = 0,
117  const int *elref = 0);
118 
119 FELIB int *GenerateElementPixelRef (const Mesh &mesh, const IVector &gdim,
120  const Point *bbmin, const Point *bbmax);
121 
122 FELIB void RasterLinPixel (RVector &gf, const RVector &bf,
123  const IVector &gdim, const IVector &bdim, const int *elref = 0);
124 
125 FELIB void SubsampleCubPixel (const RVector &gf, RVector &bf,
126  const IVector &gdim, const IVector &bdim, const int *elref = 0);
127 
128 FELIB void RasterCubPixel (RVector &gf, const RVector &bf,
129  const IVector &gdim, const IVector &bdim, const int *elref = 0);
130 
131 FELIB Mesh *Lin2Quad (const Mesh &linmesh);
132 
133 // ==========================================================================
134 // class Mesh
135 // ==========================================================================
145 class FELIB Mesh {
146 public:
147 
148  NodeList nlist; // list of mesh nodes
149  ElementList elist; // list of mesh elements
150  ParameterList plist; // list of mesh parameters (per node)
151 
152  mutable int **nbhrs;
153  // list of edge-adjacent neighbours for each element
154  // this is only defined after a call to SetupNeighbourList
155 
156  int BndType;
157  // either of MESH_DIRICHLET, MESH_ROBIN, MESH_EXTRAPOL, MESH_ODD
158 
165  Mesh ();
166 
167  virtual ~Mesh ();
168  // destructor
169 
170  void Setup (bool mark_boundary=true);
171  // call this once the node list and element list have been assigned to
172  // let the mesh perform its setup stuff
173 
174  void Copy (const Mesh &mesh);
175  // copy `mesh' to *this
176 
181  int Dimension() const
182  { return (elen() ? elist[0]->Dimension() : 0); }
183 
188  int nlen() const { return nlist.Len(); }
189 
194  int elen() const { return elist.Len(); }
195 
196  int ilen() const { return priv_ilen; }
197  // number of nodes excluding Dirichlet nodes
198 
199  int nbnd() const { return priv_nbnd; }
200  // number of boundary nodes (valid after Setup)
201 
202  RDenseMatrix ElGeom (int el) const;
203  // returns a matrix containing the global coordinates of all nodes of
204  // element el
205 
206  double ElSize (int el) const;
207  // returns the size of element el (area for 2D, volume for 3D) in global
208  // coordinates.
209 
210  Point ElCentre (int el) const;
211  // returns the centre of element el in global coordinates
212 
213  Point ElSideCentre (int el, int sd) const;
214  // returns the centre of side sd of element el in global coordinates
215 
216  double ElSideSize (int el, int sd) const;
217  // returns the size of side 'sd' of element 'el'
218 
219  RVector ElDirectionCosine (int el, int sd, Point *p = 0) const;
220  // returns the direction cosine of side 'sd' of element 'el' at
221  // local point 'p'
222 
228  double FullSize () const;
229 
230  int ElFind (const Point &pt) const;
231  // returns the number of the element which contains the global coordinate
232  // 'pt', or -1 if no element is found
233 
234  int NdFind (const Point &pt, double &dist) const;
235  // returns the number of the node closest to pt and its distance
236 
250  void Reorder (const IVector &perm);
251 
252  double ElDist (int el1, int el2) const;
253  // returns the distance between the centres of elements el1 and el2
254 
255  virtual void ScaleMesh (double scale);
256  // rescale the complete mesh
257 
258  virtual void ScaleMesh (const RVector &scale);
259  // Anisotropic scaling. 'scale' must have the same dimension as the mesh
260 
261  double ParamAverage (const ParameterType prmtp) const;
262  // returns the average of parameter `prmtp' over the entire mesh
263 
264  int MaxNodeDiff (int mode=BW_AUTO) const;
265  // calculates the maximum node number difference within a single element
266  // of the mesh, either using all nodes (mode=BW_TOTAL) or only internal
267  // nodes (mode=BW_INTERNAL). By default (mode=BW_AUTO) it uses all nodes
268  // for Robin meshes, and internal nodes for all other meshes.
269  // To get the semi-bandwith of the system matrix including the diagonal,
270  // add 1 to the return value of MaxNodeDiff
271 
272  Point NeighbourBarycentre (int node);
273  // returns the barycentre position of the neighbours of 'node'.
274 
275  void SparseRowStructure (idxtype *&rowptr, idxtype *&colidx, int &nzero) const;
276  // generate row and column index lists for a system matrix in
277  // compressed row format corresponding to the mesh
278  // See SparseLib++ documentation, "Compressed row storage" for format
279  // Lists rowptr and colidx are allocated internally and must be freed
280  // by the caller when done.
281 
282  void NeighbourCount (int *plist, int nnode, bool include_self = false)
283  const;
284  // returns a list of length intdof or totdof, containing for each node the
285  // number of neighbouring nodes, i.e. the number of nodes which share an
286  // element with the first node.
287  // nnode should be totdof for Robin meshes, or intdof for all others
288  // If include_self==TRUE then each entry of plist is incremented by 1
289 
290  void SysMatrixStructure (int *nz, int **row_ind, int **col_ind);
291  // returns the number of nonzero entries in the system matrix
292  // and lists of row and column indices for each nozero entry
293  // row_ind and col_ind must be deleted after use
294 
295  int FindBoundarySegment (const Point &p, int *n1, int *n2, double *dist1,
296  double *dist2) const;
297  // Calculate the two neighbouring boundary nodes closest to p, and their
298  // distance to p. Return the number of the element owning these nodes
299  // Uses physical boundary for extrapolated meshes
300 
301  double BoundaryDistance (int node) const;
302  // Returns the distance of node `node' from the boundary.
303  // (Currently this only returns the distance between `node' and the
304  // closest boundary node)
305 
306  int BoundaryList (int **bndellist, int **bndsdlist) const;
307  // Generate a list of boundary segments. Each segment i is defined by the
308  // element number *bndellist[i] and relative side number *bndsdlist[i].
309  // return value is the number of boundary segments found.
310 
311  bool PullToBoundary (const Point &p, Point &pshift, int &element,
312  int &side, double sub = 0) const;
313  // calculates the projection pshift of p onto the surface of the nearest
314  // boundary segment of the mesh, and returns the element and side number of
315  // this segment.
316  // if sub > 0 then pshift is not on the surface but at a distance sub
317  // below it.
318  // if sub < 0 then the distance is calculated internally as 1/mus of the
319  // affected element
320  // return value is false if no element was found.
321 
322  bool PullToBoundary_old (const Point &p, Point &pshift, int &element,
323  int &side, double sub = 0) const;
324  // This contains the old algorithm which is used whenever the above fails
325 
326  void SetupNeighbourList () const;
327  // sets up a list of edge-adjacent elements for each element in the mesh
328  // and stores it in nbhrs
329 
330  void NodeNeighbourList (int **_nnbhrs, int ***_nbhrs) const;
331  // generates a list of neighbour nodes for each node in the mesh, and
332  // returns it in the 2D array `_nbhrs'. The number of neighbours for each
333  // node is returned in the 1D array `_nnbhrs'. Both arrays should be
334  // unassigned before the call.
335 
350  bool ElConnected (int el1, int el2, int *sd1 = NULL, int *sd2 = NULL);
351 
352  double Size (Point *centre = 0) const;
353  // returns mesh size (= half length of longest bounding box size) and mesh
354  // centre if `centre' is supplied.
355 
356  void BoundingBox (Point &mmin, Point &mmax, double pad = 0.0) const;
357  // returns bounding box of mesh such that for each node N
358  // min[i] <= N[i] <= max[i], where i=0..1 or 0..2
359  // If pad > 0, the bounding box is enlarged by this margin in all directions
360 
361  Point BndIntersect (const Point &pt1, const Point &pt2);
362  // this calculates the point of intersection of the mesh boundary and the
363  // straight line from pt1 to pt2
364 
365  void ResetCoeff_homog (ParameterType prmtp, double val)
366  { plist.SetParam (prmtp, val); }
367  // resets the coefficient `prmtp' (as defined in param.h) throughout the
368  // mesh to homogeneous value `val'
369 
370  void ResetCoeff_region (ParameterType prmtp, double val, int region);
371  // Resets parameter type `prmtp' to `val' for all nodes belonging to
372  // region `region'
373 
374  void ResetCoeff_sqrt (ParameterType prmtp, double cnt, double bnd);
375  // resets the coefficient 'prmtp' (as defined in param.h) throughout the
376  // mesh, as a function of square root of distance from centre, from value
377  // 'cnt' at the centre to value 'bnd' at the boundary
378 
379  int CheckConsistency () const;
380  // performs some tests to check the consistency of the mesh
381  // returns 0 if mesh seems OK, or a nonzero errorcode if not
382  // aborts on error only if FEM_DEBUG is defined
383 
384  void MarkBoundary ();
385  // scans through mesh structure and marks nodes on the mesh surface
386  // as boundary nodes
387 
397  RCompRowMatrix *MassMatrix () const;
398 
399  friend FELIB void AddToElMatrix (const Mesh &mesh, int el,
400  RGenericSparseMatrix &M, const RVector *coeff, int mode);
401  // Assembles nodal coefficient vector 'coeff' into element matrix 'M'
402  // (only fills entries relevant for the element)
403 
404  friend FELIB void AddToElMatrix (const Mesh &mesh, int el,
405  FGenericSparseMatrix &M, const RVector *coeff, int mode);
406  // Assembles nodal coefficient vector 'coeff' into element matrix 'M'
407  // (only fills entries relevant for the element)
408 
409  friend FELIB void AddToElMatrix (const Mesh &mesh, int el,
410  SCGenericSparseMatrix &M, const RVector *coeff, int mode);
411  // Assembles nodal coefficient vector 'coeff' into element matrix 'M'
412  // (only fills entries relevant for the element)
413 
414  friend FELIB void AddToElMatrix (const Mesh &mesh, int el,
415  CGenericSparseMatrix &M, const RVector *coeff, int mode);
416  // Assembles nodal coefficient vector 'coeff' into element matrix 'M'
417  // (only fills entries relevant for the element)
418 
419  friend FELIB void AddToSysMatrix (const Mesh &mesh,
420  RGenericSparseMatrix &M, const RVector *coeff, int mode);
421  // Assembles coefficient vector 'coeff' into system matrix 'M' using
422  // the specified mode
423  // For modes FF and DD 'coeff' is ignored
424 
425  friend FELIB void AddToSysMatrix (const Mesh &mesh,
426  FGenericSparseMatrix &M, const RVector *coeff, int mode);
427  // Assembles coefficient vector 'coeff' into system matrix 'M' using
428  // the specified mode
429  // For modes FF and DD 'coeff' is ignored
430 
431  friend FELIB void AddToSysMatrix (const Mesh &mesh,
432  SCGenericSparseMatrix &M, const RVector *coeff, int mode);
433 
434  friend FELIB void AddToSysMatrix (const Mesh &mesh,
435  CGenericSparseMatrix &M, const RVector *coeff, int mode);
436  // As above but for complex system matrix. Modes can also contain assembly
437  // commands for imaginary part
438 
439  friend FELIB void AddToSysMatrix (const Mesh &mesh,
440  CGenericSparseMatrix &M, const double coeff, int mode);
441 
442  friend FELIB void AddToSysMatrix (const Mesh &mesh,
443  SCGenericSparseMatrix &M, const double coeff, int mode);
444  // This version adds a component with constant coefficient 'coeff' to
445  // the real or imaginary part of system matrix M
446 
447  friend FELIB void AddToSysMatrix_elasticity (const Mesh &mesh,
448  RGenericSparseMatrix &M, const RVector &modulus,
449  const RVector &pratio);
450 
451  friend FELIB void AddToRHS_elasticity (const Mesh &mesh, RVector &rhs,
452  const RVector *coeff, int mode);
453  // Adds a component to an rhs vector, given the specified mode
454 
455  friend FELIB void AddToRHS_thermal_expansion (const Mesh &mesh,
456  RVector &rhs, const RVector &modulus, const RVector &pratio,
457  const RVector &thermal_expansion, double deltaT);
458 
459  friend FELIB void AddElasticStrainDisplacementToSysMatrix (const Mesh &mesh,
460  RGenericSparseMatrix &M, double E, double nu, int *nf);
461 
479  friend FELIB RGenericSparseMatrix *GridMapMatrix (const Mesh &mesh,
480  const IVector &gdim, const Point *bbmin, const Point *bbmax,
481  const int *elref);
482 
502  friend FELIB RGenericSparseMatrix *NodeMapMatrix (const Mesh &mesh,
503  const IVector &gdim, const Point *bbmin, const Point *bbmax,
504  const int *elref);
505 
506  friend FELIB RGenericSparseMatrix *NodeMapMatrix2 (const Mesh &mesh,
507  const IVector &gdim, const Point *bbmin, const Point *bbmax,
508  const int *elref);
509 
510  friend FELIB RGenericSparseMatrix *Grid2LinPixMatrix (const IVector &gdim,
511  const IVector &bdim, const int *elref);
512  // Generate a sparse matrix which maps a bitmap of dimension gdim into
513  // a linear pixel basis of dimension bdim
514 
515  friend FELIB RGenericSparseMatrix *LinPix2GridMatrix (const IVector &gdim,
516  const IVector &bdim, const int *elref);
517 
518  friend FELIB RGenericSparseMatrix *CubicPix2GridMatrix (const IVector &bdim,
519  const IVector &gdim, const int *elref);
520 
521  friend FELIB int *GenerateElementPixelRef (const Mesh &mesh,
522  const IVector &gdim, const Point *bbmin, const Point *bbmax);
523  // Generate element index list for pixels in grid defined by gdim.
524  // This list is required by GridMapMatrix and NodeMapMatrix
525 
526  friend FELIB void GenerateVoxelPositions (const Mesh &mesh,
527  const IVector &gdim, const Point *bbmin, const Point *bbmax,
528  RDenseMatrix &pos);
529  // Return the positions of the voxel vertices of a regular grid, defined
530  // by (gdim,bbmin,bbmax), in dense matrix pos
531 
532  friend FELIB void SubsampleLinPixel (const RVector &gf, RVector &bf,
533  const IVector &gdim, const IVector &bdim, const int *elref);
534  // Subsample an image gf from the raster grid of dimension gdim to a
535  // (coarser) linear pixel basis of dimension bdim.
536  // Both grids are assumed to have identical bounding boxes
537  // elref (as returned by GenerateElementPixelRef) contains the mesh support
538  // information: elref[i] < 0 indicates that pixel i has no overlap with the
539  // mesh. If elref==0 then full support is assumed.
540 
541  friend FELIB void RasterLinPixel (RVector &gf, const RVector &bf,
542  const IVector &gdim, const IVector &bdim, const int *elref);
543  // Inverse of SubsampleLinPixel: expand linear pixel basis into raster
544  // image
545 
546  friend FELIB void SubsampleCubPixel (const RVector &gf, RVector &bf,
547  const IVector &gdim, const IVector &bdim, const int *elref);
548  // Same as SubsampleLinPixel, but for cubic pixel basis
549 
550  friend FELIB void RasterCubPixel (RVector &gf, const RVector &bf,
551  const IVector &gdim, const IVector &bdim, const int *elref);
552  // Same as RasterLinPixel, but for cubic pixels
553 
554  // I/O
555  friend FELIB std::istream& operator>> (std::istream& i, Mesh& mesh);
556  friend FELIB std::ostream& operator<< (std::ostream& o, Mesh& mesh);
557  void put (std::ostream &os, ParameterType p1 = PRM_MUA,
558  ParameterType p2 = PRM_KAPPA, ParameterType p3 = PRM_N);
559  void WriteVtk (ostream &os, const RVector &nim);
560 
561  bool trap_load_error;
562  // set this to false if mesh input errors should not cause an abort
563  // default is true
564 
565  Surface *Boundary() const { return boundary; }
566  // The parametric (outer) surface of the mesh (or NULL if no surface)
567 
568  void SetBoundary (const Surface &_boundary);
569  // Set or reset parametric mesh surface
570 
571  void PopulateNeighbourLists ();
572 
573  void InitSubdivisionSupport ();
574 
583  int RefineElement (int el);
584 
585  RVector *bnd_param;
586  // List of boundary parametrisations for all boundary nodes
587  // (dimension priv_nbnd). Valid after Setup, and only if boundary != NULL
588 
589  int *IndexBnd2Node;
590  int *IndexNode2Bnd;
591  // index lists to map between absolute node numbers and boundary node
592  // numbers. Valid after call to Setup
593  // IndexBnd2Node[i] is the absolute node number of the i-th boundary node
594  // IndexNode2Bnd[j] is the boundary index of node j, or -1 if j is not
595  // a boundary node.
596 
597 private:
598  bool is_set_up;
599  // True once Setup has been called
600 
601  int priv_ilen;
602  //SymMatrix *elk, *elc, *ela; // list of element matrices
603 
604  int priv_nbnd;
605  // number of boundary nodes (valid after Setup)
606 
607  mutable int lastel_found;
608  // contains the element returned by the last call to ElFind
609  // The next search starts around this point
610 
611  double CalcFullSize () const;
612  // returns mesh size by summing up element sizes. This is called by
613  // Setup(), and by FullSize() in case Setup() was not invoked
614 
615  mutable double fullsize;
616  // mesh size (area for 2D meshes, volume for 3D meshes)
617  // This is set by Setup() or by the first call to FullSize()
618 
619  Surface *boundary;
620  // The parametric (outer) surface of the mesh (or NULL if no surface)
621 
622  //void SetupElementMatrices (void);
623  // generate element matrix lists elc and elk, to be subsequently assembled
624  // into system matrices. This function must be called after any
625  // manipulations to the mesh topology (eg. Extrapolate) and before system
626  // matrix assembly (e.g. before a ForwardSolver is instantiated)
627  // The element matrices depend only on mesh topology, not on element
628  // mua or kappa (mua and kappa are added only during system matrix
629  // assembly). SetupElementMatrices can be called repeatedly to reflect
630  // topology changes
631 
632 #ifdef TOAST_PARALLEL
633  static void Setup_engine (void*,int,int);
634 #endif
635 };
636 
637  int MakeNodalFreedomArray (int *&nf, int nlen, int dofnod, bool *rest);
638 
639  void CreateVoxelMesh (int ex, int ey, int ez, bool *egrid,
640  double dx, double dy, double dz, Mesh &mesh);
641 
642 #endif // !__MESH_H
Definition: ndlist.h:14
Virtual base class for sparse matrix types.
Definition: gsmatrix.h:47
Templated vector class.
Definition: vector.h:39
Definition: surface.h:21
Definition: ellist.h:18
int Dimension() const
Mesh dimension.
Definition: mesh.h:181
Finite-element mesh management.
Definition: mesh.h:145
int elen() const
Number of mesh elements.
Definition: mesh.h:194
Definition: point.h:18
Definition: param.h:169
int nlen() const
Number of mesh nodes.
Definition: mesh.h:188
Dense matrix class.
Definition: crmatrix.h:38