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