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