1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 | // *****************************************************************************
/*!
\file src/PDE/PDEStack.hpp
\copyright 2012-2015 J. Bakosi,
2016-2018 Los Alamos National Security, LLC.,
2019-2021 Triad National Security, LLC.
All rights reserved. See the LICENSE file for details.
\brief Stack of differential equations
\details This file declares class PDEStack, which implements various
functionality related to registering and instantiating partial differential
equation types. Registration and instantiation use a partial differential
equation factory, which is a std::map (an associative container),
associating unique partial differential equation keys to their constructor
calls. For more details, see the in-code documentation of the constructor.
*/
// *****************************************************************************
#ifndef PDEStack_h
#define PDEStack_h
#include <map>
#include <set>
#include <string>
#include <vector>
#include <iostream>
#include "NoWarning/back.hpp"
#include "NoWarning/front.hpp"
#include "Tags.hpp"
#include "Types.hpp"
#include "Exception.hpp"
#include "Factory.hpp"
#include "CGPDE.hpp"
#include "DGPDE.hpp"
#include "FVPDE.hpp"
#include "PDEFactory.hpp"
#include "Inciter/InputDeck/InputDeck.hpp"
namespace inciter {
extern ctr::InputDeck g_inputdeck;
//! \brief Partial differential equations stack
class PDEStack {
private:
using ncomp_t = tk::ncomp_t;
public:
//! Constructor: register partial differential equations into factory
explicit PDEStack();
//! Instantiate selected PDEs using continuous Galerkin discretization
std::vector< CGPDE > selectedCG() const;
//! Instantiate selected PDEs using discontinuous Galerkin discretization
std::vector< DGPDE > selectedDG() const;
//! Instantiate selected PDEs using finite volume discretization
std::vector< FVPDE > selectedFV() const;
//! Constant accessor to CGPDE factory
//! \return Constant reference to the CGPDE factory
const CGFactory& cgfactory() const { return m_cgfactory; }
//! Constant accessor to DGPDE factory
//! \return Constant reference to the DGPDE factory
const DGFactory& dgfactory() const { return m_dgfactory; }
//! Constant accessor to FVPDE factory
//! \return Constant reference to the FVPDE factory
const FVFactory& fvfactory() const { return m_fvfactory; }
//! Return info on selected partial differential equations
std::vector< std::vector< std::pair< std::string, std::string > > > info()
const;
//! Return number of unique equation types registered into the CG factory
//! \return The number of unique equation types registered into the CG
//! factory the factory
std::size_t cgntypes() const { return m_cgEqTypes.size(); }
//! Return number of unique equation types registered into the DG factory
//! \return The number of unique equation types registered into the DG
//! factory the factory
std::size_t dgntypes() const { return m_dgEqTypes.size(); }
//! Return number of unique equation types registered into the FV factory
//! \return The number of unique equation types registered into the FV
//! factory the factory
std::size_t fvntypes() const { return m_fvEqTypes.size(); }
private:
//! \brief Instantiate a partial differential equation
//! \details The template argument, EqTag, is used to find the given
//! partial differential equation in the input deck, the hierarchical data
//! filled during control file parsing, containing user input. The
//! template argument Factory specifies which factory we search in. The
//! template argument PDE specifies the "base" PDE type that the
//! instantiated "child" PDE class object is used polymorphically with.
//! \param[in] f Factory in which to search PDE in
//! \param[in] eq The unique partial differential equation key whose object
//! to instantiate.
//! \param[in,out] cnt Counter, a std::map, that counts all instantiated
//! partial differential equations by type.
template< class EqTag, class Factory, class PDE >
PDE createPDE( const Factory& f,
ctr::PDEType eq,
std::map< ctr::PDEType, ncomp_t >& cnt ) const
{
auto c = ++cnt[ eq ]; // count eqs
--c; // used to index vectors starting with 0<--- Variable 'c' is assigned a value that is never used.
const auto& nc = g_inputdeck.get< tag::ncomp >();
if ( nc ) {
// re-create key and search for it
auto prob = g_inputdeck.get< EqTag, tag::problem >();
// if more than one mesh, set problem type for all additional meshes
// as user-defined
if (cnt[eq] > 1) prob = ctr::ProblemType::USER_DEFINED;
ctr::PDEKey key{{ eq,
g_inputdeck.get< EqTag, tag::physics >(), prob }};
const auto it = f.find( key );
Assert( it != end( f ),
"Can't find PDE with key('" +
ctr::PDE().name( key.get< tag::pde >() ) + "', '" +
ctr::Physics().name( key.get< tag::physics >() ) + "', '" +
ctr::Problem().name( key.get< tag::problem >() ) +
+ "') in factory" );
// Associate equation system index (value) to all variable offsets
for (ncomp_t i=0; i<nc; ++i) g_inputdeck.get<tag::sys>()[i] = c;
// instantiate and return PDE object
return it->second();
} else Throw ( "Can't create PDE with zero components" );
}
//! Wrapper of createPDE specialized for registering CG PDEs
//! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
//! \param[in,out] cnt Counter, a std::map, that counts all instantiated
//! partial differential equations by type.
//! \details The sole reason for this function is to simplify client-code
//! calling createPDE specialized to CG PDEs
template< class EqTag >
CGPDE createCG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
const {
return createPDE< EqTag, CGFactory, CGPDE >( m_cgfactory, t, cnt );
}
//! Wrapper of createPDE specialized for registering DG PDEs
//! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
//! \param[in,out] cnt Counter, a std::map, that counts all instantiated
//! partial differential equations by type.
//! \details The sole reason for this function is to simplify client-code
//! calling createPDE specialized to DG PDEs
template< class EqTag >
DGPDE createDG( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
const {
return createPDE< EqTag, DGFactory, DGPDE >( m_dgfactory, t, cnt );
}
//! Wrapper of createPDE specialized for registering FV PDEs
//! \param[in] t Enum selecting PDE type, Control/Inciter/Options/PDE.h
//! \param[in,out] cnt Counter, a std::map, that counts all instantiated
//! partial differential equations by type.
//! \details The sole reason for this function is to simplify client-code
//! calling createPDE specialized to FV PDEs
template< class EqTag >
FVPDE createFV( ctr::PDEType t, std::map< ctr::PDEType, ncomp_t >& cnt )
const {
return createPDE< EqTag, FVFactory, FVPDE >( m_fvfactory, t, cnt );
}
//! PDE factory for continuous Galerkin discretization
CGFactory m_cgfactory;
//! PDE factory for discontinuous Galerkin discretization
DGFactory m_dgfactory;
//! PDE factory for finite volume discretization
FVFactory m_fvfactory;
//! Counters for equation types registered into the CG factory
std::set< ctr::PDEType > m_cgEqTypes;
//! Counters for equation types registered into the DG factory
std::set< ctr::PDEType > m_dgEqTypes;
//! Counters for equation types registered into the FV factory
std::set< ctr::PDEType > m_fvEqTypes;
};
} // inciter::
#endif // PDEStack_h
|