OpenFPM  5.2.0
Project that contain the implementation of distributed structures
rk4.cpp
1 
2 
4 #include <stddef.h>
5 #include "Vector/vector_dist.hpp"
6 #include <iostream>
7 #include <fstream>
8 #include "Operators/Vector/vector_dist_operators.hpp"
9 #include "Vector/vector_dist_subset.hpp"
10 #include "Decomposition/Distribution/SpaceDistribution.hpp"
11 #include "OdeIntegrators/OdeIntegrators.hpp"
13 
14 
15 
17 
18 void Exponential2( const state_type &x , state_type &dxdt , const double t )
19 {
20  dxdt = x;
21 }
22 
23 void sigmoid2( const state_type &x , state_type &dxdt , const double t )
24 {
25  // g'(t) = g(t) * (1-sigma)
26  dxdt = x * (1- (1/(1+exp(-t))) );
27 }
28 
29 int main(int argc, char* argv[])
30 {
31 
32 
33 
34  // initialize the library
35  openfpm_init(&argc,&argv);
36  auto &v_cl=create_vcluster();
37 
38 
39 
40  //std::cout << "RK4"<< std::endl;
41 
42  std::ofstream output_file;
43  output_file.open("rk4_error_results.csv",std::ios_base::app);
44 
45  size_t edgeSemiSize = std::stof(argv[1]);
46  const size_t sz[2] = {edgeSemiSize,edgeSemiSize };
47  Box<2, double> box({ 0, 0 }, { 1.0, 1.0 });
48  size_t bc[2] = { NON_PERIODIC, NON_PERIODIC };
49  double spacing[2];
50  spacing[0] = 1.0 / (sz[0] - 1);
51  spacing[1] = 1.0 / (sz[1] - 1);
52  double rCut = 3.9 * spacing[0];
53  Ghost<2, double> ghost(rCut);
54 
55  // integration time
56  // double t=0.0,tf=0.5;
57  double t=-5.0,tf=5.0;
58  double init_dt = 0.01;
59 
60  vector_dist<2, double, aggregate<double, double,double>> Particles(0, box, bc, ghost);
61 
62  // analytical solution
63  auto it = Particles.getGridIterator(sz);
64  while (it.isNext()) {
65  Particles.add();
66  auto key = it.get();
67  mem_id k0 = key.get(0);
68  double xp0 = k0 * spacing[0];
69  Particles.getLastPos()[0] = xp0;
70  mem_id k1 = key.get(1);
71  double yp0 = k1 * spacing[1];
72  Particles.getLastPos()[1] = yp0;
73 
74  // Particles.getLastProp<0>() = xp0*yp0*1/(1+exp(-t));
75  // Particles.getLastProp<1>() = xp0*yp0*1/(1+exp(-tf));
76 
77  Particles.getLastProp<0>() = xp0 * yp0 * exp(t);
78  Particles.getLastProp<1>() = xp0 * yp0 * exp(tf);
79  ++it;
80  }
81 
82  auto Init = getV<0>(Particles);
83  auto Sol = getV<1>(Particles);
84  auto OdeSol = getV<2>(Particles);
85 
86  state_type x0;
87 
88  // integrate for different numbers of time steps
89 
90  double dt = init_dt;
91 
92  //std::cout << std::endl;
93  //std::cout << "--- RK4 Solving for dt = " << dt << " ..." << std::endl;
94 
95  x0 = Init;
96 
97  size_t steps = 0;
98 
99 
100  timer timer_integrate;
101  timer_integrate.start();
102 
103  // steps = integrate_adaptive( dopri5_controlled_stepper_type() , Exponential2 , x0 , t , tf , init_dt);
104  // steps = boost::numeric::odeint::integrate_const(rk4_stepper_type(), sigmoid2, x0, t, tf, dt);
105 
106 
107  void (*derivative)(const state_type& , state_type& , const double);
108  derivative = &Exponential2;
109 
110  while (t < tf - dt) {
111  state_type k1;
112  state_type k2;
113  state_type k3;
114  state_type k4;
115 
116  derivative(x0, k1, t);
117 
118  derivative(x0 + 0.5 * dt * k1, k2, t + 0.5 * dt);
119 
120  derivative(x0 + 0.5 * dt * k2, k3, t + 0.5 * dt);
121 
122  derivative(x0 + dt * k3, k4, t + dt);
123 
124  x0 = x0 + dt / 6.0 * (k1 + 2 * k2 + 2 * k3 + k4);
125 
126  t += dt;
127  steps++;
128  }
129 
130  timer_integrate.stop();
131 
132  OdeSol = x0;
133 
134  double norm_inf = 0.0;
135  double norm_l2 = 0.0;
136 
137  auto it2 = Particles.getDomainIterator();
138  while (it2.isNext()) {
139  auto p = it2.get();
140  // calculate error
141  double diff = Particles.getProp<1>(p) - Particles.getProp<2>(p);
142  // calculate infinity norm
143  if (fabs(diff) > norm_inf) {
144  norm_inf = fabs(diff);
145  }
146  // calculate L2 norm
147  norm_l2 += diff * diff;
148  ++it2;
149  }
150 
151  norm_l2 = sqrt(norm_l2);
152 
153  auto & vcl = create_vcluster();
154  if (vcl.getProcessUnitID() == 0)
155  {
156  std::cout << "Steps: " << steps << std::endl;
157  std::cout << "Time: " << timer_integrate.getwct() << std::endl;
158  std::cout << "Norm inf: " << norm_inf << std::endl;
159  std::cout << "Norm L2: " << norm_l2 << std::endl;
160  }
161  double tt=timer_integrate.getwct();
162  v_cl.sum(tt);
163  v_cl.execute();
164 
165  if(v_cl.rank()==0)
166  {output_file << steps <<","<<v_cl.size()<<"," << tt/v_cl.size() << "," << norm_inf << "," << norm_l2 << "\n";}
167  // Particles.write("particles_dt=" + boost::lexical_cast<std::string>(dt));
168  output_file.close();
169 
170 
171  openfpm_finalize();
172 
173 }
This class represent an N-dimensional box.
Definition: Box.hpp:60
Definition: Ghost.hpp:40
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
Main class that encapsulate a vector properties operand to be used for expressions construction.
Distributed vector.