/** * \copyright * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/project/license * */ #ifndef MATHLIB_ODE_CONCRETEODESOLVER_H #define MATHLIB_ODE_CONCRETEODESOLVER_H #include #include "FunctionHandles.h" #include "ODESolver.h" namespace BaseLib { class ConfigTree; } namespace MathLib { namespace ODE { template std::unique_ptr> createODESolver( BaseLib::ConfigTree const& config); //! \addtogroup ExternalODESolverInterface //! @{ /*! ODE solver with a bounds-safe interface using a concrete implementation. * * This class makes contact between the abstract \c ODESolver interface and a * certain solver \c Implementation. * * The interface of this class inherits the array bounds checking from \c * ODESolver. * Its methods forward calls to the \c Implementation erasing array bounds info * by passing \c std::array and Eigen::Matrix arguments as raw pointers. * * Thus the \c Implementation does not need template to be templated * which makes it possible for \c Implementation to use the pimpl idiom whereby * the headers of external libraries only have to be included in the final cpp * file. Thereby our namespaces do not get polluted with symbols from external * libraries. * * \tparam NumEquations the number of equations in the ODE system. * \tparam Implementation a concrete ODE solver implementation used as a * backend. */ template class ConcreteODESolver final : public ODESolver, private Implementation { public: void setFunction(Function f, JacobianFunction df) override { Implementation::setFunction( std::unique_ptr>{ new detail::FunctionHandlesImpl{f, df}}); } void setTolerance(const std::array& abstol, const double reltol) override { Implementation::setTolerance(abstol.data(), reltol); } void setTolerance(const double abstol, const double reltol) override { Implementation::setTolerance(abstol, reltol); } void setIC(const double t0, std::initializer_list const& y0) override { assert(y0.size() == NumEquations); Implementation::setIC(t0, y0.begin()); } void setIC(const double t0, Eigen::Matrix const& y0) override { Implementation::setIC(t0, y0.data()); } void preSolve() override { Implementation::preSolve(); } bool solve(const double t) override { return Implementation::solve(t); } MappedConstVector getSolution() const override { return MappedConstVector{Implementation::getSolution()}; } double getTime() const override { return Implementation::getTime(); } Eigen::Matrix getYDot( const double t, const MappedConstVector& y) const override { Eigen::Matrix y_dot; Implementation::getYDot(t, y.data(), y_dot.data()); return y_dot; } private: //! Instances of this class shall only be constructed by createODESolver(). ConcreteODESolver(BaseLib::ConfigTree const& config) : Implementation{config, NumEquations} { } friend std::unique_ptr> createODESolver(BaseLib::ConfigTree const& config); }; //! @} } // namespace ODE } // namespace MathLib #endif // MATHLIB_ODE_CONCRETEODESOLVER_H