Dendro  5.01
Dendro in Greek language means tree. The Dendro library is a large scale (262K cores on ORNL's Titan) distributed memory adaptive octree framework. The main goal of Dendro is to perform large scale multiphysics simulations efficeiently in mordern supercomputers. Dendro consists of efficient parallel data structures and algorithms to perform variational ( finite element) methods and finite difference mthods on 2:1 balanced arbitary adaptive octrees which enables the users to perform simulations raning from black holes (binary black hole mergers) to blood flow in human body, where applications ranging from relativity, astrophysics to biomedical engineering.
oda.h
Go to the documentation of this file.
1 
12 #ifndef DENDRO_5_ODA_H
13 #define DENDRO_5_ODA_H
14 
15 #include "dendro.h"
16 #include <iostream>
17 #include <vector>
18 #include "mpi.h"
19 #include "mesh.h"
20 #include "parUtils.h"
21 #include "testUtils.h"
22 #include "asyncExchangeContex.h"
23 #include "oct2vtk.h"
24 #include "odaUtils.h"
25 #include "matRecord.h"
26 #include <assert.h>
27 
28 #ifdef BUILD_WITH_PETSC
29  #include "petsc.h"
30  #include "petscvec.h"
31  #include "petscmat.h"
32  #include "petscdmda.h"
33 #endif
34 
35 #define VECType DendroScalar
36 #define MATType DendroScalar
37 
38 /***
39  * Note: All the Dendro vectors are stored like as shown below in the memory.
40  * |------- pre ghost nodes----- |-----------local nodes---------------|--------post ghost nodes--------|
41  *
42  *
43  *
44  * */
45 
46 // ODA flag information.
47 namespace ot
48 {
49  namespace DA_FLAGS
50  {
65  enum LoopType {ALL,WRITABLE,INDEPENDENT,W_DEPENDENT,W_BOUNDARY,LOCAL_ELEMENTS,PREGHOST_ELEMENTS,POSTGHOST_ELEMENTS};
66 
77  enum BdyType {X_MIN,X_MAX,Y_MIN,Y_MAX,Z_MIN,Z_MAX};
78 
79 
86  enum Refine {DA_NO_CHANGE,DA_REFINE,DA_COARSEN};
87 
88  enum WriteMode{SET_VALUES=0,ADD_VALUES};
89 
90 
91 
92  }
93 
94 }
95 
96 
97 
98 
99 namespace ot
100 {
101  class Mesh;
102  class TreeNode;
103 
105  enum DAType {OCT,PETSC};
106 
111  enum MVECType {MESH_BASED,MESH_FREE};
112 
113 
117  struct LoopCounter
118  {
120  unsigned int currentIndex;
121  unsigned int indexBegin;
122  unsigned int indexEnd;
123  };
124 
125  class DA
126  {
127 
128  private:
130  LoopCounter m_uiLoopInfo;
131 
133  double m_uiOctreeLowerBound[m_uiDim];
134 
136  double m_uiOctreeUpperBound[m_uiDim];
137 
144  std::vector<unsigned int> m_uiOctantFlags;
145 
147  ot::Mesh* m_uiMesh;
148 
149 
151  unsigned int m_uiTotalNodalSz;
153  unsigned int m_uiLocalNodalSz;
154 
156  unsigned int m_uiTotalElementSz;
157 
159  unsigned int m_uiLocalElementSz;
160 
162  std::vector<ot::AsyncExchangeContex> m_uiMPIContexts;
163 
165  unsigned int m_uiCommTag;
166 
168  std::vector<DendroIntL> m_uiLocalToGlobalNodalMap;
169 
171  DendroIntL m_uiGlobalNodeSz;
172 
173 
174 
175 
176  public:
178  std::vector<ot::TreeNode> getLocalOctants();
179 
181  const std::vector<ot::TreeNode>& getBlocks();
182 
190  DA(std::vector<ot::TreeNode> &balOct,MPI_Comm comm,unsigned int order, unsigned int grainSz=100,double sfc_tol=0.3, SM_TYPE smType=SM_TYPE::FEM_CG);
191 
196  DA(ot::Mesh* pMesh);
197 
198 
210  template<typename T>
211  DA(std::function<void(T,T,T,T*)>func,unsigned int dofSz,MPI_Comm comm,unsigned int order,double interp_tol, unsigned int grainSz=100,double sfc_tol=0.3, SM_TYPE smType=SM_TYPE::FEM_CG);
212 
226  DA(const Point* pts, unsigned int numPts,Point pt_min,Point pt_max, MPI_Comm comm,unsigned int order,unsigned int grainSz=100,double sfc_tol=0.3, SM_TYPE smType=SM_TYPE::FEM_CG);
227 
228 
229 
233  ~DA();
234 
236  inline unsigned int getLocalNodalSz() const {return m_uiLocalNodalSz;}
237 
239  inline unsigned int getPreNodalSz() const {return m_uiMesh->getNumPreMeshNodes();}
240 
242  inline unsigned int getPostNodalSz() const {return m_uiMesh->getNumPostMeshNodes();}
243 
245  inline unsigned int getTotalNodalSz() const {return m_uiTotalNodalSz;}
246 
248  inline unsigned int getLocalElemSz() const {return m_uiLocalElementSz;}
249 
251  inline unsigned int getTotalElemSz() const {return m_uiTotalElementSz;}
252 
254  inline bool isActive() const {return m_uiMesh->isActive();}
255 
257  inline unsigned int getNumNodesPerElement() const {return m_uiMesh->getNumNodesPerElement();}
258 
260  inline unsigned int getElementOrder() const {return m_uiMesh->getElementOrder();}
261 
263  inline MPI_Comm getGlobalComm() const { return m_uiMesh->getMPIGlobalCommunicator();}
264 
266  inline const std::vector<DendroIntL> getNodeLocalToGlobalMap() const {return m_uiLocalToGlobalNodalMap;}
267 
269  inline const ot::Mesh* getMesh() const {return m_uiMesh;}
270 
272  inline const std::vector<unsigned int> getOctFlags() const {return m_uiOctantFlags; }
273 
275  inline MPI_Comm getCommActive() const
276  {
277  if(m_uiMesh->isActive())
278  return m_uiMesh->getMPICommunicator();
279  else
280  return MPI_COMM_NULL;
281  }
282 
284  inline unsigned int getNpesAll() const { return m_uiMesh->getMPICommSizeGlobal();} ;
285 
287  inline unsigned int getNpesActive() const
288  {
289  if(m_uiMesh->isActive())
290  return m_uiMesh->getMPICommSize();
291  else
292  return 0;
293  }
294 
296  inline unsigned int getRankAll() const {return m_uiMesh->getMPIRankGlobal();};
297 
299  inline unsigned int getRankActive() const
300  {
301  if(m_uiMesh->isActive())
302  return m_uiMesh->getMPIRank();
303  else
304  return m_uiMesh->getMPIRankGlobal();
305  }
306 
311  bool isBoundaryOctant(unsigned int eleID) const;
312 
329  void getElementalCoords(unsigned int eleID, double* coords) const ;
330 
331 
333  inline const RefElement* getReferenceElement()const { return m_uiMesh->getReferenceElement();}
334 
335 
337  inline unsigned int getElementSize() const {return m_uiMesh->getNumLocalMeshElements();}
338 
340  inline unsigned int getPreGhostElementSize() const {return m_uiMesh->getNumPreGhostElements();}
341 
343  inline unsigned int getPostGhostElementSize() const {return m_uiMesh->getNumPostGhostElements(); }
344 
346  inline unsigned int getPreAndPostGhostNodeSize() const {return (m_uiMesh->getNumPreMeshNodes() + m_uiMesh->getNumPostMeshNodes());}
347 
349  inline unsigned int getNumLayer1GhostEleSz() const {return m_uiMesh->getLevel1GhostElementIndices().size();}
350 
352  unsigned int getGhostedElementSize() const {return (m_uiMesh->getNumPreGhostElements() + m_uiMesh->getNumPostGhostElements());}
353 
354 
356  inline unsigned int getMaxDepth() const {return m_uiMaxDepth;};
358  inline unsigned int getDimension() const {return m_uiDim;};
359 
361  inline ot::TreeNode getMinTreeNode() const {
362 
363  if(m_uiMesh->isActive())
364  {
365  const ot::TreeNode* allElements = &(*(m_uiMesh->getAllElements().begin()));
366  return allElements[m_uiMesh->getElementLocalBegin()];
367  }else
368  {
369  return ot::TreeNode(0,0,0,0,m_uiDim,m_uiMaxDepth);
370  }
371 
372  }
373 
375  inline ot::TreeNode getMaxTreeNode() const {
376 
377  if(m_uiMesh->isActive())
378  {
379  const ot::TreeNode* allElements = &(*(m_uiMesh->getAllElements().begin()));
380  return allElements[m_uiMesh->getElementLocalEnd()];
381  }else
382  {
383  return ot::TreeNode(0,0,0,0,m_uiDim,m_uiMaxDepth);
384  }
385 
386 
387  }
388 
395  void computeTreeNodeOwnerProc(const ot::TreeNode * pNodes, unsigned int n, int* ownerranks);
396 
397 
405  template<typename T>
406  int createVector(T*& local, bool isElemental=false, bool isGhosted=false, unsigned int dof=1) const;
407 
415  template<typename T>
416  int createVector(std::vector<T>& local, bool isElemental=false, bool isGhosted=false, unsigned int dof=1) const;
417 
422  template <typename T>
423  void destroyVector(T*& local) const;
424 
425  template <typename T>
426  void destroyVector(std::vector<T>& local) const;
427 
428 
429 
431  template<ot::DA_FLAGS::LoopType type>
432  void init();
433 
435  unsigned int curr();
436 
437 
439  template<ot::DA_FLAGS::LoopType type>
440  unsigned int end();
441 
443  template<ot::DA_FLAGS::LoopType type>
444  void next();
445 
449  template<typename T>
450  void readFromGhostBegin(T* vec, unsigned int dof=1);
451 
455  template<typename T>
456  void readFromGhostEnd(T* vec, unsigned int dof=1);
457 
458 
460  template<typename T>
461  void writeToGhostsBegin(T* vec, unsigned int dof=1) ;
462 
468  template<typename T>
469  void writeToGhostsEnd(T* vec, DA_FLAGS::WriteMode mode,unsigned int dof=1) ;
470 
471 
479  template<typename T>
480  void nodalVecToGhostedNodal(const T* in,T*& out,bool isAllocated=false, unsigned int dof=1)const;
481 
482 
491  template<typename T>
492  void ghostedNodalToNodalVec(const T* gVec,T*& local,bool isAllocated=false, unsigned int dof=1) const;
493 
494 
495 
503  template <typename T>
504  void getElementNodalValues(const T*in, T* eleVecOut,unsigned int eleID,unsigned int dof=1)const;
505 
513  template <typename T>
514  void eleVecToVecAccumilation(T*out, const T* eleVecIn,unsigned int eleID,unsigned int dof=1)const;
515 
521  void getOctreeBoundaryNodeIndices(std::vector<unsigned int >& bdyIndex,std::vector<double>& coords,bool isGhosted=false);
522 
528  int getNodeIndices(DendroIntL* nodeIdx,unsigned int ele,bool isGhosted) const;
529 
535  int getGlobalNodeIndices(DendroIntL* nodeIdx,unsigned int ele) const ;
536 
546  template <typename T>
547  void setVectorByFunction(T* local,std::function<void(T,T,T,T*)>func,bool isElemental=false, bool isGhosted=false, unsigned int dof=1) const;
548 
549 
560  template <typename T>
561  void setVectorByScalar(T* local,const T* value,bool isElemental=false, bool isGhosted=false, unsigned int dof=1) const;
562 
563 
571  template <typename T>
572  void vecTopvtu(T* local, const char * fPrefix,char** nodalVarNames=NULL,bool isElemental=false,bool isGhosted=false,unsigned int dof=1);
573 
574 
578  inline unsigned int getLevel(unsigned int ele) const { return m_uiMesh->getAllElements()[ele].getLevel();}
579 
584  inline ot::TreeNode getOctant(unsigned int ele) const {return m_uiMesh->getAllElements()[ele];}
585 
594  template<typename T>
595  T* getVecPointerToDof(T* in ,unsigned int dofInex, bool isElemental=false,bool isGhosted=false) const;
596 
597 
606  template<typename T>
607  void copyVectors(T* dest,const T* source,bool isElemental=false,bool isGhosted=false,unsigned int dof=1) const;
608 
616  template<typename T>
617  void copyVector(T* dest,const T* source,bool isElemental=false,bool isGhosted=false) const;
618 
619 
629  ot::DA* remesh(const DA_FLAGS::Refine * flags, unsigned int sz,unsigned int grainSz=100,double ld_bal=0.3, unsigned int sfK=2, unsigned int (*getWeight)(const ot::TreeNode *)=NULL) const;
630 
639  template<typename T>
640  void intergridTransfer(const T* varIn, T* & varOut, const ot::DA* newDA, bool isElemental=false, bool isGhosted=false, unsigned int dof=1);
641 
642 
643 
655  template<typename T>
656  int getFaceNeighborValues(unsigned int eleID, const T* in, T* out, T* coords, unsigned int * neighID, unsigned int face, NeighbourLevel & level,unsigned int dof) const;
657 
663  inline unsigned int getMortonChildNum(unsigned int eleID) const
664  {
665  return m_uiMesh->getMortonchildNum(eleID);
666  }
667 
668  // all the petsc functionalities goes below with the pre-processor gards.
669 #ifdef BUILD_WITH_PETSC
670 
679  PetscErrorCode petscCreateVector(Vec &local, bool isElemental, bool isGhosted, unsigned int dof) const;
680 
681 
688  PetscErrorCode createMatrix(Mat &M, MatType mtype, unsigned int dof=1) const;
689 
690 
691 
699  PetscErrorCode petscNodalVecToGhostedNodal(const Vec& in,Vec& out,bool isAllocated=false,unsigned int dof=1) const;
700 
701 
710  PetscErrorCode petscGhostedNodalToNodalVec(const Vec& gVec,Vec& local,bool isAllocated=false,unsigned int dof=1) const;
711 
719  void petscReadFromGhostBegin(PetscScalar * vecArry, unsigned int dof=1) ;
720 
727  void petscReadFromGhostEnd(PetscScalar * vecArry, unsigned int dof=1) ;
728 
729 
739  template<typename T>
740  void petscSetVectorByFunction(Vec& local,std::function<void(T,T,T,T*)>func,bool isElemental=false, bool isGhosted=false, unsigned int dof=1) const;
741 
742 
753  template <typename T>
754  void petscSetVectorByScalar(Vec& local,const T* value,bool isElemental=false, bool isGhosted=false, unsigned int dof=1) const;
755 
756 
764  void petscVecTopvtu(const Vec& local, const char * fPrefix,char** nodalVarNames=NULL,bool isElemental=false,bool isGhosted=false,unsigned int dof=1) ;
765 
766 
779  PetscErrorCode petscSetValuesInMatrix(Mat mat, std::vector<ot::MatRecord>& records,unsigned int dof, InsertMode mode) const;
780 
781 
782 
790  PetscErrorCode petscChangeVecToMatBased(Vec& v1,bool isElemental,bool isGhosted,unsigned int dof=1) const;
791 
792 
798  PetscErrorCode petscChangeVecToMatFree(Vec& v1,bool isElemental,bool isGhosted,unsigned int dof=1) const;
799 
808  template<typename T>
809  void petscIntergridTransfer(const Vec &varIn, Vec &varOut, const ot::DA *newDA, bool isElemental = false,bool isGhosted = false, unsigned int dof = 1);
810 
815  PetscErrorCode petscDestroyVec(Vec & vec);
816 
817 
818 #endif
819 
820 
821 
822  };
823 
824 
825 }
826 
827 
828 #include "oda.tcc"
829 
830 
831 #endif
832 
unsigned int getNumNodesPerElement() const
get number of nodes per element
Definition: oda.h:257
MPI_Comm getMPIGlobalCommunicator() const
returns the global communicator
Definition: mesh.h:1099
Simple class to manage async data transfer in the ODA class.
Definition: asyncExchangeContex.h:16
unsigned int getTotalElemSz() const
returns the local elemental size (includes the ghost elements as well)
Definition: oda.h:251
LoopType
loop flags, ALL : Loop over all the elements (note here we loop only on the local + level 1 ghost ele...
Definition: oda.h:65
unsigned int getNumPostMeshNodes() const
return the number of post ghost mesh nodes
Definition: mesh.h:1024
const std::vector< unsigned int > & getLevel1GhostElementIndices() const
returns the Level 1 ghost element indices.
Definition: mesh.h:1061
MPI_Comm getCommActive() const
: returns the active MPI sub com of the global communicator
Definition: oda.h:275
unsigned int getPreAndPostGhostNodeSize() const
: get the number of pre and post ghost elements
Definition: oda.h:346
unsigned int getGhostedElementSize() const
: get the number of pre and post ghost elements
Definition: oda.h:352
unsigned int getLocalElemSz() const
returns the local elemental size
Definition: oda.h:248
unsigned int getLevel(unsigned int ele) const
return the level of current octant
Definition: oda.h:578
A class to manage octants.
Definition: TreeNode.h:35
unsigned int getNumLayer1GhostEleSz() const
number of layer 1 ghost elements.
Definition: oda.h:349
Refine
contains the refine flags. DA_NO_CHANGE : no change needed for the octant DA_REFINE : refine the octa...
Definition: oda.h:86
unsigned int getMortonchildNum(unsigned int eleID) const
returns the morton child number
Definition: mesh.h:1167
unsigned int getPostGhostElementSize() const
: get the number of post-ghost element size
Definition: oda.h:343
Definition: mesh.h:179
ot::TreeNode getMinTreeNode() const
get min local node (nodal)
Definition: oda.h:361
const std::vector< DendroIntL > getNodeLocalToGlobalMap() const
: returns node local to node global map
Definition: oda.h:266
A point class.
Definition: point.h:36
unsigned int getRankActive() const
: rank w.r.t active comm.
Definition: oda.h:299
unsigned int getMPICommSizeGlobal() const
returns the comm size w.r.t. global comm
Definition: mesh.h:1105
unsigned int getElementLocalBegin() const
return the begin location of element local
Definition: mesh.h:1030
A set of parallel utilities.
unsigned int getNumPreGhostElements() const
Definition: mesh.h:1014
BdyType
Definition: oda.h:77
unsigned int getNumPreMeshNodes() const
return the number of pre ghost mesh nodes
Definition: mesh.h:1022
const std::vector< ot::TreeNode > & getAllElements() const
returns the pointer to All elements array.
Definition: mesh.h:1058
unsigned int getNumPostGhostElements() const
Returns the number of post-ghost elements.
Definition: mesh.h:1016
unsigned int getNumNodesPerElement() const
return the number of nodes per element.
Definition: mesh.h:1090
const RefElement * getReferenceElement() const
returns const pointer to reference element
Definition: mesh.h:1114
unsigned int getMPIRank() const
returns the rank
Definition: mesh.h:1108
: Simple structure to keep the loop counters
Definition: oda.h:117
unsigned int getMaxDepth() const
: get the max depth of the octree
Definition: oda.h:356
unsigned int getElementOrder() const
get element order
Definition: oda.h:260
Definition: oda.h:125
DAType
: DA type OCT: uses Dendro DA and PETSC uses petsc based DA
Definition: oda.h:105
unsigned int currentIndex
: current Index
Definition: oda.h:120
unsigned int getPostNodalSz() const
returns the post nodal size
Definition: oda.h:242
MVECType
: denotes the type of the matvec being computed, MESH_BASED - denotes the MatVec computation using me...
Definition: oda.h:111
unsigned int getPreGhostElementSize() const
: get the number of pre-ghost element size
Definition: oda.h:340
SM_TYPE
type of the scatter map, based on numerical computation method
Definition: mesh.h:114
unsigned int getLocalNodalSz() const
returns the local nodal size
Definition: oda.h:236
const RefElement * getReferenceElement() const
get a constant pointer for the reference element
Definition: oda.h:333
bool isActive() const
returns true if mesh is active
Definition: mesh.h:1173
unsigned int getDimension() const
: get the dimensionality of the octree
Definition: oda.h:358
unsigned int getMPIRankGlobal() const
returns the rank w.r.t. global comm
Definition: mesh.h:1102
A Set of utilities to test octrees.
unsigned int getRankAll() const
: rank with respect to the global comm.
Definition: oda.h:296
bool isActive() const
see if the current DA is active
Definition: oda.h:254
unsigned int getNumLocalMeshElements() const
Definition: mesh.h:1012
unsigned int getNpesActive() const
: number of processors active
Definition: oda.h:287
unsigned int getMortonChildNum(unsigned int eleID) const
computes the child number of the given octant
Definition: oda.h:663
unsigned int getElementOrder() const
returns the order of an element
Definition: mesh.h:1093
MPI_Comm getMPICommunicator() const
returns the communicator (acitve)
Definition: mesh.h:1096
unsigned int getPreNodalSz() const
returns the pre ghost nodal size
Definition: oda.h:239
ot::TreeNode getMaxTreeNode() const
get max localnode (nodal)
Definition: oda.h:375
unsigned int getElementLocalEnd() const
return the end location of element local
Definition: mesh.h:1032
unsigned int getNpesAll() const
: global mpi com. size
Definition: oda.h:284
const std::vector< unsigned int > getOctFlags() const
: Returns octDA flags
Definition: oda.h:272
ot::TreeNode getOctant(unsigned int ele) const
return the TreeNode of the current octnat.
Definition: oda.h:584
MPI_Comm getGlobalComm() const
: returns the global MPI communicator
Definition: oda.h:263
unsigned int getElementSize() const
: get the number of local elements.
Definition: oda.h:337
const ot::Mesh * getMesh() const
returns the mesh
Definition: oda.h:269
Definition: refel.h:69
unsigned int getTotalNodalSz() const
returns the total nodal size (this includes the ghosted region as well.)
Definition: oda.h:245
unsigned int getMPICommSize() const
returns the comm size:
Definition: mesh.h:1111