Peano
Loading...
Searching...
No Matches
EulerFWave.py
Go to the documentation of this file.
1"""
2This solver is based on
3"A Wave Propagation Method for Conservation Laws and Balance Laws with Spatially Varying Flux Functions", Bale et al., 2003, doi:10.1137/S106482750139738X
4and
5"Finite Volume Methods for Hyperbolic Equations", Randall J. LeVeque, 2002, doi:10.1017/CBO9780511791253
6"""
7
8fWave = """
9 /*******************************
10 * Flux and source preparation *
11 ******************************/
12
13 double fluxRight[NumberOfUnknowns] {0.0};
14 double fluxLeft[NumberOfUnknowns] {0.0};
15 double deltaXPsi[NumberOfUnknowns] {0.0};
16
17 tarch::la::Vector<DIMENSIONS, double> xL(x);
18 tarch::la::Vector<DIMENSIONS, double> xR(x);
19 xR[normal] += 0.5 * h(normal);
20 xL[normal] -= 0.5 * h(normal);
21
22 flux(QL, xL, h, t, dt, normal, fluxLeft);
23 flux(QR, xR, h, t, dt, normal, fluxRight);
24
25 if (normal == 1) {
26 auto densityPerturbationLeft = QL[Shortcuts::rho] - QL[Shortcuts::backgroundDensity];
27 auto densityPerturbationRight = QR[Shortcuts::rho] - QR[Shortcuts::backgroundDensity];
28
29 if (std::abs(densityPerturbationLeft) < DENSITY_THRESHOLD) {
30 densityPerturbationLeft = 0.0;
31 }
32
33 if (std::abs(densityPerturbationRight) < DENSITY_THRESHOLD) {
34 densityPerturbationRight = 0.0;
35 }
36
37 deltaXPsi[Shortcuts::rhov] = 0.5 * h(normal) * -GRAVITY * (densityPerturbationLeft + densityPerturbationRight);
38 deltaXPsi[Shortcuts::E] = 0.5 * h(normal) * -GRAVITY * (QL[Shortcuts::rhov] + QR[Shortcuts::rhov]);
39 }
40
41 std::fill_n(FL, NumberOfUnknowns, 0.0);
42 std::fill_n(FR, NumberOfUnknowns, 0.0);
43
44 /********************
45 * State extraction *
46 *******************/
47
48 // left state
49 const auto rhoL = QL[Shortcuts::rho];
50 const auto sqrtRhoL = sqrt(rhoL);
51 const auto uL = QL[Shortcuts::rhou] / rhoL;
52 const auto vL = QL[Shortcuts::rhov] / rhoL;
53 #if DIMENSIONS == 3
54 const auto wL = QL[Shortcuts::rhow] / rhoL;
55 #endif
56 const auto EL = QL[Shortcuts::E];
57
58 #if !defined(WITH_GPU)
59 assertion1(rhoL > 0, rhoL);
60 assertion1(EL > 0, EL);
61 #endif
62
63 const auto ML = QL[Shortcuts::O2] + QL[Shortcuts::O] + QL[Shortcuts::N2];
64 const auto iML = 1.0 / ML;
65 const auto meanMolecularMassL = (MOLAR_MASS_NITROGEN * QL[Shortcuts::N2] + MOLAR_MASS_MOLECULAR_OXYGEN * QL[Shortcuts::O2] + MOLAR_MASS_ATOMIC_OXYGEN * QL[Shortcuts::O]) * iML; // in kg/mol
66 const auto pressureL = QL[Shortcuts::rho] * UNIVERSAL_GAS_CONSTANT * QL[Shortcuts::T] / meanMolecularMassL;
67 #if !defined(WITH_GPU)
68 assertion5(pressureL > 0.0, ML, meanMolecularMassL, QL[Shortcuts::rho], QL[Shortcuts::T], pressureL);
69 #endif
70
71 const auto gammaL = (1.4 * (ML - QL[Shortcuts::O]) + 1.67 * QL[Shortcuts::O]) * iML;
72 const auto HL = (EL + pressureL) / QL[Shortcuts::rho];
73
74 // right state
75 const auto rhoR = QR[Shortcuts::rho];
76 const auto sqrtRhoR = sqrt(rhoR);
77 const auto uR = QR[Shortcuts::rhou] / rhoR;
78 const auto vR = QR[Shortcuts::rhov] / rhoR;
79 #if DIMENSIONS == 3
80 const auto wR = QR[Shortcuts::rhow] / rhoR;
81 #endif
82 const auto ER = QR[Shortcuts::E];
83
84 #if !defined(WITH_GPU)
85 assertion1(rhoR > 0, rhoR);
86 assertion1(ER > 0, ER);
87 #endif
88
89 const auto MR = QR[Shortcuts::O2] + QR[Shortcuts::O] + QR[Shortcuts::N2];
90 const auto iMR = 1.0 / MR;
91 const auto meanMolecularMassR = (MOLAR_MASS_NITROGEN * QR[Shortcuts::N2] + MOLAR_MASS_MOLECULAR_OXYGEN * QR[Shortcuts::O2] + MOLAR_MASS_ATOMIC_OXYGEN * QR[Shortcuts::O]) * iMR; // in kg/mol
92 const auto pressureR = QR[Shortcuts::rho] * UNIVERSAL_GAS_CONSTANT * QR[Shortcuts::T] / meanMolecularMassR;
93 #if !defined(WITH_GPU)
94 assertion5(pressureR > 0.0, MR, meanMolecularMassR, QR[Shortcuts::rho], QR[Shortcuts::T], pressureR);
95 #endif
96
97 const auto gammaR = (1.4 * (MR - QR[Shortcuts::O]) + 1.67 * QR[Shortcuts::O]) * iMR;
98 const auto HR = (ER + pressureR) / QR[Shortcuts::rho];
99
100 /********************************************
101 * Roe averages from LeVeque Chapter 15.3.4 *
102 *******************************************/
103
104 const auto iSumSqrtRho = 1 / (sqrtRhoL + sqrtRhoR);
105
106 const auto gammaAvg = 0.5 * (gammaL + gammaR);
107 const auto HRoe = (HL * sqrtRhoL + HR * sqrtRhoR) * iSumSqrtRho;
108
109 tarch::la::Vector<DIMENSIONS, double> roeAveragedVelocities(0.0);
110 roeAveragedVelocities(0) = (sqrtRhoL * uL + sqrtRhoR * uR) * iSumSqrtRho;
111 roeAveragedVelocities(1) = (sqrtRhoL * vL + sqrtRhoR * vR) * iSumSqrtRho;
112 #if DIMENSIONS == 3
113 roeAveragedVelocities(2) = (sqrtRhoL * wL + sqrtRhoR * wR) * iSumSqrtRho;
114 #endif
115 const auto qSquared = 0.5 * (roeAveragedVelocities * roeAveragedVelocities);
116 const auto speedOfSoundRoe = sqrt((gammaAvg - 1) * (HRoe - qSquared));
117
118 /*************************************************************
119 * Roe Eigenvalues from LeVeque Chapter 18.8, Equation 18.47 *
120 ************************************************************/
121
122 // in x-direction, these are uRoe - speedOfSoundRoe, DIMENSIONS x uRoe, and uRoe + speedOfSoundRoe
123 tarch::la::Vector<NumberOfUnknowns, double> roeEigenvalues(0.0);
124
125 // first eigenvalue is left uRoe - speedOfSoundRoe
126 roeEigenvalues(0) = roeAveragedVelocities(normal) - speedOfSoundRoe;
127
128 for (int eigenvalue = 1; eigenvalue <= DIMENSIONS; eigenvalue++) {
129 roeEigenvalues(eigenvalue) = roeAveragedVelocities(normal);
130 }
131
132 // last eigenvalue is right uRoe + speedOfSoundRoe
133 roeEigenvalues(DIMENSIONS + 1) = roeAveragedVelocities(normal) + speedOfSoundRoe;
134
135 /***********************************************
136 * Delta values from Bale et al. Equation 1.17 *
137 **********************************************/
138
139 tarch::la::Vector<NumberOfUnknowns, double> delta(0.0);
140
141 for (int unknown = 0; unknown < NumberOfUnknowns; ++unknown) {
142 delta(unknown) = fluxRight[unknown] - fluxLeft[unknown] - deltaXPsi[unknown];
143 }
144
145 /****************************************************************
146 * Right Eigenvectors from LeVeque Chapter 18.8, Equation 18.48 *
147 ***************************************************************/
148
149 // @todo figure out for 3D
150 // => github.com/clawpack/riemann/blob/master/src/rpn3_euler.f90
151
152 const int transverse = normal == 0 ? 1 : 0;
153
154 // first right Eigenvector
155 tarch::la::Vector<NumberOfUnknowns, double> r1(0.0);
156 r1(0) = 1.0;
157 r1(1 + normal) = roeAveragedVelocities(normal) - speedOfSoundRoe;
158 r1(1 + transverse) = roeAveragedVelocities(transverse);
159 r1(3) = HRoe - roeAveragedVelocities(normal) * speedOfSoundRoe;
160
161 // second right Eigenvector
162 tarch::la::Vector<NumberOfUnknowns, double> r2(0.0);
163 r2(0) = 0.0;
164 r2(1 + normal) = 0.0;
165 r2(1 + transverse) = 1.0;
166 r2(3) = roeAveragedVelocities(transverse);
167
168 // third right Eigenvector
169 tarch::la::Vector<NumberOfUnknowns, double> r3(0.0);
170 r3(0) = 1.0;
171 r3(1) = roeAveragedVelocities(0);
172 r3(2) = roeAveragedVelocities(1);
173 r3(3) = qSquared;
174
175
176 // fourth right Eigenvector
177 tarch::la::Vector<NumberOfUnknowns, double> r4(0.0);
178 r4(0) = 1.0;
179 r4(1 + normal) = roeAveragedVelocities(normal) + speedOfSoundRoe;
180 r4(1 + transverse) = roeAveragedVelocities(transverse);
181 r4(3) = HRoe + roeAveragedVelocities(normal) * speedOfSoundRoe;
182
183 /***************************************************
184 * Beta values following Bale et al. Equation 1.14 *
185 **************************************************/
186 // inverted Eigenvectors taken from https://github.com/clawpack/riemann/blob/master/src/rpn2_euler_4wave.f90
187
188 // @todo figure out for 3D
189 tarch::la::Vector<NumberOfUnknowns, double> beta(0.0);
190
191 beta(2) = (
192 (HRoe - 2 * qSquared) * delta(0)
193 + roeAveragedVelocities(normal) * delta(1 + normal)
194 + roeAveragedVelocities(transverse) * delta(1 + transverse)
195 - delta(3)
196 ) / (HRoe - qSquared);
197
198 beta(1) = delta(1 + transverse) - roeAveragedVelocities(transverse) * delta(0);
199
200 beta(3) = (
201 delta(1 + normal)
202 + (speedOfSoundRoe - roeAveragedVelocities(normal)) * delta(0)
203 - speedOfSoundRoe * beta(2)
204 ) / (2 * speedOfSoundRoe);
205
206 beta(0) = delta(0) - beta(2) - beta(3);
207
208 /****************
209 * fWave fluxes *
210 ***************/
211
212 const tarch::la::Vector<NumberOfUnknowns, double> fWaves[NumberOfUnknowns] = {
213 beta(0) * r1,
214 beta(1) * r2,
215 beta(2) * r3,
216 beta(3) * r4
217 };
218
219 for (int wave = 0; wave < NumberOfUnknowns; ++wave) {
220 const auto eigenvalue = roeEigenvalues(wave);
221 if (eigenvalue < 0.0) {
222 // left going wave
223 for (int unknown = 0; unknown < NumberOfUnknowns; ++unknown) {
224 FL[unknown] += fWaves[wave](unknown);
225 }
226 } else {
227 // right going wave
228 for (int unknown = 0; unknown < NumberOfUnknowns; ++unknown) {
229 FR[unknown] -= fWaves[wave](unknown);
230 }
231 }
232 }
233
234 // return largest absolute Eigenvalue
235 return tarch::la::maxAbs(roeEigenvalues);"""