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