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.
rkTransport.h
1 //
2 // Created by milinda on 5/24/17.
12 //
13 
14 #ifndef SFCSORTBENCH_RKTRANSPORT_H
15 #define SFCSORTBENCH_RKTRANSPORT_H
16 
17 #include "rk.h"
18 #include "fdCoefficient.h"
19 #include "oct2vtk.h"
20 #include "checkPoint.h"
21 #include "rkTransportUtils.h"
22 #include <string>
23 #include <iostream>
24 
25 
26 
27 #define IO_OUTPUT_FREQ 10
28 #define REMESH_TEST_FREQ 10 // test for remeshing every 10 steps.
29 #define IO_OUTPUT_GAP 1 // output IO after each 1 second of traversal.
30 
31 
32 
33 
34 namespace ode
35 {
36  namespace solver
37  {
38 
39  class RK45Transport : public RK
40  {
41 
42  private :
44  std::vector<double> m_uiU;
45 
47  std::vector<double> m_uiPrevU;
48 
50  std::vector<double> m_uiVecIm;
51 
53  std::vector<double> m_uiStage_1;
54 
56  std::vector<double> m_uiStage_2;
57 
59  std::vector<double> m_uiStage_3;
60 
62  std::vector<double> m_uiStage_4;
63 
65  std::vector<double> m_uiStage_5;
66 
68  std::vector<double> m_uiStage_6;
69 
71  std::vector<double> m_uiRHS;
72 
73 
75  std::vector<double>m_uiDxU;
77  std::vector<double>m_uiDyU;
79  std::vector<double>m_uiDzU;
80 
81 
83  std::vector<double> m_uiUZipVecIn;
84 
86  std::vector<double> m_uiUZipVecOut;
87 
88 
89 
91  Stencil<double,5,2> m_uiDxOrder4_centered;
92  Stencil<double,5,4> m_uiDxOrder4_backward;
93  Stencil<double,5,0> m_uiDxOrder4_forward;
94 
96  Stencil<double,5,2> m_uiDyOrder4_centered;
97  Stencil<double,5,4> m_uiDyOrder4_backward;
98  Stencil<double,5,0> m_uiDyOrder4_forward;
99 
101  Stencil<double,5,2> m_uiDzOrder4_centered;
102  Stencil<double,5,4> m_uiDzOrder4_backward;
103  Stencil<double,5,0> m_uiDzOrder4_forward;
104 
105 
107  double m_uiCoef_b[3];
108 
110  std::function<double(double,double,double)> m_uiFunc_g;
111 
113  std::function<double(double,double,double,double)> m_uiFunc_f;
114 
116  std::function<double(double,double,double)> m_uiFunc_f1;
117 
119  char* m_uiFilePrefix;
120 
122  double m_uiWaveletTol;
123 
125  double m_uiLoadImbTol;
126 
128  unsigned int m_uiSplitterFix;
129 
131  double m_uiLastIOTimeValue;
132 
133 
134 
135  public :
141  RK45Transport(ot::Mesh * pMesh,double pTBegin,double pTEnd,double pTh);
142 
145  ~RK45Transport();
146 
151  void setParameters(double *b, std::function<double(double,double,double)>g , std::function<double (double,double,double,double)> f ,const char * fprefix,double wltTol );
152 
158  void setLDImbParameters(double ldTol=0.1,unsigned int sfK=2);
159 
161  void applyInitialConditions();
162 
164  void performSingleIteration();
165 
168 
170  template <typename T>
171  void applyBoundaryConditions(const double time,T* vec);
172 
174  void rkSolve();
175 
179  int storeCheckPoint(const char * fNamePrefix);
180 
186  int restoreRK45Solver(const char * fNamePrefix, const unsigned int step,const MPI_Comm comm);
187 
188 
189 
190  };
191 
192 
193 
194 
195  } // end of namespace solver
196 
197 }//end of namespace ode
198 
199 
200 
201 
202 namespace ode
203 {
204  namespace solver
205  {
206 
207  template <typename T>
208  void RK45Transport::applyBoundaryConditions(const double time,T*vec)
209  {
210  // enforce boundary conditions to g(x-bt)
211  unsigned int x,y,z,sz;
212  const ot::TreeNode* pNodes=&(*(m_uiMesh->getAllElements().begin()));
213 
214  const double grid_min=0;
215  const double grid_max=1u<<(m_uiMaxDepth);
216  const double d_min=-M_PI;
217  const double d_max=M_PI;
218  const unsigned int nPe=m_uiMesh->getNumNodesPerElement();
219  const unsigned int eleOrder=m_uiMesh->getElementOrder();
220  const unsigned int *e2n=&(*(m_uiMesh->getE2NMapping().begin()));
221  const unsigned int *e2n_dg=&(*(m_uiMesh->getE2NMapping_DG().begin()));
222  double x1,y1,z1;
223  double value=1.0;
224  unsigned int owner,ii_x,jj_y,kk_z;
225 
226  for(unsigned int ele=m_uiMesh->getElementLocalBegin();ele<m_uiMesh->getElementLocalEnd();ele++)
227  {
228 
229  if((pNodes[ele].minX()==grid_min) || (pNodes[ele].minY()==grid_min) || ((pNodes[ele].minZ()==grid_min) ))
230  { // current element is a boundary element.
231 
232  for(unsigned int k=0;k<(eleOrder+1);k++)
233  for(unsigned int j=0;j<(eleOrder+1);j++)
234  for(unsigned int i=0;i<(eleOrder+1);i++)
235  {
236  if((m_uiMesh->isNodeLocal(ele,i,j,k)))
237  {
238  m_uiMesh->dg2eijk(e2n_dg[ele*nPe+k*(eleOrder+1)*(eleOrder+1)+j*(eleOrder+1)+i],owner,ii_x,jj_y,kk_z);
239  sz=1u<<(m_uiMaxDepth-pNodes[owner].getLevel());
240  x=pNodes[owner].getX()+ ii_x*(sz/eleOrder);
241  y=pNodes[owner].getY()+ jj_y*(sz/eleOrder);
242  z=pNodes[owner].getZ()+ kk_z*(sz/eleOrder);
243  if(((x==grid_min)|| (y==grid_min) || (z==grid_min) ))
244  {
245  assert(!m_uiMesh->isNodeHanging(owner,ii_x,jj_y,kk_z));
246  x1=((x-grid_min)/(grid_max-grid_min))*(d_max-d_min)+d_min;
247  y1=((y-grid_min)/(grid_max-grid_min))*(d_max-d_min)+d_min;
248  z1=((z-grid_min)/(grid_max-grid_min))*(d_max-d_min)+d_min;
249 
250  /*((x1-m_uiCoef_b[0]*m_uiCurrentTime)<d_min)? value=value*(-1)*sin(2*d_min-(x1-m_uiCoef_b[0]*m_uiCurrentTime)) :value=value*sin((x1-m_uiCoef_b[0]*m_uiCurrentTime));
251  ((y1-m_uiCoef_b[1]*m_uiCurrentTime)<d_min)? value=value*(-1)*sin(2*d_min-(y1-m_uiCoef_b[1]*m_uiCurrentTime)) :value=value*sin((y1-m_uiCoef_b[1]*m_uiCurrentTime));
252  ((z1-m_uiCoef_b[2]*m_uiCurrentTime)<d_min)? value=value*(-1)*sin(2*d_min-(z1-m_uiCoef_b[2]*m_uiCurrentTime)) :value=value*sin((z1-m_uiCoef_b[2]*m_uiCurrentTime));*/
253 
254  value=sin(x1-m_uiCoef_b[0]*time)*sin(y1-m_uiCoef_b[1]*time)*sin(z1-m_uiCoef_b[2]*time);
255  //if(!m_uiMesh->getMPIRank() && (fabs(value- m_uiU[e2n[ele*nPe+k*(eleOrder+1)*(eleOrder+1)+j*(eleOrder+1)+i]])>1e-2)) std::cout<<" rank: "<<m_uiMesh->getMPIRank()<<"bdy value: "<<value<<" computed value: "<< m_uiU[e2n[ele*nPe+k*(eleOrder+1)*(eleOrder+1)+j*(eleOrder+1)+i]]<<" i,j,k: ("<<i<<" , "<<j<<" ,"<<k<<" ) "<<std::endl;
256 
257  vec[e2n[ele*nPe+k*(eleOrder+1)*(eleOrder+1)+j*(eleOrder+1)+i]]=value;//m_uiFunc_g((x-m_uiCoef_b[0]*m_uiCurrentTime),(y-m_uiCoef_b[1]*m_uiCurrentTime),(z-m_uiCoef_b[2]*m_uiCurrentTime));
258  }
259  }
260 
261  }
262 
263  }
264  }
265 
266  }
267 
268 
269  } // end of namespace solver
270 
271 } // end of namespace ode
272 
273 
274 
275 #endif //SFCSORTBENCH_RKTRANSPORT_H
Definition: rk.h:21
RK45Transport(ot::Mesh *pMesh, double pTBegin, double pTEnd, double pTh)
Default constructor.
Definition: rkTransport.cpp:17
int restoreRK45Solver(const char *fNamePrefix, const unsigned int step, const MPI_Comm comm)
: restore rk45 solver from a given checkpoint. This will overwrite the parameters given in the origin...
Definition: rkTransport.cpp:509
void applyBoundaryConditions()
: Implementation of the base class function to apply boundary conditions.
Definition: rkTransport.cpp:318
void applyInitialConditions()
Definition: rkTransport.cpp:98
A class to manage octants.
Definition: TreeNode.h:35
Definition: mesh.h:179
const std::vector< unsigned int > & getE2NMapping_DG() const
Definition: mesh.h:1082
void rkSolve()
: starts the rk-45 solver.
Definition: rkTransport.cpp:322
bool isNodeLocal(unsigned int eleID, unsigned int ix, unsigned int jy, unsigned int kz) const
: Returns true if the specified node (e,i,j,k) is local.
Definition: mesh.h:1358
~RK45Transport()
Definition: rkTransport.cpp:42
unsigned int getElementLocalBegin() const
return the begin location of element local
Definition: mesh.h:1030
int storeCheckPoint(const char *fNamePrefix)
: stores the all the variables that is required to restore the rk45 solver at a given stage...
Definition: rkTransport.cpp:456
ot::Mesh * m_uiMesh
Definition: rk.h:26
const std::vector< ot::TreeNode > & getAllElements() const
returns the pointer to All elements array.
Definition: mesh.h:1058
unsigned int getNumNodesPerElement() const
return the number of nodes per element.
Definition: mesh.h:1090
unsigned int getLevel() const
return the level of the of the octant
Definition: TreeNode.h:387
This file contains the base class for the Rungge-Kutta 45 Method.
Definition: rk4nlsm.h:33
bool isNodeHanging(unsigned int eleID, unsigned int ix, unsigned int jy, unsigned int kz) const
: Returns true if the specified node (e,i,j,k) is hanging.
Definition: mesh.cpp:8943
void setLDImbParameters(double ldTol=0.1, unsigned int sfK=2)
Used to set the load balancing parameters for the solver.
Definition: rkTransport.cpp:92
void setParameters(double *b, std::function< double(double, double, double)>g, std::function< double(double, double, double, double)> f, const char *fprefix, double wltTol)
: set parameters for transport equation
Definition: rkTransport.cpp:47
void performSingleIteration()
: Implementation of the base class time step function
Definition: rkTransport.cpp:105
const std::vector< unsigned int > & getE2NMapping() const
Definition: mesh.h:1073
unsigned int getX() const
get integer values of the octree coordinates.
Definition: TreeNode.h:366
void dg2eijk(unsigned int dg_index, unsigned int &e, unsigned int &i, unsigned int &j, unsigned int &k) const
: Decompose the DG index to element id and it&#39;s i,j,k values.
Definition: mesh.h:1147
unsigned int getElementOrder() const
returns the order of an element
Definition: mesh.h:1093
Definition: rkTransport.h:39
unsigned int getElementLocalEnd() const
return the end location of element local
Definition: mesh.h:1032