44 #include "Operators/Vector/vector_dist_operators.hpp"
45 #include "Vector/vector_dist_subset.hpp"
46 #include "DCPSE/DCPSE_op/DCPSE_op.hpp"
47 #include "OdeIntegrators/OdeIntegrators.hpp"
77 double dt=1e-2,tf=1.0,vf=1.0;
79 void *PointerDistGlobal, *PointerDistSubset,*PointerDistSubset2;
115 template<
typename DXX,
typename DYY>
122 RHSFunctor(DXX &Dxx,DYY &Dyy):Dxx(Dxx),Dyy(Dyy)
132 auto C = getV<0>(Particles);
133 auto C_bulk = getV<0>(Particles_bulk);
134 auto dC = getV<2>(Particles);
135 auto dC_bulk = getV<2>(Particles_bulk);
142 C_bulk[x]=X.data.get<0>();
143 C_bulk[y]=X.data.get<1>();
147 dC_bulk[x] = 0.1*(Dxx(C[x])+Dyy(C[x]));
148 dC_bulk[y] = 0.1*(Dxx(C[y])+Dyy(C[y]));
151 dxdt.data.get<0>()=dC[x];
152 dxdt.data.get<1>()=dC[y];
186 template<
typename DXX,
typename DYY,
typename VerletList_type>
191 VerletList_type &verletList;
197 ObserverFunctor(DXX &Dxx, DYY &Dyy, VerletList_type& verletList,
double rCut) : Dxx(Dxx), Dyy(Dyy), verletList(verletList), rCut(rCut) {
211 auto Pos = getV<POS_PROP>(Particles);
212 auto Concentration = getV<0>(Particles);
213 auto Velocity = getV<1>(Particles);
214 auto Concentration_bulk = getV<0>(Particles_bulk);
215 auto Velocity_bulk = getV<1>(Particles_bulk);
220 Concentration_bulk[x] = X.data.get<0>();
221 Concentration_bulk[y] = X.data.get<1>();
223 Velocity_bulk[x] = -vf*Pos[y] * exp(-10.0 * (Pos[x] * Pos[x] + Pos[y] * Pos[y]));
224 Velocity_bulk[y] = vf*Pos[x] * exp(-10.0 * (Pos[x] * Pos[x] + Pos[y] * Pos[y]));
225 Pos = Pos + dt * Velocity;
231 Particles_boundary.
update();
233 Dxx.update(Particles);
234 Dyy.update(Particles);
237 X.data.get<0>() = Concentration[x];
238 X.data.get<1>() = Concentration[y];
243 std::cout<<
"Taking a step at t="<<t<<
" with dt="<<t-t_old<<std::endl;
247 Particles.write_frame(
"PDE_sol", ctr);
265 int main(
int argc,
char *argv[])
268 openfpm_init(&argc, &argv);
270 dt=std::atof(argv[1]);
271 tf=std::atof(argv[2]);
272 vf=std::atof(argv[3]);
288 const size_t sz[2] = {41, 41};
290 size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};
292 spacing[0] = 2.0 / (sz[0] - 1);
293 spacing[1] = 2.0 / (sz[1] - 1);
294 double rCut = 3.1 * spacing[0];
298 Particles.setPropNames({
"Concentration",
"Velocity",
"TempConcentration"});
300 auto it = Particles.getGridIterator(sz);
301 while (it.isNext()) {
304 double x = -1.0 + key.get(0) * spacing[0];
305 Particles.getLastPos()[0] = x;
306 double y = -1.0 + key.get(1) * spacing[1];
307 Particles.getLastPos()[1] = y;
309 if (x != -1.0 && x != 1.0 && y != -1.0 && y != 1) {
310 Particles.getLastSubset(0);
312 Particles.getLastSubset(1);
315 if (x == 0.0 && y > -0.5 && y < 0) {
316 Particles.template getLastProp<0>()[0] = 1.0;
317 Particles.template getLastProp<0>()[1] = 0.0;
318 }
else if (x == 0.0 && y > 0 && y < 0.5) {
319 Particles.template getLastProp<0>()[0] = 0.0;
320 Particles.template getLastProp<0>()[1] = 1.0;
322 Particles.template getLastProp<0>()[0] = 0.0;
323 Particles.template getLastProp<0>()[1] = 0.0;
328 Particles.ghost_get<0>();
331 Particles.write(
"Init");
352 PointerDistGlobal = (
void *) &Particles;
353 PointerDistSubset = (
void *) &Particles_bulk;
354 PointerDistSubset2 = (
void *) &Particles_boundary;
369 auto verletList = Particles.template getVerlet<VL_NON_SYMMETRIC|VL_SKIP_REF_PART>(rCut);
371 Derivative_xx<decltype(verletList)> Dxx(Particles, verletList, 2, rCut);
372 Derivative_yy<decltype(verletList)> Dyy(Particles, verletList, 2, rCut);
374 auto Pos = getV<POS_PROP>(Particles);
375 auto C = getV<0>(Particles);
376 auto V = getV<1>(Particles);
377 auto dC = getV<2>(Particles);
380 auto C_bulk = getV<0>(Particles_bulk);
381 auto dC_bulk = getV<2>(Particles_bulk);
401 boost::numeric::odeint::runge_kutta4<state_type_2d_ofp, double, state_type_2d_ofp, double, boost::numeric::odeint::vector_space_algebra_ofp> Odeint_rk4;
404 RHSFunctor<Derivative_xx<decltype(verletList)>, Derivative_yy<decltype(verletList)>> System(Dxx, Dyy);
407 ObserverFunctor<Derivative_xx<decltype(verletList)>, Derivative_yy<decltype(verletList)>, decltype(verletList)> ObserveAndUpdate(Dxx, Dyy, verletList, rCut);
413 X.data.get<x>() = C[0];
414 X.data.get<y>() = C[1];
438 std::vector<double> inter_times;
440 size_t steps = boost::numeric::odeint::integrate_const(Odeint_rk4, System, X, 0.0, tf, dt, ObserveAndUpdate);
454 std::cout <<
"No. of Time steps taken: " << steps << std::endl;
456 C_bulk[x] = X.data.get<0>();
457 C_bulk[y] = X.data.get<1>();
459 Dxx.deallocate(Particles);
460 Dyy.deallocate(Particles);
This class represent an N-dimensional box.
This class implement the point shape in an N-dimensional space.
void update()
Update the subset indexes.
void updateVerlet(VerletList< dim, St, opt, Mem_type, shift< dim, St > > &verletList, St r_cut)
for each particle get the verlet list
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
void deleteGhost()
Delete the particles on the ghost.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
A 2d Odeint and Openfpm compatible structure.