OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
main.cpp
1#include "Grid/grid_dist_id.hpp"
2#include "data_type/aggregate.hpp"
3#include "timer.hpp"
4
10constexpr int U = 0;
11constexpr int V = 1;
12constexpr int phi = 2;
13constexpr int normal = 3;
14constexpr int tgrad_u = 4;
15constexpr int tgrad_v = 5;
16constexpr int U_next = 6;
17constexpr int V_next = 7;
18
19constexpr int x = 0;
20constexpr int y = 1;
21constexpr int z = 2;
22
24
25void init(sgrid_type & grid, Box<3,double> & domain)
26{
28
29 auto it = grid.getGridIterator();
30 Point<3,double> p1({0.5,0.5,0.5});
31
32 double sx = grid.spacing(0);
33
34 Sphere<3,double> sph1(p1,0.3);
35 Sphere<3,double> sph2(p1,0.3 - sx*10);
36 Sphere<3,double> sph_zero(p1,0.3 - sx*5);
37
38 while (it.isNext())
39 {
40 // Get the local grid key
41 auto key = it.get_dist();
42 auto keyg = it.get();
43
46
47 for (int i = 0 ; i < 3 ; i++)
48 {pc.get(i) = keyg.get(i) * it.getSpacing(i);}
49
50 // Check if the point is in the first sphere
51 if (sph1.isInside(pc) == true && sph2.isInside(pc) == false)
52 {
53 Point<3,double> pn = pc - p1;
54 pn /= pn.norm();
55 double theta = acos(pn * Point<3,double>({0.0,0.0,1.0}));
56 Point<3,double> pn_ = pn;
57 pn_[2] = 0.0;
58 pn_ /= pn_.norm();
59 double aphi = acos(pn_ * Point<3,double>({1.0,0.0,0.0}));
60
61 // Create a perturbation in the solid angle
62 if (theta > 0.6 && theta < 0.8 && aphi > 0.0 && aphi < 0.2)
63 {
64 grid.template insert<U>(key) = 0.5;
65 grid.template insert<V>(key) = 0.25;
66 }
67 else
68 {
69 grid.template insert<U>(key) = 1.0;
70 grid.template insert<V>(key) = 0.0;
71 }
72 grid.template insert<phi>(key) = sph_zero.distance(pc);
73 grid.template insert<normal>(key)[0] = pn[0];
74 grid.template insert<normal>(key)[1] = pn[1];
75 grid.template insert<normal>(key)[2] = pn[2];
76
77 // Old values U and V
78 grid.template insert<U_next>(key) = 0.0;
79 grid.template insert<V_next>(key) = 0.0;
80 }
81
82 ++it;
83 }
84
86}
87
88template<unsigned int U_src,unsigned int V_src,unsigned int U_dst, unsigned int V_dst>
89void extend(sgrid_type & grid)
90{
91 double delta = 1e-10;
92 double max = 0.0;
93 auto it = grid.getDomainIterator();
94
95 while (it.isNext())
96 {
97 // center point
98 auto Cp = it.get();
99
100 // plus,minus X,Y,Z
101 auto mx = Cp.move(0,-1);
102 auto px = Cp.move(0,+1);
103 auto my = Cp.move(1,-1);
104 auto py = Cp.move(1,1);
105 auto mz = Cp.move(2,-1);
106 auto pz = Cp.move(2,1);
107
108 double s = grid.get<phi>(Cp) / sqrt(fabs(grid.get<phi>(Cp)) + delta);
109
110 double Uext = 0.0;
111 double Vext = 0.0;
112
113 double dir = s*grid.get<normal>(Cp)[x];
114
115 if (dir > 0)
116 {
117 Uext += dir * (grid.get<U_src>(Cp) - grid.get<U_src>(mx));
118 Vext += dir * (grid.get<V_src>(Cp) - grid.get<V_src>(mx));
119 }
120 else if (dir < 0)
121 {
122 Uext += dir * (grid.get<U_src>(px) - grid.get<U_src>(Cp));
123 Vext += dir * (grid.get<V_src>(px) - grid.get<V_src>(Cp));
124 }
125
126
127 dir = s*grid.get<normal>(Cp)[y];
128 if (dir > 0)
129 {
130 Uext += dir * (grid.get<U_src>(Cp) - grid.get<U_src>(my));
131 Vext += dir * (grid.get<V_src>(Cp) - grid.get<V_src>(my));
132 }
133 else if (dir < 0)
134 {
135 Uext += dir * (grid.get<U_src>(py) - grid.get<U_src>(Cp));
136 Vext += dir * (grid.get<V_src>(py) - grid.get<V_src>(Cp));
137 }
138
139 dir = s*grid.get<normal>(Cp)[z];
140 if (dir > 0)
141 {
142 Uext += dir * (grid.get<U_src>(Cp) - grid.get<U_src>(mz));
143 Vext += dir * (grid.get<V_src>(Cp) - grid.get<V_src>(mz));
144 }
145 else if (dir < 0)
146 {
147 Uext += dir * (grid.get<U_src>(pz) - grid.get<U_src>(Cp));
148 Vext += dir * (grid.get<V_src>(pz) - grid.get<V_src>(Cp));
149 }
150
151 if (Uext >= max)
152 {
153 max = Uext;
154 }
155
156 grid.insert<U_dst>(Cp) = grid.get<U_src>(Cp) - 1.0*Uext;
157 grid.insert<V_dst>(Cp) = grid.get<V_src>(Cp) - 1.0*Vext;
158
159 // Next point in the grid
160 ++it;
161 }
162
163 std::cout << "UEX max: " << max << std::endl;
164}
165
166int main(int argc, char* argv[])
167{
168 openfpm_init(&argc,&argv);
169
170 // domain
171 Box<3,double> domain({0.0,0.0,0.0},{2.5,2.5,2.5});
172
173 // grid size
174 size_t sz[3] = {512,512,512};
175
176 // Define periodicity of the grid
177 periodicity<3> bc = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
178
179 // Ghost in grid unit
181
182 // deltaT
183 double deltaT = 0.3;
184
185 // Diffusion constant for specie U
186 double du = 1*1e-5;
187
188 // Diffusion constant for specie V
189 double dv = 0.5*1e-5;
190
191#ifdef TEST_RUN
192 // Number of timesteps
193 size_t timeSteps = 200;
194#else
195 // Number of timesteps
196 size_t timeSteps = 150000;
197#endif
198
199 // K and F (Physical constant in the equation)
200 double K = 0.053;
201 double F = 0.014;
202
203 sgrid_type grid(sz,domain,g,bc);
204
205
206 // spacing of the grid on x and y
207 double spacing[3] = {grid.spacing(0),grid.spacing(1),grid.spacing(2)};
208
209 init(grid,domain);
210
211 // sync the ghost
212 size_t count = 0;
213 grid.template ghost_get<U,V>();
214
215 // because we assume that spacing[x] == spacing[y] we use formula 2
216 // and we calculate the prefactor of Eq 2
217 double uFactor = deltaT * du;
218 double vFactor = deltaT * dv;
219
220 auto & v_cl = create_vcluster();
221
222 timer tot_sim;
223 tot_sim.start();
224
225 for (size_t i = 0; i < timeSteps ; ++i)
226 {
227 {
228 auto it = grid.getDomainIterator();
229
230 while (it.isNext())
231 {
232 // center point
233 auto Cp = it.get();
234
235 // plus,minus X,Y,Z
236 auto mx = Cp.move(0,-1);
237 auto px = Cp.move(0,+1);
238 auto my = Cp.move(1,-1);
239 auto py = Cp.move(1,1);
240 auto mz = Cp.move(2,-1);
241 auto pz = Cp.move(2,1);
242
243 grid.insert<tgrad_u>(Cp)[0] = 0.0;
244 grid.insert<tgrad_u>(Cp)[1] = 0.0;
245 grid.insert<tgrad_u>(Cp)[2] = 0.0;
246 grid.insert<tgrad_v>(Cp)[0] = 0.0;
247 grid.insert<tgrad_v>(Cp)[1] = 0.0;
248 grid.insert<tgrad_v>(Cp)[2] = 0.0;
249
251
252 if (grid.existPoint(mz) == true && grid.existPoint(pz) == true &&
253 grid.existPoint(my) == true && grid.existPoint(py) == true &&
254 grid.existPoint(mx) == true && grid.existPoint(px) == true )
255 {
256 Point<3,double> gradU;
257 gradU[x] = (grid.get<U>(Cp) - grid.get<U>(mx)) / grid.spacing(0);
258 gradU[y] = (grid.get<U>(Cp) - grid.get<U>(my)) / grid.spacing(1);
259 gradU[z] = (grid.get<U>(Cp) - grid.get<U>(mz)) / grid.spacing(2);
260
261 Point<3,double> gradV;
262 gradV[x] = (grid.get<V>(Cp) - grid.get<V>(mx)) / grid.spacing(0);
263 gradV[y] = (grid.get<V>(Cp) - grid.get<V>(my)) / grid.spacing(1);
264 gradV[z] = (grid.get<V>(Cp) - grid.get<V>(mz)) / grid.spacing(2);
265
266 Point<3,double> PgradU;
267 Point<3,double> PgradV;
268
269 PgradU.zero();
270 PgradV.zero();
271
272 for (int i = 0 ; i < 3 ; i++)
273 {
274 for (int j = 0 ; j < 3 ; j++)
275 {
276 grid.insert<tgrad_u>(Cp)[i] += (((i == j)?1.0:0.0) - grid.get<normal>(Cp)[i]*grid.get<normal>(Cp)[j])*gradU[j];
277 grid.insert<tgrad_v>(Cp)[i] += (((i == j)?1.0:0.0) - grid.get<normal>(Cp)[i]*grid.get<normal>(Cp)[j])*gradV[j];
278 }
279 }
280 }
281 ++it;
282 }
283 }
284
285// Old.write_frame("Init_condition",i);
286
287 {
288 auto it = grid.getDomainIterator();
289
290 while (it.isNext())
291 {
292 // center point
293 auto Cp = it.get();
294
295 // plus,minus X,Y,Z
296 auto mx = Cp.move(0,-1);
297 auto px = Cp.move(0,+1);
298 auto my = Cp.move(1,-1);
299 auto py = Cp.move(1,1);
300 auto mz = Cp.move(2,-1);
301 auto pz = Cp.move(2,1);
302
304
305 // Mirror z
306
307 if (grid.existPoint(mz) == true && grid.existPoint(pz) == true &&
308 grid.existPoint(my) == true && grid.existPoint(py) == true &&
309 grid.existPoint(mx) == true && grid.existPoint(px) == true )
310 {
311 double lapU = 0;
312 double lapV = 0;
313
314 //Div
315 lapU += (grid.get<tgrad_u>(px)[0] - grid.get<tgrad_u>(Cp)[0]) / grid.spacing(0);
316 lapV += (grid.get<tgrad_v>(px)[0] - grid.get<tgrad_v>(Cp)[0]) / grid.spacing(0);
317 lapU += (grid.get<tgrad_u>(py)[1] - grid.get<tgrad_u>(Cp)[1]) / grid.spacing(1);
318 lapV += (grid.get<tgrad_v>(py)[1] - grid.get<tgrad_v>(Cp)[1]) / grid.spacing(1);
319 lapU += (grid.get<tgrad_u>(pz)[2] - grid.get<tgrad_u>(Cp)[2]) / grid.spacing(2);
320 lapV += (grid.get<tgrad_v>(pz)[2] - grid.get<tgrad_v>(Cp)[2]) / grid.spacing(2);
321
322 // update based on Eq 2
323 grid.insert<U_next>(Cp) = grid.get<U>(Cp) + uFactor * lapU +
324 - deltaT * grid.get<U>(Cp) * grid.get<V>(Cp) * grid.get<V>(Cp) +
325 - deltaT * F * (grid.get<U>(Cp) - 1.0);
326
327
328 // update based on Eq 2
329 grid.insert<V_next>(Cp) = grid.get<V>(Cp) + vFactor * lapV +
330 deltaT * grid.get<U>(Cp) * grid.get<V>(Cp) * grid.get<V>(Cp) +
331 - deltaT * (F+K) * grid.get<V>(Cp);
332 }
333
334 // Next point in the grid
335 ++it;
336 }
337 }
338
339// New.write_frame("update",i);
340
341 // Extend
342
343 if (i % 5 == 0)
344 {
345 for (int j = 0 ; j < 2 ; j++)
346 {
347 if (j % 2 == 0)
348 {extend<U_next,V_next,U,V>(grid);}
349 else
350 {extend<U,V,U_next,V_next>(grid);}
351
352 // Here we copy New into the old grid in preparation of the new step
353 // It would be better to alternate, but using this we can show the usage
354 // of the function copy. To note that copy work only on two grid of the same
355 // decomposition. If you want to copy also the decomposition, or force to be
356 // exactly the same, use Old = New
357 //New.copy_sparse(Old);
358 }
359 }
360
361/* auto it = grid.getDomainIterator();
362
363 while (it.isNext())
364 {
365 // center point
366 auto Cp = it.get();
367
368 // update based on Eq 2
369 grid.insert<U>(Cp) = grid.get<U_next>(Cp);
370 grid.insert<V>(Cp) = grid.get<V_next>(Cp);
371
372 ++it;
373 }*/
374
376
377 // After copy we synchronize again the ghost part U and V
378 grid.ghost_get<U,V>();
379
380 // Every 500 time step we output the configuration for
381 // visualization
382 if (i % 500 == 0)
383 {
384 grid.save("output_" + std::to_string(count));
385 count++;
386 }
387
388 if (v_cl.rank() == 0)
389 {std::cout << "STEP: " << i << " " << std::endl;}
390 if (i % 100 == 0)
391 {
392 grid.write_frame("out",i);
393 }
394 }
395
396 tot_sim.stop();
397 std::cout << "Total simulation: " << tot_sim.getwct() << std::endl;
398
400
413
414 openfpm_finalize();
415
417
426}
This class represent an N-dimensional box.
Definition Box.hpp:61
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ void zero()
Set to zero the point coordinate.
Definition Point.hpp:284
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition Point.hpp:172
__device__ __host__ T norm() const
norm of the vector
Definition Point.hpp:231
This class implement the Sphere concept in an N-dimensional space.
Definition Sphere.hpp:24
This is a distributed grid.
Class for cpu time benchmarking.
Definition timer.hpp:28
void stop()
Stop the timer.
Definition timer.hpp:119
void start()
Start the timer.
Definition timer.hpp:90
double getwct()
Return the elapsed real time.
Definition timer.hpp:130
OutputIteratorT OffsetT ReductionOpT OuputT init
< [in] The initial value of the reduction
[v_transform metafunction]
Boundary conditions.
Definition common.hpp:22