MPI-AMRVAC  3.0
The MPI - Adaptive Mesh Refinement - Versatile Advection Code
mod_finite_volume.t
Go to the documentation of this file.
1 !> Module with finite volume methods for fluxes
3 #include "amrvac.h"
4  implicit none
5  private
6 
7  public :: finite_volume
8  public :: hancock
9  public :: reconstruct_lr
10 
11 contains
12 
13  !> The non-conservative Hancock predictor for TVDLF
14  !>
15  !> on entry:
16  !> input available on ixI^L=ixG^L asks for output on ixO^L=ixG^L^LSUBnghostcells
17  !> one entry: (predictor): wCT -- w_n wnew -- w_n qdt=dt/2
18  !> on exit : (predictor): wCT -- w_n wnew -- w_n+1/2
19  subroutine hancock(qdt,ixI^L,ixO^L,idims^LIM,qtC,sCT,qt,snew,dxs,x)
20  use mod_physics
22  use mod_source, only: addsource2
23 
24  integer, intent(in) :: ixi^l, ixo^l, idims^lim
25  double precision, intent(in) :: qdt, qtc, qt, dxs(ndim), x(ixi^s,1:ndim)
26  type(state) :: sct, snew
27 
28  double precision, dimension(ixI^S,1:nw) :: wprim, wlc, wrc
29  ! left and right constructed status in primitive form, needed for better performance
30  double precision, dimension(ixI^S,1:nw) :: wlp, wrp
31  double precision, dimension(ixO^S) :: inv_volume
32  double precision :: flc(ixi^s, nwflux), frc(ixi^s, nwflux)
33  double precision :: dxinv(1:ndim)
34  integer :: idims, iw, ix^l, hxo^l
35  logical :: active
36 
37  associate(wct=>sct%w,wnew=>snew%w)
38  ! Expand limits in each idims direction in which fluxes are added
39  ix^l=ixo^l;
40  do idims= idims^lim
41  ix^l=ix^l^laddkr(idims,^d);
42  end do
43  if (ixi^l^ltix^l|.or.|.or.) &
44  call mpistop("Error in Hancock: Nonconforming input limits")
45 
46  wprim=wct
47  call phys_to_primitive(ixi^l,ixi^l,wprim,x)
48 
49  dxinv=-qdt/dxs
50  if(.not.slab_uniform) inv_volume = 1.d0/block%dvolume(ixo^s)
51  do idims= idims^lim
52  b0i=idims
53  ! Calculate w_j+g_j/2 and w_j-g_j/2
54  ! First copy all variables, then upwind wLC and wRC.
55  ! wLC is to the left of ixO, wRC is to the right of wCT.
56  hxo^l=ixo^l-kr(idims,^d);
57 
58  wrp(hxo^s,1:nwflux)=wprim(ixo^s,1:nwflux)
59  wlp(ixo^s,1:nwflux)=wprim(ixo^s,1:nwflux)
60 
61  ! apply limited reconstruction for left and right status at cell interfaces
62  call reconstruct_lr(ixi^l,ixo^l,hxo^l,idims,wprim,wlc,wrc,wlp,wrp,x,dxs(idims))
63 
64  ! Calculate the fLC and fRC fluxes
65  call phys_get_flux(wrc,wrp,x,ixi^l,hxo^l,idims,frc)
66  call phys_get_flux(wlc,wlp,x,ixi^l,ixo^l,idims,flc)
67 
68  ! Advect w(iw)
69  if (slab_uniform) then
70  do iw=1,nwflux
71  wnew(ixo^s,iw)=wnew(ixo^s,iw)+dxinv(idims)* &
72  (flc(ixo^s, iw)-frc(hxo^s, iw))
73  end do
74  else
75  do iw=1,nwflux
76  wnew(ixo^s,iw)=wnew(ixo^s,iw) - qdt * inv_volume &
77  *(block%surfaceC(ixo^s,idims)*flc(ixo^s, iw) &
78  -block%surfaceC(hxo^s,idims)*frc(hxo^s, iw))
79  end do
80  end if
81  end do ! next idims
82  b0i=0
83 
84  if (.not.slab.and.idimsmin==1) call phys_add_source_geom(qdt,ixi^l,ixo^l,wct,wnew,x)
85 
86  call addsource2(qdt*dble(idimsmax-idimsmin+1)/dble(ndim), &
87  ixi^l,ixo^l,1,nw,qtc,wct,qt,wnew,x,.false.,active,wprim)
88 
89  ! check and optionally correct unphysical values
90  if(fix_small_values) then
91  call phys_handle_small_values(.false.,wnew,x,ixi^l,ixo^l,'exit hancock finite_volume')
92  endif
93  end associate
94  end subroutine hancock
95 
96  !> finite volume method
97  subroutine finite_volume(method,qdt,ixI^L,ixO^L,idims^LIM, &
98  qtC,sCT,qt,snew,sold,fC,fE,dxs,x)
99  use mod_physics
100  use mod_variables
102  use mod_tvd, only:tvdlimit2
103  use mod_source, only: addsource2
104  use mod_usr_methods
105 
106  integer, intent(in) :: method
107  double precision, intent(in) :: qdt, qtc, qt, dxs(ndim)
108  integer, intent(in) :: ixi^l, ixo^l, idims^lim
109  double precision, dimension(ixI^S,1:ndim), intent(in) :: x
110  type(state) :: sct, snew, sold
111  double precision, dimension(ixI^S,1:nwflux,1:ndim) :: fc
112  double precision, dimension(ixI^S,7-2*ndim:3) :: fe
113 
114  ! primitive w at cell center
115  double precision, dimension(ixI^S,1:nw) :: wprim
116  ! left and right constructed status in conservative form
117  double precision, dimension(ixI^S,1:nw) :: wlc, wrc
118  ! left and right constructed status in primitive form, needed for better performance
119  double precision, dimension(ixI^S,1:nw) :: wlp, wrp
120  double precision, dimension(ixI^S,1:nwflux) :: flc, frc
121  double precision, dimension(ixI^S,1:number_species) :: cmaxc
122  double precision, dimension(ixI^S,1:number_species) :: cminc
123  double precision, dimension(ixI^S) :: hspeed
124  double precision, dimension(ixO^S) :: inv_volume
125  double precision, dimension(1:ndim) :: dxinv
126  integer, dimension(ixI^S) :: patchf
127  integer :: idims, iw, ix^l, hxo^l, ixc^l, ixcr^l, kxc^l, kxr^l, ii
128  logical :: active
129  type(ct_velocity) :: vcts
130 
131  associate(wct=>sct%w, wnew=>snew%w, wold=>sold%w)
132 
133  fc=0.d0
134  flc=0.d0
135  frc=0.d0
136 
137  ! The flux calculation contracts by one in the idims direction it is applied.
138  ! The limiter contracts the same directions by one more, so expand ixO by 2.
139  ix^l=ixo^l;
140  do idims= idims^lim
141  ix^l=ix^l^ladd2*kr(idims,^d);
142  end do
143  if (ixi^l^ltix^l|.or.|.or.) &
144  call mpistop("Error in fv : Nonconforming input limits")
145 
146  wprim=wct
147  call phys_to_primitive(ixi^l,ixi^l,wprim,x)
148 
149  do idims= idims^lim
150  ! use interface value of w0 at idims
151  b0i=idims
152 
153  hxo^l=ixo^l-kr(idims,^d);
154 
155  kxcmin^d=iximin^d; kxcmax^d=iximax^d-kr(idims,^d);
156  kxr^l=kxc^l+kr(idims,^d);
157 
158  if(stagger_grid) then
159  ! ct needs all transverse cells
160  ixcmax^d=ixomax^d+nghostcells-nghostcells*kr(idims,^d);
161  ixcmin^d=hxomin^d-nghostcells+nghostcells*kr(idims,^d);
162  else
163  ! ixC is centered index in the idims direction from ixOmin-1/2 to ixOmax+1/2
164  ixcmax^d=ixomax^d; ixcmin^d=hxomin^d;
165  end if
166 
167  ! wRp and wLp are defined at the same locations, and will correspond to
168  ! the left and right reconstructed values at a cell face. Their indexing
169  ! is similar to cell-centered values, but in direction idims they are
170  ! shifted half a cell towards the 'lower' direction.
171  wrp(kxc^s,1:nw)=wprim(kxr^s,1:nw)
172  wlp(kxc^s,1:nw)=wprim(kxc^s,1:nw)
173 
174  ! Determine stencil size
175  {ixcrmin^d = max(ixcmin^d - phys_wider_stencil,ixglo^d)\}
176  {ixcrmax^d = min(ixcmax^d + phys_wider_stencil,ixghi^d)\}
177 
178  ! apply limited reconstruction for left and right status at cell interfaces
179  call reconstruct_lr(ixi^l,ixcr^l,ixcr^l,idims,wprim,wlc,wrc,wlp,wrp,x,dxs(idims))
180 
181  ! special modification of left and right status before flux evaluation
182  call phys_modify_wlr(ixi^l,ixcr^l,qt,wlc,wrc,wlp,wrp,sct,idims)
183 
184  ! evaluate physical fluxes according to reconstructed status
185  call phys_get_flux(wlc,wlp,x,ixi^l,ixc^l,idims,flc)
186  call phys_get_flux(wrc,wrp,x,ixi^l,ixc^l,idims,frc)
187 
188  if(h_correction) then
189  call phys_get_h_speed(wprim,x,ixi^l,ixo^l,idims,hspeed)
190  end if
191  ! estimating bounds for the minimum and maximum signal velocities
192  if(method==fs_tvdlf.or.method==fs_tvdmu) then
193  call phys_get_cbounds(wlc,wrc,wlp,wrp,x,ixi^l,ixc^l,idims,hspeed,cmaxc)
194  ! index of var velocity appears in the induction eq.
195  if(stagger_grid) call phys_get_ct_velocity(vcts,wlp,wrp,ixi^l,ixc^l,idims,cmaxc(ixi^s,index_v_mag))
196  else
197  call phys_get_cbounds(wlc,wrc,wlp,wrp,x,ixi^l,ixc^l,idims,hspeed,cmaxc,cminc)
198  if(stagger_grid) call phys_get_ct_velocity(vcts,wlp,wrp,ixi^l,ixc^l,idims,cmaxc(ixi^s,index_v_mag),cminc(ixi^s,index_v_mag))
199  end if
200 
201  ! use approximate Riemann solver to get flux at interfaces
202  select case(method)
203  case(fs_hll)
204  do ii=1,number_species
205  call get_riemann_flux_hll(start_indices(ii),stop_indices(ii))
206  end do
207  case(fs_hllc,fs_hllcd)
208  do ii=1,number_species
209  call get_riemann_flux_hllc(start_indices(ii),stop_indices(ii))
210  end do
211  case(fs_hlld)
212  do ii=1,number_species
213  if(ii==index_v_mag) then
214  call get_riemann_flux_hlld(start_indices(ii),stop_indices(ii))
215  else
216  call get_riemann_flux_hll(start_indices(ii),stop_indices(ii))
217  endif
218  end do
219  case(fs_tvdlf)
220  do ii=1,number_species
221  call get_riemann_flux_tvdlf(start_indices(ii),stop_indices(ii))
222  end do
223  case(fs_tvdmu)
225  case default
226  call mpistop('unkown Riemann flux in finite volume')
227  end select
228 
229  end do ! Next idims
230  b0i=0
231 
232  if(stagger_grid) call phys_update_faces(ixi^l,ixo^l,qt,qdt,wprim,fc,fe,sct,snew,vcts)
233 
234  if(slab_uniform) then
235  dxinv=-qdt/dxs
236  do idims= idims^lim
237  hxo^l=ixo^l-kr(idims,^d);
238 
239  ! Multiply the fluxes by -dt/dx since Flux fixing expects this
240  fc(ixi^s,1:nwflux,idims)=dxinv(idims)*fc(ixi^s,1:nwflux,idims)
241 
242  wnew(ixo^s,iwstart:nwflux)=wnew(ixo^s,iwstart:nwflux)+&
243  (fc(ixo^s,iwstart:nwflux,idims)-fc(hxo^s,iwstart:nwflux,idims))
244 
245  ! For the MUSCL scheme apply the characteristic based limiter
246  if(method==fs_tvdmu) &
247  call tvdlimit2(method,qdt,ixi^l,ixc^l,ixo^l,idims,wlc,wrc,wnew,x,fc,dxs)
248 
249  end do ! Next idims
250  else
251  inv_volume = 1.d0/block%dvolume(ixo^s)
252  do idims= idims^lim
253  hxo^l=ixo^l-kr(idims,^d);
254 
255  if(.not. angmomfix) then ! default case
256  do iw=iwstart,nwflux
257  fc(ixi^s,iw,idims)=-qdt*fc(ixi^s,iw,idims)*block%surfaceC(ixi^s,idims)
258  wnew(ixo^s,iw)=wnew(ixo^s,iw) + (fc(ixo^s,iw,idims)-fc(hxo^s,iw,idims)) * &
259  inv_volume
260  end do
261  else
262  ! If angular momentum conserving way to solve the equations,
263  ! some fluxes additions need to be treated specifically
264  call phys_angmomfix(fc,x,wnew,ixi^l,ixo^l,idims)
265  end if
266 
267  ! For the MUSCL scheme apply the characteristic based limiter
268  if (method==fs_tvdmu) &
269  call tvdlimit2(method,qdt,ixi^l,ixc^l,ixo^l,idims,wlc,wrc,wnew,x,fc,dxs)
270 
271  end do ! Next idims
272  end if
273 
274  if (.not.slab.and.idimsmin==1) &
275  call phys_add_source_geom(qdt,ixi^l,ixo^l,wct,wnew,x)
276 
277  if(stagger_grid) call phys_face_to_center(ixo^l,snew)
278 
279  ! check and optionally correct unphysical values
280  if(fix_small_values) then
281  call phys_handle_small_values(.false.,wnew,x,ixi^l,ixo^l,'multi-D finite_volume')
282  end if
283 
284  call addsource2(qdt*dble(idimsmax-idimsmin+1)/dble(ndim), &
285  ixi^l,ixo^l,1,nw,qtc,wct,qt,wnew,x,.false.,active,wprim)
286 
287  if(phys_solve_eaux.and.levmin==levmax) then
288  ! synchronize internal energy for uniform grid
289  call phys_energy_synchro(ixi^l,ixo^l,wnew,x)
290  end if
291 
292  end associate
293  contains
294 
296  do iw=iwstart,nwflux
297  ! To save memory we use fLC to store (F_L+F_R)/2=half*(fLC+fRC)
298  flc(ixc^s, iw)=half*(flc(ixc^s, iw)+frc(ixc^s, iw))
299  fc(ixc^s,iw,idims)=flc(ixc^s, iw)
300  end do
301  end subroutine get_riemann_flux_tvdmu
302 
303  subroutine get_riemann_flux_tvdlf(iws,iwe)
304  integer, intent(in) :: iws,iwe
305  double precision :: fac(ixC^S)
306 
307  fac(ixc^s) = -0.5d0*tvdlfeps*cmaxc(ixc^s,ii)
308  ! Calculate fLC=f(uL_j+1/2) and fRC=f(uR_j+1/2) for each iw
309  do iw=iws,iwe
310  ! To save memory we use fLC to store (F_L+F_R)/2=half*(fLC+fRC)
311  flc(ixc^s, iw)=0.5d0*(flc(ixc^s, iw)+frc(ixc^s, iw))
312  ! Add TVDLF dissipation to the flux
313  if (flux_type(idims, iw) /= flux_no_dissipation) then
314  flc(ixc^s, iw)=flc(ixc^s, iw) + fac(ixc^s)*(wrc(ixc^s,iw)-wlc(ixc^s,iw))
315  end if
316  fc(ixc^s,iw,idims)=flc(ixc^s, iw)
317  end do ! Next iw
318 
319  end subroutine get_riemann_flux_tvdlf
320 
321  subroutine get_riemann_flux_hll(iws,iwe)
322  integer, intent(in) :: iws,iwe
323  integer :: ix^D
324 
325  do iw=iws,iwe
326  if(flux_type(idims, iw) == flux_tvdlf) then
327  ! CT MHD does not need normal B flux
328  if(stagger_grid) cycle
329  fc(ixc^s,iw,idims) = -tvdlfeps*half*max(cmaxc(ixc^s,ii),dabs(cminc(ixc^s,ii))) * &
330  (wrc(ixc^s,iw)-wlc(ixc^s,iw))
331  else
332  {do ix^db=ixcmin^db,ixcmax^db\}
333  if(cminc(ix^d,ii) >= zero) then
334  fc(ix^d,iw,idims)=flc(ix^d,iw)
335  else if(cmaxc(ix^d,ii) <= zero) then
336  fc(ix^d,iw,idims)=frc(ix^d,iw)
337  else
338  ! Add hll dissipation to the flux
339  fc(ix^d,iw,idims)=(cmaxc(ix^d,ii)*flc(ix^d, iw)-cminc(ix^d,ii)*frc(ix^d,iw)&
340  +cminc(ix^d,ii)*cmaxc(ix^d,ii)*(wrc(ix^d,iw)-wlc(ix^d,iw)))&
341  /(cmaxc(ix^d,ii)-cminc(ix^d,ii))
342  end if
343  {end do\}
344  endif
345  end do
346 
347  end subroutine get_riemann_flux_hll
348 
349  subroutine get_riemann_flux_hllc(iws,iwe)
350  integer, intent(in) :: iws, iwe
351  double precision, dimension(ixI^S,1:nwflux) :: whll, Fhll, fCD
352  double precision, dimension(ixI^S) :: lambdaCD
353 
354  integer :: rho_, p_, e_, eaux_, mom(1:ndir)
355 
356  rho_ = iw_rho
357  if (allocated(iw_mom)) mom(:) = iw_mom(:)
358  e_ = iw_e
359  eaux_ = iw_eaux
360 
361  if(associated(phys_hllc_init_species)) then
362  call phys_hllc_init_species(ii, rho_, mom(:), e_, eaux_)
363  endif
364 
365  p_ = e_
366 
367  patchf(ixc^s) = 1
368  where(cminc(ixc^s,1) >= zero)
369  patchf(ixc^s) = -2
370  elsewhere(cmaxc(ixc^s,1) <= zero)
371  patchf(ixc^s) = 2
372  endwhere
373  ! Use more diffusive scheme, is actually TVDLF and selected by patchf=4
374  if(method==fs_hllcd) &
375  call phys_diffuse_hllcd(ixi^l,ixc^l,idims,wlc,wrc,flc,frc,patchf)
376 
377  !---- calculate speed lambda at CD ----!
378  if(any(patchf(ixc^s)==1)) &
379  call phys_get_lcd(wlc,wrc,flc,frc,cminc(ixi^s,ii),cmaxc(ixi^s,ii),idims,ixi^l,ixc^l, &
380  whll,fhll,lambdacd,patchf)
381 
382  ! now patchf may be -1 or 1 due to phys_get_lCD
383  if(any(abs(patchf(ixc^s))== 1))then
384  !======== flux at intermediate state ========!
385  call phys_get_wcd(wlc,wrc,whll,frc,flc,fhll,patchf,lambdacd,&
386  cminc(ixi^s,ii),cmaxc(ixi^s,ii),ixi^l,ixc^l,idims,fcd)
387  endif ! Calculate the CD flux
388 
389  ! use hll flux for the auxiliary internal e
390  if(phys_energy.and.phys_solve_eaux .and. eaux_>0) then
391  iw=eaux_
392  fcd(ixc^s, iw) = (cmaxc(ixc^s,ii)*flc(ixc^s, iw)-cminc(ixc^s,ii) * frc(ixc^s, iw) &
393  +cminc(ixc^s,ii)*cmaxc(ixc^s,ii)*(wrc(ixc^s,iw)-wlc(ixc^s,iw)))/(cmaxc(ixc^s,ii)-cminc(ixc^s,ii))
394  end if
395 
396  do iw=iws,iwe
397  if (flux_type(idims, iw) == flux_tvdlf) then
398  flc(ixc^s,iw)=-tvdlfeps*half*max(cmaxc(ixc^s,ii),abs(cminc(ixc^s,ii))) * &
399  (wrc(ixc^s,iw) - wlc(ixc^s,iw))
400  else
401  where(patchf(ixc^s)==-2)
402  flc(ixc^s,iw)=flc(ixc^s,iw)
403  elsewhere(abs(patchf(ixc^s))==1)
404  flc(ixc^s,iw)=fcd(ixc^s,iw)
405  elsewhere(patchf(ixc^s)==2)
406  flc(ixc^s,iw)=frc(ixc^s,iw)
407  elsewhere(patchf(ixc^s)==3)
408  ! fallback option, reducing to HLL flux
409  flc(ixc^s,iw)=fhll(ixc^s,iw)
410  elsewhere(patchf(ixc^s)==4)
411  ! fallback option, reducing to TVDLF flux
412  flc(ixc^s,iw) = half*((flc(ixc^s,iw)+frc(ixc^s,iw)) &
413  -tvdlfeps * max(cmaxc(ixc^s,ii), dabs(cminc(ixc^s,ii))) * &
414  (wrc(ixc^s,iw)-wlc(ixc^s,iw)))
415  endwhere
416  end if
417 
418  fc(ixc^s,iw,idims)=flc(ixc^s,iw)
419 
420  end do ! Next iw
421  end subroutine get_riemann_flux_hllc
422 
423  !> HLLD Riemann flux from Miyoshi 2005 JCP, 208, 315 and Guo 2016 JCP, 327, 543
424  subroutine get_riemann_flux_hlld(iws,iwe)
425  integer, intent(in) :: iws, iwe
426  double precision, dimension(ixI^S,1:nwflux) :: w1R,w1L,f1R,f1L,f2R,f2L
427  double precision, dimension(ixI^S,1:nwflux) :: w2R,w2L
428  double precision, dimension(ixI^S) :: sm,s1R,s1L,suR,suL,Bx
429  double precision, dimension(ixI^S) :: pts,ptR,ptL,signBx,r1L,r1R,tmp
430  ! velocity from the right and the left reconstruction
431  double precision, dimension(ixI^S,ndir) :: vRC, vLC
432  ! magnetic field from the right and the left reconstruction
433  double precision, dimension(ixI^S,ndir) :: BR, BL
434  integer :: ip1,ip2,ip3,idir,ix^D
435  integer :: rho_, p_, e_, eaux_, mom(1:ndir), mag(1:ndir)
436 
437  associate(sr=>cmaxc,sl=>cminc)
438 
439  rho_ = iw_rho
440  mom(:) = iw_mom(:)
441  mag(:) = iw_mag(:)
442  e_ = iw_e
443  eaux_ = iw_eaux
444 
445  p_ = e_
446 
447  f1r=0.d0
448  f1l=0.d0
449  f2r=0.d0
450  f2l=0.d0
451  w1l=0.d0
452  w1r=0.d0
453  w2l=0.d0
454  w2r=0.d0
455  ip1=idims
456  ip3=3
457  vrc(ixc^s,:)=wrp(ixc^s,mom(:))
458  vlc(ixc^s,:)=wlp(ixc^s,mom(:))
459  if(b0field) then
460  br(ixc^s,:)=wrc(ixc^s,mag(:))+block%B0(ixc^s,:,ip1)
461  bl(ixc^s,:)=wlc(ixc^s,mag(:))+block%B0(ixc^s,:,ip1)
462  else
463  br(ixc^s,:)=wrc(ixc^s,mag(:))
464  bl(ixc^s,:)=wlc(ixc^s,mag(:))
465  end if
466  if(stagger_grid) then
467  bx(ixc^s)=block%ws(ixc^s,ip1)
468  else
469  ! HLL estimation of normal magnetic field at cell interfaces
470  ! Li, Shenghai, 2005 JCP, 203, 344, equation (33)
471  bx(ixc^s)=(sr(ixc^s,ii)*br(ixc^s,ip1)-sl(ixc^s,ii)*bl(ixc^s,ip1))/(sr(ixc^s,ii)-sl(ixc^s,ii))
472  end if
473  ptr(ixc^s)=wrp(ixc^s,p_)+0.5d0*sum(br(ixc^s,:)**2,dim=ndim+1)
474  ptl(ixc^s)=wlp(ixc^s,p_)+0.5d0*sum(bl(ixc^s,:)**2,dim=ndim+1)
475  if(iw_equi_rho>0) then
476  sur(ixc^s) = wrc(ixc^s,rho_)+ block%equi_vars(ixc^s,iw_equi_rho,ip1)
477  else
478  sur(ixc^s) = wrc(ixc^s,rho_)
479  endif
480  sur(ixc^s)=(sr(ixc^s,ii)-vrc(ixc^s,ip1))*sur(ixc^s)
481  if(iw_equi_rho>0) then
482  sul(ixc^s) = wlc(ixc^s,rho_)+ block%equi_vars(ixc^s,iw_equi_rho,ip1)
483  else
484  sul(ixc^s) = wlc(ixc^s,rho_)
485  endif
486  sul(ixc^s)=(sl(ixc^s,ii)-vlc(ixc^s,ip1))*sul(ixc^s)
487  ! Miyoshi equation (38) and Guo euqation (20)
488  sm(ixc^s)=(sur(ixc^s)*vrc(ixc^s,ip1)-sul(ixc^s)*vlc(ixc^s,ip1)-&
489  ptr(ixc^s)+ptl(ixc^s))/(sur(ixc^s)-sul(ixc^s))
490  ! Miyoshi equation (39) and Guo euqation (28)
491  w1r(ixc^s,mom(ip1))=sm(ixc^s)
492  w1l(ixc^s,mom(ip1))=sm(ixc^s)
493  w2r(ixc^s,mom(ip1))=sm(ixc^s)
494  w2l(ixc^s,mom(ip1))=sm(ixc^s)
495  ! Guo equation (22)
496  w1r(ixc^s,mag(ip1))=bx(ixc^s)
497  w1l(ixc^s,mag(ip1))=bx(ixc^s)
498  if(b0field) then
499  ptr(ixc^s)=wrp(ixc^s,p_)+0.5d0*sum(wrc(ixc^s,mag(:))**2,dim=ndim+1)
500  ptl(ixc^s)=wlp(ixc^s,p_)+0.5d0*sum(wlc(ixc^s,mag(:))**2,dim=ndim+1)
501  end if
502 
503  ! Miyoshi equation (43) and Guo equation (27)
504  w1r(ixc^s,rho_)=sur(ixc^s)/(sr(ixc^s,ii)-sm(ixc^s))
505  w1l(ixc^s,rho_)=sul(ixc^s)/(sl(ixc^s,ii)-sm(ixc^s))
506 
507  ip2=mod(ip1+1,ndir)
508  if(ip2==0) ip2=ndir
509  r1r(ixc^s)=sur(ixc^s)*(sr(ixc^s,ii)-sm(ixc^s))-bx(ixc^s)**2
510  where(abs(r1r(ixc^s))>smalldouble)
511  r1r(ixc^s)=1.d0/r1r(ixc^s)
512  else where
513  r1r(ixc^s)=0.d0
514  end where
515  r1l(ixc^s)=sul(ixc^s)*(sl(ixc^s,ii)-sm(ixc^s))-bx(ixc^s)**2
516  where(abs(r1l(ixc^s))>smalldouble)
517  r1l(ixc^s)=1.d0/r1l(ixc^s)
518  else where
519  r1l(ixc^s)=0.d0
520  end where
521  ! Miyoshi equation (44)
522  w1r(ixc^s,mom(ip2))=vrc(ixc^s,ip2)-bx(ixc^s)*br(ixc^s,ip2)*&
523  (sm(ixc^s)-vrc(ixc^s,ip1))*r1r(ixc^s)
524  w1l(ixc^s,mom(ip2))=vlc(ixc^s,ip2)-bx(ixc^s)*bl(ixc^s,ip2)*&
525  (sm(ixc^s)-vlc(ixc^s,ip1))*r1l(ixc^s)
526  ! partial solution for later usage
527  w1r(ixc^s,mag(ip2))=(sur(ixc^s)*(sr(ixc^s,ii)-vrc(ixc^s,ip1))-bx(ixc^s)**2)*r1r(ixc^s)
528  w1l(ixc^s,mag(ip2))=(sul(ixc^s)*(sl(ixc^s,ii)-vlc(ixc^s,ip1))-bx(ixc^s)**2)*r1l(ixc^s)
529  if(ndir==3) then
530  ip3=mod(ip1+2,ndir)
531  if(ip3==0) ip3=ndir
532  ! Miyoshi equation (46)
533  w1r(ixc^s,mom(ip3))=vrc(ixc^s,ip3)-bx(ixc^s)*br(ixc^s,ip3)*&
534  (sm(ixc^s)-vrc(ixc^s,ip1))*r1r(ixc^s)
535  w1l(ixc^s,mom(ip3))=vlc(ixc^s,ip3)-bx(ixc^s)*bl(ixc^s,ip3)*&
536  (sm(ixc^s)-vlc(ixc^s,ip1))*r1l(ixc^s)
537  ! Miyoshi equation (47)
538  w1r(ixc^s,mag(ip3))=br(ixc^s,ip3)*w1r(ixc^s,mag(ip2))
539  w1l(ixc^s,mag(ip3))=bl(ixc^s,ip3)*w1l(ixc^s,mag(ip2))
540  end if
541  ! Miyoshi equation (45)
542  w1r(ixc^s,mag(ip2))=br(ixc^s,ip2)*w1r(ixc^s,mag(ip2))
543  w1l(ixc^s,mag(ip2))=bl(ixc^s,ip2)*w1l(ixc^s,mag(ip2))
544  if(b0field) then
545  ! Guo equation (26)
546  w1r(ixc^s,mag(:))=w1r(ixc^s,mag(:))-block%B0(ixc^s,:,ip1)
547  w1l(ixc^s,mag(:))=w1l(ixc^s,mag(:))-block%B0(ixc^s,:,ip1)
548  end if
549  ! equation (48)
550  if(phys_energy) then
551  ! Guo equation (25) equivalent to Miyoshi equation (41)
552  w1r(ixc^s,p_)=sur(ixc^s)*(sm(ixc^s)-vrc(ixc^s,ip1))+ptr(ixc^s)
553  !w1L(ixC^S,p_)=suL(ixC^S)*(sm(ixC^S)-vLC(ixC^S,ip1))+ptL(ixC^S)
554  w1l(ixc^s,p_)=w1r(ixc^s,p_)
555  if(b0field) then
556  ! Guo equation (32)
557  w1r(ixc^s,p_)=w1r(ixc^s,p_)+sum(block%B0(ixc^s,:,ip1)*(wrc(ixc^s,mag(:))-w1r(ixc^s,mag(:))),dim=ndim+1)
558  w1l(ixc^s,p_)=w1l(ixc^s,p_)+sum(block%B0(ixc^s,:,ip1)*(wlc(ixc^s,mag(:))-w1l(ixc^s,mag(:))),dim=ndim+1)
559  end if
560  ! Miyoshi equation (48) and main part of Guo euqation (31)
561  w1r(ixc^s,e_)=((sr(ixc^s,ii)-vrc(ixc^s,ip1))*wrc(ixc^s,e_)-ptr(ixc^s)*vrc(ixc^s,ip1)+&
562  w1r(ixc^s,p_)*sm(ixc^s)+bx(ixc^s)*(sum(vrc(ixc^s,:)*wrc(ixc^s,mag(:)),dim=ndim+1)-&
563  sum(w1r(ixc^s,mom(:))*w1r(ixc^s,mag(:)),dim=ndim+1)))/(sr(ixc^s,ii)-sm(ixc^s))
564  w1l(ixc^s,e_)=((sl(ixc^s,ii)-vlc(ixc^s,ip1))*wlc(ixc^s,e_)-ptl(ixc^s)*vlc(ixc^s,ip1)+&
565  w1l(ixc^s,p_)*sm(ixc^s)+bx(ixc^s)*(sum(vlc(ixc^s,:)*wlc(ixc^s,mag(:)),dim=ndim+1)-&
566  sum(w1l(ixc^s,mom(:))*w1l(ixc^s,mag(:)),dim=ndim+1)))/(sl(ixc^s,ii)-sm(ixc^s))
567  if(b0field) then
568  ! Guo equation (31)
569  w1r(ixc^s,e_)=w1r(ixc^s,e_)+(sum(w1r(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*sm(ixc^s)-&
570  sum(wrc(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*vrc(ixc^s,ip1))/(sr(ixc^s,ii)-sm(ixc^s))
571  w1l(ixc^s,e_)=w1l(ixc^s,e_)+(sum(w1l(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*sm(ixc^s)-&
572  sum(wlc(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*vlc(ixc^s,ip1))/(sl(ixc^s,ii)-sm(ixc^s))
573  end if
574  if(iw_equi_p>0) then
575 #if !defined(E_RM_W0) || E_RM_W0 == 1
576  w1r(ixc^s,e_)= w1r(ixc^s,e_) + 1d0/(phys_gamma - 1) * block%equi_vars(ixc^s,iw_equi_p,ip1) * &
577  (sm(ixc^s)-vrc(ixc^s,ip1))/(sr(ixc^s,ii)-sm(ixc^s))
578  w1l(ixc^s,e_)= w1l(ixc^s,e_) + 1d0/(phys_gamma - 1) * block%equi_vars(ixc^s,iw_equi_p,ip1) * &
579  (sm(ixc^s)-vlc(ixc^s,ip1))/(sl(ixc^s,ii)-sm(ixc^s))
580 #else
581  w1r(ixc^s,e_)= w1r(ixc^s,e_) + phys_gamma /(phys_gamma - 1) * block%equi_vars(ixc^s,iw_equi_p,ip1) * &
582  (sm(ixc^s)-vrc(ixc^s,ip1))/(sr(ixc^s,ii)-sm(ixc^s))
583  w1l(ixc^s,e_)= w1l(ixc^s,e_) + phys_gamma /(phys_gamma - 1) * block%equi_vars(ixc^s,iw_equi_p,ip1) * &
584  (sm(ixc^s)-vlc(ixc^s,ip1))/(sl(ixc^s,ii)-sm(ixc^s))
585 #endif
586  endif
587  end if
588 
589  ! Miyoshi equation (49) and Guo equation (35)
590  w2r(ixc^s,rho_)=w1r(ixc^s,rho_)
591  w2l(ixc^s,rho_)=w1l(ixc^s,rho_)
592  w2r(ixc^s,mag(ip1))=w1r(ixc^s,mag(ip1))
593  w2l(ixc^s,mag(ip1))=w1l(ixc^s,mag(ip1))
594 
595  r1r(ixc^s)=sqrt(w1r(ixc^s,rho_))
596  r1l(ixc^s)=sqrt(w1l(ixc^s,rho_))
597  tmp(ixc^s)=1.d0/(r1r(ixc^s)+r1l(ixc^s))
598  signbx(ixc^s)=sign(1.d0,bx(ixc^s))
599  ! Miyoshi equation (51) and Guo equation (33)
600  s1r(ixc^s)=sm(ixc^s)+abs(bx(ixc^s))/r1r(ixc^s)
601  s1l(ixc^s)=sm(ixc^s)-abs(bx(ixc^s))/r1l(ixc^s)
602  ! Miyoshi equation (59) and Guo equation (41)
603  w2r(ixc^s,mom(ip2))=(r1l(ixc^s)*w1l(ixc^s,mom(ip2))+r1r(ixc^s)*w1r(ixc^s,mom(ip2))+&
604  (w1r(ixc^s,mag(ip2))-w1l(ixc^s,mag(ip2)))*signbx(ixc^s))*tmp(ixc^s)
605  w2l(ixc^s,mom(ip2))=w2r(ixc^s,mom(ip2))
606  ! Miyoshi equation (61) and Guo equation (43)
607  w2r(ixc^s,mag(ip2))=(r1l(ixc^s)*w1r(ixc^s,mag(ip2))+r1r(ixc^s)*w1l(ixc^s,mag(ip2))+&
608  r1l(ixc^s)*r1r(ixc^s)*(w1r(ixc^s,mom(ip2))-w1l(ixc^s,mom(ip2)))*signbx(ixc^s))*tmp(ixc^s)
609  w2l(ixc^s,mag(ip2))=w2r(ixc^s,mag(ip2))
610  if(ndir==3) then
611  ! Miyoshi equation (60) and Guo equation (42)
612  w2r(ixc^s,mom(ip3))=(r1l(ixc^s)*w1l(ixc^s,mom(ip3))+r1r(ixc^s)*w1r(ixc^s,mom(ip3))+&
613  (w1r(ixc^s,mag(ip3))-w1l(ixc^s,mag(ip3)))*signbx(ixc^s))*tmp(ixc^s)
614  w2l(ixc^s,mom(ip3))=w2r(ixc^s,mom(ip3))
615  ! Miyoshi equation (62) and Guo equation (44)
616  w2r(ixc^s,mag(ip3))=(r1l(ixc^s)*w1r(ixc^s,mag(ip3))+r1r(ixc^s)*w1l(ixc^s,mag(ip3))+&
617  r1l(ixc^s)*r1r(ixc^s)*(w1r(ixc^s,mom(ip3))-w1l(ixc^s,mom(ip3)))*signbx(ixc^s))*tmp(ixc^s)
618  w2l(ixc^s,mag(ip3))=w2r(ixc^s,mag(ip3))
619  end if
620  ! Miyoshi equation (63) and Guo equation (45)
621  if(phys_energy) then
622  w2r(ixc^s,e_)=w1r(ixc^s,e_)+r1r(ixc^s)*(sum(w1r(ixc^s,mom(:))*w1r(ixc^s,mag(:)),dim=ndim+1)-&
623  sum(w2r(ixc^s,mom(:))*w2r(ixc^s,mag(:)),dim=ndim+1))*signbx(ixc^s)
624  w2l(ixc^s,e_)=w1l(ixc^s,e_)-r1l(ixc^s)*(sum(w1l(ixc^s,mom(:))*w1l(ixc^s,mag(:)),dim=ndim+1)-&
625  sum(w2l(ixc^s,mom(:))*w2l(ixc^s,mag(:)),dim=ndim+1))*signbx(ixc^s)
626  end if
627 
628  ! convert velocity to momentum
629  do idir=1,ndir
630  w1r(ixc^s,mom(idir))=w1r(ixc^s,mom(idir))*w1r(ixc^s,rho_)
631  w1l(ixc^s,mom(idir))=w1l(ixc^s,mom(idir))*w1l(ixc^s,rho_)
632  w2r(ixc^s,mom(idir))=w2r(ixc^s,mom(idir))*w2r(ixc^s,rho_)
633  w2l(ixc^s,mom(idir))=w2l(ixc^s,mom(idir))*w2l(ixc^s,rho_)
634  end do
635  if(iw_equi_rho>0) then
636  w1r(ixc^s,rho_) = w1r(ixc^s,rho_) - block%equi_vars(ixc^s,iw_equi_rho,ip1)
637  w1l(ixc^s,rho_) = w1l(ixc^s,rho_) - block%equi_vars(ixc^s,iw_equi_rho,ip1)
638  w2r(ixc^s,rho_) = w2r(ixc^s,rho_) - block%equi_vars(ixc^s,iw_equi_rho,ip1)
639  w2l(ixc^s,rho_) = w2l(ixc^s,rho_) - block%equi_vars(ixc^s,iw_equi_rho,ip1)
640  endif
641  ! get fluxes of intermedate states
642  do iw=iws,iwe
643  if(flux_type(idims, iw) == flux_special) then
644  ! known flux (fLC=fRC) for normal B and psi_ in GLM method
645  f1l(ixc^s,iw)=flc(ixc^s,iw)
646  f1r(ixc^s,iw)=f1l(ixc^s,iw)
647  f2l(ixc^s,iw)=f1l(ixc^s,iw)
648  f2r(ixc^s,iw)=f1l(ixc^s,iw)
649  else if(flux_type(idims, iw) == flux_hll) then
650  ! using hll flux for eaux and tracers
651  f1l(ixc^s,iw)=(sr(ixc^s,ii)*flc(ixc^s, iw)-sl(ixc^s,ii)*frc(ixc^s, iw) &
652  +sr(ixc^s,ii)*sl(ixc^s,ii)*(wrc(ixc^s,iw)-wlc(ixc^s,iw)))/(sr(ixc^s,ii)-sl(ixc^s,ii))
653  f1r(ixc^s,iw)=f1l(ixc^s,iw)
654  f2l(ixc^s,iw)=f1l(ixc^s,iw)
655  f2r(ixc^s,iw)=f1l(ixc^s,iw)
656  else
657  ! construct hlld flux
658  f1l(ixc^s,iw)=flc(ixc^s,iw)+sl(ixc^s,ii)*(w1l(ixc^s,iw)-wlc(ixc^s,iw))
659  f1r(ixc^s,iw)=frc(ixc^s,iw)+sr(ixc^s,ii)*(w1r(ixc^s,iw)-wrc(ixc^s,iw))
660  f2l(ixc^s,iw)=f1l(ixc^s,iw)+s1l(ixc^s)*(w2l(ixc^s,iw)-w1l(ixc^s,iw))
661  f2r(ixc^s,iw)=f1r(ixc^s,iw)+s1r(ixc^s)*(w2r(ixc^s,iw)-w1r(ixc^s,iw))
662  end if
663  end do
664 
665  ! Miyoshi equation (66) and Guo equation (46)
666  {do ix^db=ixcmin^db,ixcmax^db\}
667  if(sl(ix^d,ii)>0.d0) then
668  fc(ix^d,iws:iwe,ip1)=flc(ix^d,iws:iwe)
669  else if(s1l(ix^d)>=0.d0) then
670  fc(ix^d,iws:iwe,ip1)=f1l(ix^d,iws:iwe)
671  else if(sm(ix^d)>=0.d0) then
672  fc(ix^d,iws:iwe,ip1)=f2l(ix^d,iws:iwe)
673  else if(s1r(ix^d)>=0.d0) then
674  fc(ix^d,iws:iwe,ip1)=f2r(ix^d,iws:iwe)
675  else if(sr(ix^d,ii)>=0.d0) then
676  fc(ix^d,iws:iwe,ip1)=f1r(ix^d,iws:iwe)
677  else if(sr(ix^d,ii)<0.d0) then
678  fc(ix^d,iws:iwe,ip1)=frc(ix^d,iws:iwe)
679  end if
680  {end do\}
681 
682  end associate
683  end subroutine get_riemann_flux_hlld
684 
685  !> HLLD Riemann flux from Miyoshi 2005 JCP, 208, 315 and Guo 2016 JCP, 327, 543
686  !> https://arxiv.org/pdf/2108.04991.pdf
687  subroutine get_riemann_flux_hlld_mag2()
688  !use mod_mhd_phys
689  use mod_variables
690  use mod_physics
691  implicit none
692  double precision, dimension(ixI^S,1:nwflux) :: w1R,w1L,f1R,f1L,f2R,f2L
693  double precision, dimension(ixI^S,1:nwflux) :: w2R,w2L
694  double precision, dimension(ixI^S) :: sm,s1R,s1L,suR,suL,Bx
695  double precision, dimension(ixI^S) :: pts,ptR,ptL,signBx,r1L,r1R,tmp
696  ! velocity from the right and the left reconstruction
697  double precision, dimension(ixI^S,ndir) :: vRC, vLC
698  ! magnetic field from the right and the left reconstruction
699  double precision, dimension(ixI^S,ndir) :: BR, BL
700  integer :: ip1,ip2,ip3,idir,ix^D
701  double precision :: phiPres, thetaSM, du, dv, dw
702  integer :: ixV^L, ixVb^L, ixVc^L, ixVd^L, ixVe^L, ixVf^L
703  integer :: rho_, p_, e_, eaux_, mom(1:ndir), mag(1:ndir)
704  double precision, parameter :: aParam = 4d0
705 
706  rho_ = iw_rho
707  mom(:) = iw_mom(:)
708  mag(:) = iw_mag(:)
709  p_ = iw_e
710  e_ = iw_e
711  eaux_ = iw_eaux
712 
713  associate(sr=>cmaxc,sl=>cminc)
714 
715  f1r=0.d0
716  f1l=0.d0
717  ip1=idims
718  ip3=3
719 
720  vrc(ixc^s,:)=wrp(ixc^s,mom(:))
721  vlc(ixc^s,:)=wlp(ixc^s,mom(:))
722 
723  ! reuse s1L s1R
724  call get_hlld2_modif_c(wlp,x,ixi^l,ixo^l,s1l)
725  call get_hlld2_modif_c(wrp,x,ixi^l,ixo^l,s1r)
726  !phiPres = min(1, maxval(max(s1L(ixO^S),s1R(ixO^S))/cmaxC(ixO^S,1)))
727  phipres = min(1d0, maxval(max(s1l(ixo^s),s1r(ixo^s)))/maxval(cmaxc(ixo^s,1)))
728  phipres = phipres*(2d0 - phipres)
729 
730  !we use here not reconstructed velocity: wprim?
731  ixv^l=ixo^l;
732  !first dim
733  ixvmin1=ixomin1+1
734  ixvmax1=ixomax1+1
735  du = minval(wprim(ixv^s,mom(1))-wprim(ixo^s,mom(1)))
736  if(du>0d0) du=0d0
737  dv = 0d0
738  dw = 0d0
739 
740  {^nooned
741  !second dim
742  !i,j-1,k
743  ixv^l=ixo^l;
744  ixvmin2=ixomin2-1
745  ixvmax2=ixomax2-1
746 
747  !i,j+1,k
748  ixvb^l=ixo^l;
749  ixvbmin2=ixomin2+1
750  ixvbmax2=ixomax2+1
751 
752  !i+1,j,k
753  ixvc^l=ixo^l;
754  ixvcmin1=ixomin1+1
755  ixvcmax1=ixomax1+1
756 
757  !i+1,j-1,k
758  ixvd^l=ixo^l;
759  ixvdmin1=ixomin1+1
760  ixvdmax1=ixomax1+1
761  ixvdmin2=ixomin2-1
762  ixvdmax2=ixomax2-1
763 
764  !i+1,j+1,k
765  ixve^l=ixo^l;
766  ixvemin1=ixomin1+1
767  ixvemax1=ixomax1+1
768  ixvemin2=ixomin2+1
769  ixvemax2=ixomax2+1
770 
771  dv = minval(min(wprim(ixo^s,mom(2))-wprim(ixv^s,mom(2)),&
772  wprim(ixvb^s,mom(2))-wprim(ixo^s,mom(2)),&
773  wprim(ixvc^s,mom(2))-wprim(ixvd^s,mom(2)),&
774  wprim(ixve^s,mom(2))-wprim(ixvc^s,mom(2))&
775  ))
776  if(dv>0d0) dv=0d0}
777 
778  {^ifthreed
779  !third dim
780  !i,j,k-1
781  ixv^l=ixo^l;
782  ixvmin3=ixomin3-1
783  ixvmax3=ixomax3-1
784 
785  !i,j,k+1
786  ixvb^l=ixo^l;
787  ixvbmin3=ixomin3+1
788  ixvbmax3=ixomax3+1
789 
790  !i+1,j,k
791  ixvc^l=ixo^l;
792  ixvcmin1=ixomin1+1
793  ixvcmax1=ixomax1+1
794 
795  !i+1,j,k-1
796  ixvd^l=ixo^l;
797  ixvdmin1=ixomin1+1
798  ixvdmax1=ixomax1+1
799  ixvdmin3=ixomin3-1
800  ixvdmax3=ixomax3-1
801 
802  !i+1,j,k+1
803  ixve^l=ixo^l;
804  ixvemin1=ixomin1+1
805  ixvemax1=ixomax1+1
806  ixvemin3=ixomin3+1
807  ixvemax3=ixomax3+1
808  dw = minval(min(wprim(ixo^s,mom(3))-wprim(ixv^s,mom(3)),&
809  wprim(ixvb^s,mom(3))-wprim(ixo^s,mom(3)),&
810  wprim(ixvc^s,mom(3))-wprim(ixvd^s,mom(3)),&
811  wprim(ixve^s,mom(3))-wprim(ixvc^s,mom(3))&
812  ))
813  if(dw>0d0) dw=0d0}
814  thetasm = maxval(cmaxc(ixo^s,1))
815 
816  thetasm = (min(1d0, (thetasm-du)/(thetasm-min(dv,dw))))**aparam
817  !print*, "HLLD2 ", du,dv,dw, thetaSM, phiPres
818 
819  if(b0field) then
820  br(ixc^s,:)=wrc(ixc^s,mag(:))+block%B0(ixc^s,:,ip1)
821  bl(ixc^s,:)=wlc(ixc^s,mag(:))+block%B0(ixc^s,:,ip1)
822  else
823  br(ixc^s,:)=wrc(ixc^s,mag(:))
824  bl(ixc^s,:)=wlc(ixc^s,mag(:))
825  end if
826  ! HLL estimation of normal magnetic field at cell interfaces
827  bx(ixc^s)=(sr(ixc^s,index_v_mag)*br(ixc^s,ip1)-sl(ixc^s,index_v_mag)*bl(ixc^s,ip1)-&
828  flc(ixc^s,mag(ip1))-frc(ixc^s,mag(ip1)))/(sr(ixc^s,index_v_mag)-sl(ixc^s,index_v_mag))
829  ptr(ixc^s)=wrp(ixc^s,p_)+0.5d0*sum(br(ixc^s,:)**2,dim=ndim+1)
830  ptl(ixc^s)=wlp(ixc^s,p_)+0.5d0*sum(bl(ixc^s,:)**2,dim=ndim+1)
831  sur(ixc^s)=(sr(ixc^s,index_v_mag)-vrc(ixc^s,ip1))*wrc(ixc^s,rho_)
832  sul(ixc^s)=(sl(ixc^s,index_v_mag)-vlc(ixc^s,ip1))*wlc(ixc^s,rho_)
833  ! Miyoshi equation (38) and Guo euqation (20)
834  sm(ixc^s)=(sur(ixc^s)*vrc(ixc^s,ip1)-sul(ixc^s)*vlc(ixc^s,ip1)-&
835  thetasm*(ptr(ixc^s)-ptl(ixc^s)) )/(sur(ixc^s)-sul(ixc^s))
836  ! Miyoshi equation (39) and Guo euqation (28)
837  w1r(ixc^s,mom(ip1))=sm(ixc^s)
838  w1l(ixc^s,mom(ip1))=sm(ixc^s)
839  w2r(ixc^s,mom(ip1))=sm(ixc^s)
840  w2l(ixc^s,mom(ip1))=sm(ixc^s)
841  ! Guo equation (22)
842  w1r(ixc^s,mag(ip1))=bx(ixc^s)
843  w1l(ixc^s,mag(ip1))=bx(ixc^s)
844  if(b0field) then
845  ptr(ixc^s)=wrp(ixc^s,p_)+0.5d0*sum(wrc(ixc^s,mag(:))**2,dim=ndim+1)
846  ptl(ixc^s)=wlp(ixc^s,p_)+0.5d0*sum(wlc(ixc^s,mag(:))**2,dim=ndim+1)
847  end if
848 
849  ! Miyoshi equation (43) and Guo equation (27)
850  w1r(ixc^s,rho_)=sur(ixc^s)/(sr(ixc^s,index_v_mag)-sm(ixc^s))
851  w1l(ixc^s,rho_)=sul(ixc^s)/(sl(ixc^s,index_v_mag)-sm(ixc^s))
852 
853  ip2=mod(ip1+1,ndir)
854  if(ip2==0) ip2=ndir
855  r1r(ixc^s)=sur(ixc^s)*(sr(ixc^s,index_v_mag)-sm(ixc^s))-bx(ixc^s)**2
856  where(r1r(ixc^s)/=0.d0)
857  r1r(ixc^s)=1.d0/r1r(ixc^s)
858  endwhere
859  r1l(ixc^s)=sul(ixc^s)*(sl(ixc^s,index_v_mag)-sm(ixc^s))-bx(ixc^s)**2
860  where(r1l(ixc^s)/=0.d0)
861  r1l(ixc^s)=1.d0/r1l(ixc^s)
862  endwhere
863  ! Miyoshi equation (44)
864  w1r(ixc^s,mom(ip2))=vrc(ixc^s,ip2)-bx(ixc^s)*br(ixc^s,ip2)*&
865  (sm(ixc^s)-vrc(ixc^s,ip1))*r1r(ixc^s)
866  w1l(ixc^s,mom(ip2))=vlc(ixc^s,ip2)-bx(ixc^s)*bl(ixc^s,ip2)*&
867  (sm(ixc^s)-vlc(ixc^s,ip1))*r1l(ixc^s)
868  ! partial solution for later usage
869  w1r(ixc^s,mag(ip2))=(sur(ixc^s)*(sr(ixc^s,index_v_mag)-vrc(ixc^s,ip1))-bx(ixc^s)**2)*r1r(ixc^s)
870  w1l(ixc^s,mag(ip2))=(sul(ixc^s)*(sl(ixc^s,index_v_mag)-vlc(ixc^s,ip1))-bx(ixc^s)**2)*r1l(ixc^s)
871  if(ndir==3) then
872  ip3=mod(ip1+2,ndir)
873  if(ip3==0) ip3=ndir
874  ! Miyoshi equation (46)
875  w1r(ixc^s,mom(ip3))=vrc(ixc^s,ip3)-bx(ixc^s)*br(ixc^s,ip3)*&
876  (sm(ixc^s)-vrc(ixc^s,ip1))*r1r(ixc^s)
877  w1l(ixc^s,mom(ip3))=vlc(ixc^s,ip3)-bx(ixc^s)*bl(ixc^s,ip3)*&
878  (sm(ixc^s)-vlc(ixc^s,ip1))*r1l(ixc^s)
879  ! Miyoshi equation (47)
880  w1r(ixc^s,mag(ip3))=br(ixc^s,ip3)*w1r(ixc^s,mag(ip2))
881  w1l(ixc^s,mag(ip3))=bl(ixc^s,ip3)*w1l(ixc^s,mag(ip2))
882  end if
883  ! Miyoshi equation (45)
884  w1r(ixc^s,mag(ip2))=br(ixc^s,ip2)*w1r(ixc^s,mag(ip2))
885  w1l(ixc^s,mag(ip2))=bl(ixc^s,ip2)*w1l(ixc^s,mag(ip2))
886  if(b0field) then
887  ! Guo equation (26)
888  w1r(ixc^s,mag(:))=w1r(ixc^s,mag(:))-block%B0(ixc^s,:,ip1)
889  w1l(ixc^s,mag(:))=w1l(ixc^s,mag(:))-block%B0(ixc^s,:,ip1)
890  end if
891  ! equation (48)
892  if(phys_energy) then
893  ! Guo equation (25) equivalent to Miyoshi equation (41)
894  w1r(ixc^s,p_)=(sur(ixc^s)*ptl(ixc^s) - sul(ixc^s)*ptr(ixc^s) +&
895  phipres * sur(ixc^s)*sul(ixc^s)*(vrc(ixc^s,ip1)-vlc(ixc^s,ip1)))/&
896  (sur(ixc^s)-sul(ixc^s))
897  w1l(ixc^s,p_)=w1r(ixc^s,p_)
898  !if(mhd_solve_eaux) then
899  ! w1R(ixC^S,eaux_)=(w1R(ixC^S,p_)-half*sum(w1R(ixC^S,mag(:))**2,dim=ndim+1))/(mhd_gamma-one)
900  ! w1L(ixC^S,eaux_)=(w1L(ixC^S,p_)-half*sum(w1L(ixC^S,mag(:))**2,dim=ndim+1))/(mhd_gamma-one)
901  !end if
902  if(b0field) then
903  ! Guo equation (32)
904  w1r(ixc^s,p_)=w1r(ixc^s,p_)+sum(block%B0(ixc^s,:,ip1)*(wrc(ixc^s,mag(:))-w1r(ixc^s,mag(:))),dim=ndim+1)
905  w1l(ixc^s,p_)=w1l(ixc^s,p_)+sum(block%B0(ixc^s,:,ip1)*(wlc(ixc^s,mag(:))-w1l(ixc^s,mag(:))),dim=ndim+1)
906  end if
907  ! Miyoshi equation (48) and main part of Guo euqation (31)
908  w1r(ixc^s,e_)=((sr(ixc^s,index_v_mag)-vrc(ixc^s,ip1))*wrc(ixc^s,e_)-ptr(ixc^s)*vrc(ixc^s,ip1)+&
909  w1r(ixc^s,p_)*sm(ixc^s)+bx(ixc^s)*(sum(vrc(ixc^s,:)*wrc(ixc^s,mag(:)),dim=ndim+1)-&
910  sum(w1r(ixc^s,mom(:))*w1r(ixc^s,mag(:)),dim=ndim+1)))/(sr(ixc^s,index_v_mag)-sm(ixc^s))
911  w1l(ixc^s,e_)=((sl(ixc^s,index_v_mag)-vlc(ixc^s,ip1))*wlc(ixc^s,e_)-ptl(ixc^s)*vlc(ixc^s,ip1)+&
912  w1l(ixc^s,p_)*sm(ixc^s)+bx(ixc^s)*(sum(vlc(ixc^s,:)*wlc(ixc^s,mag(:)),dim=ndim+1)-&
913  sum(w1l(ixc^s,mom(:))*w1l(ixc^s,mag(:)),dim=ndim+1)))/(sl(ixc^s,index_v_mag)-sm(ixc^s))
914  if(b0field) then
915  ! Guo equation (31)
916  w1r(ixc^s,e_)=w1r(ixc^s,e_)+(sum(w1r(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*sm(ixc^s)-&
917  sum(wrc(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*vrc(ixc^s,ip1))/(sr(ixc^s,index_v_mag)-sm(ixc^s))
918  w1l(ixc^s,e_)=w1l(ixc^s,e_)+(sum(w1l(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*sm(ixc^s)-&
919  sum(wlc(ixc^s,mag(:))*block%B0(ixc^s,:,ip1),dim=ndim+1)*vlc(ixc^s,ip1))/(sl(ixc^s,index_v_mag)-sm(ixc^s))
920  end if
921  end if
922 
923  ! Miyoshi equation (49) and Guo equation (35)
924  w2r(ixc^s,rho_)=w1r(ixc^s,rho_)
925  w2l(ixc^s,rho_)=w1l(ixc^s,rho_)
926  w2r(ixc^s,mag(ip1))=w1r(ixc^s,mag(ip1))
927  w2l(ixc^s,mag(ip1))=w1l(ixc^s,mag(ip1))
928 
929  r1r(ixc^s)=sqrt(w1r(ixc^s,rho_))
930  r1l(ixc^s)=sqrt(w1l(ixc^s,rho_))
931  tmp(ixc^s)=1.d0/(r1r(ixc^s)+r1l(ixc^s))
932  signbx(ixc^s)=sign(1.d0,bx(ixc^s))
933  ! Miyoshi equation (51) and Guo equation (33)
934  s1r(ixc^s)=sm(ixc^s)+abs(bx(ixc^s))/r1r(ixc^s)
935  s1l(ixc^s)=sm(ixc^s)-abs(bx(ixc^s))/r1l(ixc^s)
936  ! Miyoshi equation (59) and Guo equation (41)
937  w2r(ixc^s,mom(ip2))=(r1l(ixc^s)*w1l(ixc^s,mom(ip2))+r1r(ixc^s)*w1r(ixc^s,mom(ip2))+&
938  (w1r(ixc^s,mag(ip2))-w1l(ixc^s,mag(ip2)))*signbx(ixc^s))*tmp(ixc^s)
939  w2l(ixc^s,mom(ip2))=w2r(ixc^s,mom(ip2))
940  ! Miyoshi equation (61) and Guo equation (43)
941  w2r(ixc^s,mag(ip2))=(r1l(ixc^s)*w1r(ixc^s,mag(ip2))+r1r(ixc^s)*w1l(ixc^s,mag(ip2))+&
942  r1l(ixc^s)*r1r(ixc^s)*(w1r(ixc^s,mom(ip2))-w1l(ixc^s,mom(ip2)))*signbx(ixc^s))*tmp(ixc^s)
943  w2l(ixc^s,mag(ip2))=w2r(ixc^s,mag(ip2))
944  if(ndir==3) then
945  ! Miyoshi equation (60) and Guo equation (42)
946  w2r(ixc^s,mom(ip3))=(r1l(ixc^s)*w1l(ixc^s,mom(ip3))+r1r(ixc^s)*w1r(ixc^s,mom(ip3))+&
947  (w1r(ixc^s,mag(ip3))-w1l(ixc^s,mag(ip3)))*signbx(ixc^s))*tmp(ixc^s)
948  w2l(ixc^s,mom(ip3))=w2r(ixc^s,mom(ip3))
949  ! Miyoshi equation (62) and Guo equation (44)
950  w2r(ixc^s,mag(ip3))=(r1l(ixc^s)*w1r(ixc^s,mag(ip3))+r1r(ixc^s)*w1l(ixc^s,mag(ip3))+&
951  r1l(ixc^s)*r1r(ixc^s)*(w1r(ixc^s,mom(ip3))-w1l(ixc^s,mom(ip3)))*signbx(ixc^s))*tmp(ixc^s)
952  w2l(ixc^s,mag(ip3))=w2r(ixc^s,mag(ip3))
953  end if
954  ! Miyoshi equation (63) and Guo equation (45)
955  if(phys_energy) then
956  w2r(ixc^s,e_)=w1r(ixc^s,e_)+r1r(ixc^s)*(sum(w1r(ixc^s,mom(:))*w1r(ixc^s,mag(:)),dim=ndim+1)-&
957  sum(w2r(ixc^s,mom(:))*w2r(ixc^s,mag(:)),dim=ndim+1))*signbx(ixc^s)
958  w2l(ixc^s,e_)=w1l(ixc^s,e_)-r1l(ixc^s)*(sum(w1l(ixc^s,mom(:))*w1l(ixc^s,mag(:)),dim=ndim+1)-&
959  sum(w2l(ixc^s,mom(:))*w2l(ixc^s,mag(:)),dim=ndim+1))*signbx(ixc^s)
960  end if
961 
962  ! convert velocity to momentum
963  do idir=1,ndir
964  w1r(ixc^s,mom(idir))=w1r(ixc^s,mom(idir))*w1r(ixc^s,rho_)
965  w1l(ixc^s,mom(idir))=w1l(ixc^s,mom(idir))*w1l(ixc^s,rho_)
966  w2r(ixc^s,mom(idir))=w2r(ixc^s,mom(idir))*w2r(ixc^s,rho_)
967  w2l(ixc^s,mom(idir))=w2l(ixc^s,mom(idir))*w2l(ixc^s,rho_)
968  end do
969 
970  ! get fluxes of intermedate states
971  do iw=1,nwflux
972  ! CT MHD does not need normal B flux
973  if(stagger_grid .and. flux_type(idims, iw) == flux_tvdlf) cycle
974  if(flux_type(idims, iw) == flux_special) then
975  ! known flux (fLC=fRC) for normal B and psi_ in GLM method
976  f1l(ixc^s,iw)=flc(ixc^s,iw)
977  f1r(ixc^s,iw)=f1l(ixc^s,iw)
978  f2l(ixc^s,iw)=f1l(ixc^s,iw)
979  f2r(ixc^s,iw)=f1l(ixc^s,iw)
980  else if(flux_type(idims, iw) == flux_hll) then
981  ! using hll flux for eaux and tracers
982  f1l(ixc^s,iw)=(sr(ixc^s,index_v_mag)*flc(ixc^s, iw)-sl(ixc^s,index_v_mag)*frc(ixc^s, iw) &
983  +sr(ixc^s,index_v_mag)*sl(ixc^s,index_v_mag)*(wrc(ixc^s,iw)-wlc(ixc^s,iw)))/(sr(ixc^s,index_v_mag)-sl(ixc^s,index_v_mag))
984  f1r(ixc^s,iw)=f1l(ixc^s,iw)
985  f2l(ixc^s,iw)=f1l(ixc^s,iw)
986  f2r(ixc^s,iw)=f1l(ixc^s,iw)
987  else
988  f1l(ixc^s,iw)=flc(ixc^s,iw)+sl(ixc^s,index_v_mag)*(w1l(ixc^s,iw)-wlc(ixc^s,iw))
989  f1r(ixc^s,iw)=frc(ixc^s,iw)+sr(ixc^s,index_v_mag)*(w1r(ixc^s,iw)-wrc(ixc^s,iw))
990  f2l(ixc^s,iw)=f1l(ixc^s,iw)+s1l(ixc^s)*(w2l(ixc^s,iw)-w1l(ixc^s,iw))
991  f2r(ixc^s,iw)=f1r(ixc^s,iw)+s1r(ixc^s)*(w2r(ixc^s,iw)-w1r(ixc^s,iw))
992  end if
993  end do
994 
995  ! Miyoshi equation (66) and Guo equation (46)
996  {do ix^db=ixcmin^db,ixcmax^db\}
997  if(sl(ix^d,index_v_mag)>0.d0) then
998  fc(ix^d,1:nwflux,ip1)=flc(ix^d,1:nwflux)
999  else if(s1l(ix^d)>=0.d0) then
1000  fc(ix^d,1:nwflux,ip1)=f1l(ix^d,1:nwflux)
1001  else if(sm(ix^d)>=0.d0) then
1002  fc(ix^d,1:nwflux,ip1)=f2l(ix^d,1:nwflux)
1003  else if(s1r(ix^d)>=0.d0) then
1004  fc(ix^d,1:nwflux,ip1)=f2r(ix^d,1:nwflux)
1005  else if(sr(ix^d,index_v_mag)>=0.d0) then
1006  fc(ix^d,1:nwflux,ip1)=f1r(ix^d,1:nwflux)
1007  else if(sr(ix^d,index_v_mag)<0.d0) then
1008  fc(ix^d,1:nwflux,ip1)=frc(ix^d,1:nwflux)
1009  end if
1010  {end do\}
1011 
1012  end associate
1013  end subroutine get_riemann_flux_hlld_mag2
1014 
1015  !> Calculate fast magnetosonic wave speed
1016  subroutine get_hlld2_modif_c(w,x,ixI^L,ixO^L,csound)
1018 
1019  integer, intent(in) :: ixI^L, ixO^L
1020  double precision, intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
1021  double precision, intent(out):: csound(ixI^S)
1022  double precision :: cfast2(ixI^S), AvMinCs2(ixI^S), b2(ixI^S), kmax
1023  double precision :: inv_rho(ixO^S), gamma_A2(ixO^S)
1024  integer :: rho_, p_, e_, eaux_, mom(1:ndir), mag(1:ndir)
1025 
1026  rho_ = iw_rho
1027  mom(:) = iw_mom(:)
1028  mag(:) = iw_mag(:)
1029  p_ = iw_e
1030  e_ = iw_e
1031  eaux_ = iw_eaux
1032 
1033  inv_rho=1.d0/w(ixo^s,rho_)
1034 
1035  ! store |B|^2 in v
1036 
1037  if (b0field) then
1038  b2(ixo^s) = sum((w(ixo^s, mag(:))+block%B0(ixo^s,:,b0i))**2, dim=ndim+1)
1039  else
1040  b2(ixo^s) = sum(w(ixo^s, mag(:))**2, dim=ndim+1)
1041  end if
1042 
1043 
1044  if (b0field) then
1045  avmincs2= w(ixo^s, mag(idims))+block%B0(ixo^s,idims,b0i)
1046  else
1047  avmincs2= w(ixo^s, mag(idims))
1048  end if
1049 
1050 
1051  csound(ixo^s) = sum(w(ixo^s, mom(:))**2, dim=ndim+1)
1052 
1053  cfast2(ixo^s) = b2(ixo^s) * inv_rho+csound(ixo^s)
1054  avmincs2(ixo^s) = cfast2(ixo^s)**2-4.0d0*csound(ixo^s) &
1055  * avmincs2(ixo^s)**2 &
1056  * inv_rho
1057 
1058  where(avmincs2(ixo^s)<zero)
1059  avmincs2(ixo^s)=zero
1060  end where
1061 
1062  avmincs2(ixo^s)=sqrt(avmincs2(ixo^s))
1063 
1064  csound(ixo^s) = sqrt(half*(cfast2(ixo^s)+avmincs2(ixo^s)))
1065 
1066  end subroutine get_hlld2_modif_c
1067 
1068  end subroutine finite_volume
1069 
1070  !> Determine the upwinded wLC(ixL) and wRC(ixR) from w.
1071  !> the wCT is only used when PPM is exploited.
1072  subroutine reconstruct_lr(ixI^L,ixL^L,ixR^L,idims,w,wLC,wRC,wLp,wRp,x,dxdim)
1073  use mod_physics
1075  use mod_limiter
1076 
1077  integer, intent(in) :: ixi^l, ixl^l, ixr^l, idims
1078  double precision, intent(in) :: dxdim
1079  double precision, dimension(ixI^S,1:nw) :: w
1080  ! left and right constructed status in conservative form
1081  double precision, dimension(ixI^S,1:nw) :: wlc, wrc
1082  ! left and right constructed status in primitive form
1083  double precision, dimension(ixI^S,1:nw) :: wlp, wrp
1084  double precision, dimension(ixI^S,1:ndim) :: x
1085 
1086  integer :: jxr^l, ixc^l, jxc^l, iw
1087  double precision :: ldw(ixi^s), rdw(ixi^s), dwc(ixi^s)
1088  double precision :: a2max
1089 
1090  select case (type_limiter(block%level))
1091  case (limiter_mp5)
1092  call mp5limiter(ixi^l,ixl^l,idims,w,wlp,wrp)
1093  case (limiter_weno3)
1094  call weno3limiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,1)
1095  case (limiter_wenoyc3)
1096  call weno3limiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,2)
1097  case (limiter_weno5)
1098  call weno5limiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,1)
1099  case (limiter_weno5nm)
1100  call weno5nmlimiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,1)
1101  case (limiter_wenoz5)
1102  call weno5limiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,2)
1103  case (limiter_wenoz5nm)
1104  call weno5nmlimiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,2)
1105  case (limiter_wenozp5)
1106  call weno5limiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,3)
1107  case (limiter_wenozp5nm)
1108  call weno5nmlimiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp,3)
1109  case (limiter_weno5cu6)
1110  call weno5cu6limiter(ixi^l,ixl^l,idims,w,wlp,wrp)
1111  case (limiter_teno5ad)
1112  call teno5adlimiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp)
1113  case (limiter_weno7)
1114  call weno7limiter(ixi^l,ixl^l,idims,w,wlp,wrp,1)
1115  case (limiter_mpweno7)
1116  call weno7limiter(ixi^l,ixl^l,idims,w,wlp,wrp,2)
1117  case (limiter_venk)
1118  call venklimiter(ixi^l,ixl^l,idims,dxdim,w,wlp,wrp)
1119  if(fix_small_values) then
1120  call phys_handle_small_values(.true.,wlp,x,ixi^l,ixl^l,'reconstruct left')
1121  call phys_handle_small_values(.true.,wrp,x,ixi^l,ixr^l,'reconstruct right')
1122  end if
1123  case (limiter_ppm)
1124  call ppmlimiter(ixi^l,ixm^ll,idims,w,w,wlp,wrp)
1125  if(fix_small_values) then
1126  call phys_handle_small_values(.true.,wlp,x,ixi^l,ixl^l,'reconstruct left')
1127  call phys_handle_small_values(.true.,wrp,x,ixi^l,ixr^l,'reconstruct right')
1128  end if
1129  case default
1130  jxr^l=ixr^l+kr(idims,^d);
1131  ixcmax^d=jxrmax^d; ixcmin^d=ixlmin^d-kr(idims,^d);
1132  jxc^l=ixc^l+kr(idims,^d);
1133  do iw=1,nwflux
1134  if (loglimit(iw)) then
1135  w(ixcmin^d:jxcmax^d,iw)=dlog10(w(ixcmin^d:jxcmax^d,iw))
1136  wlp(ixl^s,iw)=dlog10(wlp(ixl^s,iw))
1137  wrp(ixr^s,iw)=dlog10(wrp(ixr^s,iw))
1138  end if
1139 
1140  dwc(ixc^s)=w(jxc^s,iw)-w(ixc^s,iw)
1141  if(need_global_a2max) then
1142  a2max=a2max_global(idims)
1143  else
1144  select case(idims)
1145  case(1)
1146  a2max=schmid_rad1
1147  {^iftwod
1148  case(2)
1149  a2max=schmid_rad2}
1150  {^ifthreed
1151  case(2)
1152  a2max=schmid_rad2
1153  case(3)
1154  a2max=schmid_rad3}
1155  case default
1156  call mpistop("idims is wrong in mod_limiter")
1157  end select
1158  end if
1159 
1160  ! limit flux from left and/or right
1161  call dwlimiter2(dwc,ixi^l,ixc^l,idims,type_limiter(block%level),ldw,rdw,a2max=a2max)
1162  wlp(ixl^s,iw)=wlp(ixl^s,iw)+half*ldw(ixl^s)
1163  wrp(ixr^s,iw)=wrp(ixr^s,iw)-half*rdw(jxr^s)
1164 
1165  if (loglimit(iw)) then
1166  w(ixcmin^d:jxcmax^d,iw)=10.0d0**w(ixcmin^d:jxcmax^d,iw)
1167  wlp(ixl^s,iw)=10.0d0**wlp(ixl^s,iw)
1168  wrp(ixr^s,iw)=10.0d0**wrp(ixr^s,iw)
1169  end if
1170  end do
1171  if(fix_small_values) then
1172  call phys_handle_small_values(.true.,wlp,x,ixi^l,ixl^l,'reconstruct left')
1173  call phys_handle_small_values(.true.,wrp,x,ixi^l,ixr^l,'reconstruct right')
1174  end if
1175  end select
1176 
1177  wlc(ixl^s,1:nw)=wlp(ixl^s,1:nw)
1178  wrc(ixr^s,1:nw)=wrp(ixr^s,1:nw)
1179  call phys_to_conserved(ixi^l,ixl^l,wlc,x)
1180  call phys_to_conserved(ixi^l,ixr^l,wrc,x)
1181 
1182  end subroutine reconstruct_lr
1183 
1184 end module mod_finite_volume
subroutine mpistop(message)
Exit MPI-AMRVAC with an error message.
Definition: comm_lib.t:194
subroutine get_hlld2_modif_c(w, x, ixIL, ixOL, csound)
Calculate fast magnetosonic wave speed.
subroutine get_riemann_flux_tvdmu()
Module with finite volume methods for fluxes.
subroutine, public reconstruct_lr(ixIL, ixLL, ixRL, idims, w, wLC, wRC, wLp, wRp, x, dxdim)
Determine the upwinded wLC(ixL) and wRC(ixR) from w. the wCT is only used when PPM is exploited.
subroutine, public finite_volume(method, qdt, ixIL, ixOL, idimsLIM, qtC, sCT, qt, snew, sold, fC, fE, dxs, x)
finite volume method
subroutine, public hancock(qdt, ixIL, ixOL, idimsLIM, qtC, sCT, qt, snew, dxs, x)
The non-conservative Hancock predictor for TVDLF.
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
logical h_correction
If true, do H-correction to fix the carbuncle problem at grid-aligned shocks.
integer, parameter fs_tvdlf
integer ixghi
Upper index of grid block arrays.
integer, parameter fs_hlld
integer, dimension(3, 3) kr
Kronecker delta tensor.
logical, dimension(:), allocatable loglimit
integer, parameter fs_hllcd
integer, parameter ndim
Number of spatial dimensions for grid variables.
logical angmomfix
Enable to strictly conserve the angular momentum (works both in cylindrical and spherical coordinates...
logical stagger_grid
True for using stagger grid.
integer, parameter fs_tvdmu
integer b0i
background magnetic field location indicator
integer, dimension(:), allocatable, parameter d
logical need_global_a2max
global value for schmid scheme
integer ixm
the mesh range (within a block with ghost cells)
logical slab
Cartesian geometry or not.
integer, parameter fs_hll
flux schemes
logical b0field
split magnetic field as background B0 field
integer, dimension(:), allocatable type_limiter
Type of slope limiter used for reconstructing variables on cell edges.
integer nghostcells
Number of ghost cells surrounding a grid.
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
integer, parameter fs_hllc
double precision, dimension(ndim) a2max_global
global largest a2 for schmid scheme
integer, parameter ixglo
Lower index of grid block arrays (always 1)
Module with slope/flux limiters.
Definition: mod_limiter.t:2
integer, parameter limiter_weno5cu6
Definition: mod_limiter.t:37
integer, parameter limiter_mpweno7
Definition: mod_limiter.t:40
integer, parameter limiter_teno5ad
Definition: mod_limiter.t:38
integer, parameter limiter_weno3
Definition: mod_limiter.t:29
integer, parameter limiter_ppm
Definition: mod_limiter.t:27
subroutine dwlimiter2(dwC, ixIL, ixCL, idims, typelim, ldw, rdw, a2max)
Limit the centered dwC differences within ixC for iw in direction idim. The limiter is chosen accordi...
Definition: mod_limiter.t:128
integer, parameter limiter_wenozp5
Definition: mod_limiter.t:35
integer, parameter limiter_weno5
Definition: mod_limiter.t:31
integer, parameter limiter_wenoz5
Definition: mod_limiter.t:33
integer, parameter limiter_wenoz5nm
Definition: mod_limiter.t:34
integer, parameter limiter_weno7
Definition: mod_limiter.t:39
integer, parameter limiter_wenozp5nm
Definition: mod_limiter.t:36
integer, parameter limiter_mp5
Definition: mod_limiter.t:28
integer, parameter limiter_venk
Definition: mod_limiter.t:25
integer, parameter limiter_weno5nm
Definition: mod_limiter.t:32
integer, parameter limiter_wenoyc3
Definition: mod_limiter.t:30
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition: mod_physics.t:4
procedure(sub_get_ct_velocity), pointer phys_get_ct_velocity
Definition: mod_physics.t:82
procedure(sub_convert), pointer phys_to_primitive
Definition: mod_physics.t:59
integer, parameter flux_tvdlf
Indicates the flux should be treated with tvdlf.
Definition: mod_physics.t:48
procedure(sub_small_values), pointer phys_handle_small_values
Definition: mod_physics.t:81
procedure(sub_get_flux), pointer phys_get_flux
Definition: mod_physics.t:66
procedure(sub_get_cbounds), pointer phys_get_cbounds
Definition: mod_physics.t:65
logical phys_solve_eaux
Solve internal energy and total energy equations.
Definition: mod_physics.t:39
integer, parameter flux_hll
Indicates the flux should be treated with hll.
Definition: mod_physics.t:54
procedure(sub_add_source_geom), pointer phys_add_source_geom
Definition: mod_physics.t:70
integer, parameter flux_special
Indicates the flux should be specially treated.
Definition: mod_physics.t:52
integer, dimension(:, :), allocatable flux_type
Array per direction per variable, which can be used to specify that certain fluxes have to be treated...
Definition: mod_physics.t:43
integer phys_wider_stencil
To use wider stencils in flux calculations. A value of 1 will extend it by one cell in both direction...
Definition: mod_physics.t:23
procedure(sub_update_faces), pointer phys_update_faces
Definition: mod_physics.t:83
procedure(sub_convert), pointer phys_to_conserved
Definition: mod_physics.t:58
procedure(sub_energy_synchro), pointer phys_energy_synchro
Definition: mod_physics.t:67
procedure(sub_face_to_center), pointer phys_face_to_center
Definition: mod_physics.t:84
procedure(sub_modify_wlr), pointer phys_modify_wlr
Definition: mod_physics.t:60
procedure(sub_get_h_speed), pointer phys_get_h_speed
Definition: mod_physics.t:64
procedure(sub_angmomfix), pointer phys_angmomfix
Definition: mod_physics.t:80
logical phys_energy
Solve energy equation or not.
Definition: mod_physics.t:30
Module for handling split source terms (split from the fluxes)
Definition: mod_source.t:2
subroutine, public addsource2(qdt, ixIL, ixOL, iwLIM, qtC, wCT, qt, w, x, qsourcesplit, src_active, wCTprim)
Add source within ixO for iws: w=w+qdt*S[wCT].
Definition: mod_source.t:121
Subroutines for TVD-MUSCL schemes.
Definition: mod_tvd.t:2
subroutine, public tvdlimit2(method, qdt, ixIL, ixICL, ixOL, idims, wL, wR, wnew, x, fC, dxs)
Definition: mod_tvd.t:39
Module with all the methods that users can customize in AMRVAC.
integer nw
Total number of variables.
Definition: mod_variables.t:23
integer iwstart
Definition: mod_variables.t:38
integer iw_eaux
Index of the internal energy density.
Definition: mod_variables.t:64
integer number_species
number of species: each species has different characterictic speeds and should be used accordingly in...
Definition: mod_variables.t:74
integer, dimension(:), allocatable iw_mom
Indices of the momentum density.
Definition: mod_variables.t:55
integer, dimension(:), allocatable start_indices
the indices in 1:nwflux array are assumed consecutive for each species this array should be of size n...
Definition: mod_variables.t:83
integer, dimension(:), allocatable stop_indices
the indices in 1:nwflux array are assumed consecutive for each species this array should be of size n...
Definition: mod_variables.t:87
integer, dimension(:), allocatable, protected iw_mag
Indices of the magnetic field components.
Definition: mod_variables.t:67
integer iw_rho
Index of the (gas) density.
Definition: mod_variables.t:52
integer nwflux
Number of flux variables.
Definition: mod_variables.t:8
integer index_v_mag
index of the var whose velocity appears in the induction eq.
Definition: mod_variables.t:78
integer iw_e
Index of the energy density.
Definition: mod_variables.t:58