25
25
26
26
#include < cmath>
27
27
#include < fstream>
28
+ #include < iomanip>
28
29
#include < vector>
29
30
30
31
#include " Config.hpp"
34
35
#ifndef HAS_CXX11
35
36
#include < boost/foreach.hpp>
36
37
#endif
37
- // Boost.Odeint includes
38
- #include < boost/numeric/odeint.hpp>
39
38
40
39
#include " utils/MathUtils.hpp"
41
- #include " utils/RungeKutta4.hpp"
40
+ #include " utils/RungeKutta.hpp"
41
+ #include " utils/SplineFunction.hpp"
42
42
43
43
/* ! \file InterfacesImpl.hpp */
44
44
45
45
namespace pcm {
46
46
namespace green {
47
47
namespace detail {
48
+ /* ! \brief Abstract class for an system of ordinary differential equations
49
+ * \tparam Order The order of the ordinary differential equation
50
+ * \author Roberto Di Remigio
51
+ * \date 2018
52
+ */
53
+ template <size_t Order = 1 > class ODESystem {
54
+ public:
55
+ typedef pcm::array<double , Order> StateType;
56
+ size_t ODEorder () const { return Order; }
57
+ void operator ()(const StateType & f, StateType & dfdx, const double t) const {
58
+ RHS (f, dfdx, t);
59
+ }
60
+ virtual ~ODESystem () {}
61
+
62
+ private:
63
+ virtual void RHS (const StateType & f, StateType & dfdx, const double t) const = 0;
64
+ };
48
65
49
66
/* ! \typedef ProfileEvaluator
50
67
* \brief sort of a function pointer to the dielectric profile evaluation function
51
68
*/
52
69
typedef pcm::function<pcm::tuple<double , double >(const double )> ProfileEvaluator;
53
70
54
- /* ! \struct IntegratorParameters
55
- * \brief holds parameters for the integrator
56
- */
57
- struct IntegratorParameters {
58
- /* ! Lower bound of the integration interval */
59
- double r_0_;
60
- /* ! Upper bound of the integration interval */
61
- double r_infinity_;
62
- /* ! Time step between observer calls */
63
- double observer_step_;
64
- IntegratorParameters (double r0, double rinf, double step)
65
- : r_0_(r0), r_infinity_(rinf), observer_step_(step) {}
66
- };
67
-
68
71
/* ! \class LnTransformedRadial
69
72
* \brief system of ln-transformed first-order radial differential equations
70
73
* \author Roberto Di Remigio
@@ -73,25 +76,25 @@ struct IntegratorParameters {
73
76
* Provides a handle to the system of differential equations for the integrator.
74
77
* The dielectric profile comes in as a boost::function object.
75
78
*/
76
- class LnTransformedRadial __final : public pcm::utils ::detail::ODESystem<2 > {
79
+ class LnTransformedRadial __final : public pcm::green ::detail::ODESystem<2 > {
77
80
public:
78
81
/* ! Type of the state vector of the ODE */
79
- typedef pcm::utils ::detail::ODESystem<2 >::StateType StateType;
82
+ typedef pcm::green ::detail::ODESystem<2 >::StateType StateType;
80
83
/* ! Constructor from profile evaluator and angular momentum */
81
84
LnTransformedRadial (const ProfileEvaluator & e, int lval) : eval_(e), l_(lval) {}
82
85
83
86
private:
84
87
/* ! Dielectric profile function and derivative evaluation */
85
- ProfileEvaluator eval_;
88
+ const ProfileEvaluator eval_;
86
89
/* ! Angular momentum */
87
- int l_;
88
- /* ! Provides a functor for the evaluation of the system
89
- * of first-order ODEs needed by Boost.Odeint
90
- * The second-order ODE and the system of first-order ODEs
91
- * are reported in the manuscript.
90
+ const int l_;
91
+ /* ! \brief Provides a functor for the evaluation of the system of first-order ODEs.
92
92
* \param[in] rho state vector holding the function and its first derivative
93
93
* \param[out] drhodr state vector holding the first and second derivative
94
94
* \param[in] y logarithmic position on the integration grid
95
+ *
96
+ * The second-order ODE and the system of first-order ODEs
97
+ * are reported in the manuscript.
95
98
*/
96
99
virtual void RHS (const StateType & rho, StateType & drhodr, const double y) const {
97
100
// Evaluate the dielectric profile
@@ -107,7 +110,6 @@ class LnTransformedRadial __final : public pcm::utils::detail::ODESystem<2> {
107
110
};
108
111
} // namespace detail
109
112
110
- using detail::IntegratorParameters;
111
113
using detail::ProfileEvaluator;
112
114
113
115
/* ! \class RadialFunction
@@ -138,21 +140,25 @@ template <typename ODE> class RadialFunction __final {
138
140
RadialFunction (int l,
139
141
double ymin,
140
142
double ymax,
141
- const ProfileEvaluator & eval ,
142
- const IntegratorParameters & parms )
143
+ double ystep ,
144
+ const ProfileEvaluator & eval )
143
145
: L_(l),
144
146
y_min_ (ymin),
145
147
y_max_(ymax),
146
148
y_sign_(pcm::utils::sign(y_max_ - y_min_)) {
147
- compute (eval, parms );
149
+ compute (ystep, eval );
148
150
}
149
151
pcm::tuple<double , double > operator ()(double point) const {
150
152
return pcm::make_tuple (function_impl (point), derivative_impl (point));
151
153
}
152
154
friend std::ostream & operator <<(std::ostream & os, RadialFunction & obj) {
153
155
for (size_t i = 0 ; i < obj.function_ [0 ].size (); ++i) {
154
- os << obj.function_ [0 ][i] << " " << obj.function_ [1 ][i] << " "
156
+ // clang-format off
157
+ os << std::fixed << std::left << std::setprecision (14 )
158
+ << obj.function_ [0 ][i] << " "
159
+ << obj.function_ [1 ][i] << " "
155
160
<< obj.function_ [2 ][i] << std::endl;
161
+ // clang-format on
156
162
}
157
163
return os;
158
164
}
@@ -176,36 +182,36 @@ template <typename ODE> class RadialFunction __final {
176
182
function_[2 ].push_back (x[1 ]);
177
183
}
178
184
/* ! \brief Calculates radial solution
179
- * \param[in] eval dielectric profile evaluator function object
180
- * \param[in] parms parameters for the integrator
185
+ * \param[in] step ODE integrator step
186
+ * \param[in] eval dielectric profile evaluator function object
187
+ * \return the number of integration steps
181
188
*
182
- * This function discriminates between the first, i.e. the one with r^l
183
- * behavior, and the second radial solution, i.e. the one with r^(-l-1)
184
- * behavior, based on the sign of the integration interval y_sign_.
189
+ * This function discriminates between the first (zeta-type), i.e. the one
190
+ * with r^l behavior, and the second (omega-type) radial solution, i.e. the
191
+ * one with r^(-l-1) behavior, based on the sign of the integration interval
192
+ * y_sign_.
185
193
*/
186
- void compute (const ProfileEvaluator & eval, const IntegratorParameters & parms) {
187
- namespace odeint = boost::numeric::odeint;
188
- odeint::runge_kutta4<StateType> stepper;
189
-
194
+ size_t compute (const double step, const ProfileEvaluator & eval) {
190
195
ODE system (eval, L_);
191
- // Holds the initial conditions
192
- StateType init;
193
196
// Set initial conditions
197
+ StateType init;
194
198
if (y_sign_ > 0.0 ) { // zeta-type solution
195
199
init[0 ] = y_sign_ * L_ * y_min_;
196
200
init[1 ] = y_sign_ * L_;
197
201
} else { // omega-type solution
198
202
init[0 ] = y_sign_ * (L_ + 1 ) * y_min_;
199
203
init[1 ] = y_sign_ * (L_ + 1 );
200
204
}
201
- odeint::integrate_const (
205
+ pcm::utils::RungeKutta4<StateType> stepper;
206
+ size_t nSteps = pcm::utils::integrate_const (
202
207
stepper,
203
208
system ,
204
209
init,
205
210
y_min_,
206
211
y_max_,
207
- y_sign_ * parms. observer_step_ ,
212
+ y_sign_ * step ,
208
213
pcm::bind (&RadialFunction<ODE>::push_back, this , pcm::_1, pcm::_2));
214
+
209
215
// clang-format off
210
216
// Reverse order of function_ if omega-type solution was computed
211
217
// this ensures that they are in ascending order, as later expected by
@@ -218,9 +224,10 @@ template <typename ODE> class RadialFunction __final {
218
224
#endif /* HAS_CXX11 */
219
225
std::reverse (comp.begin (), comp.end ());
220
226
}
221
- }
227
+ // clang-format on
222
228
}
223
- // clang-format on
229
+ return nSteps;
230
+ }
224
231
/* ! \brief Returns value of function at given point
225
232
* \param[in] point evaluation point
226
233
*
0 commit comments