Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/PDE/PDEStack.cpp
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 partial differential equations
9 : : \details This file defines 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 : :
18 : : #include "PDEStack.hpp"
19 : :
20 : : #include "ConfigureTransport.hpp"
21 : : #include "ConfigureCompFlow.hpp"
22 : : #include "ConfigureMultiMat.hpp"
23 : : #include "ConfigureMultiSpecies.hpp"
24 : :
25 : : using inciter::PDEStack;
26 : :
27 : 2271 : PDEStack::PDEStack() : m_cgfactory(), m_dgfactory(), m_fvfactory(),
28 [ + - ]: 2271 : m_cgEqTypes(), m_dgEqTypes(), m_fvEqTypes()
29 : : // *****************************************************************************
30 : : // Constructor: register all partial differential equations into factory
31 : : //! \details This constructor consists of several blocks, each registering a
32 : : //! potentially large number of entries in a partial differential equation
33 : : //! factory, a standard associative container. At this time, each type of
34 : : //! partial differential equation can be configured to use a unique _physics
35 : : //! policy_ and a unique _problem policy_. (More types of policies might be
36 : : //! introduced in the future.) Policy classes are template arguments to the
37 : : //! partial differential equation classes and influence their behavior in a
38 : : //! different way, abstracting away certain functions, e.g., how to set
39 : : //! problem-specific initial and/or boundary conditions and how to update
40 : : //! their coefficients during time integration. For more information on
41 : : //! policy-based design, see http://en.wikipedia.org/wiki/Policy-based_design.
42 : : //! This abstraction allows [separation of concerns]
43 : : //! (http://en.wikipedia.org/wiki/Separation_of_concerns).
44 : : //!
45 : : //! Since the functionality of the policies are orthogonal to each other,
46 : : //! i.e., they do not depend on each other or their host (the partial
47 : : //! differential equation class), a Cartesian product of combinations are
48 : : //! possible, depending on which policies are selected. _This constructor
49 : : //! registers all possible combinations of policies for all available
50 : : //! differential equations._ By _register_, we mean, an entry is recorded in
51 : : //! an associative container, a std::map, that associates a lightweight key of
52 : : //! type inciter::ctr::PDEKey, consisting of only an enum for each policy
53 : : //! type, to an std::function object that holds the constructor bound to its
54 : : //! arguments corresponding to a particular partial differential equation +
55 : : //! policies combination. Note that registering these entries in the map does
56 : : //! not invoke the constructors. The mapped value simply stores how the
57 : : //! constructors should be invoked at a later time. At some point later,
58 : : //! based on user input, we then instantiate only the partial differential
59 : : //! equations (and only those configurations) that are requested by the user.
60 : : //!
61 : : //! Since all partial differential equation types (registered in the factory)
62 : : //! "inherit" from a common "base", client-code is unform and generic, and
63 : : //! thus immune to changes in the inner workings of the particular partial
64 : : //! differential equations as long as they fullfill certain concepts, i.e.,
65 : : //! implement certain member functinos, enforced by the _common base_, PDE.
66 : : //! The words "inherit and "base" are quoted here, because the common base
67 : : //! does not use inheritance in the normal OOP sense and does not use
68 : : //! reference semantics, i.e., pointers, visible to client-code either. The
69 : : //! relationship is more of a _models a_-type, which simplifies client-code
70 : : //! and allows for the benfits of runtime inheritance with value-semantics
71 : : //! which is less error prone and easier to read. See more about the
72 : : //! _models-a_ relationship and its implementation in, e.g., PDE/CGPDE.h.
73 : : //!
74 : : //! The design discussed above allows the registration, instantiation, and
75 : : //! use of the partial differential equations to be generic, which eliminates
76 : : //! a lot of boiler-plate code and makes client-code uniform.
77 : : //!
78 : : //! _Details of registration using brigand::for_each and
79 : : //! tk::cartesian_product:_
80 : : //!
81 : : //! The template argument to brigand::for_each, as used below, requires a
82 : : //! list of list of types. We use brigand::list of brigand::list of types,
83 : : //! listing all possible policies, where the inner list must have exactly two
84 : : //! types, as the list of lists is constructed from two lists using the
85 : : //! cartesian product, and the length of the outer list (the list of lists) is
86 : : //! arbitrary. The constructor argument to brigand::for_each is a functor that
87 : : //! is to be applied to all members of the outer list. tk::cartesian_product
88 : : //! will create all possible combinations of these types and call the functor
89 : : //! with each type of the created sequence as a template parameter. The
90 : : //! functor here inherits from registerPDE, which, i.e., its constructor call,
91 : : //! needs a single template argument, a class templated on policy classes.
92 : : //! This is the partial differential equation class to be configured by
93 : : //! selecting policies and to be registered. The arguments to registerPDE's
94 : : //! constructor are the factory, the enum denoting the differential equation
95 : : //! type, and a reference to a variable of type std::set< ctr::PDEType >,
96 : : //! which is only used internally to PDEStack for counting up the number of
97 : : //! unique differential equation types registered, used for diagnostics
98 : : //! purposes.
99 : : // *****************************************************************************
100 : : {
101 [ + - ]: 2271 : registerTransport( m_cgfactory, m_dgfactory, m_cgEqTypes, m_dgEqTypes );
102 [ + - ]: 2271 : registerCompFlow( m_cgfactory, m_dgfactory, m_cgEqTypes, m_dgEqTypes );
103 [ + - ]: 2271 : registerMultiMat( m_dgfactory, m_fvfactory, m_dgEqTypes, m_fvEqTypes );
104 [ + - ]: 2271 : registerMultiSpecies( m_dgfactory, m_fvfactory, m_dgEqTypes, m_fvEqTypes );
105 : 2271 : }
106 : :
107 : : std::vector< inciter::CGPDE >
108 [ + + ]: 694 : PDEStack::selectedCG() const
109 : : // *****************************************************************************
110 : : // Instantiate all selected PDEs using continuous Galerkin discretization
111 : : //! \return std::vector of instantiated partial differential equation objects
112 : : // *****************************************************************************
113 : : {
114 : : std::map< ctr::PDEType, ncomp_t > cnt; // count PDEs per type
115 : : std::vector< CGPDE > pdes; // will store instantiated PDEs
116 : :
117 : 694 : const auto sch = g_inputdeck.get< tag::scheme >();
118 [ + + ]: 694 : if (sch == ctr::SchemeType::ALECG || sch == ctr::SchemeType::OversetFE) {
119 : :
120 : : const auto& d = g_inputdeck.get< tag::pde >();
121 [ + + ]: 643 : for (std::size_t i=0; i<g_inputdeck.get< tag::mesh >().size(); ++i) {
122 [ + + ]: 326 : if (d == ctr::PDEType::TRANSPORT)
123 : 206 : pdes.push_back( createCG< tag::transport >( d, cnt ) );
124 [ + - ]: 120 : else if (d == ctr::PDEType::COMPFLOW)
125 : 120 : pdes.push_back( createCG< tag::compflow >( d, cnt ) );
126 [ - - ][ - - ]: 0 : else Throw( "Can't find selected CGPDE" );
[ - - ][ - - ]
[ - - ][ - - ]
127 : : }
128 : :
129 : : }
130 : :
131 : 694 : return pdes;
132 : : }
133 : :
134 : : std::vector< inciter::DGPDE >
135 [ + + ]: 694 : PDEStack::selectedDG() const
136 : : // *****************************************************************************
137 : : // Instantiate all selected PDEs using discontinuous Galerkin discretization
138 : : //! \return std::vector of instantiated partial differential equation objects
139 : : // *****************************************************************************
140 : : {
141 : : std::map< ctr::PDEType, ncomp_t > cnt; // count PDEs per type
142 : : std::vector< DGPDE > pdes; // will store instantiated PDEs
143 : :
144 : 694 : auto sch = g_inputdeck.get< tag::scheme >();
145 : 694 : if (sch == ctr::SchemeType::DG ||
146 : : sch == ctr::SchemeType::P0P1 || sch == ctr::SchemeType::DGP1 ||
147 [ + + ]: 694 : sch == ctr::SchemeType::DGP2 || sch == ctr::SchemeType::PDG ||
148 : : sch == ctr::SchemeType::FV) {
149 : :
150 : : const auto& d = g_inputdeck.get< tag::pde >();
151 [ + + ]: 754 : for (std::size_t i=0; i<g_inputdeck.get< tag::mesh >().size(); ++i) {
152 [ + + ]: 377 : if (d == ctr::PDEType::TRANSPORT)
153 : 148 : pdes.push_back( createDG< tag::transport >( d, cnt ) );
154 [ + + ]: 229 : else if (d == ctr::PDEType::COMPFLOW)
155 : 106 : pdes.push_back( createDG< tag::compflow >( d, cnt ) );
156 [ + - ]: 123 : else if (d == ctr::PDEType::MULTIMAT)
157 : 123 : pdes.push_back( createDG< tag::multimat >( d, cnt ) );
158 [ - - ]: 0 : else if (d == ctr::PDEType::MULTISPECIES)
159 : 0 : pdes.push_back( createDG< tag::multispecies >( d, cnt ) );
160 [ - - ][ - - ]: 0 : else Throw( "Can't find selected DGPDE" );
[ - - ][ - - ]
[ - - ][ - - ]
161 : : }
162 : :
163 : : }
164 : :
165 : 694 : return pdes;
166 : : }
167 : :
168 : : std::vector< inciter::FVPDE >
169 [ + + ]: 694 : PDEStack::selectedFV() const
170 : : // *****************************************************************************
171 : : // Instantiate all selected PDEs using finite volume discretization
172 : : //! \return std::vector of instantiated partial differential equation objects
173 : : // *****************************************************************************
174 : : {
175 : : std::map< ctr::PDEType, ncomp_t > cnt; // count PDEs per type
176 : : std::vector< FVPDE > pdes; // will store instantiated PDEs
177 : :
178 : 694 : auto sch = g_inputdeck.get< tag::scheme >();
179 [ + + ]: 694 : if (sch == ctr::SchemeType::FV) {
180 : :
181 : : const auto& d = g_inputdeck.get< tag::pde >();
182 [ + + ]: 162 : for (std::size_t i=0; i<g_inputdeck.get< tag::mesh >().size(); ++i) {
183 [ + - ]: 81 : if (d == ctr::PDEType::MULTIMAT)
184 : 81 : pdes.push_back( createFV< tag::multimat >( d, cnt ) );
185 [ - - ][ - - ]: 0 : else Throw( "Can't find selected FVPDE" );
[ - - ][ - - ]
[ - - ][ - - ]
186 : : }
187 : :
188 : : }
189 : :
190 : 694 : return pdes;
191 : : }
192 : :
193 : : std::vector< std::vector< std::pair< std::string, std::string > > >
194 [ + + ]: 189 : PDEStack::info() const
195 : : // *****************************************************************************
196 : : // Return information on all selected partial differential equations
197 : : //! \return A vector of vector of pair of strings, containing the configuration
198 : : //! for each selected partial differential equation
199 : : // *****************************************************************************
200 : : {
201 : : std::map< ctr::PDEType, ncomp_t > cnt; // count PDEs per type
202 : : // will store info on all differential equations selected
203 : : std::vector< std::vector< std::pair< std::string, std::string > > > nfo;
204 : :
205 : : const auto& d = g_inputdeck.get< tag::pde >();
206 [ + + ]: 189 : if (d == ctr::PDEType::TRANSPORT)
207 [ + - ][ + - ]: 92 : nfo.emplace_back( infoTransport( cnt ) );
208 [ + + ]: 97 : else if (d == ctr::PDEType::COMPFLOW)
209 [ + - ][ + - ]: 64 : nfo.emplace_back( infoCompFlow( cnt ) );
210 [ + - ]: 33 : else if (d == ctr::PDEType::MULTIMAT)
211 [ + - ][ + - ]: 33 : nfo.emplace_back( infoMultiMat( cnt ) );
212 [ - - ]: 0 : else if (d == ctr::PDEType::MULTISPECIES)
213 [ - - ][ - - ]: 0 : nfo.emplace_back( infoMultiSpecies( cnt ) );
214 [ - - ][ - - ]: 0 : else Throw( "Can't find selected PDE" );
[ - - ][ - - ]
[ - - ][ - - ]
215 : :
216 : 189 : return nfo;
217 : : }
|