OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
main.cpp
1 #include "Grid/grid_dist_id.hpp"
2 #include "data_type/aggregate.hpp"
3 #include "timer.hpp"
4 
69 constexpr int U = 0;
70 constexpr int V = 1;
71 
72 constexpr int x = 0;
73 constexpr int y = 1;
74 constexpr int z = 2;
75 
77 
78 void init(sgrid_type & Old, sgrid_type & New, Box<3,double> & domain)
79 {
81 
82  auto it = Old.getGridIterator();
83  Point<3,double> p1;
84  Point<3,double> p2;
85  Point<3,double> p3;
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 
112  Point<3,double> pc;
113  Point<3,double> vp;
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 
170 int 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
184  Ghost<3,long int> g(1);
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 
423 
425  openfpm_finalize();
426 
428 
437 }
bool write(std::string output, size_t opt=VTK_WRITER|FORMAT_BINARY)
Write the distributed grid information.
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:18
size_t size() const
Return the total number of points in the grid.
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.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
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
St spacing(size_t i) const
Get the spacing of the grid in direction i.
double getwct()
Return the elapsed real time.
Definition: timer.hpp:130
Definition: Ghost.hpp:39
__device__ __host__ T norm()
norm of the vector
Definition: Point.hpp:231
void save(const std::string &filename) const
Save the grid state on HDF5.
This is a distributed grid.
bool existPoint(const grid_dist_key_dx< dim, bg_key > &v1) const
Check if the point exist.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop)
void start()
Start the timer.
Definition: timer.hpp:90
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)
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.
This class represent an N-dimensional box.
Definition: Box.hpp:60
This class implement the Sphere concept in an N-dimensional space.
Definition: Sphere.hpp:23
void ghost_get(size_t opt=0)
It synchronize the ghost parts.
OutputIteratorT OffsetT ReductionOpT OuputT init
< [in] The initial value of the reduction
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
Boundary conditions.
Definition: common.hpp:21
Class for cpu time benchmarking.
Definition: timer.hpp:27
void stop()
Stop the timer.
Definition: timer.hpp:119
[v_transform metafunction]