@@ -29,8 +29,10 @@ def __init__(self, eos: TwoPhaseEOS, do_relaxation: bool):
29
29
def relaxForLinearizedEOS (self , values : Q ):
30
30
fields = Q .fields
31
31
32
- arho1 = values [..., fields .arho1 ]
33
- arho2 = values [..., fields .arho2 ]
32
+ ad = values [..., fields .ad ]
33
+ arho1 = values [..., fields .arho1 ] / (1 - ad )
34
+ arho2 = values [..., fields .arho2 ] / (1 - ad )
35
+ arho1d = values [..., fields .arho1d ]
34
36
35
37
rho10 = self .problem .eos [Phases .PHASE1 ].rho0
36
38
rho20 = self .problem .eos [Phases .PHASE2 ].rho0
@@ -48,8 +50,10 @@ def relaxForLinearizedEOS(self, values: Q):
48
50
) / (2.0 * arho2 * c2 ** 2 )
49
51
50
52
alpha = betaPos / (1.0 + betaPos )
51
- values [..., fields .alpha ] = alpha
52
- values [..., fields .arho ] = alpha * (arho1 + arho2 )
53
+ values [..., fields .abar ] = alpha
54
+ values [..., fields .abarrho ] = alpha * (
55
+ arho1 * (1 - ad ) + arho2 * (1 - ad ) + arho1d
56
+ )
53
57
54
58
"""General relaxation procedure for all other EOS"""
55
59
@@ -58,134 +62,117 @@ def relaxation(self, values: Q):
58
62
59
63
arho1 = values [..., fields .arho1 ]
60
64
arho2 = values [..., fields .arho2 ]
65
+ arho1d = values [..., fields .arho1d ]
66
+ ad = values [..., fields .ad ]
67
+ abarrho = values [..., fields .abarrho ]
68
+ rho = arho1 + arho2 + arho1d
61
69
62
70
# Compute estimator of the relaxation within [0,1]
63
- alpha = np .minimum (np .maximum (values [..., fields .arho ] / (arho1 + arho2 ), 0 ), 1 )
71
+ abar = np .minimum (np .maximum (abarrho / rho , 0 ), 1 )
72
+
73
+ values [..., fields .abar ] = abar
64
74
65
- # Solve for alpha using p1(arho1/alpha) = p2(arho2/alpha) with Newton
66
- # Note that arho1 and arho2 remain constant
67
- def phi (arho1 : np .ndarray , arho2 : np .ndarray , alpha : np .ndarray ):
75
+ # Note that rho remain constant
76
+ def phi (
77
+ arho1 : np .ndarray ,
78
+ arho2 : np .ndarray ,
79
+ abar : np .ndarray ,
80
+ ad : np .ndarray ,
81
+ ):
68
82
rho1 = np .full_like (arho1 , np .nan )
69
83
rho2 = np .full_like (arho1 , np .nan )
70
- np .divide (arho1 , alpha , where = (alpha > 0 ) & (arho1 > 0 ), out = rho1 )
84
+ np .divide (arho1 , abar * ( 1 - ad ) , where = (abar > 0 ) & (arho1 > 0 ), out = rho1 )
71
85
np .divide (
72
- arho2 , 1.0 - alpha , where = (1.0 - alpha > 0 ) & (arho2 > 0 ), out = rho2
86
+ arho2 ,
87
+ (1 - abar ) * (1 - ad ),
88
+ where = ((1.0 - abar ) > 0 ) & (arho2 > 0 ),
89
+ out = rho2 ,
90
+ )
91
+ return (1 - ad ) * (
92
+ self .problem .eos [Phases .PHASE1 ].p (rho1 )
93
+ - self .problem .eos [Phases .PHASE2 ].p (rho2 )
73
94
)
74
- return self .problem .eos [Phases .PHASE1 ].p (rho1 ) - self .problem .eos [
75
- Phases .PHASE2
76
- ].p (rho2 )
77
95
78
- def dphi_dalpha (arho1 : np .ndarray , arho2 : np .ndarray , alpha : np .ndarray ):
96
+ def dphi_dabar (
97
+ arho1 : np .ndarray , arho2 : np .ndarray , abar : np .ndarray , ad : np .ndarray
98
+ ):
79
99
# Note that dp_drho = c^2 for barotropic EOS
80
100
return (
81
101
- arho1
82
- / (alpha ** 2 )
83
- * self .problem .eos [Phases .PHASE1 ].sound_velocity (arho1 / alpha ) ** 2
102
+ / (abar ** 2 )
103
+ * self .problem .eos [Phases .PHASE1 ].sound_velocity (
104
+ arho1 / abar / (1 - ad )
105
+ )
106
+ ** 2
84
107
- arho2
85
- / ((1.0 - alpha ) ** 2 )
86
- * self .problem .eos [Phases .PHASE2 ].sound_velocity (arho2 / (1.0 - alpha ))
108
+ / ((1.0 - abar ) ** 2 )
109
+ * self .problem .eos [Phases .PHASE2 ].sound_velocity (
110
+ arho2 / (1.0 - abar ) / (1 - ad )
111
+ )
87
112
** 2
88
113
)
89
114
90
115
# Init NR method
91
- dalpha = np .zeros_like (alpha )
116
+ dabar = np .zeros_like (abar )
92
117
iter = 0
93
118
94
119
# Index that locates the cell where there the pressures need to be relaxed
95
120
eps = 1e-9
96
- index = np .where (np .abs (phi (arho1 , arho2 , alpha )) > eps * 1e5 )
121
+ tol = 1e-5
122
+ p0 = self .problem .eos [Phases .PHASE1 ].p0
123
+ index = np .where (
124
+ (np .abs (phi (arho1 , arho2 , abar , ad )) > tol * p0 )
125
+ & (abar > eps )
126
+ & (1 - abar > eps )
127
+ )
97
128
while index [0 ].size > 0 :
98
129
# Counter
99
130
iter += 1
100
131
101
132
# NR step
102
- dalpha [index ] = - phi (
103
- arho1 [index ], arho2 [index ], alpha [index ]
104
- ) / dphi_dalpha ( arho1 [ index ], arho2 [ index ], alpha [ index ])
133
+ dabar [index ] = - phi ( arho1 [ index ], arho2 [ index ], abar [ index ], ad [ index ]) / (
134
+ dphi_dabar ( arho1 [index ], arho2 [index ], abar [index ], ad [ index ])
135
+ )
105
136
106
137
# Prevent the NR method to explore out of the interval [0,1]
107
- alpha [index ] += np .where (
108
- dalpha [index ] < 0 ,
109
- np .maximum (dalpha [index ], - 0.9 * alpha [index ]),
110
- np .minimum (dalpha [index ], 0.9 * (1 - alpha [index ])),
138
+ abar [index ] += np .where (
139
+ dabar [index ] < 0 ,
140
+ np .maximum (dabar [index ], - 0.9 * abar [index ]),
141
+ np .minimum (dabar [index ], 0.9 * (1 - abar [index ])),
111
142
)
112
- tol = 1e-6
113
- alpha = np .where (alpha < tol , 0 , alpha )
114
- alpha = np .where (1 - alpha < tol , 1 , alpha )
115
143
116
144
# Update the index where the NR method is applied
117
- index = np .where ((np .abs (phi (arho1 , arho2 , alpha )) > eps * 1e5 ))
145
+ index = np .where (
146
+ (np .abs (phi (arho1 , arho2 , abar , ad )) > tol * p0 )
147
+ & (abar > eps )
148
+ & (1 - abar > eps )
149
+ )
118
150
119
151
# Safety check
120
152
if iter > 50 :
121
153
exit ()
122
154
123
- # Update the alpha-dependent conservative field
124
- values [..., fields .arho ] = alpha * (arho1 + arho2 )
125
-
126
- def prim2Q (self , values : Q ):
127
- fields = Q .fields
128
-
129
- rho = values [..., fields .rho ]
130
- P = values [..., fields .P ]
131
- U = values [..., fields .U ]
132
- V = values [..., fields .V ]
133
-
134
- rho1 = self .problem .eos [Phases .PHASE1 ].rho (P )
135
- rho2 = self .problem .eos [Phases .PHASE2 ].rho (P )
136
- c1 = self .problem .eos [Phases .PHASE1 ].sound_velocity (rho1 )
137
- c2 = self .problem .eos [Phases .PHASE2 ].sound_velocity (rho2 )
138
-
139
- alpha = np .minimum (np .maximum ((rho - rho2 ) / (rho1 - rho2 ), 0 ), 1 )
140
- # alpha = (rho - rho2) / (rho1 - rho2)
141
-
142
- if np .any (alpha < 0.0 ) or np .any (alpha > 1.0 ):
143
- print (alpha )
144
- exit ()
145
- if np .any (rho < 0 ):
146
- print (rho )
147
- exit ()
148
-
149
- values [..., fields .arho ] = alpha * rho
150
- values [..., fields .arho1 ] = alpha * rho1
151
- values [..., fields .arho2 ] = (1 - alpha ) * rho2
152
- values [..., fields .rhoU ] = rho * U
153
- values [..., fields .rhoV ] = rho * V
154
-
155
- values [..., fields .c ] = np .sqrt (
156
- (alpha * rho1 * c1 ** 2 + (1 - alpha ) * rho2 * c2 ** 2 ) / rho
157
- )
158
- values [..., fields .alpha ] = alpha
159
- values [..., fields .p1 ] = P
160
- values [..., fields .p2 ] = P
161
- values [..., fields .c1 ] = c1
162
- values [..., fields .c2 ] = c2
155
+ # Update the abar-dependent conservative field
156
+ values [..., fields .abarrho ] = abar * rho
163
157
164
158
def auxilliaryVariableUpdate (self , values : Q ):
165
159
fields = Q .fields
166
160
167
- arho = values [..., fields .arho ]
161
+ abarrho = values [..., fields .abarrho ]
168
162
arho1 = values [..., fields .arho1 ]
169
163
arho2 = values [..., fields .arho2 ]
164
+ arho1d = values [..., fields .arho1d ]
170
165
rhoU = values [..., fields .rhoU ]
171
166
rhoV = values [..., fields .rhoV ]
167
+ ad = values [..., fields .ad ]
172
168
173
- rho = arho1 + arho2
174
- alpha = arho / rho
175
-
176
- if np .any (alpha < 0.0 ):
177
- print (alpha )
178
- exit ()
179
- # if np.any(alpha > 1.0):
180
- # print(np.where(alpha > 1))
181
- # print(alpha[np.where(alpha > 1)])
182
- # print(alpha)
183
- # exit()
169
+ rho = arho1 + arho2 + arho1d
170
+ abar = abarrho / rho
184
171
185
- alphas = PhasePair (alpha , 1.0 - alpha )
172
+ alphabars = PhasePair (abar , 1.0 - abar )
186
173
arhos = PhasePair (arho1 , arho2 )
187
174
188
- values [..., fields .alpha ] = alpha
175
+ values [..., fields .abar ] = abar
189
176
values [..., fields .rho ] = rho
190
177
values [..., fields .U ] = rhoU / rho
191
178
values [..., fields .V ] = rhoV / rho
@@ -195,11 +182,10 @@ def auxilliaryVariableUpdate(self, values: Q):
195
182
for phase in Phases :
196
183
phase_values = values .view (Q ).get_phase (phase )
197
184
198
- alpha = alphas [phase ]
185
+ alphabar = alphabars [phase ]
199
186
arho = arhos [phase ]
200
187
201
- rho = np .full_like (alpha , np .nan )
202
- np .divide (arho , alpha , where = alpha > 0 , out = rho )
188
+ rho = arho / alphabar / (1 - ad )
203
189
p = self .problem .eos [phase ].p (rho )
204
190
c = self .problem .eos [phase ].sound_velocity (rho )
205
191
@@ -210,27 +196,35 @@ def auxilliaryVariableUpdate(self, values: Q):
210
196
phase ,
211
197
phase_values ,
212
198
)
213
- if np .invert (np .isnan (c )):
214
- c_sq += arho * c ** 2
215
199
216
- values [..., fields . c ] = np . sqrt ( c_sq / values [..., fields . rho ])
200
+ c_sq += arho * c ** 2
217
201
218
- alpha = values [..., fields .alpha ]
202
+ values [..., fields .cFd ] = np .sqrt (c_sq / values [..., fields .rho ]) / (1 - ad )
203
+
204
+ abar = values [..., fields .abar ]
219
205
p1 = values [..., fields .p1 ]
220
206
p2 = values [..., fields .p2 ]
221
- values [..., fields .P ] = np .nan
222
- values [..., fields .P ] = np .where (
223
- (alpha > 0 ) * (alpha < 1 ),
224
- alpha * p1 + (1 - alpha ) * p2 ,
225
- np .where (alpha == 0 , p2 , p1 ),
207
+ values [..., fields .pbar ] = np .nan
208
+ values [..., fields .pbar ] = np .where (
209
+ (abar > 0 ) * (abar < 1 ),
210
+ abar * p1 + (1 - abar ) * p2 ,
211
+ np .where (abar == 0 , p2 , p1 ),
226
212
)
227
213
228
214
def post_extrapolation (self , values : Q ):
229
- self .prim2Q (values )
230
- # self.relaxation(values)
215
+ """During the step we update the conservative values. After the
216
+ step we update the non-conservative variables. This method updates
217
+ the values of the non-conservative (auxiliary) variables using the
218
+ :class:`~.EOS`
219
+ """
220
+
221
+ # auxilliary variables update
222
+ self .auxilliaryVariableUpdate (values )
223
+
224
+ self .relaxation (values )
231
225
232
226
# auxilliary variables update
233
- # self.auxilliaryVariableUpdate(values)
227
+ self .auxilliaryVariableUpdate (values )
234
228
235
229
def post_step (self , values : Q ):
236
230
"""During the step we update the conservative values. After the
@@ -245,6 +239,28 @@ def post_step(self, values: Q):
245
239
# auxilliary variables update
246
240
self .auxilliaryVariableUpdate (values )
247
241
242
+ def CFL (
243
+ self ,
244
+ cells : MeshCellSet ,
245
+ CFL_value ,
246
+ ) -> float :
247
+ dt = super ().CFL (cells , CFL_value )
248
+
249
+ dx = cells .min_length
250
+
251
+ # Get the velocity components
252
+ UV_slice = slice (Q .fields .U , Q .fields .V + 1 )
253
+ UV = cells .values [..., UV_slice ]
254
+
255
+ U = np .linalg .norm (UV , axis = - 1 , keepdims = True )
256
+ c = cells .values [..., Q .fields .cFd ]
257
+
258
+ sigma = np .max (np .abs (U ) + c [..., np .newaxis ])
259
+
260
+ dt = np .min ((dt , CFL_value * dx / sigma ))
261
+
262
+ return dt
263
+
248
264
249
265
class Rusanov (TSFourEqScheme ):
250
266
def intercellFlux (
@@ -286,8 +302,8 @@ def intercellFlux(
286
302
# Find the normal velocity
287
303
U = np .einsum ("...mkl,...l->...mk" , UV , normals )
288
304
U_neigh = np .einsum ("...mkl,...l->...mk" , UV_neighs , normals )
289
- c = Q_L [..., fields .c ]
290
- c_neigh = Q_R [..., fields .c ]
305
+ c = Q_L [..., fields .cFd ]
306
+ c_neigh = Q_R [..., fields .cFd ]
291
307
292
308
# Let's retrieve the values of the sigma for current cell
293
309
sigma = EulerRusanov .compute_sigma (U , U_neigh , c , c_neigh )
@@ -307,25 +323,3 @@ def intercellFlux(
307
323
)
308
324
309
325
return FS
310
-
311
- def CFL (
312
- self ,
313
- cells : MeshCellSet ,
314
- CFL_value ,
315
- ) -> float :
316
- dt = super ().CFL (cells , CFL_value )
317
-
318
- dx = cells .min_length
319
-
320
- # Get the velocity components
321
- UV_slice = slice (Q .fields .U , Q .fields .V + 1 )
322
- UV = cells .values [..., [0 ], UV_slice ]
323
-
324
- U = np .linalg .norm (UV , axis = - 1 )
325
- c = cells .values [..., [0 ], Q .fields .c ]
326
-
327
- sigma = np .max (np .abs (U ) + c [..., np .newaxis ])
328
-
329
- dt = np .min ((dt , CFL_value * dx / sigma ))
330
-
331
- return dt
0 commit comments