OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
main.cu
1 #include "Grid/grid_dist_id.hpp"
2 #include "data_type/aggregate.hpp"
3 #include "timer.hpp"
4 
63 #ifdef __NVCC__
64 
65 constexpr int U = 0;
66 constexpr int V = 1;
67 
68 constexpr int U_next = 2;
69 constexpr int V_next = 3;
70 
71 constexpr int x = 0;
72 constexpr int y = 1;
73 constexpr int z = 2;
74 
76 
77 typedef sgrid_dist_id_gpu<3,float,aggregate<float,float,float,float> > SparseGridType;
78 
80 
81 void init(SparseGridType & grid, Box<3,float> & domain)
82 {
84 
85  typedef typename GetAddBlockType<SparseGridType>::type InsertBlockT;
86 
87  grid.addPoints([] __device__ (int i, int j, int k)
88  {
89  return true;
90  },
91  [] __device__ (InsertBlockT & data, int i, int j, int k)
92  {
93  data.template get<U>() = 1.0;
94  data.template get<V>() = 0.0;
95  }
96  );
97 
98 
99  grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
100 
102 
103  long int x_start = grid.size(0)*1.55f/domain.getHigh(0);
104  long int y_start = grid.size(1)*1.55f/domain.getHigh(1);
105  long int z_start = grid.size(1)*1.55f/domain.getHigh(2);
106 
107  long int x_stop = grid.size(0)*1.85f/domain.getHigh(0);
108  long int y_stop = grid.size(1)*1.85f/domain.getHigh(1);
109  long int z_stop = grid.size(1)*1.85f/domain.getHigh(2);
110 
112 
113  grid_key_dx<3> start({x_start,y_start,z_start});
114  grid_key_dx<3> stop ({x_stop,y_stop,z_stop});
115 
116  grid.addPoints(start,stop,[] __device__ (int i, int j, int k)
117  {
118  return true;
119  },
120  [] __device__ (InsertBlockT & data, int i, int j, int k)
121  {
122  data.template get<U>() = 0.5;
123  data.template get<V>() = 0.24;
124  }
125  );
126 
127  grid.template flush<smax_<U>,smax_<V>>(flush_type::FLUSH_ON_DEVICE);
128 
130 }
131 
132 
133 int main(int argc, char* argv[])
134 {
135  openfpm_init(&argc,&argv);
136 
137  // domain
138  Box<3,float> domain({0.0,0.0,0.0},{2.5,2.5,2.5});
139 
140  // grid size
141  size_t sz[3] = {256,256,256};
142 
143  // Define periodicity of the grid
144  periodicity<3> bc = {PERIODIC,PERIODIC,PERIODIC};
145 
146  // Ghost in grid unit
147  Ghost<3,long int> g(1);
148 
149  // deltaT
150  float deltaT = 0.25;
151 
152  // Diffusion constant for specie U
153  float du = 2*1e-5;
154 
155  // Diffusion constant for specie V
156  float dv = 1*1e-5;
157 
158  // Number of timesteps
159 #ifdef TEST_RUN
160  size_t timeSteps = 300;
161 #else
162  size_t timeSteps = 15000;
163 #endif
164 
165  // K and F (Physical constant in the equation)
166  float K = 0.053;
167  float F = 0.014;
168 
169  sgrid_dist_id_gpu<3, float, aggregate<float,float,float,float>> grid(sz,domain,g,bc);
170 
171  // spacing of the grid on x and y
172  float spacing[3] = {grid.spacing(0),grid.spacing(1),grid.spacing(2)};
173 
174  init(grid,domain);
175 
176  // sync the ghost
177  grid.template ghost_get<U,V>(RUN_ON_DEVICE);
178 
179  // because we assume that spacing[x] == spacing[y] we use formula 2
180  // and we calculate the prefactor of Eq 2
181  float uFactor = deltaT * du/(spacing[x]*spacing[x]);
182  float vFactor = deltaT * dv/(spacing[x]*spacing[x]);
183 
184  auto & v_cl = create_vcluster();
185 
186  timer tot_sim;
187  tot_sim.start();
188 
189  for (size_t i = 0; i < timeSteps ; ++i)
190  {
191  if (v_cl.rank() == 0)
192  {std::cout << "STEP: " << i << std::endl;}
193 /* if (i % 300 == 0)
194  {
195  std::cout << "STEP: " << i << std::endl;
196  grid.write_frame("out",i,VTK_WRITER);
197  }*/
198 
200 
201  typedef typename GetCpBlockType<decltype(grid),0,1>::type CpBlockType;
202 
204 
205  auto func = [uFactor,vFactor,deltaT,F,K] __device__ (float & u_out, float & v_out,
206  CpBlockType & u, CpBlockType & v,
207  int i, int j, int k){
208 
209  float uc = u(i,j,k);
210  float vc = v(i,j,k);
211 
212  u_out = uc + uFactor *(u(i-1,j,k) + u(i+1,j,k) +
213  u(i,j-1,k) + u(i,j+1,k) +
214  u(i,j,k-1) + u(i,j,k+1) - 6.0*uc) - deltaT * uc*vc*vc
215  - deltaT * F * (uc - 1.0);
216 
217 
218  v_out = vc + vFactor *(v(i-1,j,k) + v(i+1,j,k) +
219  v(i,j+1,k) + v(i,j-1,k) +
220  v(i,j,k-1) + v(i,j,k+1) - 6.0*vc) + deltaT * uc*vc*vc
221  - deltaT * (F+K) * vc;
222  };
223 
225 
227 
228  if (i % 2 == 0)
229  {
230  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);
231 
232  // After copy we synchronize again the ghost part U and V
233 
234  grid.ghost_get<U_next,V_next>(RUN_ON_DEVICE | SKIP_LABELLING);
235  }
236  else
237  {
238  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);
239 
240  // After copy we synchronize again the ghost part U and V
241  grid.ghost_get<U,V>(RUN_ON_DEVICE | SKIP_LABELLING);
242  }
243 
245 
246  // Every 500 time step we output the configuration for
247  // visualization
248 // if (i % 500 == 0)
249 // {
250 // grid.save("output_" + std::to_string(count));
251 // count++;
252 // }
253  }
254 
255  tot_sim.stop();
256  std::cout << "Total simulation: " << tot_sim.getwct() << std::endl;
257 
258  grid.deviceToHost<U,V,U_next,V_next>();
259  grid.write("final");
260 
262 
274 
276  openfpm_finalize();
277 
279 
288 }
289 
290 #else
291 
292 int main(int argc, char* argv[])
293 {
294  return 0;
295 }
296 
297 #endif
298 
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
double getwct()
Return the elapsed real time.
Definition: timer.hpp:130
Definition: Ghost.hpp:39
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
void start()
Start the timer.
Definition: timer.hpp:90
get the type of the block
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
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]