OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
main.cu
1#include "Grid/grid_dist_id.hpp"
2#include "data_type/aggregate.hpp"
3#include "timer.hpp"
4
35#ifdef __NVCC__
36
37constexpr int U = 0;
38constexpr int V = 1;
39constexpr int U_next = 2;
40constexpr int V_next = 3;
41
42typedef sgrid_dist_id_gpu<3,double,aggregate<double,double,double,double> > sgrid_type;
43
44void init(sgrid_type & grid, Box<3,double> & domain)
45{
46 auto it = grid.getGridIterator();
50
51 // Shere1
52 for (int i = 0 ; i < 3 ; i++)
53 {p1.get(i) = 2.0;}
54
55 // Shere2
56 for (int i = 0 ; i < 3 ; i++)
57 {p2.get(i) = 1.0;}
58
59 // Shere3
60 for (int i = 0 ; i < 3 ; i++)
61 {p3.get(i) = 0.5;}
62
63 Sphere<3,double> sph1(p1,0.3);
64 Sphere<3,double> sph2(p2,0.3);
65 Sphere<3,double> sph3(p3,0.3);
66
67 Point<3,double> u({1.0,1.0,1.0});
68 Box<3,double> channel_box(p3,p1);
69
70 double spacing_x = grid.spacing(0);
71 double spacing_y = grid.spacing(1);
72 double spacing_z = grid.spacing(2);
73
74 typedef typename GetAddBlockType<sgrid_type>::type InsertBlockT;
75
76 grid.addPoints([spacing_x,spacing_y,spacing_z,u,sph1,sph2,sph3,channel_box] __device__ (int i, int j, int k)
77 {
78 Point<3,double> pc({i*spacing_x,j*spacing_y,k*spacing_z});
80
81 // calculate the distance from the diagonal
82 vp.get(0) = pc.get(1)*u.get(2) - pc.get(2)*u.get(1);
83 vp.get(1) = pc.get(2)*u.get(0) - pc.get(0)*u.get(2);
84 vp.get(2) = pc.get(0)*u.get(1) - pc.get(1)*u.get(0);
85
86 double distance = vp.norm() / sqrt(3.0f);
87
88 // Check if the point is in the domain
89 if (sph1.isInside(pc) || sph2.isInside(pc) || sph3.isInside(pc) || (distance < 0.1 && channel_box.isInside(pc)) )
90 {return true;}
91
92 return false;
93 },
94 [] __device__ (InsertBlockT & data, int i, int j, int k)
95 {
96 data.template get<U>() = 1.0;
97 data.template get<V>() = 0.0;
98 }
99 );
100
101
102 grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
103
104 long int x_start = grid.size(0)*1.95f/domain.getHigh(0);
105 long int y_start = grid.size(1)*1.95f/domain.getHigh(1);
106 long int z_start = grid.size(1)*1.95f/domain.getHigh(2);
107
108 long int x_stop = grid.size(0)*2.05f/domain.getHigh(0);
109 long int y_stop = grid.size(1)*2.05f/domain.getHigh(1);
110 long int z_stop = grid.size(1)*2.05f/domain.getHigh(2);
111
112 grid_key_dx<3> start({x_start,y_start,z_start});
113 grid_key_dx<3> stop ({x_stop,y_stop,z_stop});
114
115 grid.addPoints(start,stop,[] __device__ (int i, int j, int k)
116 {
117 return true;
118 },
119 [] __device__ (InsertBlockT & data, int i, int j, int k)
120 {
121 data.template get<U>() = 0.5;
122 data.template get<V>() = 0.24;
123 }
124 );
125
126 grid.template flush<smin_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
127}
128
129
130int main(int argc, char* argv[])
131{
132 openfpm_init(&argc,&argv);
133
134 // domain
135 Box<3,double> domain({0.0,0.0,0.0},{2.5,2.5,2.5});
136
137 // grid size
138 size_t sz[3] = {256,256,256};
139
140 // Define periodicity of the grid
141 periodicity<3> bc = {PERIODIC,PERIODIC,PERIODIC};
142
143 // Ghost in grid unit
145
146 // deltaT
147 double deltaT = 0.1;
148
149 // Diffusion constant for specie U
150 double du = 2*1e-5;
151
152 // Diffusion constant for specie V
153 double dv = 1*1e-5;
154
155#ifdef TEST_RUN
156 // Number of timesteps
157 size_t timeSteps = 300;
158#else
159 // Number of timesteps
160 size_t timeSteps = 150000;
161#endif
162
163 // K and F (Physical constant in the equation)
164 double K = 0.053;
165 double F = 0.014;
166
167 sgrid_type grid(sz,domain,g,bc);
168
169 grid.template setBackgroundValue<0>(-0.5);
170 grid.template setBackgroundValue<1>(-0.5);
171 grid.template setBackgroundValue<2>(-0.5);
172 grid.template setBackgroundValue<3>(-0.5);
173
174 // spacing of the grid on x and y
175 double spacing[3] = {grid.spacing(0),grid.spacing(1),grid.spacing(2)};
176
177 init(grid,domain);
178
179 // sync the ghost
180 grid.template ghost_get<U,V>(RUN_ON_DEVICE);
181
182 // because we assume that spacing[x] == spacing[y] we use formula 2
183 // and we calculate the prefactor of Eq 2
184 double uFactor = deltaT * du/(spacing[0]*spacing[0]);
185 double vFactor = deltaT * dv/(spacing[0]*spacing[0]);
186
187 grid.template deviceToHost<U,V>();
188 grid.write("Init_condition");
189
190 timer tot_sim;
191 tot_sim.start();
192
193 for (size_t i = 0; i < timeSteps; ++i)
194 {
196
197 typedef typename GetCpBlockType<decltype(grid),0,1>::type CpBlockType;
198
199 auto func = [uFactor,vFactor,deltaT,F,K] __device__ (double & u_out, double & v_out,
200 CpBlockType & u, CpBlockType & v,
201 int i, int j, int k){
202
203 double uc = u(i,j,k);
204 double vc = v(i,j,k);
205
206 double u_px = u(i+1,j,k);
207 double u_mx = u(i-1,j,k);
208
209 double u_py = u(i,j+1,k);
210 double u_my = u(i,j-1,k);
211
212 double u_pz = u(i,j,k+1);
213 double u_mz = u(i,j,k-1);
214
215 double v_px = v(i+1,j,k);
216 double v_mx = v(i-1,j,k);
217
218 double v_py = v(i,j+1,k);
219 double v_my = v(i,j-1,k);
220
221 double v_pz = v(i,j,k+1);
222 double v_mz = v(i,j,k-1);
223
224 // U fix
225
226 if (u_mx < -0.1 && u_px < -0.1)
227 {
228 u_mx = uc;
229 u_px = uc;
230 }
231
232 if (u_mx < -0.1)
233 {u_mx = u_px;}
234
235 if (u_px < -0.1)
236 {u_px = u_mx;}
237
238 if (u_my < -0.1 && u_py < -0.1)
239 {
240 u_my = uc;
241 u_py = uc;
242 }
243
244 if (u_my < -0.1)
245 {u_my = u_py;}
246
247 if (u_py < -0.1)
248 {u_py = u_my;}
249
250 if (u_mz < -0.1 && u_pz < -0.1)
251 {
252 u_mz = uc;
253 u_pz = uc;
254 }
255
256 if (u_mz < -0.1)
257 {u_mz = u_pz;}
258
259 if (u_pz < -0.1)
260 {u_pz = u_mz;}
261
262 // V fix
263
264 if (v_mx < -0.1 && v_px < -0.1)
265 {
266 v_mx = uc;
267 v_px = uc;
268 }
269
270 if (v_mx < -0.1)
271 {v_mx = v_px;}
272
273 if (v_px < -0.1)
274 {v_px = v_mx;}
275
276 if (v_my < -0.1 && v_py < -0.1)
277 {
278 v_my = uc;
279 v_py = uc;
280 }
281
282 if (v_my < -0.1)
283 {v_my = v_py;}
284
285 if (v_py < -0.1)
286 {v_py = v_my;}
287
288 if (v_mz < -0.1 && v_pz < -0.1)
289 {
290 v_mz = uc;
291 v_pz = uc;
292 }
293
294 if (v_mz < -0.1)
295 {v_mz = v_pz;}
296
297 if (v_pz < -0.1)
298 {v_pz = v_mz;}
299
300 u_out = uc + uFactor *(u_mx + u_px +
301 u_my + u_py +
302 u_mz + u_pz - 6.0*uc) - deltaT * uc*vc*vc
303 - deltaT * F * (uc - 1.0);
304
305
306 v_out = vc + vFactor *(v_mx + v_px +
307 v_py + v_my +
308 v_mz + v_pz - 6.0*vc) + deltaT * uc*vc*vc
309 - deltaT * (F+K) * vc;
310
311 };
312
313
314 if (i % 2 == 0)
315 {
316 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);
317
318 // After copy we synchronize again the ghost part U and V
319
320 grid.ghost_get<U_next,V_next>(RUN_ON_DEVICE | SKIP_LABELLING);
321 }
322 else
323 {
324 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);
325
326 // After copy we synchronize again the ghost part U and V
327 grid.ghost_get<U,V>(RUN_ON_DEVICE | SKIP_LABELLING);
328 }
329
331
332 // After copy we synchronize again the ghost part U and V
333
334 // Every 500 time step we output the configuration for
335 // visualization
336/* if (i % 500 == 0)
337 {
338 grid.save("output_" + std::to_string(count));
339 count++;
340 }*/
341
342 std::cout << "STEP: " << i << std::endl;
343/* if (i % 300 == 0)
344 {
345 grid.template deviceToHost<U,V>();
346 grid.write_frame("out",i);
347 }*/
348 }
349
350 tot_sim.stop();
351 std::cout << "Total simulation: " << tot_sim.getwct() << std::endl;
352
353 grid.template deviceToHost<U,V>();
354 grid.write("Final");
355
357
370
371 openfpm_finalize();
372
374
383}
384
385#else
386
387int main(int argc, char* argv[])
388{
389 return 0;
390}
391
392#endif
393
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__ 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.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
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