@@ -62,7 +62,7 @@ def constrained_transport(bx, by, flux_By_X, flux_Bx_Y, dx, dt):
6262
6363
6464# local Lax-Friedrichs/Rusanov
65- def get_flux (
65+ def get_flux_llf (
6666 rho_L ,
6767 rho_R ,
6868 vx_L ,
@@ -141,6 +141,286 @@ def get_flux(
141141 return flux_Mass , flux_Momx , flux_Momy , flux_Energy , flux_By
142142
143143
144+ # HLLD Riemann solver
145+ def get_flux_hlld (
146+ rho_L ,
147+ rho_R ,
148+ vx_L ,
149+ vx_R ,
150+ vy_L ,
151+ vy_R ,
152+ P_L ,
153+ P_R ,
154+ Bx_L ,
155+ Bx_R ,
156+ By_L ,
157+ By_R ,
158+ gamma ,
159+ ):
160+ """
161+ Calculate fluxes between 2 states with HLLD Riemann solver
162+ """
163+
164+ epsilon = 1.0e-8
165+
166+ P_L -= 0.5 * (Bx_L ** 2 + By_L ** 2 )
167+ P_R -= 0.5 * (Bx_R ** 2 + By_R ** 2 )
168+
169+ Bxi = 0.5 * (Bx_L + Bx_R )
170+
171+ Mx_L = rho_L * vx_L
172+ My_L = rho_L * vy_L
173+ E_L = (
174+ P_L / (gamma - 1.0 )
175+ + 0.5 * rho_L * (vx_L ** 2 + vy_L ** 2 )
176+ + 0.5 * (Bx_L ** 2 + By_L ** 2 )
177+ )
178+
179+ Mx_R = rho_R * vx_R
180+ My_R = rho_R * vy_R
181+ E_R = (
182+ P_R / (gamma - 1.0 )
183+ + 0.5 * rho_R * (vx_R ** 2 + vy_R ** 2 )
184+ + 0.5 * (Bx_R ** 2 + By_R ** 2 )
185+ )
186+
187+ # Step 2
188+ # Compute left & right wave speeds according to Miyoshi & Kusano, eqn. (67)
189+ #
190+
191+ pbl = 0.5 * (Bxi ** 2 + By_L ** 2 )
192+ pbr = 0.5 * (Bxi ** 2 + By_R ** 2 )
193+ gpl = gamma * P_L
194+ gpr = gamma * P_R
195+ gpbl = gpl + 2.0 * pbl
196+ gpbr = gpr + 2.0 * pbr
197+
198+ Bxsq = Bxi ** 2
199+ cfl = jnp .sqrt ((gpbl + jnp .sqrt (gpbl ** 2 - 4.0 * gpl * Bxsq )) / (2.0 * rho_L ))
200+ cfr = jnp .sqrt ((gpbr + jnp .sqrt (gpbr ** 2 - 4.0 * gpr * Bxsq )) / (2.0 * rho_R ))
201+ cfmax = jnp .maximum (cfl , cfr )
202+
203+ spd1 = (vx_L - cfmax ) * (vx_L <= vx_R ) + (vx_R - cfmax ) * (vx_L > vx_R )
204+ spd5 = (vx_R + cfmax ) * (vx_L <= vx_R ) + (vx_L + cfmax ) * (vx_L > vx_R )
205+
206+ # Step 3
207+ # Compute L/R fluxes
208+ #
209+
210+ # total pressure
211+ ptl = P_L + pbl
212+ ptr = P_R + pbr
213+
214+ FL_d = Mx_L
215+ FL_Mx = Mx_L * vx_L + ptl - Bxsq
216+ FL_My = rho_L * vx_L * vy_L - Bxi * By_L
217+ FL_E = vx_L * (E_L + ptl - Bxsq ) - Bxi * (vy_L * By_L )
218+ FL_By = By_L * vx_L - Bxi * vy_L
219+ FR_d = Mx_R
220+ FR_Mx = Mx_R * vx_R + ptr - Bxsq
221+ FR_My = rho_R * vx_R * vy_R - Bxi * By_R
222+ FR_E = vx_R * (E_R + ptr - Bxsq ) - Bxi * (vy_R * By_R )
223+ FR_By = By_R * vx_R - Bxi * vy_R
224+
225+ # Step 4
226+ # Return upwind flux if flow is supersonic
227+ #
228+
229+ # deferred to the end
230+
231+ # Step 5
232+ # Compute middle and Alfven wave speeds
233+ #
234+
235+ sdl = spd1 - vx_L
236+ sdr = spd5 - vx_R
237+
238+ # S_M: eqn (38) of Miyoshi & Kusano
239+ spd3 = (sdr * rho_R * vx_R - sdl * rho_L * vx_L - ptr + ptl ) / (
240+ sdr * rho_R - sdl * rho_L
241+ )
242+
243+ sdml = spd1 - spd3
244+ sdmr = spd5 - spd3
245+ # eqn (43) of Miyoshi & Kusano
246+ ULst_d = rho_L * sdl / sdml
247+ URst_d = rho_R * sdr / sdmr
248+ sqrtdl = jnp .sqrt (ULst_d )
249+ sqrtdr = jnp .sqrt (URst_d )
250+
251+ # eqn (51) of Miyoshi & Kusano
252+ spd2 = spd3 - jnp .abs (Bxi ) / sqrtdl
253+ spd4 = spd3 + jnp .abs (Bxi ) / sqrtdr
254+
255+ # Step 6
256+ # Compute intermediate states
257+ #
258+
259+ ptst = ptl + rho_L * sdl * (sdl - sdml )
260+
261+ # Ul*
262+ # eqn (39) of M&K
263+ ULst_Mx = ULst_d * spd3
264+ # ULst_Bx = Bxi
265+ isDegen = jnp .abs (rho_L * sdl * sdml / Bxsq - 1.0 ) < epsilon
266+
267+ # eqns (44) and (46) of M&K
268+ tmp = Bxi * (sdl - sdml ) / (rho_L * sdl * sdml - Bxsq )
269+ ULst_My = (ULst_d * vy_L ) * isDegen + (ULst_d * (vy_L - By_L * tmp )) * (~ isDegen )
270+
271+ # eqns (45) and (47) of M&K
272+ tmp = (rho_L * (sdl ) ** 2 - Bxsq ) / (rho_L * sdl * sdml - Bxsq )
273+ ULst_By = (By_L ) * isDegen + (By_L * tmp ) * (~ isDegen )
274+
275+ vbstl = (ULst_Mx * Bxi + ULst_My * ULst_By ) / ULst_d
276+ # eqn (48) of M&K#
277+ ULst_E = (
278+ sdl * E_L - ptl * vx_L + ptst * spd3 + Bxi * (vx_L * Bxi + vy_L * By_L - vbstl )
279+ ) / sdml
280+
281+ WLst_vy = ULst_My / ULst_d
282+
283+ # Ur*
284+ # eqn (39) of M&K
285+ URst_Mx = URst_d * spd3
286+ # URst_Bx = Bxi
287+ isDegen = jnp .abs (rho_R * sdr * sdmr / Bxsq - 1.0 ) < epsilon
288+
289+ # eqns (44) and (46) of M&K
290+ tmp = Bxi * (sdr - sdmr ) / (rho_R * sdr * sdmr - Bxsq )
291+ URst_My = (URst_d * vy_R ) * isDegen + (URst_d * (vy_R - By_R * tmp )) * (~ isDegen )
292+
293+ # eqns (45) and (47) of M&K
294+ tmp = (rho_R * (sdr ) ** 2 - Bxsq ) / (rho_R * sdr * sdmr - Bxsq )
295+ URst_By = (By_R ) * isDegen + (By_R * tmp ) * (~ isDegen )
296+
297+ vbstr = (URst_Mx * Bxi + URst_My * URst_By ) / URst_d
298+ # eqn (48) of M&K
299+ URst_E = (
300+ sdr * E_R - ptr * vx_R + ptst * spd3 + Bxi * (vx_R * Bxi + vy_R * By_R - vbstr )
301+ ) / sdmr
302+
303+ WRst_vy = URst_My / URst_d
304+
305+ # Ul** and Ur** - if Bx is zero, same as * -states
306+ # if(Bxi == 0.0)
307+ isDegen = 0.5 * Bxsq / jnp .minimum (pbl , pbr ) < (epsilon ) ** 2
308+ ULdst_d = ULst_d * isDegen
309+ ULdst_Mx = ULst_Mx * isDegen
310+ ULdst_My = ULst_My * isDegen
311+ ULdst_By = ULst_By * isDegen
312+ ULdst_E = ULst_E * isDegen
313+
314+ URdst_d = URst_d * isDegen
315+ URdst_Mx = URst_Mx * isDegen
316+ URdst_My = URst_My * isDegen
317+ URdst_By = URst_By * isDegen
318+ URdst_E = URst_E * isDegen
319+
320+ # else
321+ invsumd = 1.0 / (sqrtdl + sqrtdr )
322+ # Bxsig = 0 * Bxi - 1
323+ # Bxsig[Bxi > 0] = 1
324+ Bxsig = jnp .sign (Bxi )
325+
326+ ULdst_d = ULdst_d + ULst_d * (~ isDegen )
327+ URdst_d = URdst_d + URst_d * (~ isDegen )
328+
329+ ULdst_Mx = ULdst_Mx + ULst_Mx * (~ isDegen )
330+ URdst_Mx = URdst_Mx + URst_Mx * (~ isDegen )
331+
332+ # eqn (59) of M&K
333+ tmp = invsumd * (sqrtdl * WLst_vy + sqrtdr * WRst_vy + Bxsig * (URst_By - ULst_By ))
334+ ULdst_My = ULdst_My + ULdst_d * tmp * (~ isDegen )
335+ URdst_My = URdst_My + URdst_d * tmp * (~ isDegen )
336+
337+ # eqn (61) of M&K
338+ tmp = invsumd * (
339+ sqrtdl * URst_By
340+ + sqrtdr * ULst_By
341+ + Bxsig * sqrtdl * sqrtdr * (WRst_vy - WLst_vy )
342+ )
343+ ULdst_By = ULdst_By + tmp * (~ isDegen )
344+ URdst_By = URdst_By + tmp * (~ isDegen )
345+
346+ # eqn (63) of M&K
347+ tmp = spd3 * Bxi + (ULdst_My * ULdst_By ) / ULdst_d
348+ ULdst_E = ULdst_E + (ULst_E - sqrtdl * Bxsig * (vbstl - tmp )) * (~ isDegen )
349+ URdst_E = URdst_E + (URst_E + sqrtdr * Bxsig * (vbstr - tmp )) * (~ isDegen )
350+
351+ # Step 7
352+ # Compute flux
353+ #
354+
355+ flux_Mass = FL_d * (spd1 >= 0 )
356+ flux_Momx = FL_Mx * (spd1 >= 0 )
357+ flux_Momy = FL_My * (spd1 >= 0 )
358+ flux_Energy = FL_E * (spd1 >= 0 )
359+ flux_By = FL_By * (spd1 >= 0 )
360+
361+ flux_Mass += FR_d * (spd5 <= 0 )
362+ flux_Momx += FR_Mx * (spd5 <= 0 )
363+ flux_Momy += FR_My * (spd5 <= 0 )
364+ flux_Energy += FR_E * (spd5 <= 0 )
365+ flux_By += FR_By * (spd5 <= 0 )
366+
367+ # if(spd2 >= 0)
368+ # return Fl * #
369+ flux_Mass += (FL_d + spd1 * (ULst_d - rho_L )) * ((spd1 < 0 ) & (spd2 >= 0 ))
370+ flux_Momx += (FL_Mx + spd1 * (ULst_Mx - Mx_L )) * ((spd1 < 0 ) & (spd2 >= 0 ))
371+ flux_Momy += (FL_My + spd1 * (ULst_My - My_L )) * ((spd1 < 0 ) & (spd2 >= 0 ))
372+ flux_Energy += (FL_E + spd1 * (ULst_E - E_L )) * ((spd1 < 0 ) & (spd2 >= 0 ))
373+ flux_By += (FL_By + spd1 * (ULst_By - By_L )) * ((spd1 < 0 ) & (spd2 >= 0 ))
374+
375+ # elseif(spd3 >= 0)
376+ # return Fl * *
377+ tmp = spd2 - spd1
378+ flux_Mass += (FL_d - spd1 * rho_L - tmp * ULst_d + spd2 * ULdst_d ) * (
379+ (spd2 < 0 ) & (spd3 >= 0 )
380+ )
381+ flux_Momx += (FL_Mx - spd1 * Mx_L - tmp * ULst_Mx + spd2 * ULdst_Mx ) * (
382+ (spd2 < 0 ) & (spd3 >= 0 )
383+ )
384+ flux_Momy += (FL_My - spd1 * My_L - tmp * ULst_My + spd2 * ULdst_My ) * (
385+ (spd2 < 0 ) & (spd3 >= 0 )
386+ )
387+ flux_Energy += (FL_E - spd1 * E_L - tmp * ULst_E + spd2 * ULdst_E ) * (
388+ (spd2 < 0 ) & (spd3 >= 0 )
389+ )
390+ flux_By += (FL_By - spd1 * By_L - tmp * ULst_By + spd2 * ULdst_By ) * (
391+ (spd2 < 0 ) & (spd3 >= 0 )
392+ )
393+
394+ # elseif(spd4 > 0)
395+ # return Fr * *
396+ tmp = spd4 - spd5
397+ flux_Mass += (FR_d - spd5 * rho_R - tmp * URst_d + spd4 * URdst_d ) * (
398+ (spd3 < 0 ) & (spd4 > 0 )
399+ )
400+ flux_Momx += (FR_Mx - spd5 * Mx_R - tmp * URst_Mx + spd4 * URdst_Mx ) * (
401+ (spd3 < 0 ) & (spd4 > 0 )
402+ )
403+ flux_Momy += (FR_My - spd5 * My_R - tmp * URst_My + spd4 * URdst_My ) * (
404+ (spd3 < 0 ) & (spd4 > 0 )
405+ )
406+ flux_Energy += (FR_E - spd5 * E_R - tmp * URst_E + spd4 * URdst_E ) * (
407+ (spd3 < 0 ) & (spd4 > 0 )
408+ )
409+ flux_By += (FR_By - spd5 * By_R - tmp * URst_By + spd4 * URdst_By ) * (
410+ (spd3 < 0 ) & (spd4 > 0 )
411+ )
412+
413+ # else
414+ # return Fr *
415+ flux_Mass += (FR_d + spd5 * (URst_d - rho_R )) * ((spd4 <= 0 ) & (spd5 > 0 ))
416+ flux_Momx += (FR_Mx + spd5 * (URst_Mx - Mx_R )) * ((spd4 <= 0 ) & (spd5 > 0 ))
417+ flux_Momy += (FR_My + spd5 * (URst_My - My_R )) * ((spd4 <= 0 ) & (spd5 > 0 ))
418+ flux_Energy += (FR_E + spd5 * (URst_E - E_R )) * ((spd4 <= 0 ) & (spd5 > 0 ))
419+ flux_By += (FR_By + spd5 * (URst_By - By_R )) * ((spd4 <= 0 ) & (spd5 > 0 ))
420+
421+ return flux_Mass , flux_Momx , flux_Momy , flux_Energy , flux_By
422+
423+
144424def hydro_mhd2d_fluxes (rho , vx , vy , P , bx , by , gamma , dx , dt ):
145425 """Take a simulation timestep"""
146426
@@ -207,7 +487,7 @@ def hydro_mhd2d_fluxes(rho, vx, vy, P, bx, by, gamma, dx, dt):
207487 By_XL , By_XR , By_YL , By_YR = extrapolate_to_face (By_prime , By_dx , By_dy , dx )
208488
209489 # compute fluxes
210- flux_Mass_X , flux_Momx_X , flux_Momy_X , flux_Energy_X , flux_By_X = get_flux (
490+ flux_Mass_X , flux_Momx_X , flux_Momy_X , flux_Energy_X , flux_By_X = get_flux_llf (
211491 rho_XR ,
212492 rho_XL ,
213493 vx_XR ,
@@ -222,7 +502,7 @@ def hydro_mhd2d_fluxes(rho, vx, vy, P, bx, by, gamma, dx, dt):
222502 By_XL ,
223503 gamma ,
224504 )
225- flux_Mass_Y , flux_Momy_Y , flux_Momx_Y , flux_Energy_Y , flux_Bx_Y = get_flux (
505+ flux_Mass_Y , flux_Momy_Y , flux_Momx_Y , flux_Energy_Y , flux_Bx_Y = get_flux_llf (
226506 rho_YR ,
227507 rho_YL ,
228508 vy_YR ,
0 commit comments