22 double precision,
public ::
mhd_eta = 0.0d0
43 double precision,
public,
protected ::
h_ion_fr=1d0
46 double precision,
public,
protected ::
he_ion_fr=1d0
53 double precision,
public,
protected ::
rr=1d0
55 double precision :: inv_squared_c0=0.d0, inv_squared_c=0.d0
62 integer,
public,
protected ::
rho_
64 integer,
allocatable,
public,
protected ::
mom(:)
66 integer,
public,
protected :: ^
c&m^C_
68 integer,
public,
protected ::
e_
70 integer,
public,
protected :: ^
c&b^C_
72 integer,
public,
protected ::
p_
74 integer,
public,
protected ::
ne_
76 integer,
public,
protected ::
qpar_
80 integer,
public,
protected ::
psi_
82 integer,
public,
protected ::
r_e
84 integer,
public,
protected ::
te_
86 integer,
public,
protected ::
fip_ = -1
88 logical,
public,
protected ::
mhd_fip = .false.
117 integer,
allocatable,
public,
protected ::
tracer(:)
125 integer,
parameter :: divb_none = 0
126 integer,
parameter :: divb_multigrid = -1
127 integer,
parameter :: divb_glm = 1
128 integer,
parameter :: divb_powel = 2
129 integer,
parameter :: divb_janhunen = 3
130 integer,
parameter :: divb_linde = 4
131 integer,
parameter :: divb_lindejanhunen = 5
132 integer,
parameter :: divb_lindepowel = 6
133 integer,
parameter :: divb_lindeglm = 7
134 integer,
parameter :: divb_ct = 8
181 logical,
public,
protected ::
mhd_glm = .false.
224 logical :: total_energy = .true.
228 logical :: gravity_energy
230 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
232 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
234 character(len=std_len) :: typedivbdiff =
'all'
245 subroutine mask_subroutine(ixI^L,ixO^L,w,x,res)
247 integer,
intent(in) :: ixi^
l, ixo^
l
248 double precision,
intent(in) :: x(ixi^s,1:
ndim)
249 double precision,
intent(in) :: w(ixi^s,1:nw)
250 double precision,
intent(inout) :: res(ixi^s)
251 end subroutine mask_subroutine
298 subroutine mhd_read_params(files)
301 character(len=*),
intent(in) :: files(:)
327 do n = 1,
size(files)
328 open(
unitpar, file=trim(files(n)), status=
"old")
329 read(
unitpar, mhd_list,
end=111)
335 end subroutine mhd_read_params
338 subroutine mhd_write_info(fh)
340 integer,
intent(in) :: fh
343 integer,
parameter :: n_par = 1
344 double precision :: values(n_par)
345 integer,
dimension(MPI_STATUS_SIZE) :: st
346 character(len=name_len) :: names(n_par)
348 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
351 values(1) = eos%gamma
352 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
353 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
354 end subroutine mhd_write_info
383 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_internal_e=T'
387 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_internal_e=T'
394 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_hydrodynamic_e=T'
398 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_hydrodynamic_e=T'
402 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_hydrodynamic_e=T'
409 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_semirelativistic=T'
413 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_semirelativistic=T'
417 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_semirelativistic=T'
424 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_energy=F'
428 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_energy=F'
432 if(
mype==0)
write(*,*)
'WARNING: set mhd_thermal_conduction=F when mhd_energy=F'
436 if(
mype==0)
write(*,*)
'WARNING: set mhd_hyperbolic_tc=F when mhd_energy=F'
440 if(
mype==0)
write(*,*)
'WARNING: set mhd_radiative_cooling=F when mhd_energy=F'
444 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac=F when mhd_energy=F'
448 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_energy=F'
452 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_energy=F'
458 if(
mype==0)
write(*,*)
'WARNING: set either parabolic TC or hyperbolic TC to F'
459 if(
mype==0)
write(*,*)
'WARNING: defaulting to only mhd_hyperbolic_tc=T'
463 call mpistop(
"mhd_hyperbolic_tc_use_perp is not supported in 1D")
473 phys_gamma = eos%gamma
486 phys_total_energy=total_energy
489 gravity_energy=.false.
491 gravity_energy=.true.
494 gravity_energy=.false.
500 if(
mype==0)
write(*,*)
'WARNING: reset mhd_trac_type=1 for 1D simulation'
505 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac_mask==bigdouble for global TRAC method'
511 call mpistop(
"mhd_trac_type=7 requires usr_get_heating to be set in mod_usr.t")
519 type_divb = divb_none
522 if(
mhd_radiation_fld)
call mpistop(
'To verify whether mg usage for FLD versus divB can be combined')
523 type_divb = divb_multigrid
525 mg%operator_type = mg_laplacian
532 case (
'powel',
'powell')
533 type_divb = divb_powel
535 type_divb = divb_janhunen
537 type_divb = divb_linde
538 case (
'lindejanhunen')
539 type_divb = divb_lindejanhunen
541 type_divb = divb_lindepowel
545 type_divb = divb_lindeglm
550 call mpistop(
'Unknown divB fix')
553 allocate(start_indices(number_species),stop_indices(number_species))
560 mom(:) = var_set_momentum(
ndir)
566 e_ = var_set_energy()
575 mag(:) = var_set_bfield(
ndir)
579 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
585 qpar_ = var_set_fluxvar(
'q',
'q', need_bc=.false.)
587 qperp_ = var_set_fluxvar(
'qperp',
'qperp', need_bc=.false.)
598 fip_ = var_set_fluxvar(
'rho_fip',
'fip', need_bc=.false.)
604 waplus_ = var_set_fluxvar(
'wAplus',
'wAplus')
605 waminus_ = var_set_fluxvar(
'wAminus',
'wAminus')
606 wkplus_ = var_set_fluxvar(
'wkplus',
'wkplus')
607 wkminus_ = var_set_fluxvar(
'wkminus',
'wkminus')
615 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
621 write(*,*)
'Warning: CAK force addition together with FLD radiation'
626 write(*,*)
'Warning: Optically thin cooling together with FLD radiation'
630 call mpistop(
'using FLD implies the use of an energy equation, set mhd_energy=T')
633 call mpistop(
'using FLD not yet with semirelativistic energy formalism')
636 call mpistop(
'using FLD not yet with hydrodynamic or internal energy formalism')
639 call mpistop(
'using FLD not yet with split off rho and p')
643 r_e = var_set_radiation_energy()
652 phys_implicit_update => mhd_fld_implicit_update
653 phys_evaluate_implicit => mhd_fld_evaluate_implicit
665 if (eos%eos_type ==
'LTE')
then
668 else if (eos%eos_type ==
'PI')
then
686 if (iw_ne > 0) nwgc = max(nwgc, iw_ne)
687 if (iw_te > 0) nwgc = max(nwgc, iw_te)
690 stop_indices(1)=nwflux
718 allocate(iw_vector(nvector))
719 iw_vector(1) =
mom(1) - 1
720 iw_vector(2) = mag(1) - 1
723 if (.not.
allocated(flux_type))
then
724 allocate(flux_type(
ndir, nwflux))
725 flux_type = flux_default
726 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
727 call mpistop(
"phys_check error: flux_type has wrong shape")
730 if(nwflux>mag(
ndir))
then
732 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
737 flux_type(:,
psi_)=flux_special
739 flux_type(idir,mag(idir))=flux_special
743 flux_type(idir,mag(idir))=flux_tvdlf
749 phys_get_dt => mhd_get_dt
752 phys_get_cmax => mhd_get_cmax_semirelati
754 phys_get_cmax => mhd_get_cmax_semirelati_noe
758 phys_get_cmax => mhd_get_cmax_origin
760 phys_get_cmax => mhd_get_cmax_origin_noe
763 phys_get_tcutoff => mhd_get_tcutoff
764 phys_get_h_speed => mhd_get_h_speed
766 phys_get_cbounds => mhd_get_cbounds_split_rho
768 phys_get_cbounds => mhd_get_cbounds_semirelati
770 phys_get_cbounds => mhd_get_cbounds
780 phys_get_flux => mhd_get_flux_hde
783 phys_get_flux => mhd_get_flux_semirelati
785 phys_get_flux => mhd_get_flux_semirelati_noe
789 phys_get_flux => mhd_get_flux_split
791 phys_get_flux => mhd_get_flux
793 phys_get_flux => mhd_get_flux_noe
798 phys_add_source_geom => mhd_add_source_geom_semirelati
800 phys_add_source_geom => mhd_add_source_geom_split
802 phys_add_source_geom => mhd_add_source_geom
804 phys_add_source => mhd_add_source
805 phys_check_params => mhd_check_params
806 phys_write_info => mhd_write_info
809 phys_handle_small_values => mhd_handle_small_values_inte
810 mhd_handle_small_values => mhd_handle_small_values_inte
811 phys_check_w => mhd_check_w_inte
813 phys_handle_small_values => mhd_handle_small_values_hde
814 mhd_handle_small_values => mhd_handle_small_values_hde
815 phys_check_w => mhd_check_w_hde
817 phys_handle_small_values => mhd_handle_small_values_semirelati
818 mhd_handle_small_values => mhd_handle_small_values_semirelati
819 phys_check_w => mhd_check_w_semirelati
821 phys_handle_small_values => mhd_handle_small_values_split
822 mhd_handle_small_values => mhd_handle_small_values_split
823 phys_check_w => mhd_check_w_split
825 phys_handle_small_values => mhd_handle_small_values_origin
826 mhd_handle_small_values => mhd_handle_small_values_origin
827 phys_check_w => mhd_check_w_origin
829 phys_handle_small_values => mhd_handle_small_values_noe
830 mhd_handle_small_values => mhd_handle_small_values_noe
831 phys_check_w => mhd_check_w_noe
837 phys_set_equi_vars => set_equi_vars_grid
840 if(type_divb==divb_glm)
then
841 phys_modify_wlr => mhd_modify_wlr
852 transverse_ghost_cells = 1
853 phys_get_ct_velocity => mhd_get_ct_velocity_average
854 phys_update_faces => mhd_update_faces_average
856 transverse_ghost_cells = 1
857 phys_get_ct_velocity => mhd_get_ct_velocity_contact
858 phys_update_faces => mhd_update_faces_contact
860 transverse_ghost_cells = 2
861 phys_get_ct_velocity => mhd_get_ct_velocity_hll
862 phys_update_faces => mhd_update_faces_hll
864 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
867 phys_modify_wlr => mhd_modify_wlr
869 phys_boundary_adjust => mhd_boundary_adjust
875 call mpistop(
'To verify whether mg usage for FLD versus divB can be combined')
880 call mhd_physical_units()
913 case(
'fixed_reference')
923 case(
'weak_field_isotropization')
927 case(
'electron_magnetization')
929 call mpistop(
"mhd_hyperbolic_tc_coulomb_log must be positive")
932 call mpistop(
"invalid mhd_hyperbolic_tc_perp_mode: "// &
938 call mpistop(
"thermal conduction needs mhd_energy=T")
941 call mpistop(
"hyperbolic thermal conduction needs mhd_energy=T")
944 call mpistop(
"radiative cooling needs mhd_energy=T")
949 iw_log_nh = var_set_wextra()
955 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no splitting or total e in use'
958 if(
mype==0)
write(*,*)
'Will subtract thermal balance in TC or RC with mhd_equi_thermal=T'
961 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no TC or RC in use'
985 phys_e_to_ei => mhd_e_to_ei_hde
986 phys_ei_to_e => mhd_ei_to_e_hde
989 phys_e_to_ei => mhd_e_to_ei_semirelati
990 phys_ei_to_e => mhd_ei_to_e_semirelati
992 if (iw_log_nh > 0)
then
1009 phys_e_to_ei => mhd_e_to_ei_hde
1010 phys_ei_to_e => mhd_ei_to_e_hde
1012 phys_e_to_ei => mhd_e_to_ei_semirelati
1013 phys_ei_to_e => mhd_ei_to_e_semirelati
1036 phys_te_images => mhd_te_images
1042 write(*,*)
'*****Using hyperresistivity: with mhd_eta_hyper :',
mhd_eta_hyper
1046 call mpistop(
"Must have B0field=F when using hyperresistivity")
1050 call mpistop(
"Must have mhd_eta_hyper positive when using hyperresistivity")
1067 call mpistop(
"Must have has_equi_rho_and_p=F when mhd_rotating_frame=T")
1081 call mpistop(
"Must have mhd_hall=F when mhd_semirelativistic=T")
1085 call mpistop(
"Must have Cartesian coordinates for Hall")
1089 phys_wider_stencil = 1
1096 phys_wider_stencil=max(phys_wider_stencil,1)
1103 call add_sts_method(get_ambipolar_dt,sts_set_source_ambipolar,mag(1),&
1114 phys_wider_stencil = 1
1124 call mpistop(
"CAK implementation not available in internal or semirelativistic variants")
1127 call mpistop(
"CAK force implementation not available for split off pressure and density")
1135 subroutine mhd_te_images
1140 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
1142 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
1144 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
1146 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
1149 call mpistop(
"Error in synthesize emission: Unknown convert_type")
1151 end subroutine mhd_te_images
1157 subroutine mhd_sts_set_source_tc_mhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1161 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1162 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1163 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1164 double precision,
intent(in) :: my_dt
1165 logical,
intent(in) :: fix_conserve_at_step
1167 end subroutine mhd_sts_set_source_tc_mhd
1169 subroutine mhd_sts_set_source_tc_hd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1173 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1174 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1175 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1176 double precision,
intent(in) :: my_dt
1177 logical,
intent(in) :: fix_conserve_at_step
1179 end subroutine mhd_sts_set_source_tc_hd
1181 function mhd_get_tc_dt_mhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1188 integer,
intent(in) :: ixi^
l, ixo^
l
1189 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1190 double precision,
intent(in) :: w(ixi^s,1:nw)
1191 double precision :: dtnew
1194 end function mhd_get_tc_dt_mhd
1196 function mhd_get_tc_dt_hd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1203 integer,
intent(in) :: ixi^
l, ixo^
l
1204 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1205 double precision,
intent(in) :: w(ixi^s,1:nw)
1206 double precision :: dtnew
1209 end function mhd_get_tc_dt_hd
1211 subroutine mhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
1214 integer,
intent(in) :: ixi^
l,ixo^
l
1215 double precision,
intent(inout) :: w(ixi^s,1:nw)
1216 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1217 integer,
intent(in) :: step
1218 character(len=140) :: error_msg
1224 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
1225 call mhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
1226 end subroutine mhd_tc_handle_small_e
1229 subroutine tc_params_read_mhd(fl)
1231 type(tc_fluid),
intent(inout) :: fl
1233 double precision :: tc_k_para=0d0
1234 double precision :: tc_k_perp=0d0
1237 logical :: tc_perpendicular=.false.
1238 logical :: tc_saturate=.false.
1239 logical :: tc_patch_eint=.false.
1240 double precision :: trac_t_floor=0.d0
1241 character(len=std_len) :: tc_slope_limiter=
"MC"
1243 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp, tc_patch_eint, trac_t_floor
1247 read(
unitpar, tc_list,
end=111)
1251 fl%tc_perpendicular = tc_perpendicular
1252 fl%tc_saturate = tc_saturate
1253 fl%tc_patch_eint = tc_patch_eint
1254 fl%tc_k_para = tc_k_para
1255 fl%tc_k_perp = tc_k_perp
1256 fl%trac_T_floor = trac_t_floor / unit_temperature
1257 select case(tc_slope_limiter)
1259 fl%tc_slope_limiter = 0
1262 fl%tc_slope_limiter = 1
1265 fl%tc_slope_limiter = 2
1268 fl%tc_slope_limiter = 3
1271 fl%tc_slope_limiter = 4
1274 fl%tc_slope_limiter = 5
1276 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod, superbee, koren, vanleer")
1278 end subroutine tc_params_read_mhd
1282 subroutine rc_params_read(fl)
1285 type(rc_fluid),
intent(inout) :: fl
1289 double precision :: rad_damp_height=0.5d0
1290 double precision :: rad_damp_scale=0.15d0
1293 integer :: ncool = 4000
1295 logical :: tfix=.false.
1297 logical :: rc_split=.false.
1298 logical :: rad_damp=.false.
1300 character(len=std_len) :: coolcurve=
'JCcorona'
1301 logical :: rad_newton = .false.
1302 double precision :: rad_newton_trad = 0.006d0
1303 double precision :: rad_newton_rhosurf = 1.d4
1304 double precision :: rad_newton_pthick = 25.d0
1306 double precision :: cfrac=0.1d0
1307 double precision :: rad_cut_hgt=0.5d0
1308 double precision :: rad_cut_dey=0.15d0
1310 character(len=8) :: rc_y_mod_quadrature=
'boole'
1311 integer :: rc_y_mod_n_sub=16
1314 namelist /rc_list/ coolcurve, ncool, cfrac, tlow, tfix, rc_split, &
1315 rad_cut_hgt, rad_cut_dey, &
1316 rc_y_mod_quadrature, rc_y_mod_n_sub, &
1317 rad_newton, rad_newton_trad, rad_newton_rhosurf, &
1318 rad_newton_pthick, rad_damp, rad_damp_height, rad_damp_scale
1322 read(
unitpar, rc_list,
end=111)
1327 fl%coolcurve=coolcurve
1330 fl%rc_split=rc_split
1332 fl%rad_cut_hgt=rad_cut_hgt
1333 fl%rad_cut_dey=rad_cut_dey
1334 fl%Y_mod_quadrature=rc_y_mod_quadrature
1335 fl%Y_mod_N_sub=rc_y_mod_n_sub
1336 fl%rad_damp=rad_damp
1337 fl%rad_damp_height=rad_damp_height
1338 fl%rad_damp_scale=rad_damp_scale
1339 fl%rad_newton=rad_newton
1340 fl%rad_newton_trad=rad_newton_trad
1341 fl%rad_newton_rhosurf=rad_newton_rhosurf
1342 fl%rad_newton_pthick=rad_newton_pthick
1343 end subroutine rc_params_read
1346 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
1349 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
1350 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1352 double precision :: delx(ixi^s,1:
ndim)
1353 double precision :: xc(ixi^s,1:
ndim),xshift^
d
1354 integer :: idims, ixc^
l, hxo^
l, ix, idims2
1360 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
1364 hxo^
l=ixo^
l-
kr(idims,^
d);
1370 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
1373 xshift^
d=half*(one-
kr(^
d,idims));
1380 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
1384 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
1386 end subroutine set_equi_vars_grid_faces
1389 subroutine set_equi_vars_grid(igrid)
1393 integer,
intent(in) :: igrid
1399 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
1401 end subroutine set_equi_vars_grid
1404 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
1406 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
1407 double precision,
intent(in) :: w(ixi^s, 1:nw)
1408 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1409 double precision :: wnew(ixo^s, 1:nwc)
1416 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
1422 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
1426 wnew(ixo^s,
e_)=w(ixo^s,
e_)
1428 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+
block%equi_vars(ixo^s,
equi_pe0_,0)*eos%inv_gamma_minus_1
1430 if(
b0field .and. total_energy)
then
1431 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
1432 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
1436 end function convert_vars_splitting
1438 subroutine mhd_check_params
1445 ngridvars,num_particles,physics_type_particles
1448 double precision :: a,
b,xfrac,yfrac
1452 call mpistop(
'mhd_uawsom currently requires a uniform Cartesian grid')
1454 call mpistop(
'mhd_uawsom requires the standard total-energy MHD formulation')
1457 call mpistop(
'mhd_uawsom: unsupported MHD option')
1458 if(trim(eos%eos_type) /=
'FI') &
1459 call mpistop(
"mhd_uawsom currently supports eos_type='FI' only")
1461 call mpistop(
'mhd_uawsom_height_dim must be between 1 and ndim')
1464 call mpistop(
'mhd_uawsom requires zeta0>1 and 0<filling_factor<1')
1468 call mpistop(
'mhd_uawsom: scales must be positive')
1470 call mpistop(
'mhd_uawsom_sigma must be non-negative')
1472 case(
'one_dimensional_gradient',
'cartesian_gradient_vorticity')
1475 call mpistop(
'invalid mhd_uawsom_reflection_mode')
1482 if (particles_eta < zero) particles_eta =
mhd_eta
1483 if (particles_etah < zero) particles_eta =
mhd_etah
1488 if (eos%gamma <= 0.0d0)
call mpistop (
"Error: gamma <= 0")
1489 if (
mhd_adiab < 0.0d0)
call mpistop (
"Error: mhd_adiab < 0")
1492 if (eos%gamma <= 0.0d0 .or. eos%gamma == 1.0d0) &
1493 call mpistop (
"Error: gamma <= 0 or gamma == 1")
1499 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
1508 call mpistop(
"Must have has_equi_rho_and_p=F with the roe/hllc/hllcd flux schemes")
1512 call mpistop(
"Must have has_equi_rho_and_p=F when mhd_trac=T")
1518 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
1526 call mpistop(
'select IMEX scheme for FLD radiation use')
1529 call phys_set_mg_bounds()
1531 if(.not.
fld_no_mg)
call mpistop(
'multigrid must have BCs for IMEX and FLD radiation use')
1534 write(*,*)
'==FLD SETUP======================'
1535 write(*,*)
'Using FLD with settings:'
1539 write(*,*)
'Using FLD with settings: fld_bound_diff=',
fld_bound_diff
1542 write(*,*)
'Using FLD with settings: fld_kappa0=',
fld_kappa0
1543 write(*,*)
'Using FLD with settings: fld_opal_table=',
fld_opal_table
1545 write(*,*)
'Using FLD with settings: fld_bisect_tol=',
fld_bisect_tol
1546 write(*,*)
'Using FLD with settings: fld_diff_tol=',
fld_diff_tol
1549 write(*,*)
' FLD has fld_no_mg=',
fld_no_mg
1551 print *,
'WARNING: cheating with FLD diffusion ***********************'
1552 print *,
'WARNING: No MG-diffusion for radiative energy at all!!!!!!!'
1553 print *,
'WARNING: cheating with FLD diffusion ***********************'
1556 print *,
'NORMALIZED arad_norm=',
arad_norm
1557 print *,
'NORMALIZED c_norm=',
c_norm
1559 print *,
'WARNING: cheating with c_norm ***********************'
1560 print *,
'WARNING: c_norm reset to=',
fld_cnorm
1562 print *,
'WARNING: cheating with c_norm ***********************'
1570 print *,
'physical fld_kappa (in cgs or SI) =',
fld_kappa0
1573 write(*,*)
'===FLD SETUP====================='
1578 write(*,*)
'====MHD run with settings===================='
1579 write(*,*)
'Using mod_mhd_phys with settings:'
1581 write(*,*)
'Dimensionality :',
ndim
1582 write(*,*)
'vector components:',
ndir
1584 write(*,*)
'number of variables nw=',nw
1585 write(*,*)
' start index iwstart=',iwstart
1586 write(*,*)
'number of vector variables=',nvector
1587 write(*,*)
'number of stagger variables nws=',nws
1588 write(*,*)
'number of variables with BCs=',nwgc
1589 write(*,*)
'number of vars with fluxes=',nwflux
1590 write(*,*)
'number of vars with flux + BC=',nwfluxbc
1591 write(*,*)
'number of auxiliary variables=',nwaux
1592 write(*,*)
'number of extra vars without flux=',nwextra
1593 write(*,*)
'number of extra vars for wextra=',nw_extra
1594 write(*,*)
'number of auxiliary I/O variables=',
nwauxio
1596 write(*,*)
' mhd_energy=',
mhd_energy,
' with total_energy=',total_energy
1601 write(*,*)
' mhd_eta=',
mhd_eta,
' nonzero implies resistivity'
1615 write(*,*)
'*****Using particles: with mhd_eta, mhd_etah :',
mhd_eta,
mhd_etah
1616 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
1617 write(*,*)
'*****Using particles: npayload,ngridvars :', npayload,ngridvars
1618 write(*,*)
'*****Using particles: nusrpayload :', nusrpayload
1619 write(*,*)
'*****Using particles: num_particles :', num_particles
1620 write(*,*)
'*****Using particles: physics_type_particles=',physics_type_particles
1623 write(*,*)
'number due to phys_wider_stencil=',phys_wider_stencil
1624 write(*,*)
'==========================================='
1625 print *,
'========EOS and UNITS==========='
1627 print *,
'gamma=',eos%gamma
1628 print *,
'He_abundance =',eos%He_abundance
1630 print *,
'========EOS and UNITS==========='
1652 print *,
' compare this to ',mp_si*(1.d0+4.d0*eos%He_abundance)
1654 print *,
' compare this to ',mp_cgs*(1.d0+4.d0*eos%He_abundance)
1658 print *,
' compare this to ',kb_si*(2.d0+3.d0*eos%He_abundance)
1662 print *,
' compare this to ',kb_cgs*(2.d0+3.d0*eos%He_abundance)
1666 if(eos%eos_type /=
'LTE')
then
1667 print *,
'mean molecular weight mu is =',a/
b,
' = ', (1.d0+4.d0*eos%He_abundance)/(2.d0+3.d0*eos%He_abundance)
1669 yfrac=4.d0*eos%He_abundance/(1.d0+4.d0*eos%He_abundance)
1670 print *,
'mass fraction hydrogen X is =',1/a,
' and this equals ', 1.d0/(1.d0+4.d0*eos%He_abundance)
1671 print *,
'mass fraction helium Y is =',yfrac
1672 print *,
' check that 1/mu',
b/a,
' is equal to 2X+3Y/4=',2.d0*xfrac+3.d0*yfrac/4.d0
1673 print *,
' ratio n_e/n_p=',1.d0+2.0d0*eos%He_abundance
1675 print *,
'========UNITS==========='
1678 end subroutine mhd_check_params
1680 subroutine mhd_physical_units()
1682 double precision :: mp,kb,miu0,c_lightspeed,xfrac,sigma_telectron
1683 double precision :: a,
b
1691 sigma_telectron=sigma_te_si
1697 c_lightspeed=const_c
1698 sigma_telectron=sigma_te_cgs
1703 if (eos%eos_type ==
'LTE')
then
1707 eos%nH2rhoFactor = 1d0+4d0*eos%He_abundance
1708 rr=(2d0+3d0*eos%He_abundance) / (1d0+4d0*eos%He_abundance)
1709 xfrac=1.d0/(1.d0+4.d0*eos%He_abundance)
1713 a=1d0+4d0*eos%He_abundance
1714 if(eos%eos_type==
'PI')
then
1717 b=2d0+3d0*eos%He_abundance
1849 eos%inv_squared_c0 = inv_squared_c0
1850 eos%inv_squared_c = inv_squared_c
1866 end subroutine mhd_physical_units
1868 subroutine mhd_check_w_semirelati(primitive,ixI^L,ixO^L,w,flag)
1871 logical,
intent(in) :: primitive
1872 logical,
intent(inout) :: flag(ixi^s,1:nw)
1873 integer,
intent(in) :: ixi^
l, ixo^
l
1874 double precision,
intent(in) :: w(ixi^s,nw)
1876 double precision :: tmp,
b(1:
ndir),v(1:
ndir),factor
1887 {
do ix^db=ixomin^db,ixomax^db \}
1891 {
do ix^db=ixomin^db,ixomax^db \}
1893 tmp=(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)*inv_squared_c
1894 factor=1.0d0/(w(ix^d,
rho_)*(w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+)*inv_squared_c))
1895 ^
c&v(^
c)=factor*(w(ix^d,
m^
c_)*w(ix^d,
rho_)+w(ix^d,
b^
c_)*tmp)\
1898 b(1)=w(ix^d,b2_)*v(3)-w(ix^d,b3_)*v(2)
1899 b(2)=w(ix^d,b3_)*v(1)-w(ix^d,b1_)*v(3)
1900 b(3)=w(ix^d,b1_)*v(2)-w(ix^d,b2_)*v(1)
1905 b(2)=w(ix^d,b1_)*v(2)-w(ix^d,b2_)*v(1)
1911 tmp=w(ix^d,
e_)-half*((^
c&v(^
c)**2+)*w(ix^d,
rho_)&
1912 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&
b(^
c)**2+)*inv_squared_c)
1913 if(tmp<small_e) flag(ix^d,
e_)=.true.
1919 end subroutine mhd_check_w_semirelati
1921 subroutine mhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1924 logical,
intent(in) :: primitive
1925 integer,
intent(in) :: ixi^
l, ixo^
l
1926 double precision,
intent(in) :: w(ixi^s,nw)
1927 logical,
intent(inout) :: flag(ixi^s,1:nw)
1929 integer :: ix^
d, igrp
1932 {
do ix^db=ixomin^db,ixomax^db\}
1952 end subroutine mhd_check_w_origin
1954 subroutine mhd_check_w_split(primitive,ixI^L,ixO^L,w,flag)
1957 logical,
intent(in) :: primitive
1958 integer,
intent(in) :: ixi^
l, ixo^
l
1959 double precision,
intent(in) :: w(ixi^s,nw)
1960 logical,
intent(inout) :: flag(ixi^s,1:nw)
1962 double precision :: tmp
1966 {
do ix^db=ixomin^db,ixomax^db\}
1972 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1977 end subroutine mhd_check_w_split
1979 subroutine mhd_check_w_noe(primitive,ixI^L,ixO^L,w,flag)
1982 logical,
intent(in) :: primitive
1983 integer,
intent(in) :: ixi^
l, ixo^
l
1984 double precision,
intent(in) :: w(ixi^s,nw)
1985 logical,
intent(inout) :: flag(ixi^s,1:nw)
1990 {
do ix^db=ixomin^db,ixomax^db\}
1994 end subroutine mhd_check_w_noe
1996 subroutine mhd_check_w_inte(primitive,ixI^L,ixO^L,w,flag)
1999 logical,
intent(in) :: primitive
2000 integer,
intent(in) :: ixi^
l, ixo^
l
2001 double precision,
intent(in) :: w(ixi^s,nw)
2002 logical,
intent(inout) :: flag(ixi^s,1:nw)
2007 {
do ix^db=ixomin^db,ixomax^db\}
2016 end subroutine mhd_check_w_inte
2018 subroutine mhd_check_w_hde(primitive,ixI^L,ixO^L,w,flag)
2021 logical,
intent(in) :: primitive
2022 integer,
intent(in) :: ixi^
l, ixo^
l
2023 double precision,
intent(in) :: w(ixi^s,nw)
2024 logical,
intent(inout) :: flag(ixi^s,1:nw)
2029 {
do ix^db=ixomin^db,ixomax^db\}
2038 end subroutine mhd_check_w_hde
2040 subroutine mhd_bound_fip(primitive, ixI^L, ixO^L, w)
2042 logical,
intent(in) :: primitive
2043 integer,
intent(in) :: ixi^
l, ixo^
l
2044 double precision,
intent(inout) :: w(ixi^s,1:nw)
2046 double precision :: rho_safe(ixi^s), fip_prim(ixi^s)
2058 fip_prim(ixo^s) = w(ixo^s,
fip_) / rho_safe(ixo^s)
2059 fip_prim(ixo^s) = min(
maxfip, max(
minfip, fip_prim(ixo^s)))
2060 w(ixo^s,
fip_) = rho_safe(ixo^s) * fip_prim(ixo^s)
2062 end subroutine mhd_bound_fip
2066 subroutine mhd_uawsom_get_coefficients(w,x,ixI^L,ixO^L,primitive,zeta,radius,lperp_A)
2069 integer,
intent(in) :: ixi^
l, ixo^
l
2070 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
2071 logical,
intent(in) :: primitive
2072 double precision,
intent(out) :: zeta(ixi^s), radius(ixi^s), lperp_a(ixi^s)
2073 double precision :: bmag(ixi^s), btotal(ixi^s,1:
ndir), height_base
2081 btotal(ixo^s,idir)=w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,
b0i)
2083 btotal(ixo^s,idir)=w(ixo^s,mag(idir))
2086 bmag(ixo^s)=dsqrt(sum(btotal(ixo^s,1:
ndir)**2,dim=
ndim+1))
2089 height_base=xprobmin1
2092 height_base=xprobmin2
2096 height_base=xprobmin3
2107 if(any(zeta(ixo^s)<=one) .or. any(radius(ixo^s)<=zero) .or. &
2108 any(lperp_a(ixo^s)<=zero)) &
2109 call mpistop(
'mhd_uawsom coefficients require zeta>1 and positive lengths')
2110 end subroutine mhd_uawsom_get_coefficients
2114 integer,
intent(in) :: ixi^
l, ixo^
l
2115 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
2116 double precision,
intent(out) :: factor(ixi^s)
2117 double precision :: zeta(ixi^s), radius(ixi^s), lperp_a(ixi^s)
2118 call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.false.,zeta,radius,lperp_a)
2123 double precision,
intent(in) :: zeta
2124 double precision :: f
2131 double precision,
intent(in) :: wcell(:),zeta
2138 double precision,
intent(in) :: wcell(:)
2152 elemental pure double precision function mhd_uawsom_imbalance_factor(wplus,wminus)
2153 double precision,
intent(in) :: wplus,wminus
2155 if(wplus<=0.d0 .or. wminus<=0.d0)
then
2156 mhd_uawsom_imbalance_factor=0.d0
2157 else if(4.d0*wminus<=wplus)
then
2158 mhd_uawsom_imbalance_factor=1.d0-2.d0*dsqrt(wminus/wplus)
2159 else if(4.d0*wplus<=wminus)
then
2160 mhd_uawsom_imbalance_factor=-(1.d0-2.d0*dsqrt(wplus/wminus))
2162 mhd_uawsom_imbalance_factor=0.d0
2164 end function mhd_uawsom_imbalance_factor
2169 subroutine mhd_add_source_uawsom(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x)
2172 integer,
intent(in) :: ixi^
l, ixo^
l
2173 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), &
2174 wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2175 double precision,
intent(inout) :: w(ixi^s,1:nw)
2176 double precision :: v(ixi^s,1:
ndir), divv(ixi^s)
2177 double precision :: zeta(ixi^s), radius(ixi^s), lperp_a(ixi^s)
2178 double precision :: lperp_k(ixi^s), rho_e(ixi^s)
2179 double precision :: gamma_plus(ixi^s), gamma_minus(ixi^s)
2180 double precision :: gamma_kplus(ixi^s), gamma_kminus(ixi^s)
2181 double precision :: dampap(ixi^s), dampam(ixi^s), dampkp(ixi^s), dampkm(ixi^s)
2182 double precision :: btotal(ixi^s,1:
ndir), bunit(ixi^s,1:
ndir), bmag(ixi^s)
2183 double precision :: va(ixi^s), vk(ixi^s), lnva(ixi^s), lnvk(ixi^s)
2184 double precision :: grad_component(ixi^s), grad_a(ixi^s), grad_k(ixi^s)
2185 double precision :: curlv(ixi^s,1:3), vorticity(ixi^s)
2186 double precision :: rimb_a(ixi^s), rlim_a(ixi^s), rlim_k(ixi^s)
2187 double precision :: refl_rate(ixi^s), donor_reflection(ixi^s)
2188 double precision :: transfer_a(ixi^s), transfer_k(ixi^s), donor(ixi^s)
2189 double precision :: imbalance_a(ixi^s), imbalance_k(ixi^s)
2190 double precision :: wave_plus(ixi^s), wave_minus(ixi^s)
2191 double precision :: wave_kplus(ixi^s), wave_kminus(ixi^s)
2192 double precision :: f, kink_pressure(ixi^s)
2193 integer :: idir, idirmin
2194 logical :: have_reflection, have_alfven_reflection, have_kink_reflection
2200 call mhd_uawsom_get_coefficients(wct,x,ixi^
l,ixi^
l,.false.,zeta,radius,lperp_a)
2203 max(one+f*zeta(ixi^s)-f,smalldouble)
2204 lperp_k(ixi^s)=dsqrt(10.d0)*dsqrt(f*dpi)*radius(ixi^s)*&
2205 (zeta(ixi^s)+one-f)**1.5d0/&
2206 ((zeta(ixi^s)-one)*(one-f**2.5d0))
2207 gamma_plus(ixo^s)=two/lperp_a(ixo^s)*dsqrt(&
2209 gamma_minus(ixo^s)=two/lperp_a(ixo^s)*dsqrt(&
2211 dampap(ixo^s)=gamma_plus(ixo^s)*max(wct(ixo^s,
waplus_),zero)
2212 dampam(ixo^s)=gamma_minus(ixo^s)*max(wct(ixo^s,
waminus_),zero)
2213 dampkp(ixo^s)=max(wct(ixo^s,
wkplus_),zero)**1.5d0/&
2214 (dsqrt(rho_e(ixo^s))*lperp_k(ixo^s))
2215 dampkm(ixo^s)=max(wct(ixo^s,
wkminus_),zero)**1.5d0/&
2216 (dsqrt(rho_e(ixo^s))*lperp_k(ixo^s))
2217 gamma_kplus(ixo^s)=dsqrt(max(wct(ixo^s,
wkplus_),zero)/&
2218 max(rho_e(ixo^s),
small_density))/max(lperp_k(ixo^s),smalldouble)
2219 gamma_kminus(ixo^s)=dsqrt(max(wct(ixo^s,
wkminus_),zero)/&
2220 max(rho_e(ixo^s),
small_density))/max(lperp_k(ixo^s),smalldouble)
2223 half*divv(ixo^s)*wct(ixo^s,
waplus_)+dampap(ixo^s))
2225 half*divv(ixo^s)*wct(ixo^s,
waminus_)+dampam(ixo^s))
2227 half*divv(ixo^s)*wct(ixo^s,
wkplus_)+dampkp(ixo^s))
2229 half*divv(ixo^s)*wct(ixo^s,
wkminus_)+dampkm(ixo^s))
2231 kink_pressure(ixo^s)=quarter*(zeta(ixo^s)+one)*&
2233 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*(zeta(ixo^s)-one)/&
2234 (zeta(ixo^s)+one)*kink_pressure(ixo^s)*divv(ixo^s)
2236 have_alfven_reflection=.false.
2239 case(
'one_dimensional_gradient')
2241 case(
'cartesian_gradient_vorticity')
2242 have_alfven_reflection=.true.
2246 have_reflection=have_alfven_reflection .or. have_kink_reflection
2247 if(have_reflection)
then
2250 btotal(ixi^s,idir)=wct(ixi^s,mag(idir))+
block%B0(ixi^s,idir,
b0i)
2252 btotal(ixi^s,idir)=wct(ixi^s,mag(idir))
2255 bmag(ixi^s)=dsqrt(sum(btotal(ixi^s,1:
ndir)**2,dim=
ndim+1))
2257 bunit(ixi^s,idir)=btotal(ixi^s,idir)/max(bmag(ixi^s),smalldouble)
2260 vk(ixi^s)=bmag(ixi^s)/dsqrt(max(rho_e(ixi^s)*&
2261 (zeta(ixi^s)+one)/two,smalldouble))
2262 lnva(ixi^s)=dlog(max(va(ixi^s),smalldouble))
2263 lnvk(ixi^s)=dlog(max(vk(ixi^s),smalldouble))
2269 if(have_alfven_reflection)
then
2270 wave_plus(ixo^s)=max(wct(ixo^s,
waplus_),zero)
2271 wave_minus(ixo^s)=max(wct(ixo^s,
waminus_),zero)
2274 case(
'one_dimensional_gradient')
2280 max(va(ixo^s),smalldouble)*grad_component(ixo^s)
2281 donor_reflection(ixo^s)=merge(max(wct(ixo^s,
waplus_),zero),&
2282 max(wct(ixo^s,
waminus_),zero),refl_rate(ixo^s)>=zero)
2283 transfer_a(ixo^s)=refl_rate(ixo^s)*donor_reflection(ixo^s)
2284 case(
'cartesian_gradient_vorticity')
2287 call gradient(lnva,ixi^
l,ixo^
l,idir,grad_component)
2288 grad_a(ixo^s)=grad_a(ixo^s)+va(ixo^s)*bunit(ixo^s,idir)*&
2289 grad_component(ixo^s)
2292 vorticity(ixo^s)=zero
2294 vorticity(ixo^s)=vorticity(ixo^s)+bunit(ixo^s,idir)*&
2299 rimb_a(ixo^s)=dsqrt(grad_a(ixo^s)**2+vorticity(ixo^s)**2)
2300 rlim_a(ixo^s)=min(rimb_a(ixo^s),&
2301 max(gamma_plus(ixo^s),gamma_minus(ixo^s)))
2302 imbalance_a(ixo^s)=mhd_uawsom_imbalance_factor(&
2303 wave_plus(ixo^s),wave_minus(ixo^s))
2304 transfer_a(ixo^s)=rlim_a(ixo^s)*imbalance_a(ixo^s)*&
2305 dsqrt(wave_plus(ixo^s)*wave_minus(ixo^s))
2309 donor(ixo^s)=merge(max(w(ixo^s,
waplus_),zero),&
2310 max(w(ixo^s,
waminus_),zero),transfer_a(ixo^s)>=zero)
2311 transfer_a(ixo^s)=sign(min(abs(transfer_a(ixo^s)),&
2312 donor(ixo^s)/qdt),transfer_a(ixo^s))
2314 transfer_a(ixo^s)=zero
2320 if(have_kink_reflection)
then
2321 wave_kplus(ixo^s)=max(wct(ixo^s,
wkplus_),zero)
2322 wave_kminus(ixo^s)=max(wct(ixo^s,
wkminus_),zero)
2325 call gradient(lnvk,ixi^
l,ixo^
l,idir,grad_component)
2326 grad_k(ixo^s)=grad_k(ixo^s)+vk(ixo^s)*bunit(ixo^s,idir)*&
2327 grad_component(ixo^s)
2332 rlim_k(ixo^s)=min(abs(grad_k(ixo^s)),&
2333 max(gamma_kplus(ixo^s),gamma_kminus(ixo^s)))
2334 imbalance_k(ixo^s)=mhd_uawsom_imbalance_factor(&
2335 wave_kplus(ixo^s),wave_kminus(ixo^s))
2336 transfer_k(ixo^s)=rlim_k(ixo^s)*imbalance_k(ixo^s)*&
2337 dsqrt(wave_kplus(ixo^s)*wave_kminus(ixo^s))
2339 donor(ixo^s)=merge(max(w(ixo^s,
wkplus_),zero),&
2340 max(w(ixo^s,
wkminus_),zero),transfer_k(ixo^s)>=zero)
2341 transfer_k(ixo^s)=sign(min(abs(transfer_k(ixo^s)),&
2342 donor(ixo^s)/qdt),transfer_k(ixo^s))
2344 transfer_k(ixo^s)=zero
2350 end subroutine mhd_add_source_uawsom
2355 integer,
intent(in) :: ixi^
l, ixo^
l
2356 double precision,
intent(inout) :: w(ixi^s, nw)
2357 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2362 {
do ix^db=ixomin^db,ixomax^db\}
2365 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
2367 +(^
c&w(ix^
d,
b^
c_)**2+))
2370 {
do ix^db=ixomin^db,ixomax^db\}
2372 w(ix^d,
e_)=w(ix^d,
e_)&
2373 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
2374 +(^
c&w(ix^d,
b^
c_)**2+))&
2381 subroutine mhd_ei_to_e_hde(ixI^L,ixO^L,w,x)
2383 integer,
intent(in) :: ixi^
l, ixo^
l
2384 double precision,
intent(inout) :: w(ixi^s, nw)
2385 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2389 {
do ix^db=ixomin^db,ixomax^db\}
2395 end subroutine mhd_ei_to_e_hde
2398 subroutine mhd_ei_to_e_semirelati(ixI^L,ixO^L,w,x)
2400 integer,
intent(in) :: ixi^
l, ixo^
l
2401 double precision,
intent(inout) :: w(ixi^s, nw)
2402 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2404 w(ixo^s,
p_)=w(ixo^s,
e_)*eos%gamma_minus_1
2406 call eos%to_conserved(ixi^
l,ixo^
l,w,x)
2408 end subroutine mhd_ei_to_e_semirelati
2413 integer,
intent(in) :: ixi^
l, ixo^
l
2414 double precision,
intent(inout) :: w(ixi^s, nw)
2415 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2420 {
do ix^db=ixomin^db,ixomax^db\}
2423 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
2425 +(^
c&w(ix^
d,
b^
c_)**2+))
2428 {
do ix^db=ixomin^db,ixomax^db\}
2430 w(ix^d,
e_)=w(ix^d,
e_)&
2431 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
2432 +(^
c&w(ix^d,
b^
c_)**2+))&
2437 if(fix_small_values)
then
2438 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei')
2446 subroutine mhd_e_to_ei_and_cache_log_nh(ixI^L,ixO^L,w,x)
2448 integer,
intent(in) :: ixi^
l, ixo^
l
2449 double precision,
intent(inout) :: w(ixi^s, nw)
2450 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2453 block%wextra(ixo^s, iw_log_nh) = dlog10(w(ixo^s,
rho_) / eos%nH2rhoFactor)
2454 end subroutine mhd_e_to_ei_and_cache_log_nh
2457 subroutine mhd_e_to_ei_hde(ixI^L,ixO^L,w,x)
2459 integer,
intent(in) :: ixi^
l, ixo^
l
2460 double precision,
intent(inout) :: w(ixi^s, nw)
2461 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2465 {
do ix^db=ixomin^db,ixomax^db\}
2471 if(fix_small_values)
then
2472 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei_hde')
2475 end subroutine mhd_e_to_ei_hde
2478 subroutine mhd_e_to_ei_semirelati(ixI^L,ixO^L,w,x)
2480 integer,
intent(in) :: ixi^
l, ixo^
l
2481 double precision,
intent(inout) :: w(ixi^s, nw)
2482 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2484 call eos%to_primitive(ixi^
l,ixo^
l,w,x)
2485 w(ixo^s,
e_)=w(ixo^s,
p_)*eos%inv_gamma_minus_1
2487 end subroutine mhd_e_to_ei_semirelati
2489 subroutine mhd_handle_small_values_semirelati(primitive, w, x, ixI^L, ixO^L, subname)
2492 logical,
intent(in) :: primitive
2493 integer,
intent(in) :: ixi^
l,ixo^
l
2494 double precision,
intent(inout) :: w(ixi^s,1:nw)
2495 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2496 character(len=*),
intent(in) :: subname
2498 double precision :: e(ixi^s,1:
ndir), pressure(ixi^s), v(ixi^s,1:
ndir)
2499 double precision :: tmp, factor
2501 logical :: flag(ixi^s,1:nw)
2510 {
do ix^db=ixomin^db,ixomax^db\}
2512 tmp=(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)*inv_squared_c
2513 factor=1.0d0/(w(ix^
d,
rho_)*(w(ix^
d,
rho_)+(^
c&w(ix^
d,
b^
c_)**2+)*inv_squared_c))
2517 e(ix^
d,1)=w(ix^
d,b2_)*v(ix^
d,3)-w(ix^
d,b3_)*v(ix^
d,2)
2518 e(ix^
d,2)=w(ix^
d,b3_)*v(ix^
d,1)-w(ix^
d,b1_)*v(ix^
d,3)
2519 e(ix^
d,3)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
2523 e(ix^
d,2)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
2529 pressure(ix^
d)=eos%gamma_minus_1*(w(ix^
d,
e_)&
2530 -half*((^
c&v(ix^
d,^
c)**2+)*w(ix^
d,
rho_)&
2531 +(^
c&w(ix^
d,
b^
c_)**2+)+(^
c&e(ix^
d,^
c)**2+)*inv_squared_c))
2538 select case (small_values_method)
2540 {
do ix^db=ixomin^db,ixomax^db\}
2541 if(flag(ix^d,
rho_))
then
2542 w(ix^d,
rho_) = small_density
2543 ^
c&w(ix^d,
m^
c_)=0.d0\
2547 if(flag(ix^d,
e_)) w(ix^d,
p_) = small_pressure
2549 if(flag(ix^d,
e_))
then
2550 w(ix^d,
e_)=small_pressure*eos%inv_gamma_minus_1+half*((^
c&v(ix^d,^
c)**2+)*w(ix^d,
rho_)&
2551 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&e(ix^d,^
c)**2+)*inv_squared_c)
2558 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2561 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2563 w(ixo^s,
e_)=pressure(ixo^s)
2564 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2565 {
do ix^db=ixomin^db,ixomax^db\}
2566 w(ix^d,
e_)=w(ix^d,
p_)*eos%inv_gamma_minus_1+half*((^
c&v(ix^d,^
c)**2+)*w(ix^d,
rho_)&
2567 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&e(ix^d,^
c)**2+)*inv_squared_c)
2572 if(.not.primitive)
then
2574 w(ixo^s,
mom(1:ndir))=v(ixo^s,1:ndir)
2577 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2580 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2581 end subroutine mhd_handle_small_values_semirelati
2583 subroutine mhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
2586 logical,
intent(in) :: primitive
2587 integer,
intent(in) :: ixi^
l,ixo^
l
2588 double precision,
intent(inout) :: w(ixi^s,1:nw)
2589 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2590 character(len=*),
intent(in) :: subname
2592 integer :: ix^
d, igrp
2593 logical :: flag(ixi^s,1:nw)
2595 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2600 {
do ix^db=ixomin^db,ixomax^db\}
2604 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2628 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2630 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2633 call small_values_average(ixi^l,ixo^l,w,x,flag,
waplus_)
2634 call small_values_average(ixi^l,ixo^l,w,x,flag,
waminus_)
2635 call small_values_average(ixi^l,ixo^l,w,x,flag,
wkplus_)
2636 call small_values_average(ixi^l,ixo^l,w,x,flag,
wkminus_)
2639 {
do ix^db=iximin^db,iximax^db\}
2640 w(ix^d,
e_)=w(ix^d,
e_)&
2641 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))&
2644 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2646 {
do ix^db=iximin^db,iximax^db\}
2647 w(ix^d,
e_)=w(ix^d,
e_)&
2648 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))&
2653 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
2656 if(.not.primitive)
then
2658 {
do ix^db=ixomin^db,ixomax^db\}
2660 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)&
2661 -half*((^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))&
2665 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2668 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2669 end subroutine mhd_handle_small_values_origin
2671 subroutine mhd_handle_small_values_split(primitive, w, x, ixI^L, ixO^L, subname)
2674 logical,
intent(in) :: primitive
2675 integer,
intent(in) :: ixi^
l,ixo^
l
2676 double precision,
intent(inout) :: w(ixi^s,1:nw)
2677 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2678 character(len=*),
intent(in) :: subname
2680 double precision :: rho
2681 integer :: ix^
d, igrp
2682 logical :: flag(ixi^s,1:nw)
2684 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2689 {
do ix^db=ixomin^db,ixomax^db\}
2694 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2707 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2709 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2712 {
do ix^db=iximin^db,iximax^db\}
2714 w(ix^d,
e_)=w(ix^d,
e_)&
2715 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2717 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2719 {
do ix^db=iximin^db,iximax^db\}
2721 w(ix^d,
e_)=w(ix^d,
e_)&
2722 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2726 if(.not.primitive)
then
2728 {
do ix^db=ixomin^db,ixomax^db\}
2730 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
2731 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)&
2732 -half*((^
c&w(ix^d,
m^
c_)**2+)*rho+(^
c&w(ix^d,
b^
c_)**2+)))
2735 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2738 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2739 end subroutine mhd_handle_small_values_split
2741 subroutine mhd_handle_small_values_inte(primitive, w, x, ixI^L, ixO^L, subname)
2744 logical,
intent(in) :: primitive
2745 integer,
intent(in) :: ixi^
l,ixo^
l
2746 double precision,
intent(inout) :: w(ixi^s,1:nw)
2747 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2748 character(len=*),
intent(in) :: subname
2750 integer :: ix^
d, igrp
2751 logical :: flag(ixi^s,1:nw)
2753 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2758 {
do ix^db=ixomin^db,ixomax^db\}
2759 if(flag(ix^
d,
rho_))
then
2761 ^
c&w(ix^
d,
m^
c_)=0.d0\
2771 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2773 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2775 if(.not.primitive)
then
2777 {
do ix^db=ixomin^db,ixomax^db\}
2779 w(ix^d,
p_)=eos%gamma_minus_1*w(ix^d,
e_)
2782 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2785 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2786 end subroutine mhd_handle_small_values_inte
2788 subroutine mhd_handle_small_values_noe(primitive, w, x, ixI^L, ixO^L, subname)
2791 logical,
intent(in) :: primitive
2792 integer,
intent(in) :: ixi^
l,ixo^
l
2793 double precision,
intent(inout) :: w(ixi^s,1:nw)
2794 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2795 character(len=*),
intent(in) :: subname
2797 integer :: ix^
d, igrp
2798 logical :: flag(ixi^s,1:nw)
2800 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2805 {
do ix^db=ixomin^db,ixomax^db\}
2809 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2815 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2817 if(.not.primitive)
then
2819 {
do ix^db=ixomin^db,ixomax^db\}
2823 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2826 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2827 end subroutine mhd_handle_small_values_noe
2829 subroutine mhd_handle_small_values_hde(primitive, w, x, ixI^L, ixO^L, subname)
2832 logical,
intent(in) :: primitive
2833 integer,
intent(in) :: ixi^
l,ixo^
l
2834 double precision,
intent(inout) :: w(ixi^s,1:nw)
2835 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2836 character(len=*),
intent(in) :: subname
2838 integer :: ix^
d, igrp
2839 logical :: flag(ixi^s,1:nw)
2841 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2846 {
do ix^db=ixomin^db,ixomax^db\}
2847 if(flag(ix^
d,
rho_))
then
2849 ^
c&w(ix^
d,
m^
c_)=0.d0\
2859 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2861 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2863 if(.not.primitive)
then
2865 {
do ix^db=ixomin^db,ixomax^db\}
2867 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)-half*(^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_))
2870 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2873 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2874 end subroutine mhd_handle_small_values_hde
2880 integer,
intent(in) :: ixi^
l, ixo^
l
2881 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
2882 double precision,
intent(out) :: v(ixi^s,
ndir)
2884 double precision :: rho(ixi^s)
2889 rho(ixo^s)=1.d0/rho(ixo^s)
2892 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
2898 subroutine mhd_get_csound2(w,x,ixI^L,ixO^L,cs2)
2901 integer,
intent(in) :: ixi^
l, ixo^
l
2902 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2903 double precision,
intent(inout) :: cs2(ixi^s)
2905 double precision :: rho, inv_rho, ploc
2908 {
do ix^db=ixomin^db,ixomax^db \}
2918 cs2(ix^
d)=eos%gamma*ploc*inv_rho
2920 end subroutine mhd_get_csound2
2923 subroutine mhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
2926 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2927 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2928 double precision,
intent(inout) :: cmax(ixi^s)
2930 double precision :: rho, inv_rho, ploc, cfast2, avmincs2, b2, kmax
2931 double precision :: cs2(ixi^s)
2932 double precision :: uawsom_zeta(ixi^s), uawsom_radius(ixi^s), uawsom_lperp(ixi^s)
2936 if(
mhd_uawsom)
call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.true.,&
2937 uawsom_zeta,uawsom_radius,uawsom_lperp)
2940 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
2943 {
do ix^db=ixomin^db,ixomax^db \}
2952 cmax(ix^
d)=cs2(ix^
d)
2955 cfast2=b2*inv_rho+cmax(ix^
d)
2956 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
2957 if(avmincs2<zero) avmincs2=zero
2958 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2962 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2965 cmax(ix^
d)=max(cmax(ix^
d),abs(w(ix^
d,mag(idim))+&
2966 block%B0(ix^
d,idim,
b0i))*dsqrt(inv_rho))
2967 cmax(ix^
d)=max(cmax(ix^
d),abs(w(ix^
d,mag(idim))+&
2972 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
2975 {
do ix^db=ixomin^db,ixomax^db \}
2978 ploc=(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i))
2984 cmax(ix^d)=cs2(ix^d)
2986 b2=(^
c&w(ix^d,
b^
c_)**2+)
2987 cfast2=b2*inv_rho+cmax(ix^d)
2988 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2989 if(avmincs2<zero) avmincs2=zero
2990 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2994 cmax(ix^d)=max(cmax(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2997 cmax(ix^d)=max(cmax(ix^d),abs(w(ix^d,mag(idim)))*dsqrt(inv_rho))
2998 cmax(ix^d)=max(cmax(ix^d),abs(w(ix^d,mag(idim)))/dsqrt(rho*&
3002 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
3006 end subroutine mhd_get_cmax_origin
3009 subroutine mhd_get_cmax_origin_noe(w,x,ixI^L,ixO^L,idim,cmax)
3013 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3014 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3015 double precision,
intent(inout) :: cmax(ixi^s)
3017 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
3018 double precision :: adiabs(ixi^s), gammas(ixi^s)
3033 {
do ix^db=ixomin^db,ixomax^db \}
3037 cmax(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*rho**(gammas(ix^
d)-1.d0)
3039 b2=(^
c&w(ix^
d,
b^
c_)**2+)
3040 cfast2=b2*inv_rho+cmax(ix^
d)
3041 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*w(ix^
d,mag(idim))**2*inv_rho
3042 if(avmincs2<zero) avmincs2=zero
3043 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3047 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3049 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
3052 end subroutine mhd_get_cmax_origin_noe
3055 subroutine mhd_get_cmax_semirelati(w,x,ixI^L,ixO^L,idim,cmax)
3058 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3059 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3060 double precision,
intent(inout):: cmax(ixi^s)
3062 double precision :: csound, avmincs2, idim_alfven_speed2
3063 double precision :: inv_rho, alfven_speed2, gamma2
3066 {
do ix^db=ixomin^db,ixomax^db \}
3067 inv_rho=1.d0/w(ix^
d,
rho_)
3068 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3069 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3070 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
3072 csound=eos%gamma*w(ix^
d,
p_)*inv_rho
3073 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3076 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
3077 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
3078 if(avmincs2<zero) avmincs2=zero
3080 csound = sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
3081 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+csound
3084 end subroutine mhd_get_cmax_semirelati
3087 subroutine mhd_get_cmax_semirelati_noe(w,x,ixI^L,ixO^L,idim,cmax)
3091 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3092 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3093 double precision,
intent(inout):: cmax(ixi^s)
3095 double precision :: adiabs(ixi^s), gammas(ixi^s)
3096 double precision :: csound, avmincs2, idim_alfven_speed2
3097 double precision :: inv_rho, alfven_speed2, gamma2
3111 {
do ix^db=ixomin^db,ixomax^db \}
3112 inv_rho=1.d0/w(ix^
d,
rho_)
3113 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3114 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3115 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
3116 csound=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3117 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3120 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
3121 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
3122 if(avmincs2<zero) avmincs2=zero
3124 csound = sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
3125 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+csound
3128 end subroutine mhd_get_cmax_semirelati_noe
3131 subroutine mhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
3136 integer,
intent(in) :: ixi^
l,ixo^
l
3137 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3139 double precision,
intent(inout) :: w(ixi^s,1:nw)
3140 double precision,
intent(out) :: tco_local,tmax_local
3142 double precision,
parameter :: trac_delta=0.25d0
3143 double precision :: te(ixi^s),lts(ixi^s)
3144 double precision,
dimension(1:ndim) :: bdir, bunitvec
3145 double precision,
dimension(ixI^S,1:ndim) :: gradt
3146 double precision :: ltrc,ltrp,altr
3147 integer :: idims,ix^
d,jxo^
l,hxo^
l,ixa^
d,ixb^
d
3148 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
3150 double precision :: q_heat(ixi^s), ne(ixi^s), nh_arr(ixi^s)
3151 double precision :: bvec(1:
ndir)
3152 double precision :: bmin_c, bmag, gnorm, bgtd, l_t, dl_eff, vmag, bdotv, binp2
3153 double precision :: v_n, a_coeff, l1, cooling, net_cool
3154 double precision :: kappa_par, disc, dx_over_delta, kappa_trac, kappa_eff, tcoff_eff
3156 if (eos%eos_type ==
'LTE' .or. eos%eos_type ==
'PI')
then
3157 te(ixi^s) = w(ixi^s,
te_)
3159 call eos%get_Rfactor(w,x,ixi^
l,ixi^
l,te)
3160 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
3163 tmax_local=maxval(te(ixo^s))
3171 do ix1=ixomin1,ixomax1
3172 lts(ix1)=0.5d0*abs(te(ix1+1)-te(ix1-1))/te(ix1)
3173 if(lts(ix1)>trac_delta)
then
3174 tco_local=max(tco_local,te(ix1))
3186 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
3187 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
3188 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
3189 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
3191 call mpistop(
"mhd_trac_type not allowed for 1D simulation")
3202 call gradient(te,ixi^
l,ixo^
l,idims,gradt(ixi^s,idims))
3209 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
3214 ixb^d=(ixomin^d+ixomax^d-1)/2+ixa^d;
3215 bdir(1:ndim)=bdir(1:ndim)+w(ixb^d,iw_mag(1:ndim))
3219 if(bdir(1)/=0.d0)
then
3220 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3222 block%special_values(3)=0.d0
3224 if(bdir(2)/=0.d0)
then
3225 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3227 block%special_values(4)=0.d0
3231 if(bdir(1)/=0.d0)
then
3232 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+&
3233 (bdir(3)/bdir(1))**2)
3235 block%special_values(3)=0.d0
3237 if(bdir(2)/=0.d0)
then
3238 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+&
3239 (bdir(3)/bdir(2))**2)
3241 block%special_values(4)=0.d0
3243 if(bdir(3)/=0.d0)
then
3244 block%special_values(5)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+&
3245 (bdir(2)/bdir(3))**2)
3247 block%special_values(5)=0.d0
3252 block%special_values(1)=zero
3253 {
do ix^db=ixomin^db,ixomax^db\}
3255 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
3257 ^d&bdir(^d)=w({ix^d},iw_mag(^d))\
3260 if(bdir(1)/=0.d0)
then
3261 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3265 if(bdir(2)/=0.d0)
then
3266 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3271 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2))*&
3272 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3275 if(bdir(1)/=0.d0)
then
3276 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
3280 if(bdir(2)/=0.d0)
then
3281 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
3285 if(bdir(3)/=0.d0)
then
3286 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
3291 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2),block%ds(ix^d,3))*&
3292 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3294 if(lts(ix^d)>trac_delta)
then
3295 block%special_values(1)=max(block%special_values(1),te(ix^d))
3298 block%special_values(2)=tmax_local
3317 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
3321 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),1,.true.)
3322 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),1,.false.)
3326 {
do ix^db=ixpmin^db,ixpmax^db\}
3327 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
3329 if(bdir(1)/=0.d0)
then
3330 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3334 if(bdir(2)/=0.d0)
then
3335 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3341 if(bdir(1)/=0.d0)
then
3342 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
3346 if(bdir(2)/=0.d0)
then
3347 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
3351 if(bdir(3)/=0.d0)
then
3352 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
3358 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3360 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
3361 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
3364 {
do ix^db=ixpmin^db,ixpmax^db\}
3366 if(w(ix^d,iw_mag(1))/=0.d0)
then
3367 bunitvec(1)=sign(1.d0,w(ix^d,iw_mag(1)))/dsqrt(1.d0+(w(ix^d,iw_mag(2))/w(ix^d,iw_mag(1)))**2)
3371 if(w(ix^d,iw_mag(2))/=0.d0)
then
3372 bunitvec(2)=sign(1.d0,w(ix^d,iw_mag(2)))/dsqrt(1.d0+(w(ix^d,iw_mag(1))/w(ix^d,iw_mag(2)))**2)
3378 if(w(ix^d,iw_mag(1))/=0.d0)
then
3379 bunitvec(1)=sign(1.d0,w(ix^d,iw_mag(1)))/dsqrt(1.d0+(w(ix^d,iw_mag(2))/w(ix^d,iw_mag(1)))**2+&
3380 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(1)))**2)
3384 if(w(ix^d,iw_mag(2))/=0.d0)
then
3385 bunitvec(2)=sign(1.d0,w(ix^d,iw_mag(2)))/dsqrt(1.d0+(w(ix^d,iw_mag(1))/w(ix^d,iw_mag(2)))**2+&
3386 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(2)))**2)
3390 if(w(ix^d,iw_mag(3))/=0.d0)
then
3391 bunitvec(3)=sign(1.d0,w(ix^d,iw_mag(3)))/dsqrt(1.d0+(w(ix^d,iw_mag(1))/w(ix^d,iw_mag(3)))**2+&
3392 (w(ix^d,iw_mag(2))/w(ix^d,iw_mag(3)))**2)
3398 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3400 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
3401 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
3407 {
do ix^db=ixpmin^db,ixpmax^db\}
3409 altr=0.25d0*((lts(ix1-1,ix2)+two*lts(ix^d)+lts(ix1+1,ix2))*bunitvec(1)**2+&
3410 (lts(ix1,ix2-1)+two*lts(ix^d)+lts(ix1,ix2+1))*bunitvec(2)**2)
3411 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
3414 altr=0.25d0*((lts(ix1-1,ix2,ix3)+two*lts(ix^d)+lts(ix1+1,ix2,ix3))*bunitvec(1)**2+&
3415 (lts(ix1,ix2-1,ix3)+two*lts(ix^d)+lts(ix1,ix2+1,ix3))*bunitvec(2)**2+&
3416 (lts(ix1,ix2,ix3-1)+two*lts(ix^d)+lts(ix1,ix2,ix3+1))*bunitvec(3)**2)
3417 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
3427 call usr_get_heating(q_heat, ixi^l, ixo^l, w, x)
3428 call eos%get_ne_nH(ixi^l, ixo^l, w, x, ne, nh_arr)
3429 block%wextra(ixi^s,
tcoff_) = te(ixi^s)
3431 call gradient(te,ixi^l,ixo^l,idims,gradt(ixi^s,idims))
3433 bmin_c = 0.1d0/unit_magneticfield
3434 {
do ix^db=ixomin^db,ixomax^db\}
3436 bmag=bmin_c**2; bdotv=0.d0; vmag=0.d0
3438 bvec(idims)=w(ix^d,iw_mag(idims))
3439 if(b0field) bvec(idims)=bvec(idims)+block%B0(ix^d,idims,0)
3440 bmag =bmag +bvec(idims)**2
3441 bdotv=bdotv+bvec(idims)*w(ix^d,
mom(idims))
3442 vmag =vmag +w(ix^d,
mom(idims))**2
3444 bmag=dsqrt(bmag); vmag=dsqrt(vmag)
3446 gnorm=0.d0; binp2=0.d0; bgtd=0.d0
3448 gnorm=gnorm+gradt(ix^d,idims)**2
3449 binp2=binp2+bvec(idims)**2
3450 bgtd =bgtd +bvec(idims)*gradt(ix^d,idims)
3453 if(gnorm<smalldouble .or. binp2<smalldouble)
then
3454 block%wextra(ix^d,
tcoff_)=te(ix^d)
3457 l_t=te(ix^d)*bmag/(dabs(bgtd)+bmin_c*gnorm)
3461 dl_eff=dl_eff+(bvec(idims)/block%ds(ix^d,idims))**2
3463 dl_eff=bmag/dsqrt(dl_eff)
3465 v_n=(dabs(bdotv)+bmin_c*vmag)/bmag
3466 a_coeff=2.5d0*w(ix^d,
p_)*v_n/te(ix^d)
3469 if(te(ix^d)>
rc_fl%tcoolmin .and. te(ix^d)<
rc_fl%tcoolmax)
then
3470 call findl(te(ix^d),l1,
rc_fl); cooling=l1*ne(ix^d)*nh_arr(ix^d)
3471 else if(te(ix^d)>=
rc_fl%tcoolmax)
then
3472 call calc_l_extended(te(ix^d),l1,
rc_fl); cooling=l1*ne(ix^d)*nh_arr(ix^d)
3476 net_cool=dabs(cooling-q_heat(ix^d))
3477 kappa_par=
tc_fl%tc_k_para*te(ix^d)**2.5d0
3478 disc=a_coeff**2+4.d0*
tc_fl%tc_k_para*te(ix^d)**1.5d0*net_cool
3481 if(l_t<=2.d0*dx_over_delta)
then
3482 kappa_trac=(a_coeff+dsqrt(disc))/(2.d0/dx_over_delta)
3484 kappa_trac=dsqrt(4.d0*
tc_fl%tc_k_para*te(ix^d)**1.5d0*net_cool)/(2.d0/dx_over_delta)
3486 kappa_eff=max(kappa_trac,kappa_par)
3487 tcoff_eff=(kappa_eff/
tc_fl%tc_k_para)**0.4d0
3488 block%wextra(ix^d,
tcoff_)=max(te(ix^d),tcoff_eff)
3494 call mpistop(
"unknown mhd_trac_type")
3497 end subroutine mhd_get_tcutoff
3500 subroutine mhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
3503 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3504 double precision,
intent(in) :: wprim(ixi^s, nw)
3505 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3506 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
3508 double precision :: csound(ixi^s,
ndim)
3509 double precision,
allocatable :: tmp(:^
d&)
3510 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
3514 allocate(tmp(ixa^s))
3517 call mhd_get_csound_prim_split(wprim,x,ixi^
l,ixa^
l,id,tmp)
3519 call mhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
3521 csound(ixa^s,id)=tmp(ixa^s)
3524 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
3525 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
3526 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
3527 hspeed(ixc^s,1)=0.5d0*abs(wprim(jxc^s,
mom(idim))+csound(jxc^s,idim)-wprim(ixc^s,
mom(idim))+csound(ixc^s,idim))
3531 ixamax^
d=ixcmax^
d+
kr(id,^
d);
3532 ixamin^
d=ixcmin^
d+
kr(id,^
d);
3533 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(ixa^s,
mom(id))+csound(ixa^s,id)-wprim(ixc^s,
mom(id))+csound(ixc^s,id)))
3534 ixamax^
d=ixcmax^
d-
kr(id,^
d);
3535 ixamin^
d=ixcmin^
d-
kr(id,^
d);
3536 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(ixc^s,
mom(id))+csound(ixc^s,id)-wprim(ixa^s,
mom(id))+csound(ixa^s,id)))
3541 ixamax^
d=jxcmax^
d+
kr(id,^
d);
3542 ixamin^
d=jxcmin^
d+
kr(id,^
d);
3543 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(ixa^s,
mom(id))+csound(ixa^s,id)-wprim(jxc^s,
mom(id))+csound(jxc^s,id)))
3544 ixamax^
d=jxcmax^
d-
kr(id,^
d);
3545 ixamin^
d=jxcmin^
d-
kr(id,^
d);
3546 hspeed(ixc^s,1)=max(hspeed(ixc^s,1),0.5d0*abs(wprim(jxc^s,
mom(id))+csound(jxc^s,id)-wprim(ixa^s,
mom(id))+csound(ixa^s,id)))
3550 end subroutine mhd_get_h_speed
3553 subroutine mhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3557 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3558 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3559 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3560 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3561 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3562 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3563 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3565 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3567 double precision :: umean, dmean, tmp1, tmp2, tmp3
3574 call mhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3575 call mhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3580 if(
present(cmin))
then
3581 {
do ix^db=ixomin^db,ixomax^db\}
3582 tmp1=sqrt(wlp(ix^
d,
rho_))
3583 tmp2=sqrt(wrp(ix^
d,
rho_))
3584 tmp3=1.d0/(tmp1+tmp2)
3585 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3586 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3587 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3588 cmin(ix^
d,1)=umean-dmean
3589 cmax(ix^
d,1)=umean+dmean
3596 if(h_correction)
then
3597 {
do ix^db=ixomin^db,ixomax^db\}
3598 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3599 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3603 {
do ix^db=ixomin^db,ixomax^db\}
3604 tmp1=sqrt(wlp(ix^d,
rho_))
3605 tmp2=sqrt(wrp(ix^d,
rho_))
3606 tmp3=1.d0/(tmp1+tmp2)
3607 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3608 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3609 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3610 cmax(ix^d,1)=abs(umean)+dmean
3618 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3619 call mhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
3623 if(
present(cmin))
then
3624 {
do ix^db=ixomin^db,ixomax^db\}
3625 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3626 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3633 if(h_correction)
then
3634 {
do ix^db=ixomin^db,ixomax^db\}
3635 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3636 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3640 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3648 call mhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
3649 call mhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
3654 if(
present(cmin))
then
3655 {
do ix^db=ixomin^db,ixomax^db\}
3656 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3657 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3658 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3665 if(h_correction)
then
3666 {
do ix^db=ixomin^db,ixomax^db\}
3667 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3668 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3672 {
do ix^db=ixomin^db,ixomax^db\}
3673 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3674 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3683 end subroutine mhd_get_cbounds
3686 subroutine mhd_get_cbounds_semirelati(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3689 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3690 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3691 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3692 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3693 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3694 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3695 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3697 double precision,
dimension(ixO^S) :: csoundl, csoundr, gamma2l, gamma2r
3702 call mhd_get_csound_semirelati(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3703 call mhd_get_csound_semirelati(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3705 call mhd_get_csound_semirelati_noe(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3706 call mhd_get_csound_semirelati_noe(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3708 if(
present(cmin))
then
3709 {
do ix^db=ixomin^db,ixomax^db\}
3710 csoundl(ix^
d)=max(csoundl(ix^
d),csoundr(ix^
d))
3711 cmin(ix^
d,1)=min(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))-csoundl(ix^
d)
3712 cmax(ix^
d,1)=max(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))+csoundl(ix^
d)
3715 {
do ix^db=ixomin^db,ixomax^db\}
3716 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3717 cmax(ix^d,1)=max(gamma2l(ix^d)*wlp(ix^d,
mom(idim)),gamma2r(ix^d)*wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3721 end subroutine mhd_get_cbounds_semirelati
3724 subroutine mhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3727 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3728 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3729 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3730 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3731 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3732 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3733 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3735 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3736 double precision :: umean, dmean, tmp1, tmp2, tmp3
3743 call mhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3744 call mhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3745 if(
present(cmin))
then
3746 {
do ix^db=ixomin^db,ixomax^db\}
3749 tmp3=1.d0/(tmp1+tmp2)
3750 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3751 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3752 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3753 cmin(ix^
d,1)=umean-dmean
3754 cmax(ix^
d,1)=umean+dmean
3756 if(h_correction)
then
3757 {
do ix^db=ixomin^db,ixomax^db\}
3758 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3759 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3763 {
do ix^db=ixomin^db,ixomax^db\}
3766 tmp3=1.d0/(tmp1+tmp2)
3767 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3768 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3769 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3770 cmax(ix^d,1)=abs(umean)+dmean
3774 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3775 call mhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
3776 if(
present(cmin))
then
3777 {
do ix^db=ixomin^db,ixomax^db\}
3778 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3779 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3781 if(h_correction)
then
3782 {
do ix^db=ixomin^db,ixomax^db\}
3783 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3784 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3788 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3792 call mhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
3793 call mhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
3794 if(
present(cmin))
then
3795 {
do ix^db=ixomin^db,ixomax^db\}
3796 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3797 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3798 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3800 if(h_correction)
then
3801 {
do ix^db=ixomin^db,ixomax^db\}
3802 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3803 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3807 {
do ix^db=ixomin^db,ixomax^db\}
3808 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3809 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3814 end subroutine mhd_get_cbounds_split_rho
3817 subroutine mhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3820 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3821 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3822 double precision,
intent(in) :: cmax(ixi^s)
3823 double precision,
intent(in),
optional :: cmin(ixi^s)
3824 type(ct_velocity),
intent(inout):: vcts
3826 end subroutine mhd_get_ct_velocity_average
3828 subroutine mhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3831 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3832 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3833 double precision,
intent(in) :: cmax(ixi^s)
3834 double precision,
intent(in),
optional :: cmin(ixi^s)
3835 type(ct_velocity),
intent(inout):: vcts
3837 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
3839 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
3841 end subroutine mhd_get_ct_velocity_contact
3843 subroutine mhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3846 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3847 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3848 double precision,
intent(in) :: cmax(ixi^s)
3849 double precision,
intent(in),
optional :: cmin(ixi^s)
3850 type(ct_velocity),
intent(inout):: vcts
3852 integer :: idime,idimn
3854 if(.not.
allocated(vcts%vbarC))
then
3855 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
3856 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
3859 if(
present(cmin))
then
3860 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
3861 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3863 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3864 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
3867 idimn=mod(idim,
ndir)+1
3868 idime=mod(idim+1,
ndir)+1
3870 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
3871 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
3872 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
3873 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
3874 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3876 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
3877 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
3878 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
3879 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,2))&
3880 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3882 end subroutine mhd_get_ct_velocity_hll
3889 integer,
intent(in) :: ixi^
l, ixo^
l
3890 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3891 double precision,
intent(out):: csound(ixi^s)
3893 double precision :: wprim(ixi^s, nw)
3895 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
3896 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
3908 integer,
intent(in) :: ixi^
l, ixo^
l
3909 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3910 double precision,
intent(out):: csound(ixi^s)
3912 double precision :: inv_rho, b2
3913 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
3914 double precision :: prad_max(ixi^s)
3915 integer :: ix^
d,idim
3922 prad_tensor(ixo^s,idim,idim)=w(ixo^s,
r_e)/3.0d0
3927 {
do ix^db=ixomin^db,ixomax^db \}
3928 inv_rho=1.d0/w(ix^
d,
rho_)
3929 prad_max(ix^
d) = (4.0d0/3.0d0)*maxval(prad_tensor(ix^
d,:,:))
3931 csound(ix^
d)=(eos%gamma*w(ix^
d,
p_)+b2+prad_max(ix^
d))*inv_rho
3934 {
do ix^db=ixomin^db,ixomax^db \}
3935 inv_rho=1.d0/w(ix^d,
rho_)
3936 prad_max(ix^d) = (4.0d0/3.0d0)*maxval(prad_tensor(ix^d,:,:))
3937 b2=(^
c&w(ix^d,
b^
c_)**2+)
3938 csound(ix^d)=(eos%gamma*w(ix^d,
p_)+b2+prad_max(ix^d))*inv_rho
3942 if(minval(csound(ixo^s))<smalldouble)
then
3943 print *,
'issue with squared speed and rad pressure'
3944 print *,minval(csound(ixo^s))
3945 print *,minval(prad_max(ixo^s))
3946 call mpistop(
"negative squared speed in get_csrad2 for dt")
3952 subroutine mhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
3957 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3958 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3959 double precision,
intent(out):: csound(ixo^s)
3961 double precision :: adiabs(ixi^s), gammas(ixi^s)
3962 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
3963 double precision :: cs2(ixi^s)
3983 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
3988 {
do ix^db=ixomin^db,ixomax^db \}
3989 inv_rho=1.d0/w(ix^
d,
rho_)
3991 csound(ix^
d)=cs2(ix^
d)
3994 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3997 cfast2=b2*inv_rho+csound(ix^
d)
3998 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
4000 if(avmincs2<zero) avmincs2=zero
4001 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4003 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4007 {
do ix^db=ixomin^db,ixomax^db \}
4008 inv_rho=1.d0/w(ix^d,
rho_)
4010 csound(ix^d)=cs2(ix^d)
4013 csound(ix^d)=gammas(ix^d)*adiabs(ix^d)*w(ix^d,
rho_)**(gammas(ix^d)-1.d0)
4015 b2=(^
c&w(ix^d,
b^
c_)**2+)
4016 cfast2=b2*inv_rho+csound(ix^d)
4017 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
4018 if(avmincs2<zero) avmincs2=zero
4019 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4021 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4026 end subroutine mhd_get_csound_prim
4030 subroutine mhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
4033 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4034 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4035 double precision,
intent(out):: csound(ixo^s)
4037 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
4044 {
do ix^db=ixomin^db,ixomax^db \}
4049 cfast2=b2*inv_rho+csound(ix^
d)
4050 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
4052 if(avmincs2<zero) avmincs2=zero
4053 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4055 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4059 {
do ix^db=ixomin^db,ixomax^db \}
4062 csound(ix^d)=eos%gamma*(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i))*inv_rho
4063 b2=(^
c&w(ix^d,
b^
c_)**2+)
4064 cfast2=b2*inv_rho+csound(ix^d)
4065 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
4066 if(avmincs2<zero) avmincs2=zero
4067 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4069 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4074 end subroutine mhd_get_csound_prim_split
4077 subroutine mhd_get_csound_semirelati(w,x,ixI^L,ixO^L,idim,csound,gamma2)
4080 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4082 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4083 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
4085 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
4088 {
do ix^db=ixomin^db,ixomax^db\}
4089 inv_rho = 1.d0/w(ix^
d,
rho_)
4091 csound(ix^
d)=eos%gamma*w(ix^
d,
p_)*inv_rho
4092 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
4093 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
4094 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
4095 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
4098 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
4099 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
4100 if(avmincs2<zero) avmincs2=zero
4102 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
4105 end subroutine mhd_get_csound_semirelati
4108 subroutine mhd_get_csound_semirelati_noe(w,x,ixI^L,ixO^L,idim,csound,gamma2)
4112 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4114 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4115 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
4117 double precision :: adiabs(ixi^s), gammas(ixi^s)
4118 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
4131 {
do ix^db=ixomin^db,ixomax^db\}
4132 inv_rho = 1.d0/w(ix^
d,
rho_)
4134 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
4135 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
4136 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
4137 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
4138 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
4141 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
4142 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
4143 if(avmincs2<zero) avmincs2=zero
4145 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
4148 end subroutine mhd_get_csound_semirelati_noe
4161 integer,
intent(in) :: ixi^
l, ixo^
l
4162 double precision,
intent(in) :: w(ixi^s, 1:nw)
4163 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4164 double precision,
intent(out):: prad(ixi^s, 1:
ndim, 1:
ndim)
4173 integer,
intent(in) :: ixi^
l, ixo^
l
4174 double precision,
intent(in) :: w(ixi^s, 1:nw)
4175 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4176 double precision,
intent(out) :: pth_plus_prad(ixi^s)
4178 double precision :: wprim(ixi^s, 1:nw)
4179 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
4180 double precision :: prad_max(ixi^s)
4183 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
4184 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
4186 {
do ix^
d = ixomin^
d,ixomax^
d\}
4187 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
4189 pth_plus_prad(ixo^s) = wprim(ixo^s,
p_) + prad_max(ixo^s)
4197 integer,
intent(in) :: ixi^
l, ixo^
l
4198 double precision,
intent(in) :: w(ixi^s, 1:nw)
4199 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4200 double precision,
intent(out):: trad(ixi^s)
4207 subroutine mhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
4211 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4213 double precision,
intent(in) :: wc(ixi^s,nw)
4215 double precision,
intent(in) :: w(ixi^s,nw)
4216 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4217 double precision,
intent(out) :: f(ixi^s,nwflux)
4219 double precision :: vhall(ixi^s,1:
ndir)
4220 double precision :: ptotal
4221 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
4222 double precision :: bvec(ixi^s,1:
ndir)
4223 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
4224 double precision :: nperp(ixi^s,1:
ndir)
4225 double precision :: uawsom_zeta(ixi^s), uawsom_radius(ixi^s)
4226 double precision :: uawsom_lperp(ixi^s), uawsom_denom
4227 double precision :: uawsom_pwave, uawsom_bi
4228 logical :: use_perp_flux
4229 integer :: iw, ix^
d, idir
4231 if(
mhd_uawsom)
call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.true.,&
4232 uawsom_zeta,uawsom_radius,uawsom_lperp)
4235 {
do ix^db=ixomin^db,ixomax^db\}
4248 {
do ix^db=ixomin^db,ixomax^db\}
4252 ^
c&f(ix^d,
m^
c_)=wc(ix^d,
mom(idim))*w(ix^d,
m^
c_)-w(ix^d,mag(idim))*w(ix^d,
b^
c_)\
4253 ptotal=w(ix^d,
p_)+half*(^
c&w(ix^d,
b^
c_)**2+)
4256 ptotal=ptotal+uawsom_pwave
4259 f(ix^d,
mom(idim))=f(ix^d,
mom(idim))+ptotal
4262 f(ix^d,
e_)=w(ix^d,
mom(idim))*(wc(ix^d,
e_)+ptotal)&
4263 -w(ix^d,mag(idim))*(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)
4265 uawsom_denom=dsqrt(w(ix^d,
rho_)*(uawsom_zeta(ix^d)+one)/&
4268 uawsom_bi=w(ix^d,mag(idim))
4269 f(ix^d,
e_)=f(ix^d,
e_)+uawsom_bi*(&
4274 ^
c&f(ix^d,
b^
c_)=w(ix^d,
mom(idim))*w(ix^d,
b^
c_)-w(ix^d,mag(idim))*w(ix^d,
m^
c_)\
4278 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4279 {
do ix^db=ixomin^db,ixomax^db\}
4280 if(total_energy)
then
4282 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)**2+)&
4283 -w(ix^d,mag(idim))*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
4286 ^
c&f(ix^d,
b^
c_)=f(ix^d,
b^
c_)+vhall(ix^d,idim)*w(ix^d,
b^
c_)-vhall(ix^d,^
c)*w(ix^d,mag(idim))\
4291 {
do ix^db=ixomin^db,ixomax^db\}
4292 f(ix^d,mag(idim))=w(ix^d,
psi_)
4294 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4299 {
do ix^db=ixomin^db,ixomax^db\}
4300 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
4305 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4308 {
do ix^db=ixomin^db,ixomax^db\}
4309 uawsom_denom=dsqrt(w(ix^d,
rho_)*(uawsom_zeta(ix^d)+one)/&
4312 uawsom_bi=w(ix^d,mag(idim))
4314 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4316 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4323 {
do ix^db=ixomin^db,ixomax^db\}
4330 if(use_perp_flux)
then
4332 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
4334 te(ixi^s)=(w(ixi^s,
p_)+block%equi_vars(ixi^s,
equi_pe0_,b0i)) / &
4335 (r(ixi^s)*rho_loc(ixi^s))
4337 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
4339 {
do ix^db=ixomin^db,ixomax^db\}
4341 bvec(ix^d,idir)=w(ix^d,mag(idir))
4344 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
4348 {
do ix^db=ixomin^db,ixomax^db\}
4349 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*w(ix^d,mag(idim))/(dsqrt(^
c&w(ix^d,
b^
c_)**2+)+smalldouble)
4351 if(use_perp_flux)
then
4352 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4357 end subroutine mhd_get_flux
4361 subroutine mhd_get_flux_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4366 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4368 double precision,
intent(in) :: wc(ixi^s,nw)
4370 double precision,
intent(in) :: w(ixi^s,nw)
4371 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4372 double precision,
intent(out) :: f(ixi^s,nwflux)
4374 double precision :: vhall(ixi^s,1:
ndir)
4375 double precision :: adiabs(ixi^s), gammas(ixi^s)
4388 {
do ix^db=ixomin^db,ixomax^db\}
4394 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+adiabs(ix^
d)*w(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&w(ix^
d,
b^
c_)**2+)
4399 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4400 {
do ix^db=ixomin^db,ixomax^db\}
4402 ^
c&f(ix^d,
b^
c_)=f(ix^d,
b^
c_)+vhall(ix^d,idim)*w(ix^d,
b^
c_)-vhall(ix^d,^
c)*w(ix^d,mag(idim))\
4406 {
do ix^db=ixomin^db,ixomax^db\}
4407 f(ix^d,mag(idim))=w(ix^d,
psi_)
4409 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4413 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4417 {
do ix^db=ixomin^db,ixomax^db\}
4421 end subroutine mhd_get_flux_noe
4424 subroutine mhd_get_flux_hde(wC,w,x,ixI^L,ixO^L,idim,f)
4428 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4430 double precision,
intent(in) :: wc(ixi^s,nw)
4432 double precision,
intent(in) :: w(ixi^s,nw)
4433 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4434 double precision,
intent(out) :: f(ixi^s,nwflux)
4436 double precision :: vhall(ixi^s,1:
ndir)
4437 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
4438 double precision :: bvec(ixi^s,1:
ndir)
4439 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
4440 double precision :: nperp(ixi^s,1:
ndir)
4441 logical :: use_perp_flux
4442 integer :: iw, ix^
d, idir
4444 {
do ix^db=ixomin^db,ixomax^db\}
4457 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4458 {
do ix^db=ixomin^db,ixomax^db\}
4460 ^
c&f(ix^d,
b^
c_)=f(ix^d,
b^
c_)+vhall(ix^d,idim)*w(ix^d,
b^
c_)-vhall(ix^d,^
c)*w(ix^d,mag(idim))\
4464 {
do ix^db=ixomin^db,ixomax^db\}
4465 f(ix^d,mag(idim))=w(ix^d,
psi_)
4467 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4471 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4475 {
do ix^db=ixomin^db,ixomax^db\}
4481 if(use_perp_flux)
then
4483 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
4484 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
4485 {
do ix^db=ixomin^db,ixomax^db\}
4487 bvec(ix^d,idir)=w(ix^d,mag(idir))
4490 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
4493 {
do ix^db=ixomin^db,ixomax^db\}
4494 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*w(ix^d,mag(idim))/(dsqrt(^
c&w(ix^d,
b^
c_)**2+)+smalldouble)
4496 if(use_perp_flux)
then
4497 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4502 end subroutine mhd_get_flux_hde
4509 subroutine mhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
4513 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4515 double precision,
intent(in) :: wc(ixi^s,nw)
4517 double precision,
intent(in) :: w(ixi^s,nw)
4518 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4519 double precision,
intent(out) :: f(ixi^s,nwflux)
4521 double precision :: vhall(ixi^s,1:
ndir)
4522 double precision :: ptotal, btotal(ixo^s,1:
ndir)
4523 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
4524 double precision :: bvec(ixi^s,1:
ndir)
4525 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
4526 double precision :: nperp(ixi^s,1:
ndir)
4527 double precision :: uawsom_zeta(ixi^s), uawsom_radius(ixi^s)
4528 double precision :: uawsom_lperp(ixi^s), uawsom_denom
4529 double precision :: uawsom_pwave, uawsom_bi
4530 logical :: use_perp_flux
4531 integer :: iw, ix^
d, idir
4533 if(
mhd_uawsom)
call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.true.,&
4534 uawsom_zeta,uawsom_radius,uawsom_lperp)
4536 {
do ix^db=ixomin^db,ixomax^db\}
4544 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
4548 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
4552 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
4553 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
4555 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
4559 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
4563 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+uawsom_pwave
4566 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
4573 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
4574 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
4576 uawsom_denom=dsqrt(w(ix^
d,
rho_)*(uawsom_zeta(ix^
d)+one)/&
4579 uawsom_bi=btotal(ix^
d,idim)
4580 f(ix^
d,
e_)=f(ix^
d,
e_)+w(ix^
d,
mom(idim))*uawsom_pwave+uawsom_bi*(&
4588 {
do ix^db=ixomin^db,ixomax^db\}
4589 f(ix^d,mag(idim))=w(ix^d,
psi_)
4591 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4596 {
do ix^db=ixomin^db,ixomax^db\}
4597 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
4602 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4603 {
do ix^db=ixomin^db,ixomax^db\}
4605 ^
c&f(ix^d,
b^
c_)=f(ix^d,
b^
c_)+vhall(ix^d,idim)*btotal(ix^d,^
c)-btotal(ix^d,idim)*vhall(ix^d,^
c)\
4606 if(total_energy)
then
4608 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)*btotal(ix^d,^
c)+)&
4609 -btotal(ix^d,idim)*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
4614 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4617 {
do ix^db=ixomin^db,ixomax^db\}
4618 uawsom_denom=dsqrt(w(ix^d,
rho_)*(uawsom_zeta(ix^d)+one)/&
4621 uawsom_bi=btotal(ix^d,idim)
4623 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4625 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4632 {
do ix^db=ixomin^db,ixomax^db\}
4638 if(use_perp_flux)
then
4640 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
4642 te(ixi^s)=(w(ixi^s,
p_)+block%equi_vars(ixi^s,
equi_pe0_,b0i)) / &
4643 (r(ixi^s)*rho_loc(ixi^s))
4645 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
4647 {
do ix^db=ixomin^db,ixomax^db\}
4649 bvec(ix^d,idir)=btotal(ix^d,idir)
4652 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
4655 {
do ix^db=ixomin^db,ixomax^db\}
4656 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
4658 if(use_perp_flux)
then
4659 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4664 end subroutine mhd_get_flux_split
4667 subroutine mhd_get_flux_semirelati(wC,w,x,ixI^L,ixO^L,idim,f)
4671 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4673 double precision,
intent(in) :: wc(ixi^s,nw)
4675 double precision,
intent(in) :: w(ixi^s,nw)
4676 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4677 double precision,
intent(out) :: f(ixi^s,nwflux)
4678 double precision :: sa(ixo^s,1:
ndir),e(ixo^s,1:
ndir),e2
4679 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
4680 double precision :: bvec(ixi^s,1:
ndir)
4681 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
4682 double precision :: nperp(ixi^s,1:
ndir)
4683 logical :: use_perp_flux
4684 integer :: iw, ix^
d, idir
4686 {
do ix^db=ixomin^db,ixomax^db\}
4691 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4692 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4693 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4698 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4703 e2=(^
c&e(ix^
d,^
c)**2+)
4710 sa(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
4711 sa(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
4712 sa(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
4715 sa(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
4716 sa(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
4725 eos%gamma*w(ix^
d,
p_)*eos%inv_gamma_minus_1)+sa(ix^
d,idim)
4729 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4731 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+w(ix^
d,
p_)+half*((^
c&w(ix^
d,
b^
c_)**2+)+e2*inv_squared_c)
4738 {
do ix^db=ixomin^db,ixomax^db\}
4739 f(ix^d,mag(idim))=w(ix^d,
psi_)
4741 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4745 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4749 {
do ix^db=ixomin^db,ixomax^db\}
4755 if(use_perp_flux)
then
4757 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
4758 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
4759 {
do ix^db=ixomin^db,ixomax^db\}
4761 bvec(ix^d,idir)=w(ix^d,mag(idir))
4764 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
4767 {
do ix^db=ixomin^db,ixomax^db\}
4768 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*w(ix^d,mag(idim))/(dsqrt(^
c&w(ix^d,
b^
c_)**2+)+smalldouble)
4770 if(use_perp_flux)
then
4771 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4776 end subroutine mhd_get_flux_semirelati
4778 subroutine mhd_get_flux_semirelati_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4783 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4785 double precision,
intent(in) :: wc(ixi^s,nw)
4787 double precision,
intent(in) :: w(ixi^s,nw)
4788 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4789 double precision,
intent(out) :: f(ixi^s,nwflux)
4791 double precision :: adiabs(ixi^s), gammas(ixi^s)
4792 double precision :: e(ixo^s,1:
ndir),e2
4805 {
do ix^db=ixomin^db,ixomax^db\}
4810 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4811 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4812 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4813 e2=(^
c&e(ix^
d,^
c)**2+)
4818 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4828 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4830 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+adiabs(ix^
d)*w(ix^
d,
rho_)**gammas(ix^
d)+half*((^
c&w(ix^
d,
b^
c_)**2+)+e2*inv_squared_c)
4837 {
do ix^db=ixomin^db,ixomax^db\}
4838 f(ix^d,mag(idim))=w(ix^d,
psi_)
4840 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4844 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4848 {
do ix^db=ixomin^db,ixomax^db\}
4852 end subroutine mhd_get_flux_semirelati_noe
4860 subroutine add_source_ambipolar_internal_energy(qdt,ixI^L,ixO^L,wCT,w,x)
4862 integer,
intent(in) :: ixi^
l, ixo^
l
4863 double precision,
intent(in) :: qdt
4864 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
4865 double precision,
intent(inout) :: w(ixi^s,1:nw)
4867 double precision :: tmp(ixi^s),btot2(ixi^s)
4868 double precision :: jxbxb(ixi^s,1:3)
4870 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,jxbxb)
4873 where (btot2(ixo^s)>smalldouble )
4874 tmp(ixo^s) = sum(jxbxb(ixo^s,1:3)**2,dim=
ndim+1) / btot2(ixo^s)
4881 w(ixo^s,
e_)=w(ixo^s,
e_)- qdt*tmp(ixo^s)
4883 end subroutine add_source_ambipolar_internal_energy
4886 subroutine mhd_get_jxbxb(w,x,ixI^L,ixO^L,res)
4889 integer,
intent(in) :: ixi^
l, ixo^
l
4890 double precision,
intent(in) :: w(ixi^s,nw)
4891 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4892 double precision,
intent(out) :: res(ixi^s,1:3)
4894 double precision :: btot(ixi^s,1:3)
4895 double precision :: current(ixi^s,7-2*
ndir:3)
4896 double precision :: tmp(ixi^s),b2(ixi^s)
4897 integer :: idir, idirmin
4907 btot(ixo^s, idir) = w(ixo^s,mag(idir)) +
block%B0(ixo^s,idir,
b0i)
4911 btot(ixo^s, idir) = w(ixo^s,mag(idir))
4915 tmp(ixo^s)= sum(current(ixo^s,idirmin:3)*btot(ixo^s,idirmin:3),dim=
ndim+1)
4916 b2(ixo^s) = sum(btot(ixo^s,1:3)**2,dim=
ndim+1)
4918 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s)
4921 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s) - current(ixo^s,idir) * b2(ixo^s)
4926 where (b2(ixo^s)<smalldouble )
4927 res(ixo^s,idir) = zero
4930 end subroutine mhd_get_jxbxb
4936 subroutine sts_set_source_ambipolar(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
4940 integer,
intent(in) :: ixi^
l,ixo^
l,igrid,nflux
4941 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4942 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
4943 double precision,
intent(in) :: my_dt
4944 logical,
intent(in) :: fix_conserve_at_step
4946 double precision,
dimension(ixI^S,1:3) :: tmp,ff
4947 double precision :: fluxall(ixi^s,1:nflux,1:
ndim)
4948 double precision :: fe(ixi^s,
sdim:3)
4949 double precision :: btot(ixi^s,1:3),tmp2(ixi^s)
4950 integer :: i, ixa^
l, ie_
4957 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,tmp)
4974 btot(ixa^s,1:3) = 0.d0
4976 btot(ixa^s,1:
ndir) = w(ixa^s,mag(1:
ndir))
4980 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4981 if(fix_conserve_at_step) fluxall(ixi^s,1,1:
ndim)=ff(ixi^s,1:
ndim)
4983 wres(ixo^s,
e_)=-tmp2(ixo^s)
4990 ff(ixa^s,1) = tmp(ixa^s,2)
4991 ff(ixa^s,2) = -tmp(ixa^s,1)
4993 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4994 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
4995 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
4998 call update_faces_ambipolar(ixi^
l,ixo^
l,w,x,tmp,fe,btot)
5000 ixamin^
d=ixomin^
d-1;
5001 wres(ixa^s,mag(1:
ndim))=-btot(ixa^s,1:
ndim)
5011 ff(ixa^s,2) = tmp(ixa^s,3)
5012 ff(ixa^s,3) = -tmp(ixa^s,2)
5013 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5014 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
5016 wres(ixo^s,mag(1))=-tmp2(ixo^s)
5019 ff(ixa^s,1) = -tmp(ixa^s,3)
5021 ff(ixa^s,3) = tmp(ixa^s,1)
5022 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5023 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
5024 wres(ixo^s,mag(2))=-tmp2(ixo^s)
5030 ff(ixa^s,2) = tmp(ixa^s,3)
5031 ff(ixa^s,3) = -tmp(ixa^s,2)
5032 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5033 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
5035 wres(ixo^s,mag(1))=-tmp2(ixo^s)
5037 ff(ixa^s,1) = -tmp(ixa^s,3)
5039 ff(ixa^s,3) = tmp(ixa^s,1)
5040 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5041 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
5042 wres(ixo^s,mag(2))=-tmp2(ixo^s)
5047 ff(ixa^s,1) = tmp(ixa^s,2)
5048 ff(ixa^s,2) = -tmp(ixa^s,1)
5050 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5051 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
5052 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
5057 if(fix_conserve_at_step)
then
5058 fluxall=my_dt*fluxall
5065 end subroutine sts_set_source_ambipolar
5068 subroutine update_faces_ambipolar(ixI^L,ixO^L,w,x,ECC,fE,circ)
5071 integer,
intent(in) :: ixi^
l, ixo^
l
5072 double precision,
intent(in) :: w(ixi^s,1:nw)
5073 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5075 double precision,
intent(in) :: ecc(ixi^s,1:3)
5076 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
5077 double precision,
intent(out) :: circ(ixi^s,1:
ndim)
5079 integer :: hxc^
l,ixc^
l,ixa^
l
5080 integer :: idim1,idim2,idir,ix^
d
5086 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
5088 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
5089 ixamin^
d=ixcmin^
d+ix^
d;
5090 ixamax^
d=ixcmax^
d+ix^
d;
5091 fe(ixc^s,idir)=fe(ixc^s,idir)+ecc(ixa^s,idir)
5093 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0*block%dsC(ixc^s,idir)
5099 ixcmin^d=ixomin^d-1;
5106 hxc^l=ixc^l-kr(idim2,^d);
5108 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
5109 +lvc(idim1,idim2,idir)&
5114 circ(ixc^s,idim1)=circ(ixc^s,idim1)/block%surfaceC(ixc^s,idim1)
5117 end subroutine update_faces_ambipolar
5123 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
5126 integer,
intent(in) :: ixi^
l, ixo^
l
5127 double precision,
dimension(ixI^S,1:3),
intent(inout) :: ff
5128 double precision,
intent(out) :: src(ixi^s)
5130 double precision :: ffc(ixi^s,1:
ndim)
5131 double precision :: dxinv(
ndim)
5132 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
5140 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
5142 ixbmin^
d=ixcmin^
d+ix^
d;
5143 ixbmax^
d=ixcmax^
d+ix^
d;
5146 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
5148 call mpistop(
"to generalize using volume averaging")
5151 ff(ixi^s,1:ndim)=0.d0
5153 ixb^l=ixo^l-kr(idims,^d);
5154 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
5156 if({ ix^d==0 .and. ^d==idims | .or.})
then
5157 ixbmin^d=ixcmin^d-ix^d;
5158 ixbmax^d=ixcmax^d-ix^d;
5159 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
5162 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
5165 if(slab_uniform)
then
5167 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
5168 ixb^l=ixo^l-kr(idims,^d);
5169 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
5173 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
5174 ixb^l=ixo^l-kr(idims,^d);
5175 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
5177 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
5179 end subroutine get_flux_on_cell_face
5183 function get_ambipolar_dt(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
5186 integer,
intent(in) :: ixi^
l, ixo^
l
5187 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
5188 double precision,
intent(in) :: w(ixi^s,1:nw)
5189 double precision :: dtnew
5191 double precision :: coef
5192 double precision :: dxarr(
ndim)
5193 double precision :: tmp(ixi^s)
5199 coef = maxval(dabs(tmp(ixo^s)))
5206 dtnew=minval(dxarr(1:
ndim))**2.0d0*coef
5208 dtnew=minval(
block%ds(ixo^s,1:
ndim))**2.0d0*coef
5211 end function get_ambipolar_dt
5219 integer,
intent(in) :: ixi^
l, ixo^
l
5220 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
5221 double precision,
intent(inout) :: res(ixi^s)
5222 double precision :: tmp(ixi^s)
5223 double precision :: rho(ixi^s)
5230 res(ixo^s) = tmp(ixo^s) * res(ixo^s)
5235 subroutine mhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
5243 integer,
intent(in) :: ixi^
l, ixo^
l
5244 double precision,
intent(in) :: qdt,dtfactor
5245 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
5246 double precision,
intent(inout) :: w(ixi^s,1:nw)
5247 logical,
intent(in) :: qsourcesplit
5248 logical,
intent(inout) :: active
5255 if (.not. qsourcesplit)
then
5258 call mhd_add_source_uawsom(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x)
5263 call add_source_internal_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5267 call add_equi_terms(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
5273 call add_hyperbolic_tc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5282 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
5286 if (abs(
mhd_eta)>smalldouble)
then
5288 call add_source_res_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
5293 call add_source_ambi_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
5298 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
5304 call add_source_hydrodynamic_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5308 call add_source_semirelativistic(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5315 select case (type_divb)
5320 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5323 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
5326 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5327 case (divb_janhunen)
5329 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5330 case (divb_lindejanhunen)
5332 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5333 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5334 case (divb_lindepowel)
5336 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5337 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5338 case (divb_lindeglm)
5340 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5341 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
5342 case (divb_multigrid)
5347 call mpistop(
'Unknown divB fix')
5354 w,x,qsourcesplit,active,
rc_fl)
5364 w,x,gravity_energy,qsourcesplit,active)
5373 call mhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x,qsourcesplit,active)
5377 if(eos%eos_type ==
'PI')
then
5378 if(.not.qsourcesplit)
then
5380 call eos%update_eos(ixi^
l,ixo^
l,w,x)
5384 end subroutine mhd_add_source
5386 subroutine mhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
5392 integer,
intent(in) :: ixi^
l, ixo^
l
5393 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
5394 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw)
5395 double precision,
intent(inout) :: w(ixi^s,1:nw)
5396 logical,
intent(in) :: qsourcesplit
5397 logical,
intent(inout) :: active
5403 end subroutine mhd_add_radiation_source
5406 subroutine add_equi_terms(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
5411 integer,
intent(in) :: ixi^
l, ixo^
l
5412 double precision,
intent(in) :: qdt,dtfactor
5413 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5414 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5415 double precision,
intent(inout) :: w(ixi^s,1:nw)
5417 double precision :: divv(ixi^s)
5418 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
5419 double precision :: gravity_field(ixi^s,1:
ndim)
5431 divv(ixo^s)=divv(ixo^s)*eos%gamma*eos%inv_gamma_minus_1
5442 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*
block%equi_vars(ixo^s,
equi_rho0_,0)*gravity_field(ixo^s,idir)*eos%inv_gamma_minus_1
5451 a(ixo^s,idir)=
block%J0(ixo^s,idir)
5456 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*axb(ixo^s,idir)*eos%inv_gamma_minus_1
5462 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*
block%equi_vars(ixo^s,
equi_rho0_,0)*gravity_field(ixo^s,idir)*eos%inv_gamma_minus_1
5471 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*
block%equi_vars(ixo^s,
equi_rho0_,0)*gravity_field(ixo^s,idir)*eos%inv_gamma_minus_1
5475 end subroutine add_equi_terms
5477 subroutine mhd_get_hyperbolic_tc_geometry(ixI^L,ixO^L,Te,Bvec,bgradT,gradTperp_mag,nperp)
5480 integer,
intent(in) :: ixi^
l,ixo^
l
5481 double precision,
intent(in) :: te(ixi^s)
5482 double precision,
intent(in) :: bvec(ixi^s,1:
ndir)
5483 double precision,
intent(out) :: bgradt(ixi^s), gradtperp_mag(ixi^s)
5484 double precision,
intent(out) :: nperp(ixi^s,1:
ndir)
5486 double precision :: bmag, bunitvec(
ndir), gradt(
ndir), gradt_perp(
ndir)
5487 double precision :: gradt_cell(ixi^s,1:
ndir)
5488 integer :: ix^
d, idir
5493 call gradient(te,ixi^
l,ixo^
l,idir,gradt_cell(ixi^s,idir))
5498 do ix2=ixomin2,ixomax2
5499 do ix1=ixomin1,ixomax1
5502 bmag=bmag+bvec(ix^
d,idir)**2
5506 if(bmag>smalldouble)
then
5508 bunitvec(idir)=bvec(ix^
d,idir)/bmag
5516 gradt(1)=((8.d0*(te(ix1+1,ix2)-te(ix1-1,ix2))-te(ix1+2,ix2)+te(ix1-2,ix2))/12.d0)/
block%ds(ix^
d,1)
5517 gradt(2)=((8.d0*(te(ix1,ix2+1)-te(ix1,ix2-1))-te(ix1,ix2+2)+te(ix1,ix2-2))/12.d0)/
block%ds(ix^
d,2)
5518 if(
ndir>2) gradt(3)=zero
5521 gradt(idir)=gradt_cell(ix^
d,idir)
5527 bgradt(ix^
d)=bgradt(ix^
d)+bunitvec(idir)*gradt(idir)
5531 gradt_perp(idir)=gradt(idir)-bgradt(ix^
d)*bunitvec(idir)
5534 gradtperp_mag(ix^
d)=zero
5536 gradtperp_mag(ix^
d)=gradtperp_mag(ix^
d)+gradt_perp(idir)**2
5538 gradtperp_mag(ix^
d)=dsqrt(gradtperp_mag(ix^
d))
5540 if(gradtperp_mag(ix^
d)>smalldouble)
then
5542 nperp(ix^
d,idir)=gradt_perp(idir)/gradtperp_mag(ix^
d)
5545 gradtperp_mag(ix^
d)=zero
5547 nperp(ix^
d,idir)=zero
5554 do ix3=ixomin3,ixomax3
5555 do ix2=ixomin2,ixomax2
5556 do ix1=ixomin1,ixomax1
5557 bmag=dsqrt(bvec(ix^
d,1)**2+bvec(ix^
d,2)**2+bvec(ix^
d,3)**2)
5558 if(bmag>smalldouble)
then
5559 bunitvec(1)=bvec(ix^
d,1)/bmag
5560 bunitvec(2)=bvec(ix^
d,2)/bmag
5561 bunitvec(3)=bvec(ix^
d,3)/bmag
5569 gradt(1)=((8.d0*(te(ix1+1,ix2,ix3)-te(ix1-1,ix2,ix3))-te(ix1+2,ix2,ix3)+te(ix1-2,ix2,ix3))/12.d0)/
block%ds(ix^
d,1)
5570 gradt(2)=((8.d0*(te(ix1,ix2+1,ix3)-te(ix1,ix2-1,ix3))-te(ix1,ix2+2,ix3)+te(ix1,ix2-2,ix3))/12.d0)/
block%ds(ix^
d,2)
5571 gradt(3)=((8.d0*(te(ix1,ix2,ix3+1)-te(ix1,ix2,ix3-1))-te(ix1,ix2,ix3+2)+te(ix1,ix2,ix3-2))/12.d0)/
block%ds(ix^
d,3)
5574 gradt(idir)=gradt_cell(ix^
d,idir)
5580 bgradt(ix^
d)=bgradt(ix^
d)+bunitvec(idir)*gradt(idir)
5584 gradt_perp(idir)=gradt(idir)-bgradt(ix^
d)*bunitvec(idir)
5587 gradtperp_mag(ix^
d)=dsqrt(gradt_perp(1)**2+gradt_perp(2)**2+gradt_perp(3)**2)
5588 if(gradtperp_mag(ix^
d)>smalldouble)
then
5590 nperp(ix^
d,idir)=gradt_perp(idir)/gradtperp_mag(ix^
d)
5593 gradtperp_mag(ix^
d)=zero
5595 nperp(ix^
d,idir)=zero
5602 end subroutine mhd_get_hyperbolic_tc_geometry
5604 subroutine add_hyperbolic_tc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5607 integer,
intent(in) :: ixi^
l,ixo^
l
5608 double precision,
intent(in) :: qdt
5609 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
5610 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
5611 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
5613 double precision,
dimension(ixI^S) :: r,te,rho_loc,pth_loc
5614 double precision,
dimension(ixI^S) :: ne_loc,nh_dummy
5615 double precision,
dimension(ixI^S,1:ndir) :: bvec
5616 double precision,
dimension(ixI^S) :: bgradt, gradtperp_mag
5617 double precision,
dimension(ixI^S,1:ndir) :: nperp
5618 double precision,
dimension(ixI^S) :: gradt_geom
5619 double precision,
parameter :: xe_prefac_cgs = 4.753567596681522d6
5620 double precision :: kappa_t5,kappa_t5_perp,kappa_t5_perp_eff
5621 double precision :: kappa_t7,f_sat,kappat5_bgradt,kappat5_gradtperp,tau,b2,fb,gradt1
5622 double precision :: qclass_diss
5623 double precision :: bmag_loc,tloc,tcond,nloc_code,cchi,chi
5624 double precision :: cmax(
ndim),c2,cfast2,avmincs2(
ndim),inv_rho
5625 logical :: use_perp_source
5626 integer :: ix^
d,idir
5642 call eos%get_Rfactor(wct,x,ixi^
l,ixi^
l,r)
5643 {
do ix^db=iximin^db,iximax^db\}
5648 rho_loc(ix^
d)=wctprim(ix^
d,
rho_)
5649 pth_loc(ix^
d)=wctprim(ix^
d,
p_)
5651 te(ix^
d)=pth_loc(ix^
d)/(r(ix^
d)*rho_loc(ix^
d))
5658 if(eos%eos_type==
'LTE')
then
5659 call eos%get_ne_nH(ixi^l,ixi^l,wct, x,ne_loc,nh_dummy)
5660 else if(eos%eos_type==
'PI')
then
5661 ne_loc(ixi^s)=rho_loc(ixi^s)*max(r(ixi^s)*(2.d0+3.d0*eos%He_abundance) &
5662 -(1.d0+eos%He_abundance),smalldouble)
5664 ne_loc(ixi^s)=rho_loc(ixi^s)*(1.d0+2.d0*eos%He_abundance)
5670 {
do ix^db=ixomin^db,ixomax^db\}
5672 bvec(ix^d,idir)=wct(ix^d,mag(idir))+block%B0(ix^d,idir,0)
5676 {
do ix^db=ixomin^db,ixomax^db\}
5678 bvec(ix^d,idir)=wct(ix^d,mag(idir))
5683 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
5687 if(.not.slab_uniform)
then
5688 call gradient(te,ixi^l,ixo^l,1,gradt_geom)
5690 do ix1=ixomin1,ixomax1
5693 kappa_t7=kappa_t5*te(ix1)
5697 tcond = max(tcond, block%wextra(ix1,
tcoff_))
5700 kappa_t7=kappa_t5*tcond
5702 if(slab_uniform)
then
5703 gradt1=((8.d0*(te(ix1+1)-te(ix1-1))-te(ix1+2)+te(ix1-2))/12.d0)/block%ds(ix1,1)
5705 gradt1=gradt_geom(ix1)
5709 b2=b2+bvec(ix1,idir)**2
5711 if(b2>smalldouble**2)
then
5712 bgradt(ix1)=bvec(ix1,1)*gradt1/dsqrt(b2)
5716 kappat5_bgradt=kappa_t5*bgradt(ix1)
5717 inv_rho=1.d0/rho_loc(ix1)
5718 c2=eos%gamma*pth_loc(ix1)*inv_rho
5719 cfast2 = b2*inv_rho + c2
5720 avmincs2(1) = cfast2**2 - 4.0d0*c2*bvec(ix1,1)**2*inv_rho
5721 cmax(1) = sqrt(half*(cfast2 + sqrt(dabs(avmincs2(1)))))
5723 f_sat=one/(one+dabs(kappat5_bgradt)/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5724 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*cmax(1)**2))
5725 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5728 max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*cmax(1)**2))
5733 do ix2=ixomin2,ixomax2
5734 do ix1=ixomin1,ixomax1
5737 kappa_t7=kappa_t5*te(ix^d)
5741 tcond=max(tcond, block%wextra(ix^d,
tcoff_))
5744 kappa_t7 = kappa_t5*tcond
5746 kappat5_bgradt=kappa_t5*bgradt(ix^d)
5749 b2 = b2 + bvec(ix^d,idir)**2
5751 if(use_perp_source)
then
5753 case(
'fixed_reference')
5755 case(
'weak_field_isotropization')
5761 kappa_t5_perp_eff=(one-fb)*kappa_t5
5762 kappa_t5_perp=kappa_t5_perp_eff
5763 case(
'electron_magnetization')
5764 bmag_loc = dsqrt(b2)
5765 tloc = max(te(ix^d), smalldouble)
5766 nloc_code = max(ne_loc(ix^d), smalldouble)
5767 chi = cchi*bmag_loc*tloc**1.5d0/nloc_code
5768 kappa_t5_perp_eff = kappa_t5/(one+chi**2)
5769 kappa_t5_perp = kappa_t5_perp_eff
5773 kappat5_gradtperp=kappa_t5_perp*gradtperp_mag(ix^d)
5775 inv_rho=1.d0/rho_loc(ix^d)
5776 c2=eos%gamma*pth_loc(ix^d)*inv_rho
5777 cfast2 = b2*inv_rho + c2
5779 avmincs2(idir)=cfast2**2-4.0d0*c2*bvec(ix^d,idir)**2*inv_rho
5780 cmax(idir)=sqrt(half*(cfast2+sqrt(dabs(avmincs2(idir)))))\
5783 qclass_diss=dabs(kappat5_bgradt)
5784 if(use_perp_source) &
5785 qclass_diss=dsqrt(kappat5_bgradt**2+kappat5_gradtperp**2)
5786 f_sat=one/(one+qclass_diss/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5787 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5788 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5789 if(use_perp_source)
then
5793 tau=max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5795 if(use_perp_source)
then
5803 do ix3=ixomin3,ixomax3
5804 do ix2=ixomin2,ixomax2
5805 do ix1=ixomin1,ixomax1
5808 kappa_t7=kappa_t5*te(ix^d)
5812 tcond=max(tcond, block%wextra(ix^d,
tcoff_))
5815 kappa_t7 = kappa_t5*tcond
5817 kappat5_bgradt=kappa_t5*bgradt(ix^d)
5820 b2 = b2 + bvec(ix^d,idir)**2
5822 if(use_perp_source)
then
5824 case(
'fixed_reference')
5826 case(
'weak_field_isotropization')
5832 kappa_t5_perp_eff=(one-fb)*kappa_t5
5833 kappa_t5_perp=kappa_t5_perp_eff
5834 case(
'electron_magnetization')
5835 bmag_loc = dsqrt(b2)
5836 tloc = max(te(ix^d), smalldouble)
5837 nloc_code = max(ne_loc(ix^d), smalldouble)
5838 chi = cchi*bmag_loc*tloc**1.5d0/nloc_code
5839 kappa_t5_perp_eff = kappa_t5/(one+chi**2)
5840 kappa_t5_perp = kappa_t5_perp_eff
5844 kappat5_gradtperp=kappa_t5_perp*gradtperp_mag(ix^d)
5846 inv_rho=1.d0/rho_loc(ix^d)
5847 c2=eos%gamma*pth_loc(ix^d)*inv_rho
5848 cfast2 = b2*inv_rho + c2
5850 avmincs2(idir)=cfast2**2-4.0d0*c2*bvec(ix^d,idir)**2*inv_rho
5851 cmax(idir)=sqrt(half*(cfast2+sqrt(dabs(avmincs2(idir)))))\
5854 qclass_diss=dabs(kappat5_bgradt)
5855 if(use_perp_source) &
5856 qclass_diss=dsqrt(kappat5_bgradt**2+kappat5_gradtperp**2)
5857 f_sat=one/(one+qclass_diss/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5858 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5859 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5860 if(use_perp_source)
then
5864 tau=max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5866 if(use_perp_source)
then
5874 end subroutine add_hyperbolic_tc_source
5878 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
5880 integer,
intent(in) :: ixi^
l, ixo^
l
5881 double precision,
intent(in) :: w(ixi^s,1:nw)
5882 double precision,
intent(inout) :: jxb(ixi^s,3)
5883 double precision :: a(ixi^s,3),
b(ixi^s,3)
5885 double precision :: current(ixi^s,7-2*
ndir:3)
5886 integer :: idir, idirmin
5891 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
5895 b(ixo^s, idir) = w(ixo^s,mag(idir))
5904 a(ixo^s,idir)=current(ixo^s,idir)
5908 end subroutine get_lorentz_force
5912 integer,
intent(in) :: ixi^
l, ixo^
l
5913 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
5914 double precision,
intent(out) :: rho(ixi^s)
5919 rho(ixo^s) = w(ixo^s,
rho_)
5925 subroutine mhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
5928 integer,
intent(in) :: ixi^
l,ixo^
l, ie
5929 double precision,
intent(inout) :: w(ixi^s,1:nw)
5930 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5931 character(len=*),
intent(in) :: subname
5933 double precision :: rho(ixi^s)
5935 logical :: flag(ixi^s,1:nw)
5940 flag(ixo^s,ie)=.true.
5942 where(w(ixo^s,ie)<
small_e) flag(ixo^s,ie)=.true.
5944 if(any(flag(ixo^s,ie)))
then
5948 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e - &
5951 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e
5957 w(ixo^s,
e_)=w(ixo^s,
e_)*eos%gamma_minus_1
5960 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
5966 end subroutine mhd_handle_small_ei
5970 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
5973 integer,
intent(in) :: ixi^
l, ixo^
l
5974 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5975 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5976 double precision,
intent(inout) :: w(ixi^s,1:nw)
5978 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
5990 a(ixo^s,idir)=
block%J0(ixo^s,idir)
5995 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5998 axb(ixo^s,:)=axb(ixo^s,:)*qdt
6004 if(total_energy)
then
6007 b(ixo^s,:)=wctprim(ixo^s,mag(:))
6016 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
6019 axb(ixo^s,:)=axb(ixo^s,:)*qdt
6024 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
6028 call mhd_getv_hall(wct,x,ixi^
l,ixo^
l,a,.true.)
6033 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
6036 axb(ixo^s,:)=axb(ixo^s,:)*qdt
6040 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
6048 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,axb)
6053 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*axb(ixo^s,idir)*
block%J0(ixo^s,idir)
6059 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
6061 end subroutine add_source_b0split
6064 subroutine add_source_semirelativistic(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
6068 integer,
intent(in) :: ixi^
l, ixo^
l
6069 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6070 double precision,
intent(inout) :: w(ixi^s,1:nw)
6071 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
6073 double precision :: e(ixi^s,1:3),curle(ixi^s,1:3),dive(ixi^s)
6074 integer :: idir, idirmin, ix^
d
6078 {
do ix^db=iximin^db,iximax^db\}
6080 e(ix^
d,1)=w(ix^
d,b2_)*wctprim(ix^
d,m3_)-w(ix^
d,b3_)*wctprim(ix^
d,m2_)
6081 e(ix^
d,2)=w(ix^
d,b3_)*wctprim(ix^
d,m1_)-w(ix^
d,b1_)*wctprim(ix^
d,m3_)
6082 e(ix^
d,3)=w(ix^
d,b1_)*wctprim(ix^
d,m2_)-w(ix^
d,b2_)*wctprim(ix^
d,m1_)
6084 call divvector(e,ixi^l,ixo^l,dive)
6086 call curlvector(e,ixi^l,ixo^l,curle,idirmin,1,3)
6089 {
do ix^db=ixomin^db,ixomax^db\}
6090 w(ix^d,m1_)=w(ix^d,m1_)+qdt*(inv_squared_c0-inv_squared_c)*&
6091 (e(ix^d,1)*dive(ix^d)-e(ix^d,2)*curle(ix^d,3)+e(ix^d,3)*curle(ix^d,2))
6092 w(ix^d,m2_)=w(ix^d,m2_)+qdt*(inv_squared_c0-inv_squared_c)*&
6093 (e(ix^d,2)*dive(ix^d)-e(ix^d,3)*curle(ix^d,1)+e(ix^d,1)*curle(ix^d,3))
6094 w(ix^d,m3_)=w(ix^d,m3_)+qdt*(inv_squared_c0-inv_squared_c)*&
6095 (e(ix^d,3)*dive(ix^d)-e(ix^d,1)*curle(ix^d,2)+e(ix^d,2)*curle(ix^d,1) )
6099 end subroutine add_source_semirelativistic
6102 subroutine add_source_internal_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
6106 integer,
intent(in) :: ixi^
l, ixo^
l
6107 double precision,
intent(in) :: qdt
6108 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6109 double precision,
intent(inout) :: w(ixi^s,1:nw)
6110 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
6112 double precision :: divv(ixi^s), tmp
6124 {
do ix^db=ixomin^db,ixomax^db\}
6126 w(ix^
d,
e_)=w(ix^
d,
e_)-qdt*wctprim(ix^
d,
p_)*divv(ix^
d)
6132 call add_source_ambipolar_internal_energy(qdt,ixi^l,ixo^l,wct,w,x)
6135 if(fix_small_values)
then
6136 call mhd_handle_small_ei(w,x,ixi^l,ixo^l,
e_,
'add_source_internal_e')
6138 end subroutine add_source_internal_e
6141 subroutine add_source_hydrodynamic_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
6146 integer,
intent(in) :: ixi^
l, ixo^
l
6147 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6148 double precision,
intent(inout) :: w(ixi^s,1:nw)
6149 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
6151 double precision ::
b(ixi^s,3), j(ixi^s,3), jxb(ixi^s,3)
6152 double precision :: current(ixi^s,7-2*
ndir:3)
6153 double precision :: bu(ixo^s,1:
ndir), tmp(ixo^s), b2(ixo^s)
6154 double precision :: gravity_field(ixi^s,1:
ndir), vaoc
6155 integer :: idir, idirmin, idims, ix^
d
6160 b(ixo^s, idir) = wct(ixo^s,mag(idir))
6172 j(ixo^s,idir)=current(ixo^s,idir)
6251 call add_source_ambipolar_internal_energy(qdt,ixi^
l,ixo^
l,wct,w,x)
6254 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_hydrodynamic_e')
6256 end subroutine add_source_hydrodynamic_e
6262 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
6267 integer,
intent(in) :: ixi^
l, ixo^
l
6268 double precision,
intent(in) :: qdt
6269 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6270 double precision,
intent(inout) :: w(ixi^s,1:nw)
6272 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim
6273 double precision :: tmp(ixi^s),tmp2(ixi^s)
6276 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
6277 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
6278 double precision :: lapl_vec(ixi^s,1:
ndir)
6284 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6285 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
6292 gradeta(ixo^s,1:
ndim)=zero
6297 gradeta(ixo^s,idim)=tmp(ixo^s)
6304 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
6311 tmp(ixo^s)=lapl_vec(ixo^s,idir)*eta(ixo^s)
6315 do jdir=1,
ndim;
do kdir=idirmin,3
6316 if (
lvc(idir,jdir,kdir)/=0)
then
6317 if (
lvc(idir,jdir,kdir)==1)
then
6318 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
6320 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
6327 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
6328 if(total_energy)
then
6329 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
6335 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
6338 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
6340 end subroutine add_source_res1
6344 subroutine add_source_res_exp(qdt,ixI^L,ixO^L,wCT,w,x)
6349 integer,
intent(in) :: ixi^
l, ixo^
l
6350 double precision,
intent(in) :: qdt
6351 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6352 double precision,
intent(inout) :: w(ixi^s,1:nw)
6355 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
6356 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
6357 integer :: ixa^
l,idir,idirmin,idirmin1
6361 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6362 call mpistop(
"Error in add_source_res_exp: Non-conforming input limits")
6372 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
mhd_eta
6377 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
6386 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
6389 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
6394 tmp(ixo^s)=qdt*
mhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
6396 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
6398 if(total_energy)
then
6401 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
6402 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
6405 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
6409 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res_exp')
6410 end subroutine add_source_res_exp
6415 subroutine add_source_ambi_exp(qdt,ixI^L,ixO^L,wCT,w,x)
6420 integer,
intent(in) :: ixi^
l, ixo^
l
6421 double precision,
intent(in) :: qdt
6422 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6423 double precision,
intent(inout) :: w(ixi^s,1:nw)
6425 double precision :: current(ixi^s,1:3),curlj(ixi^s,1:3)
6426 double precision :: tmpvec(ixi^s,1:3),tmp(ixi^s),btot2(ixi^s)
6427 integer :: ixa^
l,idir,idirmin1
6431 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6432 call mpistop(
"Error in add_source_ambi_exp: Non-conforming input limits")
6436 call mhd_get_jxbxb(wct,x,ixi^
l,ixa^
l,current)
6450 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
6453 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
6460 where (btot2(ixa^s)>smalldouble )
6461 tmp(ixa^s) = sum(current(ixa^s,1:3)**2,dim=
ndim+1) / btot2(ixa^s)
6468 tmp(ixo^s)=-qdt*tmp(ixo^s)
6469 if(total_energy)
then
6472 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
6473 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
6476 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
6480 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_ambi_exp')
6481 end subroutine add_source_ambi_exp
6485 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
6489 integer,
intent(in) :: ixi^
l, ixo^
l
6490 double precision,
intent(in) :: qdt
6491 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6492 double precision,
intent(inout) :: w(ixi^s,1:nw)
6494 double precision :: current(ixi^s,7-2*
ndir:3)
6495 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
6496 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
6499 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6500 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
6503 tmpvec(ixa^s,1:
ndir)=zero
6505 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
6509 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
6512 tmpvec(ixa^s,1:
ndir)=zero
6513 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
6517 tmpvec2(ixa^s,1:
ndir)=zero
6518 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
6521 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
6524 if(total_energy)
then
6527 tmpvec2(ixa^s,1:
ndir)=zero
6528 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
6529 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
6530 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
6531 end do;
end do;
end do
6533 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
6534 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
6537 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
6539 end subroutine add_source_hyperres
6541 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
6548 integer,
intent(in) :: ixi^
l, ixo^
l
6549 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6550 double precision,
intent(inout) :: w(ixi^s,1:nw)
6552 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
6573 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
6576 if(total_energy)
then
6585 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
6594 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
6598 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
6600 end subroutine add_source_glm
6603 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
6606 integer,
intent(in) :: ixi^
l, ixo^
l
6607 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6608 double precision,
intent(inout) :: w(ixi^s,1:nw)
6610 double precision :: divb(ixi^s), ba(1:
ndir)
6611 integer :: idir, ix^
d
6617 {
do ix^db=ixomin^db,ixomax^db\}
6622 if (total_energy)
then
6628 {
do ix^db=ixomin^db,ixomax^db\}
6630 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
6632 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
6633 if (total_energy)
then
6635 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
6640 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
6642 end subroutine add_source_powel
6644 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
6649 integer,
intent(in) :: ixi^
l, ixo^
l
6650 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6651 double precision,
intent(inout) :: w(ixi^s,1:nw)
6653 double precision :: divb(ixi^s)
6654 integer :: idir, ix^
d
6659 {
do ix^db=ixomin^db,ixomax^db\}
6664 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
6666 end subroutine add_source_janhunen
6668 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
6673 integer,
intent(in) :: ixi^
l, ixo^
l
6674 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6675 double precision,
intent(inout) :: w(ixi^s,1:nw)
6677 double precision :: divb(ixi^s),graddivb(ixi^s)
6678 integer :: idim, idir, ixp^
l, i^
d, iside
6679 logical,
dimension(-1:1^D&) :: leveljump
6687 if(i^
d==0|.and.) cycle
6688 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
6689 leveljump(i^
d)=.true.
6691 leveljump(i^
d)=.false.
6700 i^dd=kr(^dd,^d)*(2*iside-3);
6701 if (leveljump(i^dd))
then
6703 ixpmin^d=ixomin^d-i^d
6705 ixpmax^d=ixomax^d-i^d
6716 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
6718 {
do i^db=ixpmin^db,ixpmax^db\}
6720 graddivb(i^d)=graddivb(i^d)*
divbdiff/(^d&1.0d0/block%ds({i^d},^d)**2+)
6722 w(i^d,mag(idim))=w(i^d,mag(idim))+graddivb(i^d)
6724 if (typedivbdiff==
'all' .and. total_energy)
then
6726 w(i^d,
e_)=w(i^d,
e_)+wct(i^d,mag(idim))*graddivb(i^d)
6731 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
6733 end subroutine add_source_linde
6740 integer,
intent(in) :: ixi^
l, ixo^
l
6741 double precision,
intent(in) :: w(ixi^s,1:nw)
6742 double precision :: divb(ixi^s), dsurface(ixi^s)
6744 double precision :: invb(ixo^s)
6745 integer :: ixa^
l,idims
6747 call get_divb(w,ixi^
l,ixo^
l,divb)
6749 where(invb(ixo^s)/=0.d0)
6750 invb(ixo^s)=1.d0/invb(ixo^s)
6753 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
6755 ixamin^
d=ixomin^
d-1;
6756 ixamax^
d=ixomax^
d-1;
6757 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
6759 ixa^
l=ixo^
l-
kr(idims,^
d);
6760 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
6762 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
6763 block%dvolume(ixo^s)/dsurface(ixo^s)
6774 integer,
intent(in) :: ixo^
l, ixi^
l
6775 double precision,
intent(in) :: w(ixi^s,1:nw)
6776 integer,
intent(out) :: idirmin
6779 double precision :: current(ixi^s,7-2*
ndir:3)
6780 integer :: idir, idirmin0
6786 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
6787 block%J0(ixo^s,idirmin0:3)
6791 subroutine mhd_get_dt(wprim,ixI^L,ixO^L,dtnew,dx^D,x)
6799 integer,
intent(in) :: ixi^
l, ixo^
l
6800 double precision,
intent(inout) :: dtnew
6801 double precision,
intent(in) ::
dx^
d
6802 double precision,
intent(in) :: wprim(ixi^s,1:nw)
6803 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6805 double precision :: dxarr(
ndim)
6806 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
6807 integer :: idirmin,idim
6825 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
6828 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
6850 dtnew=min(
dtdiffpar*get_ambipolar_dt(wprim,ixi^
l,ixo^
l,
dx^
d,x),dtnew)
6861 end subroutine mhd_get_dt
6866 subroutine mhd_fld_implicit_update(dtfactor,qdt,qtC,psa,psb)
6871 double precision,
intent(in) :: qdt
6872 double precision,
intent(in) :: qtc
6873 double precision,
intent(in) :: dtfactor
6876 end subroutine mhd_fld_implicit_update
6878 subroutine mhd_fld_evaluate_implicit(qtC,psa)
6882 double precision,
intent(in) :: qtc
6885 end subroutine mhd_fld_evaluate_implicit
6892 subroutine mhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6898 integer,
intent(in) :: ixi^
l, ixo^
l
6899 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6900 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6902 double precision :: adiabs(ixi^s), gammas(ixi^s)
6903 double precision :: tmp,tmp1,invr,cot
6905 integer :: mr_,mphi_
6906 integer :: br_,bphi_
6909 br_=mag(1); bphi_=mag(1)-1+
phi_
6926 {
do ix^db=ixomin^db,ixomax^db\}
6929 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6934 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6936 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6939 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
6940 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
6941 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6942 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6943 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
6945 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6946 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6947 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6950 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
6955 {
do ix^db=ixomin^db,ixomax^db\}
6957 if(local_timestep)
then
6958 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
6963 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6965 tmp1=adiabs(ix^d)*wprim(ix^d,
rho_)**gammas(ix^d)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6969 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
6972 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6973 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
6977 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
6983 cot=1.d0/tan(x(ix^d,2))
6987 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6988 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
6990 if(.not.stagger_grid)
then
6991 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6993 tmp=tmp+wprim(ix^d,
psi_)*cot
6995 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7000 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7001 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
7002 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
7004 if(.not.stagger_grid)
then
7005 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7007 tmp=tmp+wprim(ix^d,
psi_)*cot
7009 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7012 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
7013 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
7014 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7015 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
7016 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
7018 if(.not.stagger_grid)
then
7019 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
7020 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7021 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7022 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7023 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
7030 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
7033 end subroutine mhd_add_source_geom
7040 subroutine mhd_add_source_geom_semirelati(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
7046 integer,
intent(in) :: ixi^
l, ixo^
l
7047 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
7048 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
7050 double precision :: adiabs(ixi^s), gammas(ixi^s)
7051 double precision :: tmp,tmp1,tmp2,invr,cot,ef(ixo^s,1:
ndir)
7053 integer :: mr_,mphi_
7054 integer :: br_,bphi_
7057 br_=mag(1); bphi_=mag(1)-1+
phi_
7074 {
do ix^db=ixomin^db,ixomax^db\}
7077 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
7084 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)
7088 ef(ix^
d,1)=wprim(ix^
d,b2_)*wprim(ix^
d,m3_)-wprim(ix^
d,b3_)*wprim(ix^
d,m2_)
7089 ef(ix^
d,2)=wprim(ix^
d,b3_)*wprim(ix^
d,m1_)-wprim(ix^
d,b1_)*wprim(ix^
d,m3_)
7090 ef(ix^
d,3)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
7095 ef(ix^
d,2)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
7101 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+&
7102 half*((^
c&wprim(ix^
d,
b^
c_)**2+)+(^
c&ef(ix^
d,^
c)**2+)*inv_squared_c) -&
7103 wprim(ix^
d,bphi_)**2+wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)**2)
7104 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
7105 -wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)*wprim(ix^
d,mr_) &
7106 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_)+ef(ix^
d,
phi_)*ef(ix^
d,1)*inv_squared_c)
7108 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7109 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
7110 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
7113 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+half*((^
c&wprim(ix^
d,
b^
c_)**2+)+&
7114 (^
c&ef(ix^
d,^
c)**2+)*inv_squared_c))
7119 {
do ix^db=ixomin^db,ixomax^db\}
7121 if(local_timestep)
then
7122 invr=block%dt(ix^d)*dtfactor/x(ix^d,1)
7128 ef(ix^d,1)=wprim(ix^d,b2_)*wprim(ix^d,m3_)-wprim(ix^d,b3_)*wprim(ix^d,m2_)
7129 ef(ix^d,2)=wprim(ix^d,b3_)*wprim(ix^d,m1_)-wprim(ix^d,b1_)*wprim(ix^d,m3_)
7130 ef(ix^d,3)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
7134 ef(ix^d,1)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
7141 tmp1=wprim(ix^d,
p_)+half*((^
c&wprim(ix^d,
b^
c_)**2+)+(^
c&ef(ix^d,^
c)**2+)*inv_squared_c)
7143 tmp1=adiabs(ix^d)*wprim(ix^d,
rho_)**gammas(ix^d)+half*((^
c&wprim(ix^d,
b^
c_)**2+)+(^
c&ef(ix^d,^
c)**2+)*inv_squared_c)
7147 w(ix^d,m1_)=w(ix^d,m1_)+two*tmp1*invr
7150 w(ix^d,m1_)=w(ix^d,m1_)+invr*&
7151 (two*tmp1+(^ce&wprim(ix^d,
rho_)*wprim(ix^d,
m^ce_)**2-&
7152 wprim(ix^d,
b^ce_)**2-ef(ix^d,^ce)**2*inv_squared_c+))
7156 w(ix^d,b1_)=w(ix^d,b1_)+invr*2.0d0*wprim(ix^d,
psi_)
7162 cot=1.d0/tan(x(ix^d,2))
7166 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_)&
7167 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c)
7169 if(.not.stagger_grid)
then
7170 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7172 tmp=tmp+wprim(ix^d,
psi_)*cot
7174 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
7180 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_) &
7181 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c&
7182 +(wprim(ix^d,
rho_)*wprim(ix^d,m3_)**2&
7183 -wprim(ix^d,b3_)**2-ef(ix^d,3)**2*inv_squared_c)*cot)
7185 if(.not.stagger_grid)
then
7186 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7188 tmp=tmp+wprim(ix^d,
psi_)*cot
7190 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
7193 w(ix^d,m3_)=w(ix^d,m3_)+invr*&
7194 (-wprim(ix^d,m3_)*wprim(ix^d,m1_)*wprim(ix^d,
rho_) &
7195 +wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7196 +ef(ix^d,3)*ef(ix^d,1)*inv_squared_c&
7197 +(-wprim(ix^d,m2_)*wprim(ix^d,m3_)*wprim(ix^d,
rho_) &
7198 +wprim(ix^d,b2_)*wprim(ix^d,b3_)&
7199 +ef(ix^d,2)*ef(ix^d,3)*inv_squared_c)*cot)
7201 if(.not.stagger_grid)
then
7202 w(ix^d,b3_)=w(ix^d,b3_)+invr*&
7203 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7204 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7205 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7206 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
7213 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
7216 end subroutine mhd_add_source_geom_semirelati
7225 subroutine mhd_add_source_geom_split(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
7231 integer,
intent(in) :: ixi^
l, ixo^
l
7232 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
7233 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
7235 double precision :: tmp,tmp1,tmp2,invr,cot
7236 double precision :: adiabs(ixi^s), gammas(ixi^s)
7238 integer :: mr_,mphi_
7239 integer :: br_,bphi_
7255 br_=mag(1); bphi_=mag(1)-1+
phi_
7260 {
do ix^db=ixomin^db,ixomax^db\}
7263 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
7268 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
7270 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
7274 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
7275 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
7279 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
7280 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
7281 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
7283 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(
block%B0(ix^
d,
phi_,0)*wprim(ix^
d,br_)+wprim(ix^
d,bphi_)*
block%B0(ix^
d,
r_,0))
7286 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7287 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
7288 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
7290 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7296 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
7301 {
do ix^db=ixomin^db,ixomax^db\}
7303 if(local_timestep)
then
7304 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
7308 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
7309 if(b0field) tmp2=(^
c&block%B0(ix^d,^
c,0)*wprim(ix^d,
b^
c_)+)
7312 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
7313 if(b0field) w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp2*invr
7317 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
7318 (two*(tmp1+tmp2)+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+)- &
7319 (^ce&two*block%B0(ix^d,^ce,0)*wprim(ix^d,
b^ce_)+))
7321 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
7322 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
7327 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
7333 cot=1.d0/tan(x(ix^d,2))
7338 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7339 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
7340 +wprim(ix^d,b1_)*block%B0(ix^d,2,0))
7342 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7343 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
7346 if(.not.stagger_grid)
then
7348 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
7349 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
7351 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7354 tmp=tmp+wprim(ix^d,
psi_)*cot
7356 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7362 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7363 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
7364 +wprim(ix^d,b1_)*block%B0(ix^d,2,0)&
7365 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2-two*block%B0(ix^d,3,0)*wprim(ix^d,b3_))*cot)
7367 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7368 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
7369 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
7372 if(.not.stagger_grid)
then
7374 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
7375 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
7377 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7380 tmp=tmp+wprim(ix^d,
psi_)*cot
7382 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7386 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
7387 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
7388 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7389 +block%B0(ix^d,1,0)*wprim(ix^d,b3_) &
7390 +wprim(ix^d,b1_)*block%B0(ix^d,3,0) &
7391 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
7392 -wprim(ix^d,b2_)*wprim(ix^d,b3_) &
7393 +block%B0(ix^d,2,0)*wprim(ix^d,b3_) &
7394 +wprim(ix^d,b2_)*block%B0(ix^d,3,0))*cot)
7396 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
7397 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
7398 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7399 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
7400 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
7403 if(.not.stagger_grid)
then
7405 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
7406 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7407 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7408 +wprim(ix^d,m1_)*block%B0(ix^d,3,0) &
7409 -wprim(ix^d,m3_)*block%B0(ix^d,1,0) &
7410 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7411 -wprim(ix^d,m2_)*wprim(ix^d,b3_) &
7412 +wprim(ix^d,m3_)*block%B0(ix^d,2,0) &
7413 -wprim(ix^d,m2_)*block%B0(ix^d,3,0))*cot)
7415 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
7416 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7417 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7418 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7419 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
7427 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
7430 end subroutine mhd_add_source_geom_split
7435 integer,
intent(in) :: ixi^
l, ixo^
l
7436 double precision,
intent(in) :: w(ixi^s, nw)
7437 double precision :: mge(ixo^s)
7440 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
7442 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
7446 subroutine mhd_getv_hall(w,x,ixI^L,ixO^L,vHall,partial)
7450 integer,
intent(in) :: ixi^
l, ixo^
l
7451 double precision,
intent(in) :: w(ixi^s,nw)
7452 double precision,
intent(in) :: x(ixi^s,1:
ndim)
7453 double precision,
intent(inout) :: vhall(ixi^s,1:
ndir)
7454 logical,
intent(in),
optional :: partial
7456 double precision :: current(ixi^s,7-2*
ndir:3)
7457 double precision :: rho(ixi^s)
7458 integer :: idir, idirmin, ix^
d
7459 logical :: use_partial
7462 if(
present(partial)) use_partial=partial
7464 if(.not.use_partial)
then
7475 do idir = idirmin,
ndir
7476 {
do ix^db=ixomin^db,ixomax^db\}
7477 vhall(ix^
d,idir)=-
mhd_etah*current(ix^
d,idir)/rho(ix^
d)
7481 end subroutine mhd_getv_hall
7483 subroutine mhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
7486 integer,
intent(in) :: ixi^
l, ixo^
l, idir
7487 double precision,
intent(in) :: qt
7488 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
7489 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
7492 double precision :: db(ixo^s), dpsi(ixo^s)
7496 {
do ix^db=ixomin^db,ixomax^db\}
7497 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7498 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7499 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7500 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7509 {
do ix^db=ixomin^db,ixomax^db\}
7510 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
7511 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
7512 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
7513 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
7514 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7516 if(total_energy)
then
7517 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
7518 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
7520 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7522 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7525 if(total_energy)
then
7526 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
7527 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
7532 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
7534 end subroutine mhd_modify_wlr
7536 subroutine mhd_boundary_adjust(igrid,psb)
7538 integer,
intent(in) :: igrid
7541 integer :: ib, idims, iside, ixo^
l, i^
d
7550 i^
d=
kr(^
d,idims)*(2*iside-3);
7551 if (neighbor_type(i^
d,igrid)/=1) cycle
7552 ib=(idims-1)*2+iside
7570 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
7575 end subroutine mhd_boundary_adjust
7577 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
7580 integer,
intent(in) :: ixg^
l,ixo^
l,ib
7581 double precision,
intent(inout) :: w(ixg^s,1:nw)
7582 double precision,
intent(in) :: x(ixg^s,1:
ndim)
7584 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
7585 integer :: ix^
d,ixf^
l
7591 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7599 do ix1=ixfmax1,ixfmin1,-1
7600 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
7601 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7602 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7605 do ix1=ixfmax1,ixfmin1,-1
7606 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
7607 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
7608 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7609 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7610 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7611 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7612 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7626 do ix1=ixfmax1,ixfmin1,-1
7627 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7628 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7629 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7630 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7631 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7632 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7635 do ix1=ixfmax1,ixfmin1,-1
7636 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7637 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7638 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7639 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7640 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7641 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7642 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7643 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7644 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7645 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7646 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7647 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7648 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7649 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7650 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7651 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7652 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7653 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7658 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7661 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7669 do ix1=ixfmin1,ixfmax1
7670 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
7671 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7672 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7675 do ix1=ixfmin1,ixfmax1
7676 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
7677 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
7678 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7679 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7680 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7681 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7682 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7696 do ix1=ixfmin1,ixfmax1
7697 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7698 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7699 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7700 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7701 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7702 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7705 do ix1=ixfmin1,ixfmax1
7706 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7707 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7708 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7709 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7710 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7711 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7712 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7713 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7714 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7715 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7716 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7717 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7718 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7719 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7720 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7721 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7722 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7723 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7728 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7731 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7739 do ix2=ixfmax2,ixfmin2,-1
7740 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
7741 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7742 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7745 do ix2=ixfmax2,ixfmin2,-1
7746 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
7747 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
7748 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7749 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7750 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7751 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7752 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7766 do ix2=ixfmax2,ixfmin2,-1
7767 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7768 ix2+1,ixfmin3:ixfmax3,mag(2)) &
7769 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7770 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7771 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7772 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7775 do ix2=ixfmax2,ixfmin2,-1
7776 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
7777 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
7778 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7779 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
7780 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7781 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7782 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7783 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7784 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7785 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7786 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7787 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7788 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7789 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7790 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7791 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7792 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
7793 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7798 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7801 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7809 do ix2=ixfmin2,ixfmax2
7810 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
7811 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7812 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7815 do ix2=ixfmin2,ixfmax2
7816 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
7817 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
7818 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7819 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7820 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7821 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7822 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7836 do ix2=ixfmin2,ixfmax2
7837 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7838 ix2-1,ixfmin3:ixfmax3,mag(2)) &
7839 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7840 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7841 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7842 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7845 do ix2=ixfmin2,ixfmax2
7846 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
7847 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
7848 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7849 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
7850 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7851 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7852 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7853 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7854 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7855 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7856 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7857 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7858 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7859 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7860 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7861 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7862 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
7863 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7868 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7872 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7882 do ix3=ixfmax3,ixfmin3,-1
7883 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
7884 ixfmin2:ixfmax2,ix3+1,mag(3)) &
7885 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
7886 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
7887 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
7888 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
7891 do ix3=ixfmax3,ixfmin3,-1
7892 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
7893 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
7894 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
7895 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
7896 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
7897 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7898 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
7899 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
7900 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7901 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
7902 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
7903 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
7904 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
7905 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
7906 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
7907 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
7908 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
7909 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
7913 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7916 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7926 do ix3=ixfmin3,ixfmax3
7927 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
7928 ixfmin2:ixfmax2,ix3-1,mag(3)) &
7929 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
7930 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
7931 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
7932 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
7935 do ix3=ixfmin3,ixfmax3
7936 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
7937 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
7938 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
7939 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
7940 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
7941 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7942 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
7943 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
7944 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7945 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
7946 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
7947 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
7948 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
7949 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
7950 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
7951 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
7952 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
7953 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
7957 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7960 call mpistop(
"Special boundary is not defined for this region")
7963 end subroutine fixdivb_boundary
7972 double precision,
intent(in) :: qdt
7973 double precision,
intent(in) :: qt
7974 logical,
intent(inout) :: active
7977 integer,
parameter :: max_its = 50
7978 double precision :: residual_it(max_its), max_divb
7979 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
7980 double precision :: res
7981 double precision,
parameter :: max_residual = 1
d-3
7982 double precision,
parameter :: residual_reduction = 1
d-10
7983 integer :: iigrid, igrid
7984 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
7987 mg%operator_type = mg_laplacian
7995 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7996 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7999 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
8000 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8002 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8003 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8006 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8007 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8011 write(*,*)
"mhd_clean_divb_multigrid warning: unknown boundary type"
8012 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8013 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8021 do iigrid = 1, igridstail
8022 igrid = igrids(iigrid);
8025 lvl =
mg%boxes(id)%lvl
8026 nc =
mg%box_size_lvl(lvl)
8032 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
8034 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
8035 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
8040 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
8043 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
8044 if (
mype == 0) print *,
"iteration vs residual"
8047 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
8048 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
8049 if (residual_it(n) < residual_reduction * max_divb)
exit
8051 if (
mype == 0 .and. n > max_its)
then
8052 print *,
"divb_multigrid warning: not fully converged"
8053 print *,
"current amplitude of divb: ", residual_it(max_its)
8054 print *,
"multigrid smallest grid: ", &
8055 mg%domain_size_lvl(:,
mg%lowest_lvl)
8056 print *,
"note: smallest grid ideally has <= 8 cells"
8057 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
8058 print *,
"note: dx/dy/dz should be similar"
8062 call mg_fas_vcycle(
mg, max_res=res)
8063 if (res < max_residual)
exit
8065 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
8070 do iigrid = 1, igridstail
8071 igrid = igrids(iigrid);
8080 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
8084 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
8086 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
8088 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
8101 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
8102 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
8105 if(total_energy)
then
8107 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
8110 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
8120 subroutine mhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
8124 integer,
intent(in) :: ixi^
l, ixo^
l
8125 double precision,
intent(in) :: qt,qdt
8127 double precision,
intent(in) :: wp(ixi^s,1:nw)
8128 type(state) :: sct, s
8129 type(ct_velocity) :: vcts
8130 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
8131 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
8133 double precision :: circ(ixi^s,1:
ndim)
8135 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
8136 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
8137 integer :: idim1,idim2,idir,iwdim1,iwdim2
8139 associate(bfaces=>s%ws,x=>s%x)
8146 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8153 i1kr^
d=
kr(idim1,^
d);
8156 i2kr^
d=
kr(idim2,^
d);
8159 if (
lvc(idim1,idim2,idir)==1)
then
8161 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8163 {
do ix^db=ixcmin^db,ixcmax^db\}
8164 fe(ix^
d,idir)=quarter*&
8165 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
8166 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
8168 if(
mhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
8173 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
8181 if(
associated(usr_set_electric_field)) &
8182 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
8184 circ(ixi^s,1:ndim)=zero
8189 ixcmin^d=ixomin^d-kr(idim1,^d);
8191 ixa^l=ixc^l-kr(idim2,^d);
8194 if(lvc(idim1,idim2,idir)==1)
then
8196 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8199 else if(lvc(idim1,idim2,idir)==-1)
then
8201 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8207 {
do ix^db=ixcmin^db,ixcmax^db\}
8209 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
8211 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
8218 end subroutine mhd_update_faces_average
8221 subroutine mhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
8226 integer,
intent(in) :: ixi^
l, ixo^
l
8227 double precision,
intent(in) :: qt, qdt
8229 double precision,
intent(in) :: wp(ixi^s,1:nw)
8230 type(state) :: sct, s
8231 type(ct_velocity) :: vcts
8232 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
8233 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
8235 double precision :: circ(ixi^s,1:
ndim)
8237 double precision :: ecc(ixi^s,
sdim:3)
8238 double precision :: ein(ixi^s,
sdim:3)
8240 double precision :: el(ixi^s),er(ixi^s)
8242 double precision :: elc,erc
8244 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
8246 double precision :: jce(ixi^s,
sdim:3)
8248 double precision :: xs(ixgs^t,1:
ndim)
8249 double precision :: gradi(ixgs^t)
8250 integer :: ixc^
l,ixa^
l
8251 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
8253 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
8256 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8262 {
do ix^db=iximin^db,iximax^db\}
8265 ecc(ix^
d,1)=(wp(ix^
d,b2_)+
block%B0(ix^
d,2,0))*wp(ix^
d,m3_)-(wp(ix^
d,b3_)+
block%B0(ix^
d,3,0))*wp(ix^
d,m2_)
8266 ecc(ix^
d,2)=(wp(ix^
d,b3_)+
block%B0(ix^
d,3,0))*wp(ix^
d,m1_)-(wp(ix^
d,b1_)+
block%B0(ix^
d,1,0))*wp(ix^
d,m3_)
8267 ecc(ix^
d,3)=(wp(ix^
d,b1_)+
block%B0(ix^
d,1,0))*wp(ix^
d,m2_)-(wp(ix^
d,b2_)+
block%B0(ix^
d,2,0))*wp(ix^
d,m1_)
8270 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
8277 {
do ix^db=iximin^db,iximax^db\}
8280 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
8281 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
8282 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
8285 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
8299 i1kr^d=kr(idim1,^d);
8302 i2kr^d=kr(idim2,^d);
8305 if (lvc(idim1,idim2,idir)==1)
then
8307 ixcmin^d=ixomin^d+kr(idir,^d)-1;
8310 {
do ix^db=ixcmin^db,ixcmax^db\}
8311 fe(ix^d,idir)=quarter*&
8312 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
8313 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
8318 ixamax^d=ixcmax^d+i1kr^d;
8319 {
do ix^db=ixamin^db,ixamax^db\}
8320 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
8321 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
8324 do ix^db=ixcmin^db,ixcmax^db\}
8325 if(vnorm(ix^d,idim1)>0.d0)
then
8327 else if(vnorm(ix^d,idim1)<0.d0)
then
8328 elc=el({ix^d+i1kr^d})
8330 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
8332 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
8334 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
8335 erc=er({ix^d+i1kr^d})
8337 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
8339 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
8344 ixamax^d=ixcmax^d+i2kr^d;
8345 {
do ix^db=ixamin^db,ixamax^db\}
8346 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
8347 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
8350 do ix^db=ixcmin^db,ixcmax^db\}
8351 if(vnorm(ix^d,idim2)>0.d0)
then
8353 else if(vnorm(ix^d,idim2)<0.d0)
then
8354 elc=el({ix^d+i2kr^d})
8356 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
8358 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
8360 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
8361 erc=er({ix^d+i2kr^d})
8363 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
8365 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
8369 if(
mhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
8374 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
8388 if (lvc(idim1,idim2,idir)==0) cycle
8390 ixcmin^d=ixomin^d+kr(idir,^d)-1;
8391 ixamax^d=ixcmax^d-kr(idir,^d)+1;
8394 xs(ixa^s,:)=x(ixa^s,:)
8395 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
8396 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
8397 if (lvc(idim1,idim2,idir)==1)
then
8398 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
8400 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
8407 ixcmin^d=ixomin^d+kr(idir,^d)-1;
8409 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
8413 {
do ix^db=ixomin^db,ixomax^db\}
8414 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
8415 +ein(ix1,ix2-1,ix3-1,idir))
8416 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
8417 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
8419 else if(idir==2)
then
8420 {
do ix^db=ixomin^db,ixomax^db\}
8421 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
8422 +ein(ix1-1,ix2,ix3-1,idir))
8423 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
8424 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
8427 {
do ix^db=ixomin^db,ixomax^db\}
8428 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
8429 +ein(ix1-1,ix2-1,ix3,idir))
8430 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
8431 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
8437 {
do ix^db=ixomin^db,ixomax^db\}
8438 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
8439 +ein(ix1-1,ix2-1,idir))
8440 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
8441 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
8452 if(
associated(usr_set_electric_field)) &
8453 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
8455 circ(ixi^s,1:ndim)=zero
8460 ixcmin^d=ixomin^d-kr(idim1,^d);
8462 ixa^l=ixc^l-kr(idim2,^d);
8465 if(lvc(idim1,idim2,idir)==1)
then
8467 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8470 else if(lvc(idim1,idim2,idir)==-1)
then
8472 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8478 {
do ix^db=ixcmin^db,ixcmax^db\}
8480 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
8482 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
8489 end subroutine mhd_update_faces_contact
8492 subroutine mhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
8497 integer,
intent(in) :: ixi^
l, ixo^
l
8498 double precision,
intent(in) :: qt, qdt
8500 double precision,
intent(in) :: wp(ixi^s,1:nw)
8501 type(state) :: sct, s
8502 type(ct_velocity) :: vcts
8503 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
8504 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
8506 double precision :: vtill(ixi^s,2)
8507 double precision :: vtilr(ixi^s,2)
8508 double precision :: bfacetot(ixi^s,
ndim)
8509 double precision :: btill(ixi^s,
ndim)
8510 double precision :: btilr(ixi^s,
ndim)
8511 double precision :: cp(ixi^s,2)
8512 double precision :: cm(ixi^s,2)
8513 double precision :: circ(ixi^s,1:
ndim)
8515 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
8516 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
8517 integer :: idim1,idim2,idir,ix^
d
8519 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
8520 cbarmax=>vcts%cbarmax)
8533 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8549 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
8553 idim2=mod(idir+1,3)+1
8555 jxc^
l=ixc^
l+
kr(idim1,^
d);
8556 ixcp^
l=ixc^
l+
kr(idim2,^
d);
8560 vtill(ixi^s,2),vtilr(ixi^s,2))
8563 vtill(ixi^s,1),vtilr(ixi^s,1))
8569 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
8570 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
8572 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
8573 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
8576 btill(ixi^s,idim1),btilr(ixi^s,idim1))
8579 btill(ixi^s,idim2),btilr(ixi^s,idim2))
8583 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
8584 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
8586 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
8587 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
8591 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
8592 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
8593 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
8594 /(cp(ixc^s,1)+cm(ixc^s,1)) &
8595 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
8596 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
8597 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
8598 /(cp(ixc^s,2)+cm(ixc^s,2))
8601 if(
mhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
8605 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
8619 circ(ixi^s,1:
ndim)=zero
8624 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
8628 if(
lvc(idim1,idim2,idir)/=0)
then
8629 hxc^
l=ixc^
l-
kr(idim2,^
d);
8631 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8632 +
lvc(idim1,idim2,idir)&
8638 {
do ix^db=ixcmin^db,ixcmax^db\}
8640 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
8642 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
8648 end subroutine mhd_update_faces_hll
8651 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
8656 integer,
intent(in) :: ixi^
l, ixo^
l
8658 double precision,
intent(in) :: wp(ixi^s,1:nw)
8659 type(state),
intent(in) :: sct, s
8661 double precision :: jce(ixi^s,
sdim:3)
8664 double precision :: jcc(ixi^s,7-2*
ndir:3)
8666 double precision :: xs(ixgs^t,1:
ndim)
8668 double precision :: eta(ixi^s)
8669 double precision :: gradi(ixgs^t)
8670 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
8672 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
8678 if (
lvc(idim1,idim2,idir)==0) cycle
8680 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8681 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
8684 xs(ixb^s,:)=x(ixb^s,:)
8685 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
8686 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
8687 if (
lvc(idim1,idim2,idir)==1)
then
8688 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
8690 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
8697 jce(ixi^s,:)=jce(ixi^s,:)*
mhd_eta
8705 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8706 jcc(ixc^s,idir)=0.d0
8708 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8709 ixamin^
d=ixcmin^
d+ix^
d;
8710 ixamax^
d=ixcmax^
d+ix^
d;
8711 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
8713 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
8714 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
8719 end subroutine get_resistive_electric_field
8722 subroutine get_ambipolar_electric_field(ixI^L,ixO^L,w,x,fE)
8725 integer,
intent(in) :: ixi^
l, ixo^
l
8726 double precision,
intent(in) :: w(ixi^s,1:nw)
8727 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8728 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
8730 double precision :: jxbxb(ixi^s,1:3)
8731 integer :: idir,ixa^
l,ixc^
l,ix^
d
8734 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,jxbxb)
8741 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8744 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8745 ixamin^
d=ixcmin^
d+ix^
d;
8746 ixamax^
d=ixcmax^
d+ix^
d;
8747 fe(ixc^s,idir)=fe(ixc^s,idir)+jxbxb(ixa^s,idir)
8749 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0
8752 end subroutine get_ambipolar_electric_field
8758 integer,
intent(in) :: ixo^
l
8768 do ix^db=ixomin^db,ixomax^db\}
8770 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8771 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
8772 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8773 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
8774 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
8775 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
8778 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8779 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
8780 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8781 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
8824 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
8825 double precision,
intent(inout) :: ws(ixis^s,1:nws)
8826 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8828 double precision :: adummy(ixis^s,1:3)
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine cak_init(phys_gamma)
Initialize the module.
subroutine cak_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine cak_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter bigdouble
A very large real number.
double precision, parameter zero
some frequently used numbers
subroutine reconstruct(ixil, ixcl, idir, q, ql, qr)
Reconstruct scalar q within ixO^L to 1/2 dx in direction idir Return both left and right reconstructe...
subroutine b_from_vector_potentiala(ixisl, ixil, ixol, ws, x, a)
calculate magnetic field from vector potential A at cell edges
subroutine add_convert_method(phys_convert_vars, nwc, dataset_names, file_suffix)
PI (partial-ionisation) ionisation-degree backend for the eos% family.
Equation of state for AMRVAC, handled through a single eos_container object.
Module for flux conservation near refinement boundaries.
subroutine, public store_flux(igrid, fc, idimlim, nwfluxin)
subroutine, public store_edge(igrid, ixil, fe, idimlim)
Module for flux limited diffusion (FLD)-approximation in Radiation-(Magneto)hydrodynamics simulations...
double precision, public fld_bisect_tol
Tolerance for bisection method for Energy sourceterms This is a percentage of the minimum of gas- and...
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x, fl)
get dt limit for radiation force and FLD explicit source additions NOTE: w is primitive on entry
double precision, public fld_diff_tol
Tolerance for radiative Energy diffusion.
character(len=40) fld_fluxlimiter
flux limiter choice
character(len=40) fld_opal_table
double precision, public fld_cnorm
double precision, public fld_kappa0
Opacity value when using constant opacity.
subroutine, public add_fld_rad_force(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
character(len=40) fld_opacity_law
switches for opacity
character(len=40) fld_interaction_method
Which method to find the root for the energy interaction polynomial.
subroutine, public fld_get_radpress(w, x, ixil, ixol, rad_pressure, fl)
Returns Radiation Pressure as tensor NOTE: w is primitive on entry.
logical fld_radforce_split
source split for energy interact and radforce:
logical fld_bound_diff
switches for using changed cmax-cmin bounds
subroutine, public fld_implicit_update(dtfactor, qdt, qtc, psa, psb, fl)
Calling all subroutines to perform the multigrid method Communicates rad_e and diff_coeff to multigri...
subroutine, public fld_evaluate_implicit(qtc, psa, fl)
inplace update of psa==>F_im(psa)
subroutine, public fld_init()
Initialising FLD-module Read opacities Initialise Multigrid and adimensionalise kappa.
integer nth_for_diff_mg
diffusion coefficient stencil control
Module with basic grid data structures.
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
subroutine, public get_divb(w, ixil, ixol, divb, nth_in)
Calculate div B within ixO.
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
Module with geometry-related routines (e.g., divergence, curl)
subroutine divvector(qvec, ixil, ixol, divq, nth_in)
integer, parameter cartesian
subroutine laplacian_of_vector(qvec, ixil, ixol, lapl_qvec)
integer, parameter cylindrical
subroutine curlvector(qvec, ixil, ixol, curlvec, idirmin, idirmin0, ndir0, fourthorder)
Calculate curl of a vector qvec within ixL Options to employ standard second order CD evaluations use...
subroutine gradient(q, ixil, ixol, idir, gradq, nth_in)
subroutine gradientf(q, x, ixil, ixol, idir, gradq, nth_in, pm_in)
subroutine gradientl(q, ixil, ixol, idir, gradq)
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.
double precision const_kappae
double precision arad_norm
Normalised radiation constant.
double precision dtdiffpar
For resistive MHD, the time step is also limited by the diffusion time: .
character(len=std_len) typegrad
double precision unit_charge
Physical scaling factor for charge.
double precision small_pressure
integer ixghi
Upper index of grid block arrays.
pure subroutine cross_product(ixil, ixol, a, b, axb)
Cross product of two vectors.
integer, dimension(3, 3, 3) lvc
Levi-Civita tensor.
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
double precision unit_opacity
Physical scaling factor for Opacity.
integer, parameter unitpar
file handle for IO
integer, parameter bc_asymm
double precision unit_mass
Physical scaling factor for mass.
logical use_imex_scheme
whether IMEX in use or not
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision phys_trac_mask
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
double precision unit_numberdensity
Physical scaling factor for number density.
integer, parameter fs_hllcd
character(len=std_len) convert_type
Which format to use when converting.
double precision unit_pressure
Physical scaling factor for pressure.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision unit_length
Physical scaling factor for length.
logical stagger_grid
True for using stagger grid.
double precision const_rad_a
Physical factors useful for radiation fld.
double precision cmax_global
global fastest wave speed needed in fd scheme and glm method
logical use_particles
Use particles module or not.
integer, parameter fs_tvdmu
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer icomm
The MPI communicator.
double precision bdip
amplitude of background dipolar, quadrupolar, octupolar, user's field
integer b0i
background magnetic field location indicator
integer mype
The rank of the current MPI task.
logical local_timestep
each cell has its own timestep or not
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ixm
the mesh range of a physical block without ghost cells
integer ierrmpi
A global MPI error return code.
logical autoconvert
If true, already convert to output format during the run.
integer, dimension(:), allocatable flux_method
Which flux scheme of spatial discretization to use (per grid level)
double precision, dimension(:), allocatable, parameter d
logical slab
Cartesian geometry or not.
integer, parameter bc_periodic
integer, parameter bc_special
boundary condition types
double precision unit_magneticfield
Physical scaling factor for magnetic field.
double precision const_sigmasb
integer nwauxio
Number of auxiliary variables that are only included in output.
double precision unit_velocity
Physical scaling factor for velocity.
double precision small_r_e
double precision c_norm
Normalised speed of light.
logical b0field
split magnetic field as background B0 field
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision unit_temperature
Physical scaling factor for temperature.
double precision unit_radflux
Physical scaling factor for radiation flux.
integer, parameter bc_cont
logical si_unit
Use SI units (.true.) or use cgs units (.false.)
double precision, dimension(:,:), allocatable dx
spatial steps for all dimensions at all levels
integer nghostcells
Number of ghost cells surrounding a grid.
integer, parameter sdim
starting dimension for electric field
integer, parameter bc_symm
logical phys_trac
Use TRAC for MHD or 1D HD.
logical need_global_cmax
need global maximal wave speed
logical convert
If true and restart_from_file is given, convert snapshots to other file formats.
logical fix_small_values
fix small values with average or replace methods
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
logical use_multigrid
Use multigrid (only available in 2D and 3D)
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
double precision small_density
integer, parameter fs_hllc
integer max_blocks
The maximum number of grid blocks in a processor.
integer r_
Indices for cylindrical coordinates FOR TESTS, negative value when not used:
integer boundspeed
bound (left/min and right.max) speed of Riemann fan
integer phys_trac_finegrid
integer, parameter unitconvert
double precision unit_erad
Physical scaling factor for radiation energy density.
integer number_equi_vars
number of equilibrium set variables, besides the mag field
integer, parameter ixglo
Lower index of grid block arrays (always 1)
Module for including gravity in (magneto)hydrodynamics simulations.
subroutine gravity_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
subroutine gravity_init()
Initialize the module.
subroutine gravity_add_source(qdt, ixil, ixol, wct, wctprim, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
module mod_magnetofriction.t Purpose: use magnetofrictional method to relax 3D magnetic field to forc...
subroutine magnetofriction_init()
Initialize the module.
Magneto-hydrodynamics module.
subroutine, public mhd_get_trad(w, x, ixil, ixol, trad)
Calculates radiation temperature.
integer, public, protected c_
logical, public, protected mhd_gravity
Whether gravity is added.
integer, public, protected fip_
Index of the FIP passive scalar rho*fip in conserved form, fip in primitive form.
logical, public, protected mhd_internal_e
Whether internal energy is solved instead of total energy.
double precision, public, protected mhd_trac_delta
TRAC-7 (Johnston 2021, A&A 654 A2): target number of cells resolving the TR.
logical, public, protected mhd_glm_extended
Whether extended GLM-MHD is used with additional sources.
logical, public mhd_hyperbolic_tc_constant
character(len=std_len), public, protected type_ct
Method type of constrained transport.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
subroutine, public mhd_clean_divb_multigrid(qdt, qt, active)
integer, public, protected qpar_
Index of the field-aligned heat flux q_parallel.
logical, public, protected mhd_radiative_cooling
Whether radiative cooling is added.
subroutine, public mhd_e_to_ei(ixil, ixol, w, x)
Transform total energy to internal energy.
double precision, public mhd_adiab
The adiabatic constant.
double precision, public divbdiff
Coefficient of diffusive divB cleaning.
double precision, public mhd_eta_hyper
The MHD hyper-resistivity.
character(len=std_len), public, protected mhd_uawsom_reflection_mode
Algebra used by the Alfven-wave reflection source. one_dimensional_gradient retains the original one-...
double precision, public, protected mhd_hyperbolic_tc_bmin
Field-strength transition scale for perpendicular closure.
double precision, public, protected rr
double precision, public, protected h_ion_fr
Ionization fraction of H H_ion_fr = H+/(H+ + H)
double precision, public, protected mhd_uawsom_sigma
Dimensionless multiplier in the one_dimensional_gradient source only.
integer, public, protected mhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
integer, public, protected wkminus_
double precision, public, protected mhd_uawsom_thread_radius0
subroutine, public get_normalized_divb(w, ixil, ixol, divb)
get dimensionless div B = |divB| * volume / area / |B|
integer, public, protected mhd_uawsom_height_dim
Cartesian direction used for the prescribed density contrast and reflection gradient.
logical, public numerical_resistive_heating
Whether numerical resistive heating is included when solving partial energy equation.
type(tc_fluid), allocatable, public tc_fl
type of fluid for thermal conduction
logical, public, protected mhd_rotating_frame
Whether rotating frame is activated.
logical, public, protected mhd_semirelativistic
Whether semirelativistic MHD equations (Gombosi 2002 JCP) are solved.
integer, public, protected mhd_divb_nth
Whether divB is computed with a fourth order approximation.
integer, public, protected mhd_n_tracer
Number of tracer species.
integer, public, protected te_
Indices of temperature.
integer, public, protected m
integer, public equi_rho0_
equi vars indices in the stateequi_vars array
integer, public, protected mhd_trac_type
Which TRAC method is used.
logical, public, protected mhd_cak_force
Whether plasma is partially ionized Whether CAK radiation line force is activated.
logical, public, protected source_split_divb
Whether divB cleaning sources are added splitting from fluid solver.
double precision, public, protected mhd_uawsom_zeta0
Base transverse density contrast and filling factor.
integer, public, protected ne_
Index of the electron number density for LTE module.
logical, public, protected mhd_hall
Whether Hall-MHD is used.
type(te_fluid), allocatable, public te_fl_mhd
type of fluid for thermal emission synthesis
logical, public, protected mhd_ambipolar
Whether Ambipolar term is used.
logical, public, protected mhd_hyperbolic_tc
Whether thermal conduction is used.
logical, public, protected mhd_hyperbolic_tc_sat
Whether saturation is considered for hyperbolic TC. When the perpendicular channel is active,...
double precision, public, protected mhd_hyperbolic_tc_kappa_perp_factor
Relative perpendicular hyperbolic-TC coefficient in fixed/strong-field limit: kappa_perp0 = mhd_hyper...
logical, public has_equi_rho_and_p
whether split off equilibrium density and pressure
double precision, public mhd_glm_alpha
GLM-MHD parameter: ratio of the diffusive and advective time scales for div b taking values within [0...
double precision function, dimension(ixo^s), public mhd_mag_en_all(w, ixil, ixol)
Compute 2 times total magnetic energy.
pure double precision function, public mhd_uawsom_wave_energy_cell(wcell)
logical, public, protected mhd_radiation_fld
Whether radiation-gas interaction is handled using flux limited diffusion.
subroutine, public multiplyambicoef(ixil, ixol, res, w, x)
multiply res by the ambipolar coefficient The ambipolar coefficient is calculated as -mhd_eta_ambi/rh...
subroutine, public b_from_vector_potential(ixisl, ixil, ixol, ws, x)
calculate magnetic field from vector potential
double precision, public, protected he_ion_fr
Ionization fraction of He He_ion_fr = (He2+ + He+)/(He2+ + He+ + He)
integer, public, protected waminus_
logical, public, protected mhd_viscosity
Whether viscosity is added.
subroutine, public mhd_get_pradiation_from_prim(w, x, ixil, ixol, prad)
Calculate radiation pressure within ixO^L.
double precision, public, protected mhd_reduced_c
Reduced speed of light for semirelativistic MHD: 2% of light speed.
logical, public, protected mhd_energy
Whether an energy equation is used.
logical, public, protected mhd_ambipolar_exp
Whether Ambipolar term is implemented explicitly.
double precision, public mhd_hyperbolic_tc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
logical, public, protected mhd_glm
Whether GLM-MHD is used to control div B.
double precision, public, protected mhd_uawsom_zeta_scale
Physical input scales (lengths and magnetic field); converted to code units at init.
type(fld_fluid), allocatable, public fld_fl
Radiation fluid object (gas-EoS callbacks for FLD), wired in mhd_link_eos.
logical, public clean_initial_divb
clean initial divB
double precision, public mhd_eta
The MHD resistivity.
logical, public divbwave
Add divB wave in Roe solver.
logical, public, protected mhd_uawsom_reflection
Enable conservative Alfvén reflection (one-dimensional or Cartesian gradient-vorticity)
logical, public, protected mhd_magnetofriction
Whether magnetofriction is added.
double precision, public, protected mhd_trac_mask
Height of the mask used in the TRAC method.
procedure(mask_subroutine), pointer, public usr_mask_ambipolar
elemental pure double precision function, public mhd_uawsom_rho2_factor_cell(zeta)
character(len=std_len), public, protected typedivbfix
Method type to clean divergence of B.
logical, public, protected mhd_uawsom_kink_reflection
Enable conservative kink-wave reflection from the kink-speed gradient.
double precision, public, protected mhd_uawsom_filling_factor
integer, public, protected waplus_
Conserved wave-energy indices. The plus variables propagate against B.
subroutine, public mhd_uawsom_rho2_factor(ixil, ixol, w, x, factor)
double precision, public, protected mhd_uawsom_alfven_corr_length0
logical, public, protected mhd_thermal_conduction
Whether thermal conduction is used.
integer, public equi_pe0_
subroutine, public mhd_get_csrad2_prim(w, x, ixil, ixol, csound)
Calculate modified squared fast wave speed for FLD NOTE: w is primitive on entry here!...
integer, public, protected qperp_
Index of the perpendicular heat flux q_perp.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
character(len=std_len), public, protected mhd_hyperbolic_tc_perp_mode
Perpendicular hyperbolic-TC closure mode: 'off' = disabled 'fixed_reference' = fixed classical ratio ...
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
pure double precision function, public mhd_uawsom_wave_pressure_cell(wcell, zeta)
logical, public, protected mhd_dump_full_vars
whether dump full variables (when splitting is used) in a separate dat file
logical, public, protected mhd_particles
Whether particles module is added.
integer, public, protected b
subroutine, public mhd_face_to_center(ixol, s)
calculate cell-center values from face-center values
logical, dimension(2 *^nd), public, protected boundary_divbfix
To control divB=0 fix for boundary.
subroutine, public get_current(w, ixil, ixol, idirmin, current)
Calculate idirmin and the idirmin:3 components of the common current array make sure that dxlevel(^D)...
double precision, public mhd_etah
Hall resistivity.
subroutine, public mhd_get_v(w, x, ixil, ixol, v)
Calculate v vector.
double precision, public mhd_eta_ambi
The MHD ambipolar coefficient.
logical, public, protected mhd_fip
Whether FIP passive scalar is enabled.
logical, public, protected mhd_hydrodynamic_e
Whether hydrodynamic energy is solved instead of total energy.
integer, public, protected r_e
Index of the radiation energy.
subroutine, public mhd_phys_init()
logical, public, protected mhd_trac
Whether TRAC method is used.
subroutine, public mhd_get_csrad2(w, x, ixil, ixol, csound)
Calculate modified squared sound speed for FLD NOTE: only for diagnostic purposes,...
subroutine, public mhd_get_pthermal_plus_pradiation(w, x, ixil, ixol, pth_plus_prad)
Calculates the sum of the gas pressure and the max Prad tensor element.
type(rc_fluid), allocatable, public rc_fl
type of fluid for radiative cooling
integer, public, protected wkplus_
integer, dimension(:), allocatable, public, protected tracer
Indices of the tracers.
double precision, public, protected mhd_hyperbolic_tc_coulomb_log
Constant Coulomb logarithm used by the simplified electron-magnetization closure. It is a namelist pa...
integer, public, protected rho_
Index of the density (in the w array)
double precision, public, protected mhd_uawsom_bref
logical, public, protected b0field_forcefree
B0 field is force-free.
integer, dimension(2 *^nd), public, protected boundary_divbfix_skip
To skip * layer of ghost cells during divB=0 fix for boundary.
integer, public, protected tweight_
logical, public, protected mhd_ambipolar_sts
Whether Ambipolar term is implemented using supertimestepping.
logical, public, protected mhd_hyperbolic_tc_use_perp
Whether the perpendicular hyperbolic-TC channel is enabled.
subroutine, public mhd_ei_to_e(ixil, ixol, w, x)
Transform internal energy to total energy.
integer, public, protected e_
Index of the energy density (-1 if not present)
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
subroutine, public mhd_get_rho(w, x, ixil, ixol, rho)
logical, public, protected mhd_uawsom
Enable the Uniturbulence and Alfven Wave Solar Model extension.
logical, public, protected mhd_fld_pradtensor
integer, public, protected psi_
Indices of the GLM psi.
logical, public mhd_equi_thermal
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
type(mg_t) mg
Data structure containing the multigrid tree.
Module containing all the particle routines.
subroutine particles_init()
Initialize particle data and parameters.
This module defines the procedures of a physics module. It contains function pointers for the various...
module radiative cooling – add optically thin radiative cooling
subroutine radiative_cooling_init_params(phys_gamma, he_abund)
Radiative cooling initialization.
subroutine findl(tpoint, lpoint, fl)
subroutine radiative_cooling_init(fl, read_params)
subroutine radiative_cooling_add_source(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
subroutine calc_l_extended(tpoint, lpoint, fl)
Module for including rotating frame in (magneto)hydrodynamics simulations The rotation vector is assu...
subroutine rotating_frame_add_source(qdt, dtfactor, ixil, ixol, wct, w, x)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine rotating_frame_init()
Initialize the module.
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method which can be used for multiple source terms in the governing equatio...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
double precision function, public get_tc_dt_mhd(w, ixil, ixol, dxd, x, fl)
Get the explicit timestep for the TC (mhd implementation) Note: for multi-D MHD (1D MHD will use HD f...
double precision function, public get_tc_dt_hd(w, ixil, ixol, dxd, x, fl)
Get the explicit timestep for the TC (hd implementation) Note: also used in 1D MHD (or for neutrals i...
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_hd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine, public tc_get_mhd_params(fl, read_mhd_params)
Init TC coefficients: MHD case.
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
double precision time_htc_total
double precision time_htc0
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_adiab), pointer usr_set_adiab
procedure(set_adiab), pointer usr_set_gamma
procedure(sub_get_heating), pointer usr_get_heating
procedure(phys_gravity), pointer usr_gravity
procedure(uawsom_coefficients), pointer usr_uawsom_coefficients
Optionally provide local UAWSoM closure coefficients. The returned thread radius and Alfven correlati...
procedure(set_equi_vars), pointer usr_set_equi_vars
procedure(set_electric_field), pointer usr_set_electric_field
The module add viscous source terms and check time step.
subroutine, public viscosity_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
procedure(sub_add_source), pointer, public viscosity_add_source
subroutine, public viscosity_init(phys_wider_stencil)
Initialize the module.
Radiation fluid object: gas-EoS callbacks the FLD module needs, wired by the physics module at link t...
The data structure that contains information about a tree node/grid block.