2525
2626#include < cmath>
2727#include < fstream>
28+ #include < iomanip>
2829#include < vector>
2930
3031#include " Config.hpp"
3435#ifndef HAS_CXX11
3536#include < boost/foreach.hpp>
3637#endif
37- // Boost.Odeint includes
38- #include < boost/numeric/odeint.hpp>
3938
4039#include " utils/MathUtils.hpp"
41- #include " utils/RungeKutta4.hpp"
40+ #include " utils/RungeKutta.hpp"
41+ #include " utils/SplineFunction.hpp"
4242
4343/* ! \file InterfacesImpl.hpp */
4444
4545namespace pcm {
4646namespace green {
4747namespace 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+ };
4865
4966/* ! \typedef ProfileEvaluator
5067 * \brief sort of a function pointer to the dielectric profile evaluation function
5168 */
5269typedef pcm::function<pcm::tuple<double , double >(const double )> ProfileEvaluator;
5370
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-
6871/* ! \class LnTransformedRadial
6972 * \brief system of ln-transformed first-order radial differential equations
7073 * \author Roberto Di Remigio
@@ -73,25 +76,25 @@ struct IntegratorParameters {
7376 * Provides a handle to the system of differential equations for the integrator.
7477 * The dielectric profile comes in as a boost::function object.
7578 */
76- class LnTransformedRadial __final : public pcm::utils ::detail::ODESystem<2 > {
79+ class LnTransformedRadial __final : public pcm::green ::detail::ODESystem<2 > {
7780public:
7881 /* ! 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;
8083 /* ! Constructor from profile evaluator and angular momentum */
8184 LnTransformedRadial (const ProfileEvaluator & e, int lval) : eval_(e), l_(lval) {}
8285
8386private:
8487 /* ! Dielectric profile function and derivative evaluation */
85- ProfileEvaluator eval_;
88+ const ProfileEvaluator eval_;
8689 /* ! 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.
9292 * \param[in] rho state vector holding the function and its first derivative
9393 * \param[out] drhodr state vector holding the first and second derivative
9494 * \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.
9598 */
9699 virtual void RHS (const StateType & rho, StateType & drhodr, const double y) const {
97100 // Evaluate the dielectric profile
@@ -107,7 +110,6 @@ class LnTransformedRadial __final : public pcm::utils::detail::ODESystem<2> {
107110};
108111} // namespace detail
109112
110- using detail::IntegratorParameters;
111113using detail::ProfileEvaluator;
112114
113115/* ! \class RadialFunction
@@ -138,21 +140,25 @@ template <typename ODE> class RadialFunction __final {
138140 RadialFunction (int l,
139141 double ymin,
140142 double ymax,
141- const ProfileEvaluator & eval ,
142- const IntegratorParameters & parms )
143+ double ystep ,
144+ const ProfileEvaluator & eval )
143145 : L_(l),
144146 y_min_ (ymin),
145147 y_max_(ymax),
146148 y_sign_(pcm::utils::sign(y_max_ - y_min_)) {
147- compute (eval, parms );
149+ compute (ystep, eval );
148150 }
149151 pcm::tuple<double , double > operator ()(double point) const {
150152 return pcm::make_tuple (function_impl (point), derivative_impl (point));
151153 }
152154 friend std::ostream & operator <<(std::ostream & os, RadialFunction & obj) {
153155 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] << " "
155160 << obj.function_ [2 ][i] << std::endl;
161+ // clang-format on
156162 }
157163 return os;
158164 }
@@ -176,36 +182,36 @@ template <typename ODE> class RadialFunction __final {
176182 function_[2 ].push_back (x[1 ]);
177183 }
178184 /* ! \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
181188 *
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_.
185193 */
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) {
190195 ODE system (eval, L_);
191- // Holds the initial conditions
192- StateType init;
193196 // Set initial conditions
197+ StateType init;
194198 if (y_sign_ > 0.0 ) { // zeta-type solution
195199 init[0 ] = y_sign_ * L_ * y_min_;
196200 init[1 ] = y_sign_ * L_;
197201 } else { // omega-type solution
198202 init[0 ] = y_sign_ * (L_ + 1 ) * y_min_;
199203 init[1 ] = y_sign_ * (L_ + 1 );
200204 }
201- odeint::integrate_const (
205+ pcm::utils::RungeKutta4<StateType> stepper;
206+ size_t nSteps = pcm::utils::integrate_const (
202207 stepper,
203208 system,
204209 init,
205210 y_min_,
206211 y_max_,
207- y_sign_ * parms. observer_step_ ,
212+ y_sign_ * step ,
208213 pcm::bind (&RadialFunction<ODE>::push_back, this , pcm::_1, pcm::_2));
214+
209215 // clang-format off
210216 // Reverse order of function_ if omega-type solution was computed
211217 // this ensures that they are in ascending order, as later expected by
@@ -218,9 +224,10 @@ template <typename ODE> class RadialFunction __final {
218224#endif /* HAS_CXX11 */
219225 std::reverse (comp.begin (), comp.end ());
220226 }
221- }
227+ // clang-format on
222228 }
223- // clang-format on
229+ return nSteps;
230+ }
224231 /* ! \brief Returns value of function at given point
225232 * \param[in] point evaluation point
226233 *
0 commit comments