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
69constexpr int U = 0;
70constexpr int V = 1;
71
72constexpr int x = 0;
73constexpr int y = 1;
74constexpr int z = 2;
75
77
78void init(sgrid_type & Old, sgrid_type & New, Box<3,double> & domain)
79{
81
82 auto it = Old.getGridIterator();
86
87 // Shere1
88 for (int i = 0 ; i < 3 ; i++)
89 {p1.get(i) = 2.0;}
90
91 // Shere2
92 for (int i = 0 ; i < 3 ; i++)
93 {p2.get(i) = 1.0;}
94
95 // Shere3
96 for (int i = 0 ; i < 3 ; i++)
97 {p3.get(i) = 0.5;}
98
99 Sphere<3,double> sph1(p1,0.3);
100 Sphere<3,double> sph2(p2,0.3);
101 Sphere<3,double> sph3(p3,0.3);
102
103 Point<3,double> u({1.0,1.0,1.0});
104 Box<3,double> channel_box(p3,p1);
105
106 while (it.isNext())
107 {
108 // Get the local grid key
109 auto key = it.get_dist();
110 auto keyg = it.get();
111
114
115 for (int i = 0 ; i < 3 ; i++)
116 {pc.get(i) = keyg.get(i) * it.getSpacing(i);}
117
118 // calculate the distance from the diagonal
119 vp.get(0) = pc.get(1)*u.get(2) - pc.get(2)*u.get(1);
120 vp.get(1) = pc.get(2)*u.get(0) - pc.get(0)*u.get(2);
121 vp.get(2) = pc.get(0)*u.get(1) - pc.get(1)*u.get(0);
122
123 double distance = vp.norm() / sqrt(3);
124
125 // Check if the point is in the first sphere
126 if (sph1.isInside(pc) || sph2.isInside(pc) || sph3.isInside(pc) || (distance < 0.1 && channel_box.isInside(pc)) )
127 {
128 // Old values U and V
129 Old.template insert<U>(key) = 1.0;
130 Old.template insert<V>(key) = 0.0;
131
132 // Old values U and V
133 New.template insert<U>(key) = 0.0;
134 New.template insert<V>(key) = 0.0;
135 }
136
137 ++it;
138 }
139
141
143
144 long int x_start = Old.size(0)*1.95f/domain.getHigh(0);
145 long int y_start = Old.size(1)*1.95f/domain.getHigh(1);
146 long int z_start = Old.size(1)*1.95f/domain.getHigh(2);
147
148 long int x_stop = Old.size(0)*2.05f/domain.getHigh(0);
149 long int y_stop = Old.size(1)*2.05f/domain.getHigh(1);
150 long int z_stop = Old.size(1)*2.05f/domain.getHigh(2);
151
152 grid_key_dx<3> start({x_start,y_start,z_start});
153 grid_key_dx<3> stop ({x_stop,y_stop,z_stop});
154 auto it_init = Old.getGridIterator(start,stop);
155
156 while (it_init.isNext())
157 {
158 auto key = it_init.get_dist();
159
160 Old.template insert<U>(key) = 0.5 + (((double)std::rand())/RAND_MAX -0.5)/10.0;
161 Old.template insert<V>(key) = 0.25 + (((double)std::rand())/RAND_MAX -0.5)/20.0;
162
163 ++it_init;
164 }
165
167}
168
169
170int main(int argc, char* argv[])
171{
172 openfpm_init(&argc,&argv);
173
174 // domain
175 Box<3,double> domain({0.0,0.0,0.0},{2.5,2.5,2.5});
176
177 // grid size
178 size_t sz[3] = {256,256,256};
179
180 // Define periodicity of the grid
181 periodicity<3> bc = {PERIODIC,PERIODIC,PERIODIC};
182
183 // Ghost in grid unit
185
186 // deltaT
187 double deltaT = 0.1;
188
189 // Diffusion constant for specie U
190 double du = 2*1e-5;
191
192 // Diffusion constant for specie V
193 double dv = 1*1e-5;
194
195#ifdef TEST_RUN
196 // Number of timesteps
197 size_t timeSteps = 200;
198#else
199 // Number of timesteps
200 size_t timeSteps = 150000;
201#endif
202
203 // K and F (Physical constant in the equation)
204 double K = 0.053;
205 double F = 0.014;
206
207 sgrid_type Old(sz,domain,g,bc);
208
209 // New grid with the decomposition of the old grid
210 sgrid_type New(Old.getDecomposition(),sz,g);
211
212
213 // spacing of the grid on x and y
214 double spacing[3] = {Old.spacing(0),Old.spacing(1),Old.spacing(2)};
215
216 init(Old,New,domain);
217
218 // sync the ghost
219 size_t count = 0;
220 Old.template ghost_get<U,V>();
221
222 // because we assume that spacing[x] == spacing[y] we use formula 2
223 // and we calculate the prefactor of Eq 2
224 double uFactor = deltaT * du/(spacing[x]*spacing[x]);
225 double vFactor = deltaT * dv/(spacing[x]*spacing[x]);
226
227 auto & v_cl = create_vcluster();
228
229 Old.write("Init_condition");
230
231 timer tot_sim;
232 tot_sim.start();
233
234 for (size_t i = 0; i < timeSteps; ++i)
235 {
236 auto it = Old.getDomainIterator();
237
238 while (it.isNext())
239 {
240 // center point
241 auto Cp = it.get();
242
243 // plus,minus X,Y,Z
244 auto mx = Cp.move(0,-1);
245 auto px = Cp.move(0,+1);
246 auto my = Cp.move(1,-1);
247 auto py = Cp.move(1,1);
248 auto mz = Cp.move(2,-1);
249 auto pz = Cp.move(2,1);
250
252
253 double LapU = 0.0;
254 double LapV = 0.0;
255
256 // Mirror z
257
258 if (Old.existPoint(mz) == true)
259 {
260 LapU += Old.get<U>(mz);
261 LapV += Old.get<V>(mz);
262 }
263 else if (Old.existPoint(pz) == true)
264 {
265 LapU += Old.get<U>(pz);
266 LapV += Old.get<V>(pz);
267 }
268 else
269 {
270 LapU += Old.get<U>(Cp);
271 LapV += Old.get<V>(Cp);
272 }
273
274 if (Old.existPoint(pz) == true)
275 {
276 LapU += Old.get<U>(pz);
277 LapV += Old.get<V>(pz);
278 }
279 else if (Old.existPoint(mz) == true)
280 {
281 LapU+= Old.get<U>(mz);
282 LapV += Old.get<V>(mz);
283 }
284 else
285 {
286 LapU+= Old.get<U>(Cp);
287 LapV += Old.get<V>(Cp);
288 }
289
290
291 // Mirror y
292
293 if (Old.existPoint(my) == true)
294 {
295 LapU += Old.get<U>(my);
296 LapV += Old.get<V>(my);
297 }
298 else if (Old.existPoint(py) == true)
299 {
300 LapU += Old.get<U>(py);
301 LapV += Old.get<V>(py);
302 }
303 else
304 {
305 LapU+= Old.get<U>(Cp);
306 LapV += Old.get<V>(Cp);
307 }
308
309 if (Old.existPoint(py) == true)
310 {
311 LapU += Old.get<U>(py);
312 LapV += Old.get<V>(py);
313 }
314 else if (Old.existPoint(my) == true)
315 {
316 LapU+= Old.get<U>(my);
317 LapV += Old.get<V>(my);
318 }
319 else
320 {
321 LapU+= Old.get<U>(Cp);
322 LapV += Old.get<V>(Cp);
323 }
324
325 // Mirror x
326
327 if (Old.existPoint(mx) == true)
328 {
329 LapU += Old.get<U>(mx);
330 LapV += Old.get<V>(mx);
331 }
332 else if (Old.existPoint(px) == true)
333 {
334 LapU += Old.get<U>(px);
335 LapV += Old.get<V>(px);
336 }
337 else
338 {
339 LapU+= Old.get<U>(Cp);
340 LapV += Old.get<V>(Cp);
341 }
342
343 if (Old.existPoint(px) == true)
344 {
345 LapU += Old.get<U>(px);
346 LapV += Old.get<V>(px);
347 }
348 else if (Old.existPoint(mx) == true)
349 {
350 LapU+= Old.get<U>(mx);
351 LapV += Old.get<V>(mx);
352 }
353 else
354 {
355 LapU+= Old.get<U>(Cp);
356 LapV += Old.get<V>(Cp);
357 }
358
359 LapU -= 6.0*Old.get<U>(Cp);
360 LapV -= 6.0*Old.get<V>(Cp);
361
363
364 // update based on Eq 2
365 New.insert<U>(Cp) = Old.get<U>(Cp) + uFactor * LapU +
366 - deltaT * Old.get<U>(Cp) * Old.get<V>(Cp) * Old.get<V>(Cp) +
367 - deltaT * F * (Old.get<U>(Cp) - 1.0);
368
369
370 // update based on Eq 2
371 New.insert<V>(Cp) = Old.get<V>(Cp) + vFactor * LapV +
372 deltaT * Old.get<U>(Cp) * Old.get<V>(Cp) * Old.get<V>(Cp) +
373 - deltaT * (F+K) * Old.get<V>(Cp);
374
375 // Next point in the grid
376 ++it;
377 }
378
380
381 // Here we copy New into the old grid in preparation of the new step
382 // It would be better to alternate, but using this we can show the usage
383 // of the function copy. To note that copy work only on two grid of the same
384 // decomposition. If you want to copy also the decomposition, or force to be
385 // exactly the same, use Old = New
386 Old.copy_sparse(New);
387
388 // After copy we synchronize again the ghost part U and V
389 Old.ghost_get<U,V>();
390
391 // Every 500 time step we output the configuration for
392 // visualization
393 if (i % 500 == 0)
394 {
395 Old.save("output_" + std::to_string(count));
396 count++;
397 }
398
399 if (v_cl.rank() == 0)
400 {std::cout << "STEP: " << i << " " << std::endl;}
401 if (i % 300 == 0)
402 {
403 Old.write_frame("out",i);
404 }
405 }
406
407 tot_sim.stop();
408 std::cout << "Total simulation: " << tot_sim.getwct() << std::endl;
409
411
424
425 openfpm_finalize();
426
428
437}
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.
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > & copy_sparse(grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > &g, bool use_memcpy=true)
Copy the give grid into this grid.
void ghost_get(size_t opt=0)
It synchronize the ghost parts.
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
bool existPoint(const grid_dist_key_dx< dim, bg_key > &v1) const
Check if the point exist.
size_t size() const
Return the total number of points in the grid.
St spacing(size_t i) const
Get the spacing of the grid in direction i.
bool write(std::string output, size_t opt=VTK_WRITER|FORMAT_BINARY)
Write the distributed grid information.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
void save(const std::string &filename) const
Save the grid state on HDF5.
auto get(const grid_dist_key_dx< dim, bg_key > &v1) const -> typename std::add_lvalue_reference< decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))>::type
Get the reference of the selected element.
auto insert(const grid_dist_key_dx< dim, bg_key > &v1) -> decltype(loc_grid.get(v1.getSub()).template insert< p >(v1.getKey()))
insert an element in the grid
bool write_frame(std::string output, size_t i, size_t opt=VTK_WRITER|FORMAT_ASCII)
Write the distributed grid information.
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
OutputIteratorT OffsetT ReductionOpT OuputT init
< [in] The initial value of the reduction
[v_transform metafunction]
Boundary conditions.
Definition common.hpp:22