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 
31 
33 #include "Grid/grid_dist_id.hpp"
34 #include "Matrix/SparseMatrix.hpp"
35 #include "Vector/Vector.hpp"
36 #include "FiniteDifference/FDScheme.hpp"
37 #include "FiniteDifference/util/common.hpp"
38 #include "FiniteDifference/eq.hpp"
39 #include "Solvers/petsc_solver.hpp"
40 #include "Solvers/petsc_solver.hpp"
41 
42 struct lid_nn
43 {
44  // dimensionaly of the equation (2D problem 3D problem ...)
45  static const unsigned int dims = 2;
46 
47  // number of fields in the system v_x, v_y, P so a total of 3
48  static const unsigned int nvar = 3;
49 
50  // boundary conditions PERIODIC OR NON_PERIODIC
51  static const bool boundary[];
52 
53  // type of space float, double, ...
54  typedef float stype;
55 
56  // type of base grid, it is the distributed grid that will store the result
57  // Note the first property is a 2D vector (velocity), the second is a scalar (Pressure)
59 
60  // type of SparseMatrix, for the linear system, this parameter is bounded by the solver
61  // that you are using, in case of umfpack using <double,int> it is the only possible choice
62  // Here we choose PETSC implementation
63  typedef SparseMatrix<double,int,PETSC_BASE> SparseMatrix_type;
64 
65  // type of Vector for the linear system, this parameter is bounded by the solver
66  // that you are using
67  typedef Vector<double,PETSC_BASE> Vector_type;
68 
69  // Define that the underline grid where we discretize the system of equation is staggered
70  static const int grid_type = STAGGERED_GRID;
71 };
72 
73 const bool lid_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC};
74 
76 
77 
108 
110 // Constant Field
111 struct eta
112 {
113  typedef void const_field;
114 
115  static float val() {return 1.0;}
116 };
117 
118 // Convenient constants
119 constexpr unsigned int v[] = {0,1};
120 constexpr unsigned int P = 2;
121 constexpr unsigned int ic = 2;
122 constexpr int x = 0;
123 constexpr int y = 1;
124 
125 // Create field that we have v_x, v_y, P
126 typedef Field<v[x],lid_nn> v_x; // Definition 1 v_x
127 typedef Field<v[y],lid_nn> v_y; // Definition 2 v_y
128 typedef Field<P,lid_nn> Prs; // Definition 3 Prs
129 
130 // Eq1 V_x
131 
132 typedef mul<eta,Lap<v_x,lid_nn>,lid_nn> eta_lap_vx; // Step 1
133 typedef D<x,Prs,lid_nn> p_x; // Step 2
134 typedef minus<p_x,lid_nn> m_p_x; // Step 3
135 typedef sum<eta_lap_vx,m_p_x,lid_nn> vx_eq; // Step 4
136 
137 // Eq2 V_y
138 
140 typedef D<y,Prs,lid_nn> p_y;
141 typedef minus<p_y,lid_nn> m_p_y;
143 
144 // Eq3 Incompressibility
145 
146 typedef D<x,v_x,lid_nn,FORWARD> dx_vx; // Step 5
147 typedef D<y,v_y,lid_nn,FORWARD> dy_vy; // Step 6
148 typedef sum<dx_vx,dy_vy,lid_nn> ic_eq; // Step 7
149 
151 
184 
186 // Equation for boundary conditions
187 
188 // Directional Avg
189 typedef Avg<x,v_y,lid_nn> avg_vy;
190 typedef Avg<y,v_x,lid_nn> avg_vx;
191 
194 
195 // Usefull constants (as MACRO)
196 #define EQ_1 0
197 #define EQ_2 1
198 #define EQ_3 2
199 
201 
202 #include "Vector/vector_dist.hpp"
203 #include "data_type/aggregate.hpp"
204 
205 int main(int argc, char* argv[])
206 {
226 
228  // Initialize
229  openfpm_init(&argc,&argv);
230 
231  // velocity in the grid is the property 0, pressure is the property 1
232  constexpr int velocity = 0;
233  constexpr int pressure = 1;
234 
235  // Domain, a rectangle
236  Box<2,float> domain({0.0,0.0},{12.0,4.0});
237 
238  // Ghost (Not important in this case but required)
239  Ghost<2,float> g(0.01);
240 
241  // Grid points on x=96 and y=32
242  long int sz[] = {96,32};
243  size_t szu[2];
244  szu[0] = (size_t)sz[0];
245  szu[1] = (size_t)sz[1];
246 
247  // We need one more point on the left and down part of the domain
248  // This is given by the boundary conditions that we impose.
249  //
250  Padding<2> pd({1,1},{0,0});
251 
253 
265 
268 
270 
288 
290  // It is the maximum extension of the stencil (order 2 laplacian stencil has extension 1)
291  Ghost<2,long int> stencil_max(1);
292 
293  // Finite difference scheme
294  FDScheme<lid_nn> fd(pd, stencil_max, domain, g_dist);
295 
297 
321 
323  fd.impose(ic_eq(),0.0, EQ_3, {0,0},{sz[0]-2,sz[1]-2},true);
324  fd.impose(Prs(), 0.0, EQ_3, {0,0},{0,0});
325 
326  // Here we impose the Eq1 and Eq2
327  fd.impose(vx_eq(),0.0, EQ_1, {1,0},{sz[0]-2,sz[1]-2});
328  fd.impose(vy_eq(),0.0, EQ_2, {0,1},{sz[0]-2,sz[1]-2});
329 
330  // v_x and v_y
331  // Imposing B1
332  fd.impose(v_x(),0.0, EQ_1, {0,0},{0,sz[1]-2});
333  fd.impose(avg_vy_f(),0.0, EQ_2 , {-1,0},{-1,sz[1]-1});
334  // Imposing B2
335  fd.impose(v_x(),0.0, EQ_1, {sz[0]-1,0},{sz[0]-1,sz[1]-2});
336  fd.impose(avg_vy(),1.0, EQ_2, {sz[0]-1,0},{sz[0]-1,sz[1]-1});
337 
338  // Imposing B3
339  fd.impose(avg_vx_f(),0.0, EQ_1, {0,-1},{sz[0]-1,-1});
340  fd.impose(v_y(), 0.0, EQ_2, {0,0},{sz[0]-2,0});
341  // Imposing B4
342  fd.impose(avg_vx(),0.0, EQ_1, {0,sz[1]-1},{sz[0]-1,sz[1]-1});
343  fd.impose(v_y(), 0.0, EQ_2, {0,sz[1]-1},{sz[0]-2,sz[1]-1});
344 
345  // When we pad the grid, there are points of the grid that are not
346  // touched by the previous condition. Mathematically this lead
347  // to have too many variables for the conditions that we are imposing.
348  // Here we are imposing variables that we do not touch to zero
349  //
350 
351  // Padding pressure
352  fd.impose(Prs(), 0.0, EQ_3, {-1,-1},{sz[0]-1,-1});
353  fd.impose(Prs(), 0.0, EQ_3, {-1,sz[1]-1},{sz[0]-1,sz[1]-1});
354  fd.impose(Prs(), 0.0, EQ_3, {-1,0},{-1,sz[1]-2});
355  fd.impose(Prs(), 0.0, EQ_3, {sz[0]-1,0},{sz[0]-1,sz[1]-2});
356 
357  // Impose v_x Padding Impose v_y padding
358  fd.impose(v_x(), 0.0, EQ_1, {-1,-1},{-1,sz[1]-1});
359  fd.impose(v_y(), 0.0, EQ_2, {-1,-1},{sz[0]-1,-1});
360 
362 
381 
383  // Create a PETSC solver
384  petsc_solver<double> solver;
385 
386  // Set the maxumum nunber if iterations
387  solver.setMaxIter(1000);
388 
389  solver.setRestart(200);
390 
391  // Give to the solver A and b, return x, the solution
392  auto x = solver.try_solve(fd.getA(),fd.getB());
393 
395 
407 
409  fd.template copy<velocity,pressure>(x,{0,0},{sz[0]-1,sz[1]-1},g_dist);
410 
411  g_dist.write("lid_driven_cavity_p_petsc");
412 
414 
415 
427 
429  openfpm_finalize();
430 
432 
433 
442 }
443 
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
void setMaxIter(PetscInt n)
Set the maximum number of iteration for Krylov solvers.
Class that contain Padding information on each direction positive and Negative direction.
Definition: Ghost.hpp:117
Definition: Ghost.hpp:39
Vector< double, PETSC_BASE > try_solve(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b)
Try to solve the system using all the solvers and generate a report.
void setRestart(PetscInt n)
For GMRES based method, the number of Krylov directions to orthogonalize against. ...
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]
This class represent an N-dimensional box.
Definition: Box.hpp:56
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