OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
main.cu
1#include "Decomposition/Distribution/BoxDistribution.hpp"
2#include "Grid/grid_dist_id.hpp"
3#include "data_type/aggregate.hpp"
4#include "timer.hpp"
5
64#ifdef __NVCC__
65
66constexpr int U = 0;
67constexpr int V = 1;
68
69constexpr int U_next = 2;
70constexpr int V_next = 3;
71
72constexpr int x = 0;
73constexpr int y = 1;
74constexpr int z = 2;
75
77
78typedef sgrid_dist_id_gpu<3,float,aggregate<float,float,float,float>,CudaMemory, Dec> SparseGridType;
79
80void init(SparseGridType & grid, Box<3,float> & domain, size_t (& div)[3])
81{
83
84 double spacing_x = grid.spacing(0);
85 double spacing_y = grid.spacing(1);
86 double spacing_z = grid.spacing(2);
87
88 typedef typename GetAddBlockType<SparseGridType>::type InsertBlockT;
89
90 // Get the processor domain in continuos
91
92 for (int i = 0 ; i < div[0] ; i++)
93 {
94 for (int j = 0 ; j < div[1] ; j++)
95 {
96 for (int k = 0 ; k < div[2] ; k++)
97 {
98 Point<3,double> p({0.5+i*1.0,0.5+j*1.0,0.5+k*1.0});
99 Sphere<3,double> sph(p,0.3);
100
101 Box<3,size_t> bx;
102
103 for (int s = 0 ; s < 3 ; s++)
104 {
105 bx.setLow(s,(size_t)((sph.center(s) - 0.31)/grid.spacing(s)));
106 bx.setHigh(s,(size_t)((sph.center(s) + 0.31)/grid.spacing(s)));
107 }
108
109 grid.addPoints([spacing_x,spacing_y,spacing_z,sph] __device__ (int i, int j, int k)
110 {
111 Point<3,double> pc({i*spacing_x,j*spacing_y,k*spacing_z});
112
113 // Check if the point is in the domain
114 if (sph.isInside(pc) )
115 {return true;}
116 return false;
117 },
118 [] __device__ (InsertBlockT & data, int i, int j, int k)
119 {
120 data.template get<U>() = 1.0;
121 data.template get<V>() = 0.0;
122 }
123 );
124
125 grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
126 grid.removeUnusedBuffers();
127 }
128 }
129 }
130
131 for (int i = 0 ; i < div[0] ; i++)
132 {
133 for (int j = 0 ; j < div[1] ; j++)
134 {
135 Point<3,double> u({0.0,0.0,1.0});
136 Point<3,double> c({0.5+i,0.5+j,0.0});
137
138 Box<3,size_t> bx;
139
140 bx.setLow(0,(0.4+i)/spacing_x);
141 bx.setHigh(0,(0.6+i)/spacing_x);
142
143 bx.setLow(1,(0.4+j)/spacing_y);
144 bx.setHigh(1,(0.6+j)/spacing_y);
145
146 bx.setLow(2,0);
147 bx.setHigh(2,(size_t)grid.size(2));
148
149 grid.addPoints(bx.getKP1(),bx.getKP2(),[spacing_x,spacing_y,spacing_z,u,c] __device__ (int i, int j, int k)
150 {
151 Point<3,double> pc({i*spacing_x,j*spacing_y,k*spacing_z});
152 Point<3,double> pcs({i*spacing_x,j*spacing_y,k*spacing_z});
154
155 // shift
156 pc -= c;
157
158 // calculate the distance from the diagonal
159 vp.get(0) = pc.get(1)*u.get(2) - pc.get(2)*u.get(1);
160 vp.get(1) = pc.get(2)*u.get(0) - pc.get(0)*u.get(2);
161 vp.get(2) = pc.get(0)*u.get(1) - pc.get(1)*u.get(0);
162
163 double distance = vp.norm();
164
165 // Check if the point is in the domain
166 if (distance < 0.1 )
167 {return true;}
168
169 return false;
170 },
171 [] __device__ (InsertBlockT & data, int i, int j, int k)
172 {
173 data.template get<U>() = 1.0;
174 data.template get<V>() = 0.0;
175 }
176 );
177
178 grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
179 grid.removeUnusedBuffers();
180 }
181 }
182
183 for (int i = 0 ; i < div[0] ; i++)
184 {
185 for (int k = 0 ; k < div[2] ; k++)
186 {
187 Point<3,double> u({0.0,1.0,0.0});
188 Point<3,double> c({0.5+i,0.0,0.5+k});
189
190 Box<3,size_t> bx;
191
192 bx.setLow(0,(0.4+i)/spacing_x);
193 bx.setHigh(0,(0.6+i)/spacing_x);
194
195 bx.setLow(2,(0.4+k)/spacing_z);
196 bx.setHigh(2,(0.6+k)/spacing_z);
197
198 bx.setLow(1,0);
199 bx.setHigh(1,(size_t)grid.size(1));
200
201 grid.addPoints(bx.getKP1(),bx.getKP2(),[spacing_x,spacing_y,spacing_z,u,c] __device__ (int i, int j, int k)
202 {
203 Point<3,double> pc({i*spacing_x,j*spacing_y,k*spacing_z});
204 Point<3,double> pcs({i*spacing_x,j*spacing_y,k*spacing_z});
206
207 // shift
208 pc -= c;
209
210 // calculate the distance from the diagonal
211 vp.get(0) = pc.get(1)*u.get(2) - pc.get(2)*u.get(1);
212 vp.get(1) = pc.get(2)*u.get(0) - pc.get(0)*u.get(2);
213 vp.get(2) = pc.get(0)*u.get(1) - pc.get(1)*u.get(0);
214
215 double distance = vp.norm();
216
217 // Check if the point is in the domain
218 if (distance < 0.1 )
219 {return true;}
220
221 return false;
222 },
223 [] __device__ (InsertBlockT & data, int i, int j, int k)
224 {
225 data.template get<U>() = 1.0;
226 data.template get<V>() = 0.0;
227 }
228 );
229
230 grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
231 grid.removeUnusedBuffers();
232 }
233 }
234
235 for (int j = 0 ; j < div[1] ; j++)
236 {
237 for (int k = 0 ; k < div[2] ; k++)
238 {
239 Point<3,double> u({1.0,0.0,0.0});
240 Point<3,double> c({0.0,0.5+j,0.5+k});
241
242 Box<3,size_t> bx;
243
244 bx.setLow(1,(0.4+j)/spacing_y);
245 bx.setHigh(1,(0.6+j)/spacing_y);
246
247 bx.setLow(2,(0.4+k)/spacing_z);
248 bx.setHigh(2,(0.6+k)/spacing_z);
249
250 bx.setLow(0,0);
251 bx.setHigh(0,(size_t)grid.size(0));
252
253 grid.addPoints(bx.getKP1(),bx.getKP2(),[spacing_x,spacing_y,spacing_z,u,c] __device__ (int i, int j, int k)
254 {
255 Point<3,double> pc({i*spacing_x,j*spacing_y,k*spacing_z});
256 Point<3,double> pcs({i*spacing_x,j*spacing_y,k*spacing_z});
258
259 // shift
260 pc -= c;
261
262 // calculate the distance from the diagonal
263 vp.get(0) = pc.get(1)*u.get(2) - pc.get(2)*u.get(1);
264 vp.get(1) = pc.get(2)*u.get(0) - pc.get(0)*u.get(2);
265 vp.get(2) = pc.get(0)*u.get(1) - pc.get(1)*u.get(0);
266
267 double distance = vp.norm();
268
269 // Check if the point is in the domain
270 if (distance < 0.1 )
271 {return true;}
272
273 return false;
274 },
275 [] __device__ (InsertBlockT & data, int i, int j, int k)
276 {
277 data.template get<U>() = 1.0;
278 data.template get<V>() = 0.0;
279 }
280 );
281
282 grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
283 grid.removeUnusedBuffers();
284 }
285 }
286
288
289 long int x_start = grid.size(0)*0.4f/domain.getHigh(0);
290 long int y_start = grid.size(1)*0.4f/domain.getHigh(1);
291 long int z_start = grid.size(1)*0.4f/domain.getHigh(2);
292
293 long int x_stop = grid.size(0)*0.6f/domain.getHigh(0);
294 long int y_stop = grid.size(1)*0.6f/domain.getHigh(1);
295 long int z_stop = grid.size(1)*0.6f/domain.getHigh(2);
296
298
299 grid_key_dx<3> start({x_start,y_start,z_start});
300 grid_key_dx<3> stop ({x_stop,y_stop,z_stop});
301
302 grid.addPoints(start,stop,[] __device__ (int i, int j, int k)
303 {
304 return true;
305 },
306 [] __device__ (InsertBlockT & data, int i, int j, int k)
307 {
308 data.template get<U>() = 0.5;
309 data.template get<V>() = 0.24;
310 }
311 );
312
313 grid.template flush<smin_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
314
316}
317
318
319int main(int argc, char* argv[])
320{
321 openfpm_init(&argc,&argv);
322
323 // First we check which type of decomposition BoxDistritubion prodice
324 auto & v_cl = create_vcluster();
325
327 getPrimeFactors(v_cl.size(),facts);
328
329 size_t div[3];
330
331 for (int i = 0 ; i < 3 ; i++)
332 {div[i] = 1;}
333
334 for (int i = 0 ; i < facts.size() ; i++)
335 {div[i % 3] *= facts.get(i);}
336
337 grid_sm<3,void> gdist(div);
338
339 // domain
340 Box<3,float> domain({0.0,0.0,0.0},{div[0]*1.0f,div[1]*1.0f,div[2]*1.0f});
341
342 // grid size
343 size_t sz[3] = {64*div[0],64*div[1],64*div[2]};
344
345 // Define periodicity of the grid
346 periodicity<3> bc = {PERIODIC,PERIODIC,PERIODIC};
347
348 // Ghost in grid unit
350
351 // deltaT
352 float deltaT = 0.25;
353
354 // Diffusion constant for specie U
355 float du = 2*1e-5;
356
357 // Diffusion constant for specie V
358 float dv = 1*1e-5;
359
360 // Number of timesteps
361#ifdef TEST_RUN
362 size_t timeSteps = 300;
363#else
364 size_t timeSteps = 15000;
365#endif
366
367 // K and F (Physical constant in the equation)
368 float K = 0.053;
369 float F = 0.014;
370
371 SparseGridType grid(sz,domain,g,bc,0,gdist);
372
373 // spacing of the grid on x and y
374 float spacing[3] = {grid.spacing(0),grid.spacing(1),grid.spacing(2)};
375
376 init(grid,domain,div);
377
378 grid.deviceToHost<U,V,U_next,V_next>();
379 grid.write("final");
380
381 openfpm_finalize();
382 return 0;
383
384 // sync the ghost
385 grid.template ghost_get<U,V>(RUN_ON_DEVICE);
386
387 // because we assume that spacing[x] == spacing[y] we use formula 2
388 // and we calculate the prefactor of Eq 2
389 float uFactor = deltaT * du/(spacing[x]*spacing[x]);
390 float vFactor = deltaT * dv/(spacing[x]*spacing[x]);
391
392 timer tot_sim;
393 tot_sim.start();
394
395 for (size_t i = 0; i < timeSteps ; ++i)
396 {
397 if (v_cl.rank() == 0)
398 {std::cout << "STEP: " << i << std::endl;}
399/* if (i % 300 == 0)
400 {
401 std::cout << "STEP: " << i << std::endl;
402 grid.write_frame("out",i,VTK_WRITER);
403 }*/
404
406
407 typedef typename GetCpBlockType<decltype(grid),0,1>::type CpBlockType;
408
410
411 auto func = [uFactor,vFactor,deltaT,F,K] __device__ (float & u_out, float & v_out,
412 CpBlockType & u, CpBlockType & v,
413 int i, int j, int k){
414
415 float uc = u(i,j,k);
416 float vc = v(i,j,k);
417
418 u_out = uc + uFactor *(u(i-1,j,k) + u(i+1,j,k) +
419 u(i,j-1,k) + u(i,j+1,k) +
420 u(i,j,k-1) + u(i,j,k+1) - 6.0f*uc) - deltaT * uc*vc*vc
421 - deltaT * F * (uc - 1.0f);
422
423
424 v_out = vc + vFactor *(v(i-1,j,k) + v(i+1,j,k) +
425 v(i,j+1,k) + v(i,j-1,k) +
426 v(i,j,k-1) + v(i,j,k+1) - 6.0f*vc) + deltaT * uc*vc*vc
427 - deltaT * (F+K) * vc;
428 };
429
431
433
434 if (i % 2 == 0)
435 {
436 grid.conv2<U,V,U_next,V_next,1>({0,0,0},{(long int)sz[0]-1,(long int)sz[1]-1,(long int)sz[2]-1},func);
437
438 // After copy we synchronize again the ghost part U and V
439
440 grid.ghost_get<U_next,V_next>(RUN_ON_DEVICE | SKIP_LABELLING);
441 }
442 else
443 {
444 grid.conv2<U_next,V_next,U,V,1>({0,0,0},{(long int)sz[0]-1,(long int)sz[1]-1,(long int)sz[2]-1},func);
445
446 // After copy we synchronize again the ghost part U and V
447 grid.ghost_get<U,V>(RUN_ON_DEVICE | SKIP_LABELLING);
448 }
449
451
452 // Every 500 time step we output the configuration for
453 // visualization
454// if (i % 500 == 0)
455// {
456// grid.save("output_" + std::to_string(count));
457// count++;
458// }
459 }
460
461 tot_sim.stop();
462 std::cout << "Total simulation: " << tot_sim.getwct() << std::endl;
463
464 grid.deviceToHost<U,V,U_next,V_next>();
465 grid.write("final");
466
468
481
482 openfpm_finalize();
483
485
494}
495
496#else
497
498int main(int argc, char* argv[])
499{
500 return 0;
501}
502
503#endif
504
This class represent an N-dimensional box.
Definition Box.hpp:61
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition Box.hpp:544
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition Box.hpp:533
This class decompose a space into sub-sub-domains and distribute them across processors.
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__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
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
Declaration grid_sm.
Definition grid_sm.hpp:167
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
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
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
OutputIteratorT OffsetT ReductionOpT OuputT init
< [in] The initial value of the reduction
[v_transform metafunction]
get the type of the block
Boundary conditions.
Definition common.hpp:22