OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
main_petsc.cpp
1 
32 
34 #include "Grid/grid_dist_id.hpp"
35 #include "Matrix/SparseMatrix.hpp"
36 #include "Vector/Vector.hpp"
37 #include "FiniteDifference/FDScheme.hpp"
38 #include "FiniteDifference/util/common.hpp"
39 #include "FiniteDifference/eq.hpp"
40 #include "Solvers/umfpack_solver.hpp"
41 #include "Solvers/petsc_solver.hpp"
42 
43 struct lid_nn
44 {
45  // dimensionaly of the equation ( 3D problem ...)
46  static const unsigned int dims = 3;
47 
48  // number of fields in the system v_x, v_y, v_z, P so a total of 4
49  static const unsigned int nvar = 4;
50 
51  // boundary conditions PERIODIC OR NON_PERIODIC
52  static const bool boundary[];
53 
54  // type of space float, double, ...
55  typedef float stype;
56 
57  // type of base grid, it is the distributed grid that will store the result
58  // Note the first property is a 3D vector (velocity), the second is a scalar (Pressure)
60 
61  // type of SparseMatrix, for the linear system, this parameter is bounded by the solver
62  // that you are using, in case of umfpack using <double,int> it is the only possible choice
63  // We select PETSC SparseMatrix implementation
64  typedef SparseMatrix<double,int,PETSC_BASE> SparseMatrix_type;
65 
66  // type of Vector for the linear system, this parameter is bounded by the solver
67  // that you are using, in case of umfpack using <double> it is the only possible choice
68  // We select PETSC implementation
69  typedef Vector<double,PETSC_BASE> Vector_type;
70 
71  // Define that the underline grid where we discretize the system of equation is staggered
72  static const int grid_type = STAGGERED_GRID;
73 };
74 
75 const bool lid_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
76 
78 
79 
112 
114 // Constant Field
115 struct eta
116 {
118  typedef void const_field;
119 
121  static float val() {return 1.0;}
122 };
123 
124 // Model the equations
125 
126 constexpr unsigned int v[] = {0,1,2};
127 constexpr unsigned int P = 3;
128 constexpr unsigned int ic = 3;
129 constexpr int x = 0;
130 constexpr int y = 1;
131 constexpr int z = 2;
132 
133 typedef Field<v[x],lid_nn> v_x;
134 typedef Field<v[y],lid_nn> v_y;
135 typedef Field<v[z],lid_nn> v_z;
136 typedef Field<P,lid_nn> Prs;
137 
138 // Eq1 V_x
139 
140 typedef mul<eta,Lap<v_x,lid_nn>,lid_nn> eta_lap_vx; // Step1
141 typedef D<x,Prs,lid_nn> p_x; // Step 2
142 typedef minus<p_x,lid_nn> m_p_x; // Step3
143 typedef sum<eta_lap_vx,m_p_x,lid_nn> vx_eq; // Step4
144 
145 // Eq2 V_y
146 
148 typedef D<y,Prs,lid_nn> p_y;
149 typedef minus<p_y,lid_nn> m_p_y;
151 
152 // Eq3 V_z
153 
155 typedef D<z,Prs,lid_nn> p_z;
156 typedef minus<p_z,lid_nn> m_p_z;
158 
159 // Eq4 Incompressibility
160 
161 typedef D<x,v_x,lid_nn,FORWARD> dx_vx; // Step5
162 typedef D<y,v_y,lid_nn,FORWARD> dy_vy; // Step6
163 typedef D<z,v_z,lid_nn,FORWARD> dz_vz; // Step 7
164 typedef sum<dx_vx,dy_vy,dz_vz,lid_nn> ic_eq; // Step8
165 
167 
201 
203 // Directional Avg
206 
209 
212 
215 
218 
221 
222 
223 #define EQ_1 0
224 #define EQ_2 1
225 #define EQ_3 2
226 #define EQ_4 3
227 
229 
230 #include "Vector/vector_dist.hpp"
231 #include "data_type/aggregate.hpp"
232 
233 int main(int argc, char* argv[])
234 {
254 
256  // Initialize
257  openfpm_init(&argc,&argv);
258  {
259  // velocity in the grid is the property 0, pressure is the property 1
260  constexpr int velocity = 0;
261  constexpr int pressure = 1;
262 
263  // Domain
264  Box<3,float> domain({0.0,0.0,0.0},{3.0,1.0,1.0});
265 
266  // Ghost (Not important in this case but required)
267  Ghost<3,float> g(0.01);
268 
269  // Grid points on x=36 and y=12 z=12
270  long int sz[] = {36,12,12};
271  size_t szu[3];
272  szu[0] = (size_t)sz[0];
273  szu[1] = (size_t)sz[1];
274  szu[2] = (size_t)sz[2];
275 
276 
277  // We need one more point on the left and down part of the domain
278  // This is given by the boundary conditions that we impose.
279  //
280  Padding<3> pd({1,1,1},{0,0,0});
281 
283 
295 
298 
300 
318 
320  // It is the maximum extension of the stencil (order 2 laplacian stencil has extension 1)
321  Ghost<3,long int> stencil_max(1);
322 
323  // Finite difference scheme
324  FDScheme<lid_nn> fd(pd, stencil_max, domain, g_dist);
325 
327 
351 
353  // start and end of the bulk
354 
355  fd.impose(ic_eq(),0.0, EQ_4, {0,0,0},{sz[0]-2,sz[1]-2,sz[2]-2},true);
356  fd.impose(Prs(), 0.0, EQ_4, {0,0,0},{0,0,0});
357  fd.impose(vx_eq(),0.0, EQ_1, {1,0},{sz[0]-2,sz[1]-2,sz[2]-2});
358  fd.impose(vy_eq(),0.0, EQ_2, {0,1},{sz[0]-2,sz[1]-2,sz[2]-2});
359  fd.impose(vz_eq(),0.0, EQ_3, {0,0,1},{sz[0]-2,sz[1]-2,sz[2]-2});
360 
361  // v_x
362  // R L (Right,Left)
363  fd.impose(v_x(),0.0, EQ_1, {0,0,0}, {0,sz[1]-2,sz[2]-2});
364  fd.impose(v_x(),0.0, EQ_1, {sz[0]-1,0,0},{sz[0]-1,sz[1]-2,sz[2]-2});
365 
366  // T B (Top,Bottom)
367  fd.impose(avg_y_vx_f(),0.0, EQ_1, {0,-1,0}, {sz[0]-1,-1,sz[2]-2});
368  fd.impose(avg_y_vx(),0.0, EQ_1, {0,sz[1]-1,0},{sz[0]-1,sz[1]-1,sz[2]-2});
369 
370  // A F (Forward,Backward)
371  fd.impose(avg_z_vx_f(),0.0, EQ_1, {0,-1,-1}, {sz[0]-1,sz[1]-1,-1});
372  fd.impose(avg_z_vx(),0.0, EQ_1, {0,-1,sz[2]-1},{sz[0]-1,sz[1]-1,sz[2]-1});
373 
374  // v_y
375  // R L
376  fd.impose(avg_x_vy_f(),0.0, EQ_2, {-1,0,0}, {-1,sz[1]-1,sz[2]-2});
377  fd.impose(avg_x_vy(),1.0, EQ_2, {sz[0]-1,0,0},{sz[0]-1,sz[1]-1,sz[2]-2});
378 
379  // T B
380  fd.impose(v_y(), 0.0, EQ_2, {0,0,0}, {sz[0]-2,0,sz[2]-2});
381  fd.impose(v_y(), 0.0, EQ_2, {0,sz[1]-1,0},{sz[0]-2,sz[1]-1,sz[2]-2});
382 
383  // F A
384  fd.impose(avg_z_vy(),0.0, EQ_2, {-1,0,sz[2]-1}, {sz[0]-1,sz[1]-1,sz[2]-1});
385  fd.impose(avg_z_vy_f(),0.0, EQ_2, {-1,0,-1}, {sz[0]-1,sz[1]-1,-1});
386 
387  // v_z
388  // R L
389  fd.impose(avg_x_vz_f(),0.0, EQ_3, {-1,0,0}, {-1,sz[1]-2,sz[2]-1});
390  fd.impose(avg_x_vz(),1.0, EQ_3, {sz[0]-1,0,0},{sz[0]-1,sz[1]-2,sz[2]-1});
391 
392  // T B
393  fd.impose(avg_y_vz(),0.0, EQ_3, {-1,sz[1]-1,0},{sz[0]-1,sz[1]-1,sz[2]-1});
394  fd.impose(avg_y_vz_f(),0.0, EQ_3, {-1,-1,0}, {sz[0]-1,-1,sz[2]-1});
395 
396  // F A
397  fd.impose(v_z(),0.0, EQ_3, {0,0,0}, {sz[0]-2,sz[1]-2,0});
398  fd.impose(v_z(),0.0, EQ_3, {0,0,sz[2]-1},{sz[0]-2,sz[1]-2,sz[2]-1});
399 
400  // When we pad the grid, there are points of the grid that are not
401  // touched by the previous condition. Mathematically this lead
402  // to have too many variables for the conditions that we are imposing.
403  // Here we are imposing variables that we do not touch to zero
404  //
405 
406  // L R
407  fd.impose(Prs(), 0.0, EQ_4, {-1,-1,-1},{-1,sz[1]-1,sz[2]-1});
408  fd.impose(Prs(), 0.0, EQ_4, {sz[0]-1,-1,-1},{sz[0]-1,sz[1]-1,sz[2]-1});
409 
410  // T B
411  fd.impose(Prs(), 0.0, EQ_4, {0,sz[1]-1,-1}, {sz[0]-2,sz[1]-1,sz[2]-1});
412  fd.impose(Prs(), 0.0, EQ_4, {0,-1 ,-1}, {sz[0]-2,-1, sz[2]-1});
413 
414  // F A
415  fd.impose(Prs(), 0.0, EQ_4, {0,0,sz[2]-1}, {sz[0]-2,sz[1]-2,sz[2]-1});
416  fd.impose(Prs(), 0.0, EQ_4, {0,0,-1}, {sz[0]-2,sz[1]-2,-1});
417 
418  // Impose v_x v_y v_z padding
419  fd.impose(v_x(), 0.0, EQ_1, {-1,-1,-1},{-1,sz[1]-1,sz[2]-1});
420  fd.impose(v_y(), 0.0, EQ_2, {-1,-1,-1},{sz[0]-1,-1,sz[2]-1});
421  fd.impose(v_z(), 0.0, EQ_3, {-1,-1,-1},{sz[0]-1,sz[1]-1,-1});
422 
424 
443 
445  // Create an PETSC solver
446  petsc_solver<double> solver;
447 
448  // Warning try many solver and collect statistics require a lot of time
449  // To just solve you can comment this line
450 // solver.best_solve();
451 
452  // Give to the solver A and b, return x, the solution
453  auto x = solver.solve(fd.getA(),fd.getB());
454 
456 
468 
470  // copy the solution to grid
471  fd.template copy<velocity,pressure>(x,{0,0},{sz[0]-1,sz[1]-1,sz[2]-1},g_dist);
472 
473  g_dist.write("lid_driven_cavity_p_petsc");
474 
476 
477 
489  }
491  openfpm_finalize();
492 
494 
495 
504 }
Derivative second order on h (spacing)
Definition: Derivative.hpp:28
[Definition of the system]
It ancapsulate the minus operation.
Definition: sum.hpp:141
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support...
Definition: Vector.hpp:39
Definition: eq.hpp:81
Class that contain Padding information on each direction positive and Negative direction.
Definition: Ghost.hpp:117
Vector< double, PETSC_BASE > solve(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b, bool initial_guess=false)
Here we invert the matrix and solve the system.
Definition: Ghost.hpp:39
It model an expression expr1 * expr2.
Definition: mul.hpp:119
This class decompose a space into sub-sub-domains and distribute them across processors.
Sparse Matrix implementation.
This is a distributed grid.
This class is able to do Matrix inversion in parallel with PETSC solvers.
Average.
Definition: Average.hpp:31
[Definition of the system]
void const_field
indicate it is a constant field
Definition: main_petsc.cpp:118
It model an expression expr1 + ... exprn.
Definition: sum.hpp:92
Finite Differences.
Definition: FDScheme.hpp:124
Test structure used for several test.
Definition: Point_test.hpp:105
static float val()
Eta is constant one.
Definition: main_petsc.cpp:121