Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/DiffEq/DiffEq.hpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief Differential equation
9 : : \details This file defines a generic differential equation class. The class
10 : : uses runtime polymorphism without client-side inheritance: inheritance is
11 : : confined to the internals of the class, invisible to client-code. The class
12 : : exclusively deals with ownership enabling client-side value semantics.
13 : : Credit goes to Sean Parent at Adobe: https://github.com/sean-parent/
14 : : sean-parent.github.com/wiki/Papers-and-Presentations.
15 : : */
16 : : // *****************************************************************************
17 : : #ifndef DiffEq_h
18 : : #define DiffEq_h
19 : :
20 : : #include <string>
21 : : #include <functional>
22 : : #include <memory>
23 : :
24 : : #include "Types.hpp"
25 : : #include "Particles.hpp"
26 : : #include "Statistics.hpp"
27 : :
28 : : namespace walker {
29 : :
30 : : //! \brief Differential equation
31 : : //! \details This class uses runtime polymorphism without client-side
32 : : //! inheritance: inheritance is confined to the internals of the this class,
33 : : //! invisible to client-code. The class exclusively deals with ownership
34 : : //! enabling client-side value semantics. Credit goes to Sean Parent at Adobe:
35 : : //! https://github.com/sean-parent/sean-parent.github.com/wiki/
36 : : //! Papers-and-Presentations. For example client code that models a DiffEq,
37 : : //! see walker::Beta.
38 : 339 : class DiffEq {
39 : :
40 : : public:
41 : : //! Default constructor taking no arguments for Charm++
42 : : explicit DiffEq() = default;
43 : :
44 : : //! \brief Constructor taking an object modeling Concept.
45 : : //! \details The object of class T comes pre-constructed.
46 : : //! \param[in] x Instantiated object of type T given by the template
47 : : //! argument.
48 : : template< typename T > explicit DiffEq( T x ) :
49 : : self( std::make_unique< Model<T> >( std::move(x) ) ) {}
50 : :
51 : : //! \brief Constructor taking a function pointer to a constructor of an
52 : : //! object modeling Concept.
53 : : //! \details Passing std::function allows late execution of the constructor,
54 : : //! i.e., as late as inside this class' constructor, and thus usage from
55 : : //! a factory. Note that there are at least two different ways of using
56 : : //! this constructor:
57 : : //! - Bind T's constructor arguments and place it in std::function<T()>
58 : : //! and passing no arguments as args.... This case then instantiates the
59 : : //! model via its constructor and stores it in here.
60 : : //! - Bind a single placeholder argument to T's constructor and pass it in
61 : : //! as host's args..., which then forwards it to model's constructor. This
62 : : //! allows late binding, i.e., binding the argument only here.
63 : : //! \see See also the wrapper tk::recordModel() which does the former and
64 : : //! tk::recordModelLate() which does the latter, both defined in
65 : : //! src/Base/Factory.h.
66 : : //! \param[in] x Function pointer to a constructor of an object modeling
67 : : //! Concept.
68 : : //! \param[in] args Zero or more constructor arguments
69 : : template< typename T, typename...Args >
70 [ - + ]: 285 : explicit DiffEq( std::function<T(Args...)> x, Args&&... args ) :
71 : : self( std::make_unique< Model<T> >(
72 [ + - ][ - - ]: 285 : std::move( x( std::forward<Args>(args)... ) ) ) ) {}
73 : :
74 : : //! Public interface to setting the initial conditions for the diff eq
75 : : void initialize( int stream, tk::Particles& particles ) const
76 : 960 : { self->initialize( stream, particles ); }
77 : :
78 : : //! Public interface to advancing particles in time by the diff eq
79 : : void advance( tk::Particles& particles,
80 : : int stream,
81 : : tk::real dt,
82 : : tk::real t,
83 : : const std::map< tk::ctr::Product, tk::real >& moments ) const
84 : 4508509 : { self->advance( particles, stream, dt, t, moments ); }
85 : :
86 : : //! Copy assignment
87 : : DiffEq& operator=( const DiffEq& x )
88 : : { DiffEq tmp(x); *this = std::move(tmp); return *this; }
89 : : //! Copy constructor
90 : : DiffEq( const DiffEq& x ) : self( x.self->copy() ) {}
91 : : //! Move assignment
92 : : DiffEq& operator=( DiffEq&& ) noexcept = default;
93 : : //! Move constructor
94 [ - + ]: 54 : DiffEq( DiffEq&& ) noexcept = default;
95 : :
96 : : private:
97 : : //! \brief Concept is a pure virtual base class specifying the requirements
98 : : //! of polymorphic objects deriving from it
99 : : struct Concept {
100 : : Concept() = default;
101 : 0 : Concept( const Concept& ) = default;
102 : : virtual ~Concept() = default;
103 : : virtual Concept* copy() const = 0;
104 : : virtual void initialize( int, tk::Particles& ) = 0;
105 : : virtual void advance( tk::Particles&,
106 : : int,
107 : : tk::real,
108 : : tk::real,
109 : : const std::map< tk::ctr::Product, tk::real >& ) = 0;
110 : : };
111 : :
112 : : //! \brief Model models the Concept above by deriving from it and overriding
113 : : //! the virtual functions required by Concept
114 : : template< typename T >
115 [ - - ][ - - ]: 0 : struct Model : Concept {
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
116 [ - - ][ - - ]: 285 : explicit Model( T x ) : data( std::move(x) ) {}
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ + - ][ + - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
117 : 0 : Concept* copy() const override { return new Model( *this ); }
118 : 960 : void initialize( int stream, tk::Particles& particles )
119 : 960 : override { data.initialize( stream, particles ); }
120 : 4508509 : void advance( tk::Particles& particles,
121 : : int stream,
122 : : tk::real dt,
123 : : tk::real t,
124 : : const std::map< tk::ctr::Product, tk::real >& moments )
125 : 4508509 : override { data.advance( particles, stream, dt, t, moments ); }
126 : : T data;
127 : : };
128 : :
129 : : std::unique_ptr< Concept > self; //!< Base pointer used polymorphically
130 : : };
131 : :
132 : : } // walker::
133 : :
134 : : #endif // DiffEq_h
|