DamBreak++ Wave Simulator 0.3
DamBreak++ Simulation Framework
Loading...
Searching...
No Matches
dbpp_MUSCLReconstr.hpp
Go to the documentation of this file.
1#pragma once
2
3// C++ includes
4#include <map>
5#include <list>
6#include <numeric>
7#include <functional>
8// C++20 include
9#include <ranges>
10// SfxBase19 inlcudes
11#include "include/Sfx_StateVector.h"
12#include "include/Sfx_StateVariables.h"
13#include "include/Sfx_cellFaceVariables.h"
14// DamBreak++ includes
15#include "../SfxBase/Sfx_MathFunctions.hpp" // computeDU
16// VS15 include
17//#include "../May_VS2015/Test/GlobalDiscretization.h"
18//
19//#include "dbpp_Omega.h"
20//#include "dbpp_CellFace.h"
21#include "dbpp_Enumerations.h"
22//#include "dbpp_StateVectorField.h"
25
26//namespace emcil { class GlobalDiscretization; }
27
28namespace dbpp
29{
30 // Design Note
31 // could be implemented as template, not sure yet
32 // Create a list of global cell face (deprecated used for prototyping) according to grid
33 // Reconstruction of state variables at global cell - face j+1/2
34 //const auto w_gblFaceVar = reconstr(vectorField, GlobalDiscretization);
35
61 {
62 using CellId = short;
63 //using LRvariables = std::pair<CellFaceVariables/*A*/, CellFaceVariables/*Q*/>;
64 //using mapCellFaceULR = std::map<CellId, LRvariables>;
65 using slopeLimiterFunc = std::function<float64(float64, float64)>;
66 //using pairdblvec = std::pair<std::vector<float64>, std::vector<float64>>;
67 using mapcellfaceVar = std::map<short/*face idx*/, std::pair<Sfx::StateVector/*UL*/, Sfx::StateVector/*UR*/>>;
68
69 public:
70 //default
71 MUSCLReconstr() = default;
72
73 // ctor (under construction) ???
74 MUSCLReconstr(slopeLimiterFunc aFunction, unsigned aOrder)
75 : m_dUOrder{1},
76 m_faceVarOrder{static_cast<short>(aOrder)} // need to check
77 {}
78
79 void setFaceVariableOrder(short aOrder) { m_faceVarOrder = aOrder; }
80
81 // Reconstruction of state variables at cell face by using slope limiter and TVD method
82 void setSlopeLimiter(slopeLimiterFunc aSlopeLimiterFunc/*HydroUtils::minmod*/) {} // slope limiter gradient
83 void setDUOrder(short aDUOrder) { m_dUOrder = aDUOrder; } // gradient over each cell at 1st order
84 short getDUOrder() const { return m_dUOrder; }
85// void computeDU1stOrder( const emcil::vectorField& aVec,
86// const emcil::GlobalDiscretization* aGblDiscr); // gradient
87 void setReconstrVariableOrder(short aVarOrder) { m_faceVarOrder = aVarOrder; }
88 short getReconstrVariableOrder() const { return m_faceVarOrder; }
89 void setPhysicalBndCnd() {} // to be implemented!!!
90 // enum class eFluxType {incomplete, complete};
91 public:
92
93 template<std::ranges::contiguous_range Range> // must be DIM+1 size
94 std::list<Sfx::cellFaceVariables> reconstr( const dbpp::Omega& aOmega,
95 Range&& aA, Range&& aQ) // nodal values
96 {
97 // 'DIM' metaprogramming constant
98 assert(std::ranges::size(aA) == Sfx::DIM::value + 1);
99 assert(std::ranges::size(aA)==std::ranges::size(aQ));
100
101 // check value category
102
103 // retrieve geometric node (global domain)
104 const auto& w_gnode = aOmega.omega_gnode();
105 using enum dbpp::eNodalField;
106
107 // check value type
108 static_assert(std::is_same_v<Range, std::vector<float64>>);
109
110 // support to different version of 'Range'. Vector has a push_back
111 // ... to be completed
112 if constexpr (!std::is_same_v<Range, std::vector<float64>>)
113 {
114 // Apply physical boundary cnd (half-open domain)
115 if (auto&& node = w_gnode.front(); node.isTiedNode())
116 {
117 //state variable set
118 aA[node.nodeNo()] = std::get<dbpp::toEnumType(A)>(m_upstreamBC.Values());
119 aQ[node.nodeNo()] = std::get<dbpp::toEnumType(Q)>(m_upstreamBC.Values());
120 }
121 if (auto&& node = w_gnode.back(); node.isGhostNode())
122 {
123 aA[node.nodeNo()] = std::get<dbpp::toEnumType(A)>(m_downstreamBC.Values());
124 aQ[node.nodeNo()] = std::get<dbpp::toEnumType(Q)>(m_downstreamBC.Values());
125 }
126 }
127
128 // algo steps
129 // --- compute dU
130 // --- compute left/right state variables for each faces
131 // --- return map (i,UL,UR)
132 //
133 // gradient dU (O(2))
134 //std::function<float64(float64, float64)> w_minmodFunc = MinMod19;
135 auto w_dA = Sfx::computeDU(aA, MinMod19<float64>{}); // first state variable conserved quantity (A)
136 auto w_dQ = Sfx::computeDU(aQ, MinMod19<float64>{}); // second state variable (Q)
137
138 // mapcellfaceVar w_mapULUR;
139 std::list<Sfx::cellFaceVariables> w_listReconstrVar;
140
141 // Create a list of global cell face (deprecated used for prototyping)
142 auto w_omegaGlbFaces = aOmega.getGblFaces();
143 auto begListFaces = w_omegaGlbFaces.begin();
144 //auto i = 0;
145 for( const auto& w_gnode : aOmega.omega_gnode())
146 {
147 // ++i;
148 //tied node and ghost (no part of computational domain)
149 if( w_gnode.isTiedNode() && !w_gnode.isGhostNode()) // first node is tied
150 {
151 //++begListFaces; next in the list
152 continue;
153 }
154
155 // 'cellFace' type is a representation of the cell interface (j+1/2)
156 const cellFace& w_cFace = *begListFaces++;
157 auto w_leftIdxNode = w_cFace.getLeftNodeI(); // stencil [i-1,i]
158 auto w_rightIdxNode = w_cFace.getRightNodeI(); // stencil [i,i+1]
159
160 // C++17 structured binding (bind alias) and try_emplace() if already in, do nothing!!
161 //auto [pos, succeed] = w_mapULUR.try_emplace(w_cFace.getGblFaceI(), // global face index
162 // Sfx::StateVector{ static_cast<float64>(Sfx::StateVariables{ aA[w_leftIdxNode] + 0.5 * w_dA[w_leftIdxNode]}),
163 // static_cast<float64>(Sfx::StateVariables{ aQ[w_leftIdxNode] + 0.5 * w_dQ[w_leftIdxNode] }) }, //A
164 // Sfx::StateVector{ static_cast<float64>(Sfx::StateVariables{ aA[w_rightIdxNode] - 0.5 * w_dA[w_rightIdxNode]}),
165 // static_cast<float64>(Sfx::StateVariables{ aQ[w_rightIdxNode] - 0.5 * w_dQ[w_rightIdxNode]}) } //Q
166 //);
167 // rvalue refernce version of push_back
168 w_listReconstrVar.push_back( Sfx::cellFaceVariables(w_cFace.getGblFaceI(), // global face index
169 Sfx::StateVector{ static_cast<float64>(Sfx::StateVariables{ aA[w_leftIdxNode] + 0.5 * w_dA[w_leftIdxNode]}),
170 static_cast<float64>(Sfx::StateVariables{ aQ[w_leftIdxNode] + 0.5 * w_dQ[w_leftIdxNode] }) }, // A state variable
171 Sfx::StateVector{ static_cast<float64>(Sfx::StateVariables{ aA[w_rightIdxNode] - 0.5 * w_dA[w_rightIdxNode]}),
172 static_cast<float64>(Sfx::StateVariables{ aQ[w_rightIdxNode] - 0.5 * w_dQ[w_rightIdxNode]}) } // Q state variable
173 ));
174 }//while-loop
175
176 return w_listReconstrVar;
177 }
178
179 // boundary condition
181 {
182 m_upstreamBC = aPhysBC.getLeftEnd();
183 m_downstreamBC = aPhysBC.getRightEnd();
184 }
185
186 // reconstruct a scalar field to the given order
187 // MUSCL reconstruction algorithm (Monolitic Upstream System Conservation Law)
188 virtual std::vector<Sfx::cellFaceVariables> reconstr( const Sfx::StateVectorField& aU,
189 const std::shared_ptr<FiniteVolumeDiscretization>& aGblDiscr)
190 {
191 //auto U1vec = aU.getAField().asStdVector();
192 //auto U2vec = aU.Q().values().to_stdVector();
193 std::vector<float64> U1vec(std::ranges::begin(aU.Avalues()), std::ranges::end(aU.Avalues()));
194 std::vector<float64> U2vec(std::ranges::begin(aU.Qvalues()), std::ranges::end(aU.Qvalues()));
195
196 // using enum eNodalVarComp; //C++20 using enum declaration
197 using enum eNodalField; // scoped enum
198
199 // testing what exactly?
200 const auto& w_uh = aGblDiscr->U_h();
201 const auto& arrayNodal = w_uh.vecNodalVarArray().front();
202 //auto checkNo = arrayNodal.node_no(); // debug purpose
203
204 // apply B.C. upstream state variables
205 // implicit conversion from 'int' to 'size_t' (std::get<> take size_t as arg)
206 U1vec[0] = std::get<toEnumType(A)>(m_upstreamBC.m_tpl);// A
207 U2vec[0] = std::get<toEnumType(Q)>(m_upstreamBC.m_tpl); // Q
208
209 // ReconstrUtility.h version
210 const auto& dU1vec = Sfx::computeDU(U1vec, MinMod19<float64>{});
211 const auto& dU2vec = Sfx::computeDU(U2vec, MinMod19<float64>{});
212
213 // ... to be completed
214 std::vector<Sfx::cellFaceVariables> w_retVarReconstr;
215 // main steps of the algorithm
216 w_retVarReconstr.reserve(aGblDiscr->Omega_e().getGblFaces().size());
217
218 // Compute cell face flux j+1/2 (global faces)
219 // solve for face of the cell and then compute dF = F_i+1 - F_i (bias upwind)
220 for (const auto& w_cellFace : aGblDiscr->Omega_e().getGblFaces()) //emcil::createListGlobalFaces(aGblDiscr->omega().omega_eh_array().size()))
221 {
222 // left face 'L' (x_i+1/2 global index) U_i + 0.5*dU_i
223 auto U1L = U1vec[w_cellFace.getLeftNodeI()] + 0.5 * dU1vec[w_cellFace.getLeftNodeI()];
224 auto U2L = U2vec[w_cellFace.getLeftNodeI()] + 0.5 * dU2vec[w_cellFace.getLeftNodeI()];
225
226 // right face 'R' (x_i+1/2 global index) U_i+1 - 0.5*dU_i+1
227 auto U1R = U1vec[w_cellFace.getRightNodeI()] - 0.5 * dU1vec[w_cellFace.getRightNodeI()];
228 auto U2R = U2vec[w_cellFace.getRightNodeI()] - 0.5 * dU2vec[w_cellFace.getRightNodeI()];
229
230 // psuh_back move version (pass a 'rvalue' reference)
231 w_retVarReconstr.push_back(Sfx::cellFaceVariables{ static_cast<unsigned>(w_cellFace.getGblFaceI()),
232 Sfx::StateVector{ U1L,U2L }, Sfx::StateVector{ U1R,U2R } });
233 }//for-loop
234
235 return w_retVarReconstr; //return by copy
236 }
237 private:
238 short m_dUOrder{1};
239 short m_faceVarOrder{2};
242 };
243} // End of namespace
dbpp::NodalTpl< unsigned, float64, float64, float64 > PhyBCNdlConstraint
Physics computational domain (phenomena take place: half-open as default)
Definition SimulationConfig.h:39
short getReconstrVariableOrder() const
Definition dbpp_MUSCLReconstr.hpp:88
void setSlopeLimiter(slopeLimiterFunc aSlopeLimiterFunc)
Definition dbpp_MUSCLReconstr.hpp:82
std::function< float64(float64, float64)> slopeLimiterFunc
Definition dbpp_MUSCLReconstr.hpp:65
PhyBCNdlConstraint m_upstreamBC
Definition dbpp_MUSCLReconstr.hpp:240
void setPhysicalBndCnd()
Definition dbpp_MUSCLReconstr.hpp:89
std::list< Sfx::cellFaceVariables > reconstr(const dbpp::Omega &aOmega, Range &&aA, Range &&aQ)
Definition dbpp_MUSCLReconstr.hpp:94
void setFaceVariableOrder(short aOrder)
Definition dbpp_MUSCLReconstr.hpp:79
PhyBCNdlConstraint m_downstreamBC
Definition dbpp_MUSCLReconstr.hpp:241
std::map< short, std::pair< Sfx::StateVector, Sfx::StateVector > > mapcellfaceVar
Definition dbpp_MUSCLReconstr.hpp:67
short m_faceVarOrder
Definition dbpp_MUSCLReconstr.hpp:239
void setPhysicalBC(const dbpp::PhysicalBoundaryCnd &aPhysBC)
Definition dbpp_MUSCLReconstr.hpp:180
short CellId
Definition dbpp_MUSCLReconstr.hpp:62
short getDUOrder() const
Definition dbpp_MUSCLReconstr.hpp:84
virtual std::vector< Sfx::cellFaceVariables > reconstr(const Sfx::StateVectorField &aU, const std::shared_ptr< FiniteVolumeDiscretization > &aGblDiscr)
Definition dbpp_MUSCLReconstr.hpp:188
void setReconstrVariableOrder(short aVarOrder)
Definition dbpp_MUSCLReconstr.hpp:87
MUSCLReconstr()=default
short m_dUOrder
Definition dbpp_MUSCLReconstr.hpp:238
void setDUOrder(short aDUOrder)
Definition dbpp_MUSCLReconstr.hpp:83
MUSCLReconstr(slopeLimiterFunc aFunction, unsigned aOrder)
Definition dbpp_MUSCLReconstr.hpp:74
Minmod limiter function for slope limiting gradient evaluation.
Definition dbpp_SimulationUtilities.hpp:89
Global Domain (part of global discretization) list of elements and geomeric nodes used by numerical m...
Definition dbpp_Omega.h:19
const std::list< cellFace > & getGblFaces() const
list of global cell faces
Definition dbpp_Omega.h:73
vec_Gnode & omega_gnode()
Nodal geometric nodes.
Definition dbpp_Omega.h:63
Physical boundary condition (computational domain) based on characteristic equation ....
Definition dbpp_PhysicalBoundaryCnd.h:22
PhyBCNdlConstraint getRightEnd() const
Right boundary.
Definition dbpp_PhysicalBoundaryCnd.h:62
PhyBCNdlConstraint getLeftEnd() const
Left boundary.
Definition dbpp_PhysicalBoundaryCnd.h:52
Cell face in the finite volume discretization Usage: caculFF(const cellFace& aFace) compute the numer...
Definition dbpp_CellFace.h:29
constexpr signed short getRightNodeI() const noexcept
right node neighbour
Definition dbpp_CellFace.h:63
constexpr short getLeftNodeI() const noexcept
left node neighbour
Definition dbpp_CellFace.h:58
constexpr signed short getGblFaceI() const noexcept
global face
Definition dbpp_CellFace.h:68
auto computeDU(Range aRng, FuncLimiter &&aFuncLimiter)
Compute gradient over cell by applying a slope limiter function. Range aRng Range of values (computat...
Definition Sfx_MathFunctions.hpp:119
Definition DamBreakProb.h:15
double float64
Definition dbpp_LDeltaOperator.h:12
eNodalField
Definition dbpp_Enumerations.h:24