OpenFPM  5.2.0
Project that contain the implementation of distributed structures
main_eigen.cpp
1 
43 
44 #include "Grid/grid_dist_id.hpp"
45 #include "Matrix/SparseMatrix.hpp"
46 #include "Vector/Vector.hpp"
47 #include "FiniteDifference/FDScheme.hpp"
48 #include "FiniteDifference/util/common.hpp"
49 #include "FiniteDifference/eq.hpp"
50 #include "Solvers/umfpack_solver.hpp"
51 #include "Solvers/petsc_solver.hpp"
52 
53 struct lid_nn
54 {
55  // dimensionaly of the equation (2D problem 3D problem ...)
56  static const unsigned int dims = 2;
57 
58  // number of fields in the system v_x, v_y, P so a total of 3
59  static const unsigned int nvar = 3;
60 
61  // boundary conditions PERIODIC OR NON_PERIODIC
62  static const bool boundary[];
63 
64  // type of space float, double, ...
65  typedef float stype;
66 
67  // type of base grid, it is the distributed grid that will store the result
68  // Note the first property is a 2D vector (velocity), the second is a scalar (Pressure)
70 
71  // type of SparseMatrix, for the linear system, this parameter is bounded by the solver
72  // that you are using, in case of umfpack using <double,int> it is the only possible choice
73  // By default SparseMatrix is EIGEN based
74  typedef SparseMatrix<double,int> SparseMatrix_type;
75 
76  // type of Vector for the linear system, this parameter is bounded by the solver
77  // that you are using, in case of umfpack using <double> it is the only possible choice
78  typedef Vector<double> Vector_type;
79 
80  // Define that the underline grid where we discretize the system of equation is staggered
81  static const int grid_type = STAGGERED_GRID;
82 };
83 
84 const bool lid_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC};
85 
87 
88 
120 
121 // Constant Field
122 struct eta
123 {
124  typedef void const_field;
125 
126  static float val() {return 1.0;}
127 };
128 
129 // Convenient constants
130 constexpr unsigned int v[] = {0,1};
131 constexpr unsigned int P = 2;
132 constexpr unsigned int ic = 2;
133 constexpr int x = 0;
134 constexpr int y = 1;
135 
136 // Create field that we have v_x, v_y, P
137 typedef Field<v[x],lid_nn> v_x; // Definition 1 v_x
138 typedef Field<v[y],lid_nn> v_y; // Definition 2 v_y
139 typedef Field<P,lid_nn> Prs; // Definition 3 Prs
140 
141 // Eq1 V_x
142 
143 typedef mul<eta,Lap<v_x,lid_nn>,lid_nn> eta_lap_vx; // Step 1
144 typedef D<x,Prs,lid_nn> p_x; // Step 2
145 typedef minus<p_x,lid_nn> m_p_x; // Step 3
146 typedef sum<eta_lap_vx,m_p_x,lid_nn> vx_eq; // Step 4
147 
148 // Eq2 V_y
149 
151 typedef D<y,Prs,lid_nn> p_y;
152 typedef minus<p_y,lid_nn> m_p_y;
154 
155 // Eq3 Incompressibility
156 
157 typedef D<x,v_x,lid_nn,FORWARD> dx_vx; // Step 5
158 typedef D<y,v_y,lid_nn,FORWARD> dy_vy; // Step 6
159 typedef sum<dx_vx,dy_vy,lid_nn> ic_eq; // Step 7
160 
162 
196 
197 // Equation for boundary conditions
198 
199 // Directional Avg
200 typedef Avg<x,v_y,lid_nn> avg_vy;
201 typedef Avg<y,v_x,lid_nn> avg_vx;
202 
205 
206 // Usefull constants (as MACRO)
207 #define EQ_1 0
208 #define EQ_2 1
209 #define EQ_3 2
210 
212 
213 #include "Vector/vector_dist.hpp"
214 #include "data_type/aggregate.hpp"
215 
216 int main(int argc, char* argv[])
217 {
238 
239  // Initialize
240  openfpm_init(&argc,&argv);
241 
242  // velocity in the grid is the property 0, pressure is the property 1
243  constexpr int velocity = 0;
244  constexpr int pressure = 1;
245 
246  // Domain, a rectangle
247  Box<2,float> domain({0.0,0.0},{3.0,1.0});
248 
249  // Ghost (Not important in this case but required)
250  Ghost<2,float> g(0.01);
251 
252  // Grid points on x=256 and y=64
253  long int sz[] = {96,32};
254  size_t szu[2];
255  szu[0] = (size_t)sz[0];
256  szu[1] = (size_t)sz[1];
257 
258  // We need one more point on the left and down part of the domain
259  // This is given by the boundary conditions that we impose.
260  //
261  Padding<2> pd({1,1},{0,0});
262 
264 
277 
279 
281 
300 
301  // It is the maximum extension of the stencil (order 2 laplacian stencil has extension 1)
302  Ghost<2,long int> stencil_max(1);
303 
304  // Finite difference scheme
305  FDScheme<lid_nn> fd(pd, stencil_max, domain, g_dist);
306 
308 
333 
334  fd.impose(ic_eq(),0.0, EQ_3, {0,0},{sz[0]-2,sz[1]-2},true);
335  fd.impose(Prs(), 0.0, EQ_3, {0,0},{0,0});
336 
337  // Here we impose the Eq1 and Eq2
338  fd.impose(vx_eq(),0.0, EQ_1, {1,0},{sz[0]-2,sz[1]-2});
339  fd.impose(vy_eq(),0.0, EQ_2, {0,1},{sz[0]-2,sz[1]-2});
340 
341  // v_x and v_y
342  // Imposing B1
343  fd.impose(v_x(),0.0, EQ_1, {0,0},{0,sz[1]-2});
344  fd.impose(avg_vy_f(),0.0, EQ_2 , {-1,0},{-1,sz[1]-1});
345  // Imposing B2
346  fd.impose(v_x(),0.0, EQ_1, {sz[0]-1,0},{sz[0]-1,sz[1]-2});
347  fd.impose(avg_vy(),1.0, EQ_2, {sz[0]-1,0},{sz[0]-1,sz[1]-1});
348 
349  // Imposing B3
350  fd.impose(avg_vx_f(),0.0, EQ_1, {0,-1},{sz[0]-1,-1});
351  fd.impose(v_y(), 0.0, EQ_2, {0,0},{sz[0]-2,0});
352  // Imposing B4
353  fd.impose(avg_vx(),0.0, EQ_1, {0,sz[1]-1},{sz[0]-1,sz[1]-1});
354  fd.impose(v_y(), 0.0, EQ_2, {0,sz[1]-1},{sz[0]-2,sz[1]-1});
355 
356  // When we pad the grid, there are points of the grid that are not
357  // touched by the previous condition. Mathematically this lead
358  // to have too many variables for the conditions that we are imposing.
359  // Here we are imposing variables that we do not touch to zero
360  //
361 
362  // Padding pressure
363  fd.impose(Prs(), 0.0, EQ_3, {-1,-1},{sz[0]-1,-1});
364  fd.impose(Prs(), 0.0, EQ_3, {-1,sz[1]-1},{sz[0]-1,sz[1]-1});
365  fd.impose(Prs(), 0.0, EQ_3, {-1,0},{-1,sz[1]-2});
366  fd.impose(Prs(), 0.0, EQ_3, {sz[0]-1,0},{sz[0]-1,sz[1]-2});
367 
368  // Impose v_x Padding Impose v_y padding
369  fd.impose(v_x(), 0.0, EQ_1, {-1,-1},{-1,sz[1]-1});
370  fd.impose(v_y(), 0.0, EQ_2, {-1,-1},{sz[0]-1,-1});
371 
373 
388 
389  // Create an UMFPACK solver
390  umfpack_solver<double> solver;
391 
392  // Give to the solver A and b, return x, the solution
393  auto x = solver.solve(fd.getA(),fd.getB());
394 
396 
409 
410  fd.template copy<velocity,pressure>(x,{0,0},{sz[0]-1,sz[1]-1},g_dist);
411 
412  g_dist.write("lid_driven_cavity_p_umfpack");
413 
415 
416 
429 
430  openfpm_finalize();
431 
433 
434 
443 }
Average.
Definition: Average.hpp:27
This class represent an N-dimensional box.
Definition: Box.hpp:60
This class decompose a space into sub-sub-domains and distribute them across processors.
Derivative second order on h (spacing)
Definition: Derivative.hpp:29
Finite Differences.
Definition: FDScheme.hpp:127
Definition: eq.hpp:83
Definition: Ghost.hpp:40
Class that contain Padding information on each direction positive and Negative direction.
Definition: Ghost.hpp:127
Test structure used for several test.
Definition: Point_test.hpp:106
Sparse Matrix implementation.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Definition: Vector.hpp:40
This is a distributed grid.
stub when library compiled without eigen
static Vector< double > solve(SparseMatrix< double, id_type, impl > &A, const Vector< double > &b, size_t opt=UMFPACK_NONE)
stub solve
[Definition of the system]
[Definition of the system]
It ancapsulate the minus operation.
Definition: sum.hpp:142
It model an expression expr1 * expr2.
Definition: mul.hpp:120
It model an expression expr1 + ... exprn.
Definition: sum.hpp:93