Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/PDE/PDEStack.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 Stack of differential equations
9 : : \details This file declares class PDEStack, which implements various
10 : : functionality related to registering and instantiating partial differential
11 : : equation types. Registration and instantiation use a partial differential
12 : : equation factory, which is a std::map (an associative container),
13 : : associating unique partial differential equation keys to their constructor
14 : : calls. For more details, see the in-code documentation of the constructor.
15 : : */
16 : : // *****************************************************************************
17 : : #ifndef PDEStack_h
18 : : #define PDEStack_h
19 : :
20 : : #include <map>
21 : : #include <set>
22 : : #include <string>
23 : : #include <vector>
24 : :
25 : : #include "NoWarning/back.hpp"
26 : : #include "NoWarning/front.hpp"
27 : :
28 : : #include "Tags.hpp"
29 : : #include "Exception.hpp"
30 : : #include "Factory.hpp"
31 : : #include "CGPDE.hpp"
32 : : #include "DGPDE.hpp"
33 : : #include "PDEFactory.hpp"
34 : : #include "SystemComponents.hpp"
35 : : #include "Inciter/InputDeck/InputDeck.hpp"
36 : :
37 : : namespace inciter {
38 : :
39 : : extern ctr::InputDeck g_inputdeck;
40 : :
41 : : //! \brief Partial differential equations stack
42 : : class PDEStack {
43 : :
44 : : private:
45 : : using ncomp_t = tk::ctr::ncomp_t;
46 : :
47 : : public:
48 : : //! Constructor: register partial differential equations into factory
49 : : explicit PDEStack();
50 : :
51 : : //! Instantiate selected PDEs using continuous Galerkin discretization
52 : : std::vector< CGPDE > selectedCG() const;
53 : :
54 : : //! Instantiate selected PDEs using discontinuous Galerkin discretization
55 : : std::vector< DGPDE > selectedDG() const;
56 : :
57 : : //! Constant accessor to CGPDE factory
58 : : //! \return Constant reference to the CGPDE factory
59 : : const CGFactory& cgfactory() const { return m_cgfactory; }
60 : :
61 : : //! Constant accessor to DGPDE factory
62 : : //! \return Constant reference to the DGPDE factory
63 : : const DGFactory& dgfactory() const { return m_dgfactory; }
64 : :
65 : : //! Return info on selected partial differential equations
66 : : std::vector< std::vector< std::pair< std::string, std::string > > > info()
67 : : const;
68 : :
69 : : //! Return number of unique equation types registered into the CG factory
70 : : //! \return The number of unique equation types registered into the CG
71 : : //! factory the factory
72 : : std::size_t cgntypes() const { return m_cgEqTypes.size(); }
73 : :
74 : : //! Return number of unique equation types registered into the DG factory
75 : : //! \return The number of unique equation types registered into the DG
76 : : //! factory the factory
77 : : std::size_t dgntypes() const { return m_dgEqTypes.size(); }
78 : :
79 : : private:
80 : : //! \brief Instantiate a partial differential equation
81 : : //! \details The template argument, EqTag, is used to find the given
82 : : //! partial differential equation in the input deck, the hierarchical data
83 : : //! filled during control file parsing, containing user input. The
84 : : //! template argument Factory specifies which factory we search in. The
85 : : //! template argument PDE specifies the "base" PDE type that the
86 : : //! instantiated "child" PDE class object is used polymorphically with.
87 : : //! \param[in] f Factory in which to search PDE in
88 : : //! \param[in] eq The unique partial differential equation key whose object
89 : : //! to instantiate.
90 : : //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
91 : : //! partial differential equations by type.
92 : : template< class EqTag, class Factory, class PDE >
93 : 666 : PDE createPDE( const Factory& f,
94 : : ctr::PDEType eq,
95 : : std::map< ctr::PDEType, ncomp_t >& cnt ) const
96 : : {
97 : 666 : auto c = ++cnt[ eq ]; // count eqs
98 : 666 : --c; // used to index vectors starting with 0
99 : : const auto& ncomp = g_inputdeck.get< tag::component >();
100 : : Assert( c < (ncomp.get< EqTag >().size()),
101 : : "The number of scalar components is unspecified for the PDE to "
102 : : "be instantiated. This is most likely a grammar error in the "
103 : : "parser. The parser should not allow the user to select a PDE "
104 : : "without configuring the number of scalar components the "
105 : : "equation consists of. See inciter::deck::check_eq." );
106 [ + - ]: 666 : auto nc = ncomp.get< EqTag >()[c];
107 [ + - ]: 666 : if ( nc ) {
108 : : // re-create key and search for it
109 : : ctr::PDEKey key{{ eq,
110 : 666 : g_inputdeck.get< tag::param, EqTag, tag::physics >()[c],
111 : 666 : g_inputdeck.get< tag::param, EqTag, tag::problem >()[c] }};
112 : : const auto it = f.find( key );
113 : : Assert( it != end( f ),
114 : : "Can't find PDE with key('" +
115 : : ctr::PDE().name( key.get< tag::pde >() ) + "', '" +
116 : : ctr::Physics().name( key.get< tag::physics >() ) + "', '" +
117 : : ctr::Problem().name( key.get< tag::problem >() ) +
118 : : + "') in factory" );
119 : : // Associate equation system index (value) to all variable offsets
120 : 666 : auto offset = ncomp.offset< EqTag >(c);
121 [ + + ]: 2552 : for (ncomp_t i=0; i<nc; ++i) g_inputdeck.get<tag::sys>()[offset+i] = c;
122 : : // instantiate and return PDE object
123 : 666 : return it->second( c );
124 [ - - ][ - - ]: 0 : } else Throw ( "Can't create PDE with zero components" );
[ - - ][ - - ]
[ - - ][ - - ]
125 : : }
126 : :
127 : : //! Wrapper of createPDE specialized for registering CG PDEs
128 : : //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
129 : : //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
130 : : //! partial differential equations by type.
131 : : //! \details The sole reason for this function is to simplify client-code
132 : : //! calling createPDE specialized to CG PDEs
133 : : template< class EqTag >
134 : : CGPDE createCG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
135 : : const {
136 [ + - ][ + - ]: 393 : return createPDE< EqTag, CGFactory, CGPDE >( m_cgfactory, t, cnt );
137 : : }
138 : :
139 : : //! Wrapper of createPDE specialized for registering DG PDEs
140 : : //! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
141 : : //! \param[in,out] cnt Counter, a std::map, that counts all instantiated
142 : : //! partial differential equations by type.
143 : : //! \details The sole reason for this function is to simplify client-code
144 : : //! calling createPDE specialized to DG PDEs
145 : : template< class EqTag >
146 : : DGPDE createDG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
147 : : const {
148 [ + - ][ + - ]: 273 : return createPDE< EqTag, DGFactory, DGPDE >( m_dgfactory, t, cnt );
[ + - ]
149 : : }
150 : :
151 : : //! PDE factory for continuous Galerkin discretization
152 : : CGFactory m_cgfactory;
153 : : //! PDE factory for discontinuous Galerkin discretization
154 : : DGFactory m_dgfactory;
155 : : //! Counters for equation types registered into the CG factory
156 : : std::set< ctr::PDEType > m_cgEqTypes;
157 : : //! Counters for equation types registered into the DG factory
158 : : std::set< ctr::PDEType > m_dgEqTypes;
159 : : };
160 : :
161 : : } // inciter::
162 : :
163 : : #endif // PDEStack_h
|