DamBreak++ Wave Simulator 0.3
DamBreak++ Simulation Framework
Loading...
Searching...
No Matches
dbpp_Reconstruction.hpp
Go to the documentation of this file.
1#pragma once
2
3//C+ includes
4#include <type_traits>
5#include <ranges>
6#include <vector>
7#include <numeric>
8#include <functional>
9#include <valarray>
10// App include
11#include "dbpp_SimulationUtilities.hpp" // MinMod19
12// SfxBase19 includes
13#include "include/Sfx_StateVector.h"
14#include "include/Sfx_StateVariables.h"
15#include "include/Sfx_DefineTypes.h"
16
17namespace dbpp
18{
27 template<typename FuncLimiter>
28 std::pair<std::valarray<float64>/*dU1*/, std::valarray<float64>/*dU2*/>
29 computeDU12( const std::valarray<float64>& aU1,
30 const std::valarray<float64>& aU2, FuncLimiter&& aFuncLimtr)
31 {
32 // Sanity checks
33 assert(std::size(aU1) == Sfx::EMCNEILNbSections::value);
34 assert(std::size(aU2) == Sfx::EMCNEILNbSections::value);
35
36 //
37 // Reconstruction process at the cell interface x_j+1/2
38 //
39
40 // Need documentation abpout each step of the algorithm
41 std::valarray<float64> dU1(size(aU1));
42 std::valarray<float64> dU2(size(aU2));
43
44 // compute gradient over each cell
45 std::adjacent_difference(std::ranges::begin(aU1), std::ranges::end(aU1),
46 std::ranges::begin(dU1));
47
48 std::adjacent_difference(std::ranges::begin(aU2), std::ranges::end(aU2),
49 std::ranges::begin(dU2));
50
51 dU1[0] = 0.; // force first element to 0 (adjacent_difference keep first element unchanged)
52 dU2[0] = 0.; // force first element to 0 (adjacent_difference keep first element unchanged)
53
54 // apply slope limiter function for each gradient (minimum slope)
55 std::adjacent_difference(std::ranges::begin(dU1), std::ranges::end(dU1), // range to apply limiter
56 std::ranges::begin(dU1), // result
57 aFuncLimtr); // slope limiter function
58
59 std::adjacent_difference(std::ranges::begin(dU2), std::ranges::end(dU2), // range to apply limiter
60 std::ranges::begin(dU2), // result
61 aFuncLimtr); // slope limiter function
62
63 auto w_dU1Shifted = dU1.shift(1); // circular shift (shifted element at the end with element T{})
64 auto w_dU2Shifted = dU2.shift(1); // circular shift (shifted element at the end with element T{})
65
66 // last global discretization node (ghost node) overwrite
67 w_dU1Shifted[aU1.size() - 1] = aFuncLimtr(0., aU1[aU1.size() - 1] - aU1[aU1.size() - 2]); // i+1/2
68 w_dU2Shifted[aU2.size() - 1] = aFuncLimtr(0., aU2[aU2.size() - 1] - aU2[aU2.size() - 2]); // i+1/2
69
70 // don't need anymore of shifted array, might as well to move it
71 dU1 = std::move(w_dU1Shifted); // move semantic supported by valarray
72 dU2 = std::move(w_dU2Shifted); // ditto
73
74 return { dU1,dU2 };
75 }
76
85 template<typename F, typename NumArrayType, // state variables components
86 typename = std::enable_if<std::is_same_v<NumArrayType, std::valarray<double>>>>
87 auto MUSCLReconstruction(const NumArrayType& aU1, const NumArrayType& aU2,
88 F&& aSlopeLimiter) // slope limiter function (forward/Universal reference)
89 {
90 // compute gradient over each cell by applying slope limiter function
91 auto [dU1, dU2] = computeDU12(aU1, aU2, std::forward<F>(aSlopeLimiter));
92
93 const NumArrayType w_dU1(std::ranges::begin(dU1), std::ranges::size(w_dU1)); // gradient of the first state variable
94 const NumArrayType w_dU2(std::ranges::begin(dU2), std::ranges::size(w_dU2)); // gradient of the second state variable
95
96 // MUSCL (Monotone Upwind Scheme Conservation System Law)
97 // Second-order linear extrapolation (polynomial reconstruction at the interface).
98 // Total Variation Diminishing (TVD) property guarantees convergence of such schemes
99 // Uses the Minmod limiter for the slope reconstruction.
100
101 //
102 // Reconstruction process at the cell interface x_j+1/2
103 // Second-order achieve by: U + 0.5*dU where dU derivative at first order
104 // expand state variable in a serie (dU has been computed by using a function
105 // to limit slope called "Slope limiter"), physically similar to adding dissipation or diffusion
106
107 // Compute the left and right states: UR, UL(state variables) j+1/2
108 const NumArrayType UL1{ std::begin(aU1 + 0.5 * w_dU1), Sfx::DIM::value }; // j
109 const NumArrayType UL2{ std::begin(aU2 + 0.5 * w_dU2), Sfx::DIM::value }; // j
110 const NumArrayType UR1{ std::next(std::begin(aU1 - 0.5 * dU1)), Sfx::DIM::value }; // j+1
111 const NumArrayType UR2{ std::next(std::begin(aU2 - 0.5 * dU2)), Sfx::DIM::value }; // j+1
112
113 // template argument deduction
114 return std::make_tuple(UL1, UL2, UR1, UR2);
115 }
116
127 template<typename T, typename CONT, // valid for rvalue only
128 typename std::enable_if_t<!std::is_lvalue_reference<T>::value>>
129 decltype(auto) MUSCLReconstrv( T&& aA, T&& aQ, CONT aListCellFaces)
130 {
131 // algo steps
132 // --- compute dU
133 // --- compute left/right state variables for each faces
134 // --- return map (i,UL,UR)
135 //
136 // using namespace emcil;
137
138 using mapcellfaceVar =
139 std::map<short/*face idx*/, std::pair<Sfx::StateVector/*UL*/, Sfx::StateVector/*UR*/>>;
140 // gradient dU (O(2))
141 // std::function<float64(float64, float64)> w_minmodFunc = emcil::HydroUtils::minmod;
142 auto w_dA = computeDU(aA, dbpp::MinMod19<float64>{}); // first state variable conserved quantity (A)
143 auto w_dQ = computeDU(aQ, dbpp::MinMod19<float64>{}); // second state variable (Q)
144
145 mapcellfaceVar w_mapULUR;
146 // don't know signature interface of the container, use auto&&
147 // no additional copies are made of the values we are iterating through
148 for( auto&& cellFace : aListCellFaces)
149 {
150 auto w_leftIdxNode = cellFace.getLeftNodeI(); // stencil [i-1,i]
151 auto w_rightIdxNode = cellFace.getRightNodeI(); // stencil [i,i+1]
152
153 // C++17 structured binding (bind alias) and try_emplace() if already in, do nothing!!
154 auto [pos, succeed] = w_mapULUR.try_emplace(cellFace.getGblFaceI(), // global face index
155 Sfx::StateVector{ static_cast<float64>(Sfx::StateVariables{ aA[w_leftIdxNode] + 0.5 * w_dA[w_leftIdxNode]}),
156 static_cast<float64>(Sfx::StateVariables{ aQ[w_leftIdxNode] + 0.5 * w_dQ[w_leftIdxNode] }) }, //A
157 Sfx::StateVector{ static_cast<float64>(Sfx::StateVariables{ aA[w_rightIdxNode] - 0.5 * w_dA[w_rightIdxNode]}),
158 static_cast<float64>(Sfx::StateVariables{ aQ[w_rightIdxNode] - 0.5 * w_dQ[w_rightIdxNode]}) } //Q
159 );
160 // if (!succeed) {
161 // pos->
162 // }
163 //std::cerr << "Couldn't add the cell face with id: " <<
164 }//for-loop
165
166 return w_mapULUR;
167 }
168
169#if 0 //not in use for now
170 // Some reconstruction procedure (perfect forwarding)
171 // these are templated functions and range can be vector,
172 // valarray, numerical array from Elligno math library
173 // they all support opertor [] which is a requirement
174 //
175 // Reference
176 // Check reconstr files in VS2015 project, lot of functions
177 // with different signatures ... and create a seperate file
178 // for the implementation of these algorithms
179 template<typename... Args>
180 auto MUSCLReconstrFwd(Args&&... args) // Args&& ...args??
181 {
182 //std::is_empty<Range>(aRng);
183
184 return MUSCLReconstr(std::forward<Args>(args)...);
185 }
186
187 template<typename Range>
188 auto MUSCLReconstr(Range&& aRng1, Range&& aRng2)
189 {}
190
191 template<typename Range>
192 auto MUSCLReconstr(Range& aRng1, Range& aRng2)
193 {}
194
195 template<typename Range>
196 auto MUSCLReconstr(const Range& aRng1, const Range& aRng2)
197 {}
198
199 template<typename Range>
200 auto MUSCLReconstr(const Range& aRng1, const Range& aRng2, Range& aU1LR, Range& aU2LR)
201 {}
202#endif // 0 //not in use for now
203} // End of namespace
std::valarray< float64 > NumArrayType
Definition SimulationConfig.h:24
std::map< short, std::pair< Sfx::StateVector, Sfx::StateVector > > mapcellfaceVar
Definition SimulationConfig.h:42
Minmod limiter function for slope limiting gradient evaluation.
Definition dbpp_SimulationUtilities.hpp:89
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
Definition DamBreakProb.h:15
double float64
Definition dbpp_LDeltaOperator.h:12
auto MUSCLReconstruction(const NumArrayType &aU1, const NumArrayType &aU2, F &&aSlopeLimiter)
MUSCL reconstruction procedure of state variables at cell face.
Definition dbpp_Reconstruction.hpp:87
decltype(auto) MUSCLReconstrv(T &&aA, T &&aQ, CONT aListCellFaces)
Variables extrapolation according to MUSCL algorithm.
Definition dbpp_Reconstruction.hpp:129
std::pair< std::valarray< float64 >, std::valarray< float64 > > computeDU12(const std::valarray< float64 > &aU1, const std::valarray< float64 > &aU2, FuncLimiter &&aFuncLimtr)
Slope limiter (gradient)
Definition dbpp_Reconstruction.hpp:29