-
Notifications
You must be signed in to change notification settings - Fork 2
/
reconstruct.cpp
117 lines (92 loc) · 3.8 KB
/
reconstruct.cpp
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
/**
* reconstruct.cpp
*
* Contains routines for higher order reconstruction of hydrodynamic primitives.
*/
#include "aiolos.h"
/**
* General slope limiting function based on mid, left and right values.
*/
double MonotonizedCentralSlope(double ql, double qm, double qr,
double cF=2, double cB=2, double dxF=1, double dxB=1) {
// From Mignone's (2005) reconstruction paper
double dF = (qr - qm) / dxF ;
double dB = (qm - ql) / dxB ;
if (dF*dB < 0)
return 0 ;
auto min_mod = [](double l, double r) {
if (std::abs(l) < std::abs(r))
return l;
else
return r;
} ;
return min_mod(0.5*(dF + dB), min_mod(cF*dF, cB*dB)) ;
}
/**
* Reconstruct the primitive hydro states at the cell edges based on the cell centered value and a slope, which is interpreted from the neighbouring cells.
*/
void c_Species::reconstruct_edge_states() {
const bool is_gas = !is_dust_like ;
// Step 1:
// 1st order hydrostatic reconstruction
for (int i=0; i < num_cells+2; i++) {
prim_r[i] = prim_l[i] = prim[i] ;
if (is_gas) {
if(i > 0)
prim_l[i].pres = prim[i].pres + prim[i].density * get_dp_hydrostatic(i, -1);
if(i <= num_cells)
prim_r[i].pres = prim[i].pres + prim[i].density * get_dp_hydrostatic(i, +1);
// TODO: add warning?
if (prim_l[i].pres < 0 || prim_r[i].pres < 0) {
prim_l[i] = prim_r[i] = prim[i] ;
}
}
}
// Step 2: Add 2nd order slope-limited correction
IntegrationType order = base->order ;
if (order == IntegrationType::second_order) {
const std::vector<double>&
x_i = base->x_i,
x_iVC = base->x_iVC,
dx = base->dx ;
for (int i=1; i <= num_cells; i++) {
double dp_l = 0, dp_r = 0 ;
if (is_gas) {
dp_l =
prim[ i ].density * get_dp_hydrostatic( i , -1) -
prim[i-1].density * get_dp_hydrostatic(i-1, +1) ;
dp_r =
prim[ i ].density * get_dp_hydrostatic( i , +1) -
prim[i+1].density * get_dp_hydrostatic(i+1, -1) ;
}
// Non-uniform grid factors
double cF = (x_iVC[i+1] - x_iVC[i]) / (x_i[i] - x_iVC[i]) ;
double cB = (x_iVC[i] - x_iVC[i-1]) / (x_iVC[i] - x_i[i-1]) ;
double dxF = (x_iVC[i+1] - x_iVC[i]) ;
double dxB = (x_iVC[i] - x_iVC[i-1]) ;
// Pressure perturbation
double slope ;
slope = MonotonizedCentralSlope(
prim[i-1].pres - dp_l, prim[i].pres, prim[i+1].pres - dp_r, cF, cB, dxF, dxB) ;
prim_l[i].pres += slope * (x_i[i-1] - x_iVC[i]) ;
prim_r[i].pres += slope * (x_i[ i ] - x_iVC[i]) ;
// Density
slope = MonotonizedCentralSlope(
prim[i-1].density, prim[i].density, prim[i+1].density, cF, cB, dxF, dxB) ;
prim_l[i].density += slope * (x_i[i-1] - x_iVC[i]) ;
prim_r[i].density += slope * (x_i[ i ] - x_iVC[i]) ;
// Speed
slope = MonotonizedCentralSlope(
prim[i-1].speed, prim[i].speed, prim[i+1].speed, cF, cB, dxF, dxB) ;
prim_l[i].speed += slope * (x_i[i-1] - x_iVC[i]) ;
prim_r[i].speed += slope * (x_i[ i ] - x_iVC[i]) ;
if ((prim_l[i].pres < 0) || (prim_r[i].pres < 0) ||
(prim_l[i].density < 0) || (prim_r[i].density < 0))
prim_l[i] = prim_r[i] = prim[i] ;
}
}
// Step 3:
// Extra thermodynamic variables
eos->compute_auxillary(&(prim_l[0]), num_cells+2);
eos->compute_auxillary(&(prim_r[0]), num_cells+2);
}