3 #include "Vector/vector_dist.hpp"
6 #include "Operators/Vector/vector_dist_operators.hpp"
7 #include "Vector/vector_dist_subset.hpp"
8 #include "Decomposition/Distribution/SpaceDistribution.hpp"
9 #include "OdeIntegrators/OdeIntegrators.hpp"
13 double t=-5.0, tf=5.0, dt = 0.01;
18 dxdt.data.get<0>() = x.data.get<0>();
24 dxdt.data.get<0>() = x.data.get<0>() * (1- (1/(1+exp(-t))) );
28 template <
typename stepper_type>
31 std::vector<double> &runtime_v,std::vector<double> &norm_inf_v, std::vector<double> &norm_l2_v) {
33 auto Init = getV<0>(Particles);
34 auto Sol = getV<1>(Particles);
35 auto OdeSol = getV<2>(Particles);
38 x0.data.get<0>() = Init;
40 timer timer_integrate;
41 timer_integrate.
start();
42 boost::numeric::odeint::integrate_const(stepper_type(), derivative, x0, t, tf, dt);
43 timer_integrate.
stop();
46 OdeSol = x0.data.get<0>();
48 double norm_inf = 0.0;
51 auto it2 = Particles.getDomainIterator();
52 while (it2.isNext()) {
55 double diff = Particles.getProp<1>(p) - Particles.getProp<2>(p);
57 if (fabs(diff) > norm_inf) {
58 norm_inf = fabs(diff);
61 norm_l2 += diff * diff;
64 norm_l2 = sqrt(norm_l2);
65 double rt=timer_integrate.
getwct();
66 auto &v_cl=create_vcluster();
70 runtime_v.push_back(rt);
71 norm_inf_v.push_back(norm_inf);
72 norm_l2_v.push_back(norm_l2);
80 template <
typename stepper_type>
83 std::vector<double> &runtime_v,std::vector<double> &norm_inf_v, std::vector<double> &norm_l2_v) {
85 auto Init = getV<0>(Particles);
86 auto Sol = getV<1>(Particles);
87 auto OdeSol = getV<2>(Particles);
90 x0.data.get<0>() = Init;
92 timer timer_integrate;
93 timer_integrate.
start();
94 boost::numeric::odeint::integrate_adaptive( stepper_type() , derivative , x0 , t , tf , dt);
95 timer_integrate.
stop();
98 OdeSol = x0.data.get<0>();
100 double norm_inf = 0.0;
101 double norm_l2 = 0.0;
103 auto it2 = Particles.getDomainIterator();
104 while (it2.isNext()) {
107 double diff = Particles.getProp<1>(p) - Particles.getProp<2>(p);
109 if (fabs(diff) > norm_inf) {
110 norm_inf = fabs(diff);
113 norm_l2 += diff * diff;
116 norm_l2 = sqrt(norm_l2);
118 double rt=timer_integrate.
getwct();
119 auto &v_cl=create_vcluster();
123 runtime_v.push_back(rt);
124 norm_inf_v.push_back(norm_inf);
125 norm_l2_v.push_back(norm_l2);
133 double average(std::vector<double> &nums) {
134 return std::accumulate(nums.begin(), nums.end(), 0.0) /
static_cast<double>(nums.size());
137 int main(
int argc,
char* argv[])
141 openfpm_init(&argc,&argv);
147 std::vector<double> runtime_rk4_const;
148 std::vector<double> runtime_rk5_const;
149 std::vector<double> runtime_rk78_const;
150 std::vector<double> runtime_rk5_adapt;
152 std::vector<double> norm_inf_rk4_const;
153 std::vector<double> norm_inf_rk5_const;
154 std::vector<double> norm_inf_rk78_const;
155 std::vector<double> norm_inf_rk5_adapt;
157 std::vector<double> norm_l2_rk4_const;
158 std::vector<double> norm_l2_rk5_const;
159 std::vector<double> norm_l2_rk78_const;
160 std::vector<double> norm_l2_rk5_adapt;
162 size_t edgeSemiSize = std::stof(argv[1]);
163 const size_t sz[2] = {edgeSemiSize,edgeSemiSize };
165 size_t bc[2] = { NON_PERIODIC, NON_PERIODIC };
167 spacing[0] = 1.0 / (sz[0] - 1);
168 spacing[1] = 1.0 / (sz[1] - 1);
169 double rCut = 3.9 * spacing[0];
175 auto it = Particles.getGridIterator(sz);
176 while (it.isNext()) {
179 mem_id k0 = key.get(0);
180 double xp0 = k0 * spacing[0];
181 Particles.getLastPos()[0] = xp0;
182 mem_id k1 = key.get(1);
183 double yp0 = k1 * spacing[1];
184 Particles.getLastPos()[1] = yp0;
189 Particles.getLastProp<0>() = xp0 * yp0 * exp(t);
190 Particles.getLastProp<1>() = xp0 * yp0 * exp(tf);
195 auto Init = getV<0>(Particles);
196 auto Sol = getV<1>(Particles);
197 auto OdeSol = getV<2>(Particles);
201 typedef boost::numeric::odeint::runge_kutta4<state_type_1d_ofp, double, state_type_1d_ofp, double, boost::numeric::odeint::vector_space_algebra_ofp> rk4_stepper_type;
202 typedef boost::numeric::odeint::runge_kutta_dopri5<state_type_1d_ofp, double, state_type_1d_ofp, double, boost::numeric::odeint::vector_space_algebra_ofp> dopri5_stepper_type;
203 typedef boost::numeric::odeint::runge_kutta_fehlberg78<state_type_1d_ofp, double, state_type_1d_ofp, double, boost::numeric::odeint::vector_space_algebra_ofp> fehlberg78_stepper_type;
208 for (
int i = 0; i < 3; ++i) {
210 run_stepper_const<rk4_stepper_type>(Particles, &Exponential2, runtime_rk4_const, norm_inf_rk4_const, norm_l2_rk4_const);
211 run_stepper_const<dopri5_stepper_type>(Particles, &Exponential2, runtime_rk5_const, norm_inf_rk5_const, norm_l2_rk5_const);
212 run_stepper_const<fehlberg78_stepper_type>(Particles, &Exponential2, runtime_rk78_const, norm_inf_rk78_const, norm_l2_rk78_const);
213 run_stepper_adaptive<dopri5_stepper_type>(Particles, &Exponential2, runtime_rk5_adapt, norm_inf_rk5_adapt, norm_l2_rk5_adapt);
217 auto & vcl = create_vcluster();
219 if (vcl.getProcessUnitID() == 0) {
222 std::ofstream output_runtime;
223 std::ofstream output_inf_norm;
224 std::ofstream output_l2_norm;
228 std::string headline =
"cores,rk4,dopri5,fehlberg78,dopri5 adaptive";
229 if (access(
"runtime.csv", F_OK ) == -1) {
230 output_runtime.open(
"runtime.csv");
231 output_runtime << headline <<
"\n";
234 output_runtime.open(
"runtime.csv",std::ios::app);
237 if (access(
"inf_norm.csv", F_OK ) == -1) {
238 output_inf_norm.open(
"inf_norm.csv");
239 output_inf_norm << headline <<
"\n";
242 output_inf_norm.open(
"inf_norm.csv",std::ios::app);
245 if (access(
"l2_norm.csv", F_OK ) == -1) {
246 output_l2_norm.open(
"l2_norm.csv");
247 output_l2_norm << headline <<
"\n";
250 output_l2_norm.open(
"l2_norm.csv",std::ios::app);
253 output_runtime << vcl.getProcessingUnits()
254 <<
"," << average(runtime_rk4_const)
255 <<
"," << average(runtime_rk5_const)
256 <<
"," << average(runtime_rk78_const)
257 <<
"," << average(runtime_rk5_adapt)
260 output_inf_norm << vcl.getProcessingUnits()
261 <<
"," << average(norm_inf_rk4_const)
262 <<
"," << average(norm_inf_rk5_const)
263 <<
"," << average(norm_inf_rk78_const)
264 <<
"," << average(norm_inf_rk5_adapt)
267 output_l2_norm << vcl.getProcessingUnits()
268 <<
"," << average(norm_l2_rk4_const)
269 <<
"," << average(norm_l2_rk5_const)
270 <<
"," << average(norm_l2_rk78_const)
271 <<
"," << average(norm_l2_rk5_adapt)
This class represent an N-dimensional box.
Class for cpu time benchmarking.
void stop()
Stop the timer.
void start()
Start the timer.
double getwct()
Return the elapsed real time.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
A 1d Odeint and Openfpm compatible structure.