23 double precision,
public ::
mhd_eta = 0.0d0
51 double precision,
public,
protected ::
h_ion_fr=1d0
54 double precision,
public,
protected ::
he_ion_fr=1d0
61 double precision,
public,
protected ::
rr=1d0
63 double precision :: inv_squared_c0=0.d0, inv_squared_c=0.d0
82 integer,
public,
protected ::
rho_
84 integer,
allocatable,
public,
protected ::
mom(:)
86 integer,
public,
protected :: ^
c&m^C_
88 integer,
public,
protected ::
e_
90 integer,
public,
protected :: ^
c&b^C_
92 integer,
public,
protected ::
p_
94 integer,
public,
protected ::
ne_
96 integer,
public,
protected ::
qpar_
100 integer,
public,
protected ::
psi_
102 integer,
public,
protected ::
r_e
104 integer,
public,
protected ::
te_
106 integer,
public,
protected ::
fip_ = -1
108 integer,
parameter :: uawsom_reflection_1d=1, uawsom_reflection_cartesian=2
109 integer :: uawsom_reflection_id=uawsom_reflection_1d
119 integer,
allocatable,
public,
protected ::
tracer(:)
127 integer,
parameter :: divb_none = 0
128 integer,
parameter :: divb_multigrid = -1
129 integer,
parameter :: divb_glm = 1
130 integer,
parameter :: divb_powel = 2
131 integer,
parameter :: divb_janhunen = 3
132 integer,
parameter :: divb_linde = 4
133 integer,
parameter :: divb_lindejanhunen = 5
134 integer,
parameter :: divb_lindepowel = 6
135 integer,
parameter :: divb_lindeglm = 7
136 integer,
parameter :: divb_ct = 8
140 integer,
parameter :: htc_perp_disabled=0, htc_perp_fixed=1, &
141 htc_perp_weak_field=2, htc_perp_electron=3
142 integer :: htc_perp_mode_id=htc_perp_disabled
178 logical,
public,
protected ::
mhd_glm = .false.
211 logical,
public,
protected ::
mhd_fip = .false.
226 logical :: total_energy = .true.
230 logical :: gravity_energy
245 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
247 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
249 character(len=std_len) :: typedivbdiff =
'all'
260 subroutine mask_subroutine(ixI^L,ixO^L,w,x,res)
262 integer,
intent(in) :: ixi^
l, ixo^
l
263 double precision,
intent(in) :: x(ixi^s,1:
ndim)
264 double precision,
intent(in) :: w(ixi^s,1:nw)
265 double precision,
intent(inout) :: res(ixi^s)
266 end subroutine mask_subroutine
273 procedure(
sub_e_to_ei),
pointer :: mhd_e_to_ei_base => null()
316 subroutine mhd_read_params(files)
319 character(len=*),
intent(in) :: files(:)
345 do n = 1,
size(files)
346 open(
unitpar, file=trim(files(n)), status=
"old")
347 read(
unitpar, mhd_list,
end=111)
353 end subroutine mhd_read_params
356 subroutine mhd_write_info(fh)
358 integer,
intent(in) :: fh
361 integer,
parameter :: n_par = 1
362 double precision :: values(n_par)
363 integer,
dimension(MPI_STATUS_SIZE) :: st
364 character(len=name_len) :: names(n_par)
366 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
369 values(1) = eos%gamma
370 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
371 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
372 end subroutine mhd_write_info
401 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_internal_e=T'
405 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_internal_e=T'
412 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_hydrodynamic_e=T'
416 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_hydrodynamic_e=T'
420 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_hydrodynamic_e=T'
428 call mpistop(
'B0 splitting needs mhd_energy=T when mhd_semirelativistic=T')
431 call mpistop(
'B0 splitting with mhd_semirelativistic=T needs Cartesian geometry')
436 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_semirelativistic=T'
440 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_semirelativistic=T'
447 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_energy=F'
451 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_energy=F'
455 if(
mype==0)
write(*,*)
'WARNING: set mhd_thermal_conduction=F when mhd_energy=F'
459 if(
mype==0)
write(*,*)
'WARNING: set mhd_hyperbolic_tc=F when mhd_energy=F'
463 if(
mype==0)
write(*,*)
'WARNING: set mhd_radiative_cooling=F when mhd_energy=F'
467 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac=F when mhd_energy=F'
471 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_energy=F'
475 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_energy=F'
481 if(
mype==0)
write(*,*)
'WARNING: set either parabolic TC or hyperbolic TC to F'
482 if(
mype==0)
write(*,*)
'WARNING: defaulting to only mhd_hyperbolic_tc=T'
486 call mpistop(
"mhd_hyperbolic_tc_use_perp is not supported in 1D")
496 phys_gamma = eos%gamma
509 phys_total_energy=total_energy
512 gravity_energy=.false.
514 gravity_energy=.true.
517 gravity_energy=.false.
523 if(
mype==0)
write(*,*)
'WARNING: reset mhd_trac_type=1 for 1D simulation'
528 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac_mask==bigdouble for global TRAC method'
534 call mpistop(
"mhd_trac_type=7 requires usr_get_heating to be set in mod_usr.t")
542 type_divb = divb_none
545 if(
mhd_radiation_fld)
call mpistop(
'To verify whether mg usage for FLD versus divB can be combined')
546 type_divb = divb_multigrid
548 mg%operator_type = mg_laplacian
555 case (
'powel',
'powell')
556 type_divb = divb_powel
558 type_divb = divb_janhunen
560 type_divb = divb_linde
561 case (
'lindejanhunen')
562 type_divb = divb_lindejanhunen
564 type_divb = divb_lindepowel
568 type_divb = divb_lindeglm
573 call mpistop(
'Unknown divB fix')
576 allocate(start_indices(number_species),stop_indices(number_species))
583 mom(:) = var_set_momentum(
ndir)
589 e_ = var_set_energy()
598 mag(:) = var_set_bfield(
ndir)
602 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
608 qpar_ = var_set_fluxvar(
'q',
'q', need_bc=.false.)
610 qperp_ = var_set_fluxvar(
'qperp',
'qperp', need_bc=.false.)
621 fip_ = var_set_fluxvar(
'rho_fip',
'fip', need_bc=.false.)
627 waplus_ = var_set_fluxvar(
'wAplus',
'wAplus')
628 waminus_ = var_set_fluxvar(
'wAminus',
'wAminus')
629 wkplus_ = var_set_fluxvar(
'wkplus',
'wkplus')
630 wkminus_ = var_set_fluxvar(
'wkminus',
'wkminus')
638 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
644 write(*,*)
'Warning: CAK force addition together with FLD radiation'
649 write(*,*)
'Warning: Optically thin cooling together with FLD radiation'
653 call mpistop(
'using FLD implies the use of an energy equation, set mhd_energy=T')
656 call mpistop(
'using FLD not yet with semirelativistic energy formalism')
659 call mpistop(
'using FLD not yet with hydrodynamic or internal energy formalism')
662 call mpistop(
'using FLD not yet with split off rho and p')
666 r_e = var_set_radiation_energy()
671 call fld_init(eos%eos_type, eos%ionE, eos%pi_table)
675 phys_implicit_update => mhd_fld_implicit_update
676 phys_evaluate_implicit => mhd_fld_evaluate_implicit
688 if (eos%eos_type ==
'LTE')
then
691 else if (eos%eos_type ==
'PI')
then
702 if(.not.
mhd_energy)
call mpistop(
"radiative transfer needs mhd_energy=T")
703 call rt_sc_activate()
716 if (iw_ne > 0) nwgc = max(nwgc, iw_ne)
717 if (iw_te > 0) nwgc = max(nwgc, iw_te)
720 stop_indices(1)=nwflux
748 allocate(iw_vector(nvector))
749 iw_vector(1) =
mom(1) - 1
750 iw_vector(2) = mag(1) - 1
753 if (.not.
allocated(flux_type))
then
754 allocate(flux_type(
ndir, nwflux))
755 flux_type = flux_default
756 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
757 call mpistop(
"phys_check error: flux_type has wrong shape")
760 if(nwflux>mag(
ndir))
then
762 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
767 flux_type(:,
psi_)=flux_special
769 flux_type(idir,mag(idir))=flux_special
773 flux_type(idir,mag(idir))=flux_tvdlf
779 phys_get_dt => mhd_get_dt
782 phys_get_cmax => mhd_get_cmax_semirelati
784 phys_get_cmax => mhd_get_cmax_semirelati_noe
788 phys_get_cmax => mhd_get_cmax_origin
790 phys_get_cmax => mhd_get_cmax_origin_noe
793 phys_get_tcutoff => mhd_get_tcutoff
794 phys_get_h_speed => mhd_get_h_speed
796 phys_get_cbounds => mhd_get_cbounds_split_rho
798 phys_get_cbounds => mhd_get_cbounds_semirelati
800 phys_get_cbounds => mhd_get_cbounds
810 phys_get_flux => mhd_get_flux_hde
813 phys_get_flux => mhd_get_flux_semirelati
815 phys_get_flux => mhd_get_flux_semirelati_noe
819 phys_get_flux => mhd_get_flux_split
821 phys_get_flux => mhd_get_flux
823 phys_get_flux => mhd_get_flux_noe
828 phys_add_source_geom => mhd_add_source_geom_semirelati
830 phys_add_source_geom => mhd_add_source_geom_split
832 phys_add_source_geom => mhd_add_source_geom
834 phys_add_source => mhd_add_source
835 phys_check_params => mhd_check_params
836 phys_write_info => mhd_write_info
839 phys_handle_small_values => mhd_handle_small_values_inte
840 mhd_handle_small_values => mhd_handle_small_values_inte
841 phys_check_w => mhd_check_w_inte
843 phys_handle_small_values => mhd_handle_small_values_hde
844 mhd_handle_small_values => mhd_handle_small_values_hde
845 phys_check_w => mhd_check_w_hde
847 phys_handle_small_values => mhd_handle_small_values_semirelati
848 mhd_handle_small_values => mhd_handle_small_values_semirelati
849 phys_check_w => mhd_check_w_semirelati
851 phys_handle_small_values => mhd_handle_small_values_split
852 mhd_handle_small_values => mhd_handle_small_values_split
853 phys_check_w => mhd_check_w_split
855 phys_handle_small_values => mhd_handle_small_values_origin
856 mhd_handle_small_values => mhd_handle_small_values_origin
857 phys_check_w => mhd_check_w_origin
859 phys_handle_small_values => mhd_handle_small_values_noe
860 mhd_handle_small_values => mhd_handle_small_values_noe
861 phys_check_w => mhd_check_w_noe
867 phys_set_equi_vars => set_equi_vars_grid
870 if(type_divb==divb_glm)
then
871 phys_modify_wlr => mhd_modify_wlr
882 transverse_ghost_cells = 1
883 phys_get_ct_velocity => mhd_get_ct_velocity_average
884 phys_update_faces => mhd_update_faces_average
886 transverse_ghost_cells = 1
887 phys_get_ct_velocity => mhd_get_ct_velocity_contact
888 phys_update_faces => mhd_update_faces_contact
890 transverse_ghost_cells = 2
891 phys_get_ct_velocity => mhd_get_ct_velocity_hll
892 phys_update_faces => mhd_update_faces_hll
894 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
897 phys_modify_wlr => mhd_modify_wlr
899 phys_boundary_adjust => mhd_boundary_adjust
905 call mpistop(
'To verify whether mg usage for FLD versus divB can be combined')
910 call mhd_physical_units()
930 htc_perp_mode_id=htc_perp_disabled
944 case(
'fixed_reference')
945 htc_perp_mode_id=htc_perp_fixed
955 case(
'weak_field_isotropization')
956 htc_perp_mode_id=htc_perp_weak_field
960 case(
'electron_magnetization')
961 htc_perp_mode_id=htc_perp_electron
963 call mpistop(
"mhd_hyperbolic_tc_coulomb_log must be positive")
966 call mpistop(
"invalid mhd_hyperbolic_tc_perp_mode: "// &
972 call mpistop(
"thermal conduction needs mhd_energy=T")
975 call mpistop(
"hyperbolic thermal conduction needs mhd_energy=T")
978 call mpistop(
"radiative cooling needs mhd_energy=T")
983 iw_log_nh = var_set_wextra()
989 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no splitting or total e in use'
992 if(
mype==0)
write(*,*)
'Will subtract thermal balance in TC or RC with mhd_equi_thermal=T'
995 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no TC or RC in use'
1002 phys_e_to_ei => mhd_ei_unchanged
1003 phys_ei_to_e => mhd_ei_unchanged
1005 phys_e_to_ei => mhd_e_to_ei_hde
1006 phys_ei_to_e => mhd_ei_to_e_hde
1008 phys_e_to_ei => mhd_e_to_ei_semirelati
1009 phys_ei_to_e => mhd_ei_to_e_semirelati
1016 mhd_e_to_ei_base => phys_e_to_ei
1017 phys_e_to_ei => mhd_e_to_ei_cache_log_nh
1055 phys_te_images => mhd_te_images
1061 write(*,*)
'*****Using hyperresistivity: with mhd_eta_hyper :',
mhd_eta_hyper
1065 call mpistop(
"Must have B0field=F when using hyperresistivity")
1069 call mpistop(
"Must have mhd_eta_hyper positive when using hyperresistivity")
1086 call mpistop(
"Must have has_equi_rho_and_p=F when mhd_rotating_frame=T")
1100 call mpistop(
"Must have mhd_hall=F when mhd_semirelativistic=T")
1104 call mpistop(
"Must have Cartesian coordinates for Hall")
1108 phys_wider_stencil = 1
1115 phys_wider_stencil=max(phys_wider_stencil,1)
1122 call add_sts_method(get_ambipolar_dt,sts_set_source_ambipolar,mag(1),&
1133 phys_wider_stencil = 1
1143 call mpistop(
"CAK implementation not available in internal or semirelativistic variants")
1146 call mpistop(
"CAK force implementation not available for split off pressure and density")
1154 subroutine mhd_te_images
1159 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
1161 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
1163 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
1165 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
1168 call mpistop(
"Error in synthesize emission: Unknown convert_type")
1170 end subroutine mhd_te_images
1176 subroutine mhd_sts_set_source_tc_mhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1180 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1181 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1182 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1183 double precision,
intent(in) :: my_dt
1184 logical,
intent(in) :: fix_conserve_at_step
1186 end subroutine mhd_sts_set_source_tc_mhd
1188 subroutine mhd_sts_set_source_tc_hd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1192 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1193 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1194 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1195 double precision,
intent(in) :: my_dt
1196 logical,
intent(in) :: fix_conserve_at_step
1198 end subroutine mhd_sts_set_source_tc_hd
1200 function mhd_get_tc_dt_mhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1207 integer,
intent(in) :: ixi^
l, ixo^
l
1208 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1209 double precision,
intent(in) :: w(ixi^s,1:nw)
1210 double precision :: dtnew
1213 end function mhd_get_tc_dt_mhd
1215 function mhd_get_tc_dt_hd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1222 integer,
intent(in) :: ixi^
l, ixo^
l
1223 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1224 double precision,
intent(in) :: w(ixi^s,1:nw)
1225 double precision :: dtnew
1228 end function mhd_get_tc_dt_hd
1230 subroutine mhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
1233 integer,
intent(in) :: ixi^
l,ixo^
l
1234 double precision,
intent(inout) :: w(ixi^s,1:nw)
1235 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1236 integer,
intent(in) :: step
1237 character(len=140) :: error_msg
1243 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
1244 call mhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
1245 end subroutine mhd_tc_handle_small_e
1248 subroutine tc_params_read_mhd(fl)
1250 type(tc_fluid),
intent(inout) :: fl
1252 double precision :: tc_k_para=0d0
1253 double precision :: tc_k_perp=0d0
1256 logical :: tc_perpendicular=.false.
1257 logical :: tc_saturate=.false.
1258 logical :: tc_patch_eint=.false.
1259 logical :: tc_frozen_ion=.true.
1260 double precision :: trac_t_floor=0.d0
1261 character(len=std_len) :: tc_slope_limiter=
"MC"
1263 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp, &
1264 tc_patch_eint, trac_t_floor, tc_frozen_ion
1268 read(
unitpar, tc_list,
end=111)
1272 fl%tc_perpendicular = tc_perpendicular
1273 fl%tc_saturate = tc_saturate
1274 fl%tc_patch_eint = tc_patch_eint
1275 fl%frozen_ion = tc_frozen_ion .and. .not. tc_patch_eint
1276 fl%tc_k_para = tc_k_para
1277 fl%tc_k_perp = tc_k_perp
1278 fl%trac_T_floor = trac_t_floor / unit_temperature
1279 select case(tc_slope_limiter)
1281 fl%tc_slope_limiter = 0
1284 fl%tc_slope_limiter = 1
1287 fl%tc_slope_limiter = 2
1290 fl%tc_slope_limiter = 3
1293 fl%tc_slope_limiter = 4
1296 fl%tc_slope_limiter = 5
1298 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod, superbee, koren, vanleer")
1300 end subroutine tc_params_read_mhd
1304 subroutine rc_params_read(fl)
1307 type(rc_fluid),
intent(inout) :: fl
1311 double precision :: rad_damp_height=0.5d0
1312 double precision :: rad_damp_scale=0.15d0
1315 integer :: ncool = 4000
1317 logical :: tfix=.false.
1319 logical :: rc_split=.false.
1320 logical :: rad_damp=.false.
1322 character(len=std_len) :: coolcurve=
'JCcorona'
1323 logical :: rad_newton = .false.
1324 double precision :: rad_newton_trad = 0.006d0
1325 double precision :: rad_newton_rhosurf = 1.d4
1326 double precision :: rad_newton_pthick = 25.d0
1328 double precision :: cfrac=0.1d0
1329 double precision :: rad_cut_hgt=0.5d0
1330 double precision :: rad_cut_dey=0.15d0
1332 character(len=8) :: rc_y_mod_quadrature=
'boole'
1333 integer :: rc_y_mod_n_sub=16
1336 namelist /rc_list/ coolcurve, ncool, cfrac, tlow, tfix, rc_split, &
1337 rad_cut_hgt, rad_cut_dey, &
1338 rc_y_mod_quadrature, rc_y_mod_n_sub, &
1339 rad_newton, rad_newton_trad, rad_newton_rhosurf, &
1340 rad_newton_pthick, rad_damp, rad_damp_height, rad_damp_scale
1344 read(
unitpar, rc_list,
end=111)
1349 fl%coolcurve=coolcurve
1352 fl%rc_split=rc_split
1354 fl%rad_cut_hgt=rad_cut_hgt
1355 fl%rad_cut_dey=rad_cut_dey
1356 fl%Y_mod_quadrature=rc_y_mod_quadrature
1357 fl%Y_mod_N_sub=rc_y_mod_n_sub
1358 fl%rad_damp=rad_damp
1359 fl%rad_damp_height=rad_damp_height
1360 fl%rad_damp_scale=rad_damp_scale
1361 fl%rad_newton=rad_newton
1362 fl%rad_newton_trad=rad_newton_trad
1363 fl%rad_newton_rhosurf=rad_newton_rhosurf
1364 fl%rad_newton_pthick=rad_newton_pthick
1365 end subroutine rc_params_read
1368 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
1371 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
1372 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1374 double precision :: delx(ixi^s,1:
ndim)
1375 double precision :: xc(ixi^s,1:
ndim),xshift^
d
1376 integer :: idims, ixc^
l, hxo^
l, ix, idims2
1382 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
1386 hxo^
l=ixo^
l-
kr(idims,^
d);
1392 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
1395 xshift^
d=half*(one-
kr(^
d,idims));
1402 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
1406 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
1408 end subroutine set_equi_vars_grid_faces
1411 subroutine set_equi_vars_grid(igrid)
1415 integer,
intent(in) :: igrid
1421 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
1423 end subroutine set_equi_vars_grid
1426 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
1428 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
1429 double precision,
intent(in) :: w(ixi^s, 1:nw)
1430 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1431 double precision :: wnew(ixo^s, 1:nwc)
1438 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
1444 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
1448 wnew(ixo^s,
e_)=w(ixo^s,
e_)
1450 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+
block%equi_vars(ixo^s,
equi_pe0_,0)*eos%inv_gamma_minus_1
1452 if(
b0field .and. total_energy)
then
1453 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
1454 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
1458 end function convert_vars_splitting
1460 subroutine mhd_check_params
1467 ngridvars,num_particles,physics_type_particles
1470 double precision :: a,
b,xfrac,yfrac
1476 'WARNING: typeboundspeed and H_correction are ignored',
' when mhd_semirelativistic=T'
1477 if(
boundspeed==4)
call mpistop(
"typeboundspeed='pvrs' is not implemented for mhd")
1481 call mpistop(
'mhd_uawsom currently requires a uniform Cartesian grid')
1483 call mpistop(
'mhd_uawsom requires the standard total-energy MHD formulation')
1486 call mpistop(
'mhd_uawsom: unsupported MHD option')
1487 if(trim(eos%eos_type) /=
'FI') &
1488 call mpistop(
"mhd_uawsom currently supports eos_type='FI' only")
1490 call mpistop(
'mhd_uawsom_height_dim must be between 1 and ndim')
1493 call mpistop(
'mhd_uawsom requires zeta0>1 and 0<filling_factor<1')
1497 call mpistop(
'mhd_uawsom: scales must be positive')
1499 call mpistop(
'mhd_uawsom_sigma must be non-negative')
1501 case(
'one_dimensional_gradient')
1502 uawsom_reflection_id=uawsom_reflection_1d
1503 case(
'cartesian_gradient_vorticity')
1504 uawsom_reflection_id=uawsom_reflection_cartesian
1506 call mpistop(
'invalid mhd_uawsom_reflection_mode')
1513 if (particles_eta < zero) particles_eta =
mhd_eta
1514 if (particles_etah < zero) particles_eta =
mhd_etah
1519 if (eos%gamma <= 0.0d0)
call mpistop (
"Error: gamma <= 0")
1520 if (
mhd_adiab < 0.0d0)
call mpistop (
"Error: mhd_adiab < 0")
1523 if (eos%gamma <= 0.0d0 .or. eos%gamma == 1.0d0) &
1524 call mpistop (
"Error: gamma <= 0 or gamma == 1")
1530 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
1539 call mpistop(
"Must have has_equi_rho_and_p=F with the roe/hllc/hllcd flux schemes")
1543 call mpistop(
"Must have has_equi_rho_and_p=F when mhd_trac=T")
1549 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
1557 call mpistop(
'select IMEX scheme for FLD radiation use')
1560 call phys_set_mg_bounds()
1562 if(.not.
fld_no_mg)
call mpistop(
'multigrid must have BCs for IMEX and FLD radiation use')
1565 write(*,*)
'==FLD SETUP======================'
1566 write(*,*)
'Using FLD with settings:'
1570 write(*,*)
'Using FLD with settings: fld_bound_diff=',
fld_bound_diff
1573 write(*,*)
'Using FLD with settings: fld_kappa0=',
fld_kappa0
1574 write(*,*)
'Using FLD with settings: fld_opal_table=',
fld_opal_table
1576 write(*,*)
'Using FLD with settings: fld_bisect_tol=',
fld_bisect_tol
1577 write(*,*)
'Using FLD with settings: fld_diff_tol=',
fld_diff_tol
1580 write(*,*)
' FLD has fld_no_mg=',
fld_no_mg
1582 print *,
'WARNING: cheating with FLD diffusion ***********************'
1583 print *,
'WARNING: No MG-diffusion for radiative energy at all!!!!!!!'
1584 print *,
'WARNING: cheating with FLD diffusion ***********************'
1587 print *,
'NORMALIZED arad_norm=',
arad_norm
1588 print *,
'NORMALIZED c_norm=',
c_norm
1590 print *,
'WARNING: cheating with c_norm ***********************'
1591 print *,
'WARNING: c_norm reset to=',
fld_cnorm
1593 print *,
'WARNING: cheating with c_norm ***********************'
1601 print *,
'physical fld_kappa (in cgs or SI) =',
fld_kappa0
1604 write(*,*)
'===FLD SETUP====================='
1609 write(*,*)
'====MHD run with settings===================='
1610 write(*,*)
'Using mod_mhd_phys with settings:'
1612 write(*,*)
'Dimensionality :',
ndim
1613 write(*,*)
'vector components:',
ndir
1615 write(*,*)
'number of variables nw=',nw
1616 write(*,*)
' start index iwstart=',iwstart
1617 write(*,*)
'number of vector variables=',nvector
1618 write(*,*)
'number of stagger variables nws=',nws
1619 write(*,*)
'number of variables with BCs=',nwgc
1620 write(*,*)
'number of vars with fluxes=',nwflux
1621 write(*,*)
'number of vars with flux + BC=',nwfluxbc
1622 write(*,*)
'number of auxiliary variables=',nwaux
1623 write(*,*)
'number of extra vars without flux=',nwextra
1624 write(*,*)
'number of extra vars for wextra=',nw_extra
1625 write(*,*)
'number of auxiliary I/O variables=',
nwauxio
1627 write(*,*)
' mhd_energy=',
mhd_energy,
' with total_energy=',total_energy
1632 write(*,*)
' mhd_eta=',
mhd_eta,
' nonzero implies resistivity'
1646 write(*,*)
'*****Using particles: with mhd_eta, mhd_etah :',
mhd_eta,
mhd_etah
1647 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
1648 write(*,*)
'*****Using particles: npayload,ngridvars :', npayload,ngridvars
1649 write(*,*)
'*****Using particles: nusrpayload :', nusrpayload
1650 write(*,*)
'*****Using particles: num_particles :', num_particles
1651 write(*,*)
'*****Using particles: physics_type_particles=',physics_type_particles
1654 write(*,*)
'number due to phys_wider_stencil=',phys_wider_stencil
1655 write(*,*)
'==========================================='
1656 print *,
'========EOS and UNITS==========='
1658 print *,
'gamma=',eos%gamma
1659 print *,
'He_abundance =',eos%He_abundance
1661 print *,
'========EOS and UNITS==========='
1683 print *,
' compare this to ',mp_si*(1.d0+4.d0*eos%He_abundance)
1685 print *,
' compare this to ',mp_cgs*(1.d0+4.d0*eos%He_abundance)
1689 print *,
' compare this to ',kb_si*(2.d0+3.d0*eos%He_abundance)
1693 print *,
' compare this to ',kb_cgs*(2.d0+3.d0*eos%He_abundance)
1697 if(eos%eos_type /=
'LTE')
then
1698 print *,
'mean molecular weight mu is =',a/
b,
' = ', (1.d0+4.d0*eos%He_abundance)/(2.d0+3.d0*eos%He_abundance)
1700 yfrac=4.d0*eos%He_abundance/(1.d0+4.d0*eos%He_abundance)
1701 print *,
'mass fraction hydrogen X is =',1/a,
' and this equals ', 1.d0/(1.d0+4.d0*eos%He_abundance)
1702 print *,
'mass fraction helium Y is =',yfrac
1703 print *,
' check that 1/mu',
b/a,
' is equal to 2X+3Y/4=',2.d0*xfrac+3.d0*yfrac/4.d0
1704 print *,
' ratio n_e/n_p=',1.d0+2.0d0*eos%He_abundance
1706 print *,
'========UNITS==========='
1709 end subroutine mhd_check_params
1711 subroutine mhd_physical_units()
1713 double precision :: mp,kb,miu0,c_lightspeed,xfrac,sigma_telectron
1714 double precision :: a,
b
1722 sigma_telectron=sigma_te_si
1728 c_lightspeed=const_c
1729 sigma_telectron=sigma_te_cgs
1734 if (eos%eos_type ==
'LTE')
then
1738 eos%nH2rhoFactor = 1d0+4d0*eos%He_abundance
1739 rr=(2d0+3d0*eos%He_abundance) / (1d0+4d0*eos%He_abundance)
1740 xfrac=1.d0/(1.d0+4.d0*eos%He_abundance)
1744 a=1d0+4d0*eos%He_abundance
1745 if(eos%eos_type==
'PI')
then
1748 b=2d0+3d0*eos%He_abundance
1881 eos%inv_squared_c0 = inv_squared_c0
1882 eos%inv_squared_c = inv_squared_c
1898 end subroutine mhd_physical_units
1900 subroutine mhd_check_w_semirelati(primitive,ixI^L,ixO^L,w,flag)
1903 logical,
intent(in) :: primitive
1904 logical,
intent(inout) :: flag(ixi^s,1:nw)
1905 integer,
intent(in) :: ixi^
l, ixo^
l
1906 double precision,
intent(in) :: w(ixi^s,nw)
1908 double precision :: vel(ixo^s,1:
ndir),emech(ixo^s)
1918 where(w(ixo^s,
e_)-emech(ixo^s) <
small_e) flag(ixo^s,
e_) = .true.
1922 end subroutine mhd_check_w_semirelati
1924 subroutine mhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1927 logical,
intent(in) :: primitive
1928 integer,
intent(in) :: ixi^
l, ixo^
l
1929 double precision,
intent(in) :: w(ixi^s,nw)
1930 logical,
intent(inout) :: flag(ixi^s,1:nw)
1932 integer :: ix^
d, igrp
1935 {
do ix^db=ixomin^db,ixomax^db\}
1955 end subroutine mhd_check_w_origin
1957 subroutine mhd_check_w_split(primitive,ixI^L,ixO^L,w,flag)
1960 logical,
intent(in) :: primitive
1961 integer,
intent(in) :: ixi^
l, ixo^
l
1962 double precision,
intent(in) :: w(ixi^s,nw)
1963 logical,
intent(inout) :: flag(ixi^s,1:nw)
1965 double precision :: tmp
1969 {
do ix^db=ixomin^db,ixomax^db\}
1975 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1980 end subroutine mhd_check_w_split
1982 subroutine mhd_check_w_noe(primitive,ixI^L,ixO^L,w,flag)
1985 logical,
intent(in) :: primitive
1986 integer,
intent(in) :: ixi^
l, ixo^
l
1987 double precision,
intent(in) :: w(ixi^s,nw)
1988 logical,
intent(inout) :: flag(ixi^s,1:nw)
1993 {
do ix^db=ixomin^db,ixomax^db\}
1997 end subroutine mhd_check_w_noe
1999 subroutine mhd_check_w_inte(primitive,ixI^L,ixO^L,w,flag)
2002 logical,
intent(in) :: primitive
2003 integer,
intent(in) :: ixi^
l, ixo^
l
2004 double precision,
intent(in) :: w(ixi^s,nw)
2005 logical,
intent(inout) :: flag(ixi^s,1:nw)
2010 {
do ix^db=ixomin^db,ixomax^db\}
2019 end subroutine mhd_check_w_inte
2021 subroutine mhd_check_w_hde(primitive,ixI^L,ixO^L,w,flag)
2024 logical,
intent(in) :: primitive
2025 integer,
intent(in) :: ixi^
l, ixo^
l
2026 double precision,
intent(in) :: w(ixi^s,nw)
2027 logical,
intent(inout) :: flag(ixi^s,1:nw)
2032 {
do ix^db=ixomin^db,ixomax^db\}
2041 end subroutine mhd_check_w_hde
2043 subroutine mhd_bound_fip(primitive, ixI^L, ixO^L, w)
2045 logical,
intent(in) :: primitive
2046 integer,
intent(in) :: ixi^
l, ixo^
l
2047 double precision,
intent(inout) :: w(ixi^s,1:nw)
2049 double precision :: rho_safe(ixi^s), fip_prim(ixi^s)
2061 fip_prim(ixo^s) = w(ixo^s,
fip_) / rho_safe(ixo^s)
2062 fip_prim(ixo^s) = min(
maxfip, max(
minfip, fip_prim(ixo^s)))
2063 w(ixo^s,
fip_) = rho_safe(ixo^s) * fip_prim(ixo^s)
2065 end subroutine mhd_bound_fip
2069 subroutine mhd_uawsom_get_coefficients(w,x,ixI^L,ixO^L,primitive,zeta,radius,lperp_A)
2072 integer,
intent(in) :: ixi^
l, ixo^
l
2073 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
2074 logical,
intent(in) :: primitive
2075 double precision,
intent(out) :: zeta(ixi^s), radius(ixi^s), lperp_a(ixi^s)
2076 double precision :: bmag(ixi^s), btotal(ixi^s,1:
ndir), height_base
2084 btotal(ixo^s,idir)=w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,
b0i)
2086 btotal(ixo^s,idir)=w(ixo^s,mag(idir))
2089 bmag(ixo^s)=dsqrt(sum(btotal(ixo^s,1:
ndir)**2,dim=
ndim+1))
2092 height_base=xprobmin1
2095 height_base=xprobmin2
2099 height_base=xprobmin3
2110 if(any(zeta(ixo^s)<=one) .or. any(radius(ixo^s)<=zero) .or. &
2111 any(lperp_a(ixo^s)<=zero)) &
2112 call mpistop(
'mhd_uawsom coefficients require zeta>1 and positive lengths')
2113 end subroutine mhd_uawsom_get_coefficients
2117 integer,
intent(in) :: ixi^
l, ixo^
l
2118 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
2119 double precision,
intent(out) :: factor(ixi^s)
2120 double precision :: zeta(ixi^s), radius(ixi^s), lperp_a(ixi^s)
2121 call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.false.,zeta,radius,lperp_a)
2126 double precision,
intent(in) :: zeta
2127 double precision :: f
2134 double precision,
intent(in) :: wcell(:),zeta
2141 double precision,
intent(in) :: wcell(:)
2155 elemental pure double precision function mhd_uawsom_imbalance_factor(wplus,wminus)
2156 double precision,
intent(in) :: wplus,wminus
2158 if(wplus<=0.d0 .or. wminus<=0.d0)
then
2159 mhd_uawsom_imbalance_factor=0.d0
2160 else if(4.d0*wminus<=wplus)
then
2161 mhd_uawsom_imbalance_factor=1.d0-2.d0*dsqrt(wminus/wplus)
2162 else if(4.d0*wplus<=wminus)
then
2163 mhd_uawsom_imbalance_factor=-(1.d0-2.d0*dsqrt(wplus/wminus))
2165 mhd_uawsom_imbalance_factor=0.d0
2167 end function mhd_uawsom_imbalance_factor
2172 subroutine mhd_add_source_uawsom(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x)
2175 integer,
intent(in) :: ixi^
l, ixo^
l
2176 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), &
2177 wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
2178 double precision,
intent(inout) :: w(ixi^s,1:nw)
2179 double precision :: v(ixi^s,1:
ndir), divv(ixi^s)
2180 double precision :: zeta(ixi^s), radius(ixi^s), lperp_a(ixi^s)
2181 double precision :: lperp_k(ixi^s), rho_e(ixi^s)
2182 double precision :: gamma_plus(ixi^s), gamma_minus(ixi^s)
2183 double precision :: gamma_kplus(ixi^s), gamma_kminus(ixi^s)
2184 double precision :: dampap(ixi^s), dampam(ixi^s), dampkp(ixi^s), dampkm(ixi^s)
2185 double precision :: btotal(ixi^s,1:
ndir), bunit(ixi^s,1:
ndir), bmag(ixi^s)
2186 double precision :: va(ixi^s), vk(ixi^s), lnva(ixi^s), lnvk(ixi^s)
2187 double precision :: grad_component(ixi^s), grad_a(ixi^s), grad_k(ixi^s)
2188 double precision :: curlv(ixi^s,1:3), vorticity(ixi^s)
2189 double precision :: rimb_a(ixi^s), rlim_a(ixi^s), rlim_k(ixi^s)
2190 double precision :: refl_rate(ixi^s), donor_reflection(ixi^s)
2191 double precision :: transfer_a(ixi^s), transfer_k(ixi^s), donor(ixi^s)
2192 double precision :: imbalance_a(ixi^s), imbalance_k(ixi^s)
2193 double precision :: wave_plus(ixi^s), wave_minus(ixi^s)
2194 double precision :: wave_kplus(ixi^s), wave_kminus(ixi^s)
2195 double precision :: f, kink_pressure(ixi^s)
2196 integer :: idir, idirmin
2197 logical :: have_reflection, have_alfven_reflection, have_kink_reflection
2203 call mhd_uawsom_get_coefficients(wct,x,ixi^
l,ixi^
l,.false.,zeta,radius,lperp_a)
2206 max(one+f*zeta(ixi^s)-f,smalldouble)
2207 lperp_k(ixi^s)=dsqrt(10.d0)*dsqrt(f*dpi)*radius(ixi^s)*&
2208 (zeta(ixi^s)+one-f)**1.5d0/&
2209 ((zeta(ixi^s)-one)*(one-f**2.5d0))
2210 gamma_plus(ixo^s)=two/lperp_a(ixo^s)*dsqrt(&
2212 gamma_minus(ixo^s)=two/lperp_a(ixo^s)*dsqrt(&
2214 dampap(ixo^s)=gamma_plus(ixo^s)*max(wct(ixo^s,
waplus_),zero)
2215 dampam(ixo^s)=gamma_minus(ixo^s)*max(wct(ixo^s,
waminus_),zero)
2216 dampkp(ixo^s)=max(wct(ixo^s,
wkplus_),zero)**1.5d0/&
2217 (dsqrt(rho_e(ixo^s))*lperp_k(ixo^s))
2218 dampkm(ixo^s)=max(wct(ixo^s,
wkminus_),zero)**1.5d0/&
2219 (dsqrt(rho_e(ixo^s))*lperp_k(ixo^s))
2222 gamma_kplus(ixo^s)=dsqrt(max(wct(ixo^s,
wkplus_),zero)/&
2223 max(rho_e(ixo^s),
small_density))/max(lperp_k(ixo^s),smalldouble)
2224 gamma_kminus(ixo^s)=dsqrt(max(wct(ixo^s,
wkminus_),zero)/&
2225 max(rho_e(ixo^s),
small_density))/max(lperp_k(ixo^s),smalldouble)
2229 half*divv(ixo^s)*wct(ixo^s,
waplus_)+dampap(ixo^s))
2231 half*divv(ixo^s)*wct(ixo^s,
waminus_)+dampam(ixo^s))
2233 half*divv(ixo^s)*wct(ixo^s,
wkplus_)+dampkp(ixo^s))
2235 half*divv(ixo^s)*wct(ixo^s,
wkminus_)+dampkm(ixo^s))
2237 kink_pressure(ixo^s)=quarter*(zeta(ixo^s)+one)*&
2239 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*(zeta(ixo^s)-one)/&
2240 (zeta(ixo^s)+one)*kink_pressure(ixo^s)*divv(ixo^s)
2242 have_alfven_reflection=.false.
2244 select case(uawsom_reflection_id)
2245 case(uawsom_reflection_1d)
2247 case(uawsom_reflection_cartesian)
2248 have_alfven_reflection=.true.
2252 have_reflection=have_alfven_reflection .or. have_kink_reflection
2253 if(have_reflection)
then
2256 btotal(ixi^s,idir)=wct(ixi^s,mag(idir))+
block%B0(ixi^s,idir,
b0i)
2258 btotal(ixi^s,idir)=wct(ixi^s,mag(idir))
2261 bmag(ixi^s)=dsqrt(sum(btotal(ixi^s,1:
ndir)**2,dim=
ndim+1))
2262 if(have_kink_reflection .or. &
2263 (have_alfven_reflection .and. uawsom_reflection_id==uawsom_reflection_cartesian))
then
2265 bunit(ixi^s,idir)=btotal(ixi^s,idir)/max(bmag(ixi^s),smalldouble)
2268 if(have_alfven_reflection)
then
2270 if(uawsom_reflection_id==uawsom_reflection_cartesian) &
2271 lnva(ixi^s)=dlog(max(va(ixi^s),smalldouble))
2273 if(have_kink_reflection)
then
2274 vk(ixi^s)=bmag(ixi^s)/dsqrt(max(rho_e(ixi^s)*&
2275 (zeta(ixi^s)+one)/two,smalldouble))
2276 lnvk(ixi^s)=dlog(max(vk(ixi^s),smalldouble))
2283 if(have_alfven_reflection)
then
2284 wave_plus(ixo^s)=max(wct(ixo^s,
waplus_),zero)
2285 wave_minus(ixo^s)=max(wct(ixo^s,
waminus_),zero)
2287 select case(uawsom_reflection_id)
2288 case(uawsom_reflection_1d)
2294 max(va(ixo^s),smalldouble)*grad_component(ixo^s)
2295 donor_reflection(ixo^s)=merge(max(wct(ixo^s,
waplus_),zero),&
2296 max(wct(ixo^s,
waminus_),zero),refl_rate(ixo^s)>=zero)
2297 transfer_a(ixo^s)=refl_rate(ixo^s)*donor_reflection(ixo^s)
2298 case(uawsom_reflection_cartesian)
2301 call gradient(lnva,ixi^
l,ixo^
l,idir,grad_component)
2302 grad_a(ixo^s)=grad_a(ixo^s)+va(ixo^s)*bunit(ixo^s,idir)*&
2303 grad_component(ixo^s)
2306 vorticity(ixo^s)=zero
2308 vorticity(ixo^s)=vorticity(ixo^s)+bunit(ixo^s,idir)*&
2313 rimb_a(ixo^s)=dsqrt(grad_a(ixo^s)**2+vorticity(ixo^s)**2)
2314 rlim_a(ixo^s)=min(rimb_a(ixo^s),&
2315 max(gamma_plus(ixo^s),gamma_minus(ixo^s)))
2316 imbalance_a(ixo^s)=mhd_uawsom_imbalance_factor(&
2317 wave_plus(ixo^s),wave_minus(ixo^s))
2318 transfer_a(ixo^s)=rlim_a(ixo^s)*imbalance_a(ixo^s)*&
2319 dsqrt(wave_plus(ixo^s)*wave_minus(ixo^s))
2323 donor(ixo^s)=merge(max(w(ixo^s,
waplus_),zero),&
2324 max(w(ixo^s,
waminus_),zero),transfer_a(ixo^s)>=zero)
2325 transfer_a(ixo^s)=sign(min(abs(transfer_a(ixo^s)),&
2326 donor(ixo^s)/qdt),transfer_a(ixo^s))
2328 transfer_a(ixo^s)=zero
2334 if(have_kink_reflection)
then
2335 wave_kplus(ixo^s)=max(wct(ixo^s,
wkplus_),zero)
2336 wave_kminus(ixo^s)=max(wct(ixo^s,
wkminus_),zero)
2339 call gradient(lnvk,ixi^
l,ixo^
l,idir,grad_component)
2340 grad_k(ixo^s)=grad_k(ixo^s)+vk(ixo^s)*bunit(ixo^s,idir)*&
2341 grad_component(ixo^s)
2346 rlim_k(ixo^s)=min(abs(grad_k(ixo^s)),&
2347 max(gamma_kplus(ixo^s),gamma_kminus(ixo^s)))
2348 imbalance_k(ixo^s)=mhd_uawsom_imbalance_factor(&
2349 wave_kplus(ixo^s),wave_kminus(ixo^s))
2350 transfer_k(ixo^s)=rlim_k(ixo^s)*imbalance_k(ixo^s)*&
2351 dsqrt(wave_kplus(ixo^s)*wave_kminus(ixo^s))
2353 donor(ixo^s)=merge(max(w(ixo^s,
wkplus_),zero),&
2354 max(w(ixo^s,
wkminus_),zero),transfer_k(ixo^s)>=zero)
2355 transfer_k(ixo^s)=sign(min(abs(transfer_k(ixo^s)),&
2356 donor(ixo^s)/qdt),transfer_k(ixo^s))
2358 transfer_k(ixo^s)=zero
2364 end subroutine mhd_add_source_uawsom
2369 integer,
intent(in) :: ixi^
l, ixo^
l
2370 double precision,
intent(inout) :: w(ixi^s, nw)
2371 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2376 {
do ix^db=ixomin^db,ixomax^db\}
2379 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
2381 +(^
c&w(ix^
d,
b^
c_)**2+))
2385 do ix^db=ixomin^db,ixomax^db\}
2387 w(ix^d,
e_)=w(ix^d,
e_)&
2388 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
2389 +(^
c&w(ix^d,
b^
c_)**2+))&
2396 subroutine mhd_ei_to_e_hde(ixI^L,ixO^L,w,x)
2398 integer,
intent(in) :: ixi^
l, ixo^
l
2399 double precision,
intent(inout) :: w(ixi^s, nw)
2400 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2404 {
do ix^db=ixomin^db,ixomax^db\}
2410 end subroutine mhd_ei_to_e_hde
2418 integer,
intent(in) :: ixi^
l, ixo^
l
2419 double precision,
intent(in) :: w(ixi^s,nw)
2420 double precision,
intent(out) :: vel(ixo^s,1:
ndir)
2421 double precision,
intent(out),
optional :: emech(ixo^s)
2423 double precision :: btot(1:
ndir), efd(1:
ndir)
2424 double precision :: b2, rhoc2, tmp, inv_rho
2427 {
do ix^db=ixomin^db,ixomax^db\}
2428 ^
c&btot(^
c)=w(ix^
d,
b^
c_)\
2433 b2=(^
c&btot(^
c)**2+)
2434 tmp=(^
c&btot(^
c)*w(ix^
d,
m^
c_)+)
2436 inv_rho=1.d0/(w(ix^
d,
rho_)*(rhoc2+b2))
2437 ^
c&vel(ix^
d,^
c)=(rhoc2*w(ix^
d,
m^
c_)+btot(^
c)*tmp)*inv_rho\
2438 if(
present(emech))
then
2444 efd(1)=btot(2)*vel(ix^
d,3)-btot(3)*vel(ix^
d,2)
2445 efd(2)=btot(3)*vel(ix^
d,1)-btot(1)*vel(ix^
d,3)
2446 efd(3)=btot(1)*vel(ix^
d,2)-btot(2)*vel(ix^
d,1)
2450 efd(2)=btot(1)*vel(ix^
d,2)-btot(2)*vel(ix^
d,1)
2455 emech(ix^
d)=half*((^
c&vel(ix^
d,^
c)**2+)*w(ix^
d,
rho_)&
2456 +(^
c&w(ix^
d,
b^
c_)**2+)&
2457 +(^
c&efd(^
c)**2+)*inv_squared_c)
2469 double precision,
intent(in) :: eint, rho
2470 double precision :: nh, t, rfac
2473 nh=rho/
eos%nH2rhoFactor
2478 p=
eos%gamma_minus_1*eint
2488 double precision,
intent(in) :: p, rho
2489 double precision :: nh
2492 nh=rho/
eos%nH2rhoFactor
2497 eint=p*
eos%inv_gamma_minus_1
2503 subroutine mhd_ei_to_e_semirelati(ixI^L,ixO^L,w,x)
2505 integer,
intent(in) :: ixi^
l, ixo^
l
2506 double precision,
intent(inout) :: w(ixi^s, nw)
2507 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2509 double precision :: vel(ixo^s,1:
ndir), emech(ixo^s)
2512 w(ixo^s,
e_)=w(ixo^s,
e_)+emech(ixo^s)
2514 end subroutine mhd_ei_to_e_semirelati
2519 integer,
intent(in) :: ixi^
l, ixo^
l
2520 double precision,
intent(inout) :: w(ixi^s, nw)
2521 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2526 {
do ix^db=ixomin^db,ixomax^db\}
2529 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
2531 +(^
c&w(ix^
d,
b^
c_)**2+))
2535 do ix^db=ixomin^db,ixomax^db\}
2537 w(ix^d,
e_)=w(ix^d,
e_)&
2538 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
2539 +(^
c&w(ix^d,
b^
c_)**2+))&
2544 if(fix_small_values)
then
2545 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei')
2553 subroutine mhd_e_to_ei_cache_log_nh(ixI^L,ixO^L,w,x)
2555 integer,
intent(in) :: ixi^
l, ixo^
l
2556 double precision,
intent(inout) :: w(ixi^s, nw)
2557 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2559 call mhd_e_to_ei_base(ixi^
l,ixo^
l,w,x)
2560 block%wextra(ixo^s, iw_log_nh) = dlog10(w(ixo^s,
rho_) / eos%nH2rhoFactor)
2561 end subroutine mhd_e_to_ei_cache_log_nh
2564 subroutine mhd_ei_unchanged(ixI^L,ixO^L,w,x)
2566 integer,
intent(in) :: ixi^
l, ixo^
l
2567 double precision,
intent(inout) :: w(ixi^s, nw)
2568 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2569 end subroutine mhd_ei_unchanged
2572 subroutine mhd_e_to_ei_hde(ixI^L,ixO^L,w,x)
2574 integer,
intent(in) :: ixi^
l, ixo^
l
2575 double precision,
intent(inout) :: w(ixi^s, nw)
2576 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2580 {
do ix^db=ixomin^db,ixomax^db\}
2586 if(fix_small_values)
then
2587 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei_hde')
2590 end subroutine mhd_e_to_ei_hde
2593 subroutine mhd_e_to_ei_semirelati(ixI^L,ixO^L,w,x)
2595 integer,
intent(in) :: ixi^
l, ixo^
l
2596 double precision,
intent(inout) :: w(ixi^s, nw)
2597 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2599 double precision :: vel(ixo^s,1:
ndir), emech(ixo^s)
2602 w(ixo^s,
e_)=w(ixo^s,
e_)-emech(ixo^s)
2605 call mhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,
'mhd_e_to_ei_semirelati')
2608 end subroutine mhd_e_to_ei_semirelati
2610 subroutine mhd_handle_small_values_semirelati(primitive, w, x, ixI^L, ixO^L, subname)
2613 logical,
intent(in) :: primitive
2614 integer,
intent(in) :: ixi^
l,ixo^
l
2615 double precision,
intent(inout) :: w(ixi^s,1:nw)
2616 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2617 character(len=*),
intent(in) :: subname
2619 double precision :: v(ixi^s,1:
ndir), emech(ixi^s), small_rho(ixi^s)
2620 double precision,
allocatable :: work(:^
d&,:)
2621 integer :: ix^
d, ixc^
l
2622 logical :: flag(ixi^s,1:nw)
2632 small_rho(ixc^s)=w(ixc^s,
rho_)
2634 flag(ixc^s,
rho_) = .true.
2637 if(.not.primitive)
then
2644 {
do ix^db=ixcmin^db,ixcmax^db\}
2650 if(any(flag(ixo^s,:)))
then
2651 select case (small_values_method)
2653 {
do ix^db=ixomin^db,ixomax^db\}
2654 if(flag(ix^d,
rho_))
then
2655 ^
c&w(ix^d,
m^
c_)=zero\
2659 w(ix^d,
p_) = small_pressure
2661 w(ix^d,
e_) = small_e + emech(ix^d)
2666 call small_values_average(ixi^l,ixo^l,w,x,flag,
rho_)
2669 call small_values_average(ixi^l,ixo^l,w,x,flag,
p_)
2672 w(ixc^s,
e_)=w(ixc^s,
e_)-emech(ixc^s)
2674 call small_values_average(ixi^l,ixo^l,work,x,flag,
e_)
2676 w(ixc^s,
e_)=w(ixc^s,
e_)+emech(ixc^s)
2681 if(.not.primitive)
then
2683 w(ixo^s,
mom(1:ndir))=v(ixo^s,1:ndir)
2686 where(flag(ixc^s,
rho_))
2687 w(ixc^s,
rho_)=small_rho(ixc^s)
2689 call small_values_error(w,x,ixi^l,ixo^l,flag,subname)
2692 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2693 end subroutine mhd_handle_small_values_semirelati
2695 subroutine mhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
2698 logical,
intent(in) :: primitive
2699 integer,
intent(in) :: ixi^
l,ixo^
l
2700 double precision,
intent(inout) :: w(ixi^s,1:nw)
2701 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2702 character(len=*),
intent(in) :: subname
2704 integer :: ix^
d, igrp
2705 logical :: flag(ixi^s,1:nw)
2707 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2712 {
do ix^db=ixomin^db,ixomax^db\}
2716 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2740 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2742 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2745 call small_values_average(ixi^l,ixo^l,w,x,flag,
waplus_)
2746 call small_values_average(ixi^l,ixo^l,w,x,flag,
waminus_)
2747 call small_values_average(ixi^l,ixo^l,w,x,flag,
wkplus_)
2748 call small_values_average(ixi^l,ixo^l,w,x,flag,
wkminus_)
2751 {
do ix^db=iximin^db,iximax^db\}
2752 w(ix^d,
e_)=w(ix^d,
e_)&
2753 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))&
2756 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2758 {
do ix^db=iximin^db,iximax^db\}
2759 w(ix^d,
e_)=w(ix^d,
e_)&
2760 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))&
2765 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
2768 if(.not.primitive)
then
2770 {
do ix^db=ixomin^db,ixomax^db\}
2772 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)&
2773 -half*((^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))&
2777 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2780 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2781 end subroutine mhd_handle_small_values_origin
2783 subroutine mhd_handle_small_values_split(primitive, w, x, ixI^L, ixO^L, subname)
2786 logical,
intent(in) :: primitive
2787 integer,
intent(in) :: ixi^
l,ixo^
l
2788 double precision,
intent(inout) :: w(ixi^s,1:nw)
2789 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2790 character(len=*),
intent(in) :: subname
2792 double precision :: rho
2793 integer :: ix^
d, igrp
2794 logical :: flag(ixi^s,1:nw)
2796 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2801 {
do ix^db=ixomin^db,ixomax^db\}
2806 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2819 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2821 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2824 {
do ix^db=iximin^db,iximax^db\}
2826 w(ix^d,
e_)=w(ix^d,
e_)&
2827 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2829 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2831 {
do ix^db=iximin^db,iximax^db\}
2833 w(ix^d,
e_)=w(ix^d,
e_)&
2834 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2838 if(.not.primitive)
then
2840 {
do ix^db=ixomin^db,ixomax^db\}
2842 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
2843 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)&
2844 -half*((^
c&w(ix^d,
m^
c_)**2+)*rho+(^
c&w(ix^d,
b^
c_)**2+)))
2847 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2850 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2851 end subroutine mhd_handle_small_values_split
2853 subroutine mhd_handle_small_values_inte(primitive, w, x, ixI^L, ixO^L, subname)
2856 logical,
intent(in) :: primitive
2857 integer,
intent(in) :: ixi^
l,ixo^
l
2858 double precision,
intent(inout) :: w(ixi^s,1:nw)
2859 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2860 character(len=*),
intent(in) :: subname
2862 integer :: ix^
d, igrp
2863 logical :: flag(ixi^s,1:nw)
2865 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2870 {
do ix^db=ixomin^db,ixomax^db\}
2871 if(flag(ix^
d,
rho_))
then
2873 ^
c&w(ix^
d,
m^
c_)=0.d0\
2883 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2885 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2887 if(.not.primitive)
then
2889 {
do ix^db=ixomin^db,ixomax^db\}
2891 w(ix^d,
p_)=eos%gamma_minus_1*w(ix^d,
e_)
2894 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2897 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2898 end subroutine mhd_handle_small_values_inte
2900 subroutine mhd_handle_small_values_noe(primitive, w, x, ixI^L, ixO^L, subname)
2903 logical,
intent(in) :: primitive
2904 integer,
intent(in) :: ixi^
l,ixo^
l
2905 double precision,
intent(inout) :: w(ixi^s,1:nw)
2906 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2907 character(len=*),
intent(in) :: subname
2909 integer :: ix^
d, igrp
2910 logical :: flag(ixi^s,1:nw)
2912 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2917 {
do ix^db=ixomin^db,ixomax^db\}
2921 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2927 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2929 if(.not.primitive)
then
2931 {
do ix^db=ixomin^db,ixomax^db\}
2935 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2938 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2939 end subroutine mhd_handle_small_values_noe
2941 subroutine mhd_handle_small_values_hde(primitive, w, x, ixI^L, ixO^L, subname)
2944 logical,
intent(in) :: primitive
2945 integer,
intent(in) :: ixi^
l,ixo^
l
2946 double precision,
intent(inout) :: w(ixi^s,1:nw)
2947 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2948 character(len=*),
intent(in) :: subname
2950 integer :: ix^
d, igrp
2951 logical :: flag(ixi^s,1:nw)
2953 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2958 {
do ix^db=ixomin^db,ixomax^db\}
2959 if(flag(ix^
d,
rho_))
then
2961 ^
c&w(ix^
d,
m^
c_)=0.d0\
2971 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2973 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2975 if(.not.primitive)
then
2977 {
do ix^db=ixomin^db,ixomax^db\}
2979 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)-half*(^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_))
2982 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2985 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2986 end subroutine mhd_handle_small_values_hde
2992 integer,
intent(in) :: ixi^
l, ixo^
l
2993 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
2994 double precision,
intent(out) :: v(ixi^s,
ndir)
2996 double precision :: rho(ixi^s)
3006 rho(ixo^s)=1.d0/rho(ixo^s)
3009 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
3019 subroutine mhd_uawsom_get_signal_speed(w,x,ixI^L,ixO^L,idim,csignal)
3021 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3022 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
3023 double precision,
intent(out) :: csignal(ixo^s)
3024 double precision :: cs2(ixi^s), zeta(ixi^s), radius(ixi^s), lperp(ixi^s)
3025 double precision :: btotal(1:
ndir), b2, inv_rho, qwave, sound2
3026 double precision :: cfast2, discriminant, cfast, awave, kmax
3029 call eos%get_csound2(w,x,ixi^
l,ixo^
l,cs2)
3030 call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.true.,zeta,radius,lperp)
3033 {
do ix^db=ixomin^db,ixomax^db\}
3034 inv_rho=one/w(ix^
d,
rho_)
3035 ^
c&btotal(^
c)=w(ix^
d,
b^
c_)\
3039 b2=(^
c&btotal(^
c)**2+)
3042 sound2=cs2(ix^
d)+half*qwave
3043 cfast2=b2*inv_rho+sound2
3044 discriminant=max(zero,cfast2**2-4.d0*sound2*btotal(idim)**2*inv_rho)
3045 cfast=sqrt(half*(cfast2+sqrt(discriminant)))
3049 awave=abs(btotal(idim))*sqrt(inv_rho)*max(one,&
3052 csignal(ix^
d)=half*(cfast+awave+sqrt((cfast-awave)**2+4.d0*qwave))
3054 end subroutine mhd_uawsom_get_signal_speed
3057 subroutine mhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
3060 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3061 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3062 double precision,
intent(inout) :: cmax(ixi^s)
3064 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
3065 double precision :: cs2(ixi^s)
3069 call mhd_uawsom_get_signal_speed(w,x,ixi^
l,ixo^
l,idim,cmax(ixo^s))
3070 cmax(ixo^s)=abs(w(ixo^s,
mom(idim)))+cmax(ixo^s)
3077 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
3080 {
do ix^db=ixomin^db,ixomax^db \}
3089 cfast2=b2*inv_rho+cs2(ix^
d)
3090 avmincs2=cfast2**2-4.0d0*cs2(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
3091 if(avmincs2<zero) avmincs2=zero
3092 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3096 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3098 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
3101 {
do ix^db=ixomin^db,ixomax^db \}
3109 b2=(^
c&w(ix^d,
b^
c_)**2+)
3110 cfast2=b2*inv_rho+cs2(ix^d)
3111 avmincs2=cfast2**2-4.0d0*cs2(ix^d)*w(ix^d,mag(idim))**2*inv_rho
3112 if(avmincs2<zero) avmincs2=zero
3113 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3117 cmax(ix^d)=max(cmax(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3119 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
3123 end subroutine mhd_get_cmax_origin
3126 subroutine mhd_get_cmax_origin_noe(w,x,ixI^L,ixO^L,idim,cmax)
3130 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3131 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3132 double precision,
intent(inout) :: cmax(ixi^s)
3134 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
3135 double precision :: adiabs(ixi^s), gammas(ixi^s)
3150 {
do ix^db=ixomin^db,ixomax^db \}
3151 inv_rho=1.d0/w(ix^
d,
rho_)
3153 cmax(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3155 b2=(^
c&w(ix^
d,
b^
c_)**2+)
3156 cfast2=b2*inv_rho+cmax(ix^
d)
3157 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*w(ix^
d,mag(idim))**2*inv_rho
3158 if(avmincs2<zero) avmincs2=zero
3159 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3163 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3165 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
3168 end subroutine mhd_get_cmax_origin_noe
3171 subroutine mhd_get_cmax_semirelati(w,x,ixI^L,ixO^L,idim,cmax)
3174 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3175 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3176 double precision,
intent(inout):: cmax(ixi^s)
3178 double precision :: csound(ixo^s), gamma2(ixo^s)
3180 call mhd_get_csound_semirelati(w,x,ixi^
l,ixo^
l,idim,csound,gamma2)
3182 cmax(ixo^s)=gamma2(ixo^s)*abs(w(ixo^s,
mom(idim)))+csound(ixo^s)
3184 end subroutine mhd_get_cmax_semirelati
3187 subroutine mhd_get_cmax_semirelati_noe(w,x,ixI^L,ixO^L,idim,cmax)
3191 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3192 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3193 double precision,
intent(inout):: cmax(ixi^s)
3195 double precision :: adiabs(ixi^s), gammas(ixi^s)
3196 double precision :: csound, avmincs2, idim_alfven_speed2
3197 double precision :: inv_rho, alfven_speed2, gamma2
3211 {
do ix^db=ixomin^db,ixomax^db \}
3212 inv_rho=1.d0/w(ix^
d,
rho_)
3213 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3214 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3215 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
3217 csound=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3218 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3221 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
3222 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
3223 if(avmincs2<zero) avmincs2=zero
3225 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
3228 end subroutine mhd_get_cmax_semirelati_noe
3231 subroutine mhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
3236 integer,
intent(in) :: ixi^
l,ixo^
l
3237 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3239 double precision,
intent(inout) :: w(ixi^s,1:nw)
3240 double precision,
intent(out) :: tco_local,tmax_local
3242 double precision,
parameter :: trac_delta=0.25d0
3243 double precision :: te(ixi^s),lts(ixi^s)
3244 double precision,
dimension(1:ndim) :: bdir, bunitvec
3245 double precision,
dimension(ixI^S,1:ndim) :: gradt
3246 double precision :: ltrc,ltrp,altr
3248 double precision :: q_heat(ixi^s), ne(ixi^s), nh_arr(ixi^s)
3249 double precision :: bvec(1:
ndir)
3250 double precision :: bmin_c, bmag, gnorm, bgtd, l_t, dl_eff, vmag, bdotv, binp2
3251 double precision :: v_n, a_coeff, l1, cooling, net_cool
3252 double precision :: kappa_par, disc, dx_over_delta, kappa_trac, kappa_eff, tcoff_eff
3253 integer :: idims,ix^
d,jxo^
l,hxo^
l,ixa^
d,ixb^
d
3254 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
3256 if (eos%eos_type ==
'LTE' .or. eos%eos_type ==
'PI')
then
3257 te(ixi^s) = w(ixi^s,
te_)
3260 call eos%get_Rfactor(w,x,ixi^
l,ixi^
l,te)
3261 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*ne(ixi^s))
3264 tmax_local=maxval(te(ixo^s))
3272 do ix1=ixomin1,ixomax1
3273 lts(ix1)=0.5d0*abs(te(ix1+1)-te(ix1-1))/te(ix1)
3274 if(lts(ix1)>trac_delta)
then
3275 tco_local=max(tco_local,te(ix1))
3287 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
3288 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
3289 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
3290 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
3292 call mpistop(
"mhd_trac_type not allowed for 1D simulation")
3303 call gradient(te,ixi^
l,ixo^
l,idims,gradt(ixi^s,idims))
3310 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
3315 ixb^d=(ixomin^d+ixomax^d-1)/2+ixa^d;
3316 bdir(1:ndim)=bdir(1:ndim)+w(ixb^d,iw_mag(1:ndim))
3320 if(bdir(1)/=0.d0)
then
3321 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3323 block%special_values(3)=0.d0
3325 if(bdir(2)/=0.d0)
then
3326 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3328 block%special_values(4)=0.d0
3332 if(bdir(1)/=0.d0)
then
3333 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+&
3334 (bdir(3)/bdir(1))**2)
3336 block%special_values(3)=0.d0
3338 if(bdir(2)/=0.d0)
then
3339 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+&
3340 (bdir(3)/bdir(2))**2)
3342 block%special_values(4)=0.d0
3344 if(bdir(3)/=0.d0)
then
3345 block%special_values(5)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+&
3346 (bdir(2)/bdir(3))**2)
3348 block%special_values(5)=0.d0
3353 block%special_values(1)=zero
3354 {
do ix^db=ixomin^db,ixomax^db\}
3356 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
3358 ^d&bdir(^d)=w({ix^d},iw_mag(^d))\
3361 if(bdir(1)/=0.d0)
then
3362 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3366 if(bdir(2)/=0.d0)
then
3367 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3372 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2))*&
3373 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3376 if(bdir(1)/=0.d0)
then
3377 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
3381 if(bdir(2)/=0.d0)
then
3382 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
3386 if(bdir(3)/=0.d0)
then
3387 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
3392 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2),block%ds(ix^d,3))*&
3393 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3395 if(lts(ix^d)>trac_delta)
then
3396 block%special_values(1)=max(block%special_values(1),te(ix^d))
3399 block%special_values(2)=tmax_local
3418 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
3422 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),1,.true.)
3423 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),1,.false.)
3427 {
do ix^db=ixpmin^db,ixpmax^db\}
3428 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
3430 if(bdir(1)/=0.d0)
then
3431 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3435 if(bdir(2)/=0.d0)
then
3436 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3442 if(bdir(1)/=0.d0)
then
3443 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
3447 if(bdir(2)/=0.d0)
then
3448 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
3452 if(bdir(3)/=0.d0)
then
3453 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
3459 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3461 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
3462 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
3465 {
do ix^db=ixpmin^db,ixpmax^db\}
3467 if(w(ix^d,iw_mag(1))/=0.d0)
then
3468 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)
3472 if(w(ix^d,iw_mag(2))/=0.d0)
then
3473 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)
3479 if(w(ix^d,iw_mag(1))/=0.d0)
then
3480 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+&
3481 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(1)))**2)
3485 if(w(ix^d,iw_mag(2))/=0.d0)
then
3486 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+&
3487 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(2)))**2)
3491 if(w(ix^d,iw_mag(3))/=0.d0)
then
3492 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+&
3493 (w(ix^d,iw_mag(2))/w(ix^d,iw_mag(3)))**2)
3499 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3501 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
3502 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
3508 {
do ix^db=ixpmin^db,ixpmax^db\}
3510 altr=0.25d0*((lts(ix1-1,ix2)+two*lts(ix^d)+lts(ix1+1,ix2))*bunitvec(1)**2+&
3511 (lts(ix1,ix2-1)+two*lts(ix^d)+lts(ix1,ix2+1))*bunitvec(2)**2)
3512 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
3515 altr=0.25d0*((lts(ix1-1,ix2,ix3)+two*lts(ix^d)+lts(ix1+1,ix2,ix3))*bunitvec(1)**2+&
3516 (lts(ix1,ix2-1,ix3)+two*lts(ix^d)+lts(ix1,ix2+1,ix3))*bunitvec(2)**2+&
3517 (lts(ix1,ix2,ix3-1)+two*lts(ix^d)+lts(ix1,ix2,ix3+1))*bunitvec(3)**2)
3518 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
3528 call usr_get_heating(q_heat, ixi^l, ixo^l, w, x)
3529 call eos%get_ne_nH(ixi^l, ixo^l, w, x, ne, nh_arr)
3530 block%wextra(ixi^s,
tcoff_) = te(ixi^s)
3532 call gradient(te,ixi^l,ixo^l,idims,gradt(ixi^s,idims))
3534 bmin_c = 0.1d0/unit_magneticfield
3535 {
do ix^db=ixomin^db,ixomax^db\}
3537 bmag=bmin_c**2; bdotv=0.d0; vmag=0.d0
3539 bvec(idims)=w(ix^d,iw_mag(idims))
3540 if(b0field) bvec(idims)=bvec(idims)+block%B0(ix^d,idims,0)
3541 bmag =bmag +bvec(idims)**2
3542 bdotv=bdotv+bvec(idims)*w(ix^d,
mom(idims))
3543 vmag =vmag +w(ix^d,
mom(idims))**2
3545 bmag=dsqrt(bmag); vmag=dsqrt(vmag)
3547 gnorm=0.d0; binp2=0.d0; bgtd=0.d0
3549 gnorm=gnorm+gradt(ix^d,idims)**2
3550 binp2=binp2+bvec(idims)**2
3551 bgtd =bgtd +bvec(idims)*gradt(ix^d,idims)
3554 if(gnorm<smalldouble .or. binp2<smalldouble)
then
3555 block%wextra(ix^d,
tcoff_)=te(ix^d)
3558 l_t=te(ix^d)*bmag/(dabs(bgtd)+bmin_c*gnorm)
3562 dl_eff=dl_eff+(bvec(idims)/block%ds(ix^d,idims))**2
3564 dl_eff=bmag/dsqrt(dl_eff)
3566 v_n=(dabs(bdotv)+bmin_c*vmag)/bmag
3567 a_coeff=2.5d0*w(ix^d,
p_)*v_n/te(ix^d)
3570 if(te(ix^d)>
rc_fl%tcoolmin .and. te(ix^d)<
rc_fl%tcoolmax)
then
3571 call findl(te(ix^d),l1,
rc_fl); cooling=l1*ne(ix^d)*nh_arr(ix^d)
3572 else if(te(ix^d)>=
rc_fl%tcoolmax)
then
3573 call calc_l_extended(te(ix^d),l1,
rc_fl); cooling=l1*ne(ix^d)*nh_arr(ix^d)
3577 net_cool=dabs(cooling-q_heat(ix^d))
3578 kappa_par=
tc_fl%tc_k_para*te(ix^d)**2.5d0
3579 disc=a_coeff**2+4.d0*
tc_fl%tc_k_para*te(ix^d)**1.5d0*net_cool
3582 if(l_t<=2.d0*dx_over_delta)
then
3583 kappa_trac=(a_coeff+dsqrt(disc))/(2.d0/dx_over_delta)
3585 kappa_trac=dsqrt(4.d0*
tc_fl%tc_k_para*te(ix^d)**1.5d0*net_cool)/(2.d0/dx_over_delta)
3587 kappa_eff=max(kappa_trac,kappa_par)
3588 tcoff_eff=(kappa_eff/
tc_fl%tc_k_para)**0.4d0
3589 block%wextra(ix^d,
tcoff_)=max(te(ix^d),tcoff_eff)
3595 call mpistop(
"unknown mhd_trac_type")
3598 end subroutine mhd_get_tcutoff
3601 subroutine mhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
3604 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3605 double precision,
intent(in) :: wprim(ixi^s, nw)
3606 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3607 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
3609 double precision :: csound(ixi^s,
ndim)
3610 double precision,
allocatable :: tmp(:^
d&)
3611 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
3615 allocate(tmp(ixa^s))
3618 call mhd_get_csound_prim_split(wprim,x,ixi^
l,ixa^
l,id,tmp)
3620 call mhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
3622 csound(ixa^s,id)=tmp(ixa^s)
3625 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
3626 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
3627 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
3628 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))
3632 ixamax^
d=ixcmax^
d+
kr(id,^
d);
3633 ixamin^
d=ixcmin^
d+
kr(id,^
d);
3634 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)))
3635 ixamax^
d=ixcmax^
d-
kr(id,^
d);
3636 ixamin^
d=ixcmin^
d-
kr(id,^
d);
3637 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)))
3642 ixamax^
d=jxcmax^
d+
kr(id,^
d);
3643 ixamin^
d=jxcmin^
d+
kr(id,^
d);
3644 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)))
3645 ixamax^
d=jxcmax^
d-
kr(id,^
d);
3646 ixamin^
d=jxcmin^
d-
kr(id,^
d);
3647 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)))
3651 end subroutine mhd_get_h_speed
3654 subroutine mhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3658 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3659 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3660 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3661 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3662 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3663 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3664 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3666 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3668 double precision :: umean, dmean, tmp1, tmp2, tmp3
3675 call mhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3676 call mhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3681 if(
present(cmin))
then
3682 {
do ix^db=ixomin^db,ixomax^db\}
3683 tmp1=sqrt(wlp(ix^
d,
rho_))
3684 tmp2=sqrt(wrp(ix^
d,
rho_))
3685 tmp3=1.d0/(tmp1+tmp2)
3686 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3687 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3688 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3689 cmin(ix^
d,1)=umean-dmean
3690 cmax(ix^
d,1)=umean+dmean
3697 if(h_correction)
then
3698 {
do ix^db=ixomin^db,ixomax^db\}
3699 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3700 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3704 {
do ix^db=ixomin^db,ixomax^db\}
3705 tmp1=sqrt(wlp(ix^d,
rho_))
3706 tmp2=sqrt(wrp(ix^d,
rho_))
3707 tmp3=1.d0/(tmp1+tmp2)
3708 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3709 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3710 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3711 cmax(ix^d,1)=abs(umean)+dmean
3719 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3720 call mhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
3724 if(
present(cmin))
then
3725 {
do ix^db=ixomin^db,ixomax^db\}
3726 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3727 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3734 if(h_correction)
then
3735 {
do ix^db=ixomin^db,ixomax^db\}
3736 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3737 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3741 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3749 call mhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
3750 call mhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
3755 if(
present(cmin))
then
3756 {
do ix^db=ixomin^db,ixomax^db\}
3757 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3758 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3759 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3766 if(h_correction)
then
3767 {
do ix^db=ixomin^db,ixomax^db\}
3768 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3769 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3773 {
do ix^db=ixomin^db,ixomax^db\}
3774 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3775 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3784 end subroutine mhd_get_cbounds
3787 subroutine mhd_get_cbounds_semirelati(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3790 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3791 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3792 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3793 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3794 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3795 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3796 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3798 double precision,
dimension(ixO^S) :: csoundl, csoundr, gamma2l, gamma2r
3803 call mhd_get_csound_semirelati(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3804 call mhd_get_csound_semirelati(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3806 call mhd_get_csound_semirelati_noe(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3807 call mhd_get_csound_semirelati_noe(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3809 if(
present(cmin))
then
3810 {
do ix^db=ixomin^db,ixomax^db\}
3811 csoundl(ix^
d)=max(csoundl(ix^
d),csoundr(ix^
d))
3812 cmin(ix^
d,1)=min(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))-csoundl(ix^
d)
3813 cmax(ix^
d,1)=max(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))+csoundl(ix^
d)
3816 {
do ix^db=ixomin^db,ixomax^db\}
3817 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3818 cmax(ix^d,1)=max(gamma2l(ix^d)*wlp(ix^d,
mom(idim)),gamma2r(ix^d)*wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3822 end subroutine mhd_get_cbounds_semirelati
3825 subroutine mhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3828 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3829 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3830 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3831 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3832 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3833 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3834 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3836 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3837 double precision :: umean, dmean, tmp1, tmp2, tmp3
3844 call mhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3845 call mhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3846 if(
present(cmin))
then
3847 {
do ix^db=ixomin^db,ixomax^db\}
3850 tmp3=1.d0/(tmp1+tmp2)
3851 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3852 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3853 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3854 cmin(ix^
d,1)=umean-dmean
3855 cmax(ix^
d,1)=umean+dmean
3857 if(h_correction)
then
3858 {
do ix^db=ixomin^db,ixomax^db\}
3859 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3860 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3864 {
do ix^db=ixomin^db,ixomax^db\}
3867 tmp3=1.d0/(tmp1+tmp2)
3868 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3869 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3870 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3871 cmax(ix^d,1)=abs(umean)+dmean
3875 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3876 call mhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
3877 if(
present(cmin))
then
3878 {
do ix^db=ixomin^db,ixomax^db\}
3879 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3880 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3882 if(h_correction)
then
3883 {
do ix^db=ixomin^db,ixomax^db\}
3884 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3885 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3889 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3893 call mhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
3894 call mhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
3895 if(
present(cmin))
then
3896 {
do ix^db=ixomin^db,ixomax^db\}
3897 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3898 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3899 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3901 if(h_correction)
then
3902 {
do ix^db=ixomin^db,ixomax^db\}
3903 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3904 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3908 {
do ix^db=ixomin^db,ixomax^db\}
3909 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3910 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3915 end subroutine mhd_get_cbounds_split_rho
3918 subroutine mhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3921 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3922 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3923 double precision,
intent(in) :: cmax(ixi^s)
3924 double precision,
intent(in),
optional :: cmin(ixi^s)
3925 type(ct_velocity),
intent(inout):: vcts
3927 end subroutine mhd_get_ct_velocity_average
3929 subroutine mhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3932 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3933 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3934 double precision,
intent(in) :: cmax(ixi^s)
3935 double precision,
intent(in),
optional :: cmin(ixi^s)
3936 type(ct_velocity),
intent(inout):: vcts
3938 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
3940 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
3942 end subroutine mhd_get_ct_velocity_contact
3944 subroutine mhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3947 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3948 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3949 double precision,
intent(in) :: cmax(ixi^s)
3950 double precision,
intent(in),
optional :: cmin(ixi^s)
3951 type(ct_velocity),
intent(inout):: vcts
3953 integer :: idime,idimn
3955 if(.not.
allocated(vcts%vbarC))
then
3956 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
3957 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
3960 if(
present(cmin))
then
3961 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
3962 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3964 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3965 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
3968 idimn=mod(idim,
ndir)+1
3969 idime=mod(idim+1,
ndir)+1
3971 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
3972 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
3973 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
3974 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
3975 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3977 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
3978 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
3979 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
3980 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,2))&
3981 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3983 end subroutine mhd_get_ct_velocity_hll
3990 integer,
intent(in) :: ixi^
l, ixo^
l
3991 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3992 double precision,
intent(out):: csound(ixi^s)
3994 double precision :: wprim(ixi^s, nw)
3996 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
3997 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
4009 integer,
intent(in) :: ixi^
l, ixo^
l
4010 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4011 double precision,
intent(out):: csound(ixi^s)
4013 double precision :: inv_rho, b2
4014 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
4015 double precision :: prad_max(ixi^s)
4016 integer :: ix^
d,idim
4023 prad_tensor(ixo^s,idim,idim)=w(ixo^s,
r_e)/3.0d0
4028 {
do ix^db=ixomin^db,ixomax^db \}
4029 inv_rho=1.d0/w(ix^
d,
rho_)
4030 prad_max(ix^
d) = (4.0d0/3.0d0)*maxval(prad_tensor(ix^
d,:,:))
4032 csound(ix^
d)=(eos%gamma*w(ix^
d,
p_)+b2+prad_max(ix^
d))*inv_rho
4035 {
do ix^db=ixomin^db,ixomax^db \}
4036 inv_rho=1.d0/w(ix^d,
rho_)
4037 prad_max(ix^d) = (4.0d0/3.0d0)*maxval(prad_tensor(ix^d,:,:))
4038 b2=(^
c&w(ix^d,
b^
c_)**2+)
4039 csound(ix^d)=(eos%gamma*w(ix^d,
p_)+b2+prad_max(ix^d))*inv_rho
4043 if(minval(csound(ixo^s))<smalldouble)
then
4044 print *,
'issue with squared speed and rad pressure'
4045 print *,minval(csound(ixo^s))
4046 print *,minval(prad_max(ixo^s))
4047 call mpistop(
"negative squared speed in get_csrad2 for dt")
4053 subroutine mhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
4058 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4059 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4060 double precision,
intent(out):: csound(ixo^s)
4062 double precision :: adiabs(ixi^s), gammas(ixi^s)
4063 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
4064 double precision :: cs2(ixi^s)
4068 call mhd_uawsom_get_signal_speed(w,x,ixi^
l,ixo^
l,idim,csound)
4076 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
4092 {
do ix^db=ixomin^db,ixomax^db \}
4093 inv_rho=1.d0/w(ix^
d,
rho_)
4097 cs2(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
4100 cfast2=b2*inv_rho+cs2(ix^
d)
4101 avmincs2=cfast2**2-4.0d0*cs2(ix^
d)*(w(ix^
d,mag(idim))+&
4103 if(avmincs2<zero) avmincs2=zero
4104 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4106 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4110 {
do ix^db=ixomin^db,ixomax^db \}
4111 inv_rho=1.d0/w(ix^d,
rho_)
4115 cs2(ix^d)=gammas(ix^d)*adiabs(ix^d)*w(ix^d,
rho_)**(gammas(ix^d)-1.d0)
4117 b2=(^
c&w(ix^d,
b^
c_)**2+)
4118 cfast2=b2*inv_rho+cs2(ix^d)
4119 avmincs2=cfast2**2-4.0d0*cs2(ix^d)*w(ix^d,mag(idim))**2*inv_rho
4120 if(avmincs2<zero) avmincs2=zero
4121 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4123 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4128 end subroutine mhd_get_csound_prim
4132 subroutine mhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
4135 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4136 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4137 double precision,
intent(out):: csound(ixo^s)
4139 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
4146 {
do ix^db=ixomin^db,ixomax^db \}
4151 cfast2=b2*inv_rho+csound(ix^
d)
4152 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
4154 if(avmincs2<zero) avmincs2=zero
4155 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4157 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4161 {
do ix^db=ixomin^db,ixomax^db \}
4164 csound(ix^d)=eos%gamma*(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i))*inv_rho
4165 b2=(^
c&w(ix^d,
b^
c_)**2+)
4166 cfast2=b2*inv_rho+csound(ix^d)
4167 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
4168 if(avmincs2<zero) avmincs2=zero
4169 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
4171 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
4176 end subroutine mhd_get_csound_prim_split
4179 subroutine mhd_get_csound_semirelati(w,x,ixI^L,ixO^L,idim,csound,gamma2)
4182 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4184 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4185 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
4187 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
4188 double precision :: cs2(ixi^s)
4192 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
4194 {
do ix^db=ixomin^db,ixomax^db\}
4195 inv_rho = 1.d0/w(ix^
d,
rho_)
4199 idim_alfven_speed2=(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
4201 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
4202 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
4204 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
4205 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
4208 alfven_speed2=alfven_speed2*avmincs2+cs2(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
4209 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*cs2(ix^
d)*idim_alfven_speed2*avmincs2
4210 if(avmincs2<zero) avmincs2=zero
4212 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
4215 end subroutine mhd_get_csound_semirelati
4218 subroutine mhd_get_csound_semirelati_noe(w,x,ixI^L,ixO^L,idim,csound,gamma2)
4222 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4224 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
4225 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
4227 double precision :: adiabs(ixi^s), gammas(ixi^s)
4228 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
4241 {
do ix^db=ixomin^db,ixomax^db\}
4242 inv_rho = 1.d0/w(ix^
d,
rho_)
4244 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
4245 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
4246 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
4247 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
4248 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
4251 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
4252 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
4253 if(avmincs2<zero) avmincs2=zero
4255 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
4258 end subroutine mhd_get_csound_semirelati_noe
4271 integer,
intent(in) :: ixi^
l, ixo^
l
4272 double precision,
intent(in) :: w(ixi^s, 1:nw)
4273 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4274 double precision,
intent(out):: prad(ixi^s, 1:
ndim, 1:
ndim)
4283 integer,
intent(in) :: ixi^
l, ixo^
l
4284 double precision,
intent(in) :: w(ixi^s, 1:nw)
4285 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4286 double precision,
intent(out) :: pth_plus_prad(ixi^s)
4288 double precision :: wprim(ixi^s, 1:nw)
4289 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
4290 double precision :: prad_max(ixi^s)
4293 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
4294 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
4296 {
do ix^
d = ixomin^
d,ixomax^
d\}
4297 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
4299 pth_plus_prad(ixo^s) = wprim(ixo^s,
p_) + prad_max(ixo^s)
4307 integer,
intent(in) :: ixi^
l, ixo^
l
4308 double precision,
intent(in) :: w(ixi^s, 1:nw)
4309 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4310 double precision,
intent(out):: trad(ixi^s)
4317 subroutine mhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
4321 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4323 double precision,
intent(in) :: wc(ixi^s,nw)
4325 double precision,
intent(in) :: w(ixi^s,nw)
4326 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4327 double precision,
intent(out) :: f(ixi^s,nwflux)
4329 double precision :: vhall(ixi^s,1:
ndir)
4330 double precision :: ptotal
4331 double precision :: nperp(ixi^s,1:
ndir)
4332 double precision :: uawsom_zeta(ixi^s), uawsom_radius(ixi^s)
4333 double precision :: uawsom_lperp(ixi^s), uawsom_denom
4334 double precision :: uawsom_pwave, uawsom_bi
4335 double precision :: bunit_tc(
ndir)
4338 if(
mhd_uawsom)
call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.true.,&
4339 uawsom_zeta,uawsom_radius,uawsom_lperp)
4342 {
do ix^db=ixomin^db,ixomax^db\}
4355 {
do ix^db=ixomin^db,ixomax^db\}
4359 ^
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_)\
4360 ptotal=w(ix^d,
p_)+half*(^
c&w(ix^d,
b^
c_)**2+)
4363 ptotal=ptotal+uawsom_pwave
4366 f(ix^d,
mom(idim))=f(ix^d,
mom(idim))+ptotal
4369 f(ix^d,
e_)=w(ix^d,
mom(idim))*(wc(ix^d,
e_)+ptotal)&
4370 -w(ix^d,mag(idim))*(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)
4372 uawsom_denom=dsqrt(w(ix^d,
rho_)*(uawsom_zeta(ix^d)+one)/&
4375 uawsom_bi=w(ix^d,mag(idim))
4376 f(ix^d,
e_)=f(ix^d,
e_)+uawsom_bi*(&
4381 ^
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_)\
4385 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4386 {
do ix^db=ixomin^db,ixomax^db\}
4387 if(total_energy)
then
4389 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)**2+)&
4390 -w(ix^d,mag(idim))*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
4393 ^
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))\
4398 {
do ix^db=ixomin^db,ixomax^db\}
4399 f(ix^d,mag(idim))=w(ix^d,
psi_)
4401 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4406 {
do ix^db=ixomin^db,ixomax^db\}
4407 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
4412 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4415 {
do ix^db=ixomin^db,ixomax^db\}
4416 uawsom_denom=dsqrt(w(ix^d,
rho_)*(uawsom_zeta(ix^d)+one)/&
4419 uawsom_bi=w(ix^d,mag(idim))
4421 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4423 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4430 {
do ix^db=ixomin^db,ixomax^db\}
4436 {
do ix^db=ixomin^db,ixomax^db\}
4437 bunit_tc=b_unit_vector(w(ix^d,mag(1:ndir)))
4438 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*bunit_tc(idim)
4442 call mhd_get_hyperbolic_tc_nperp(w,x,ixi^l,ixo^l,w(ixi^s,mag(1:ndir)),nperp)
4443 {
do ix^db=ixomin^db,ixomax^db\}
4444 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4449 end subroutine mhd_get_flux
4453 subroutine mhd_get_flux_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4458 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4460 double precision,
intent(in) :: wc(ixi^s,nw)
4462 double precision,
intent(in) :: w(ixi^s,nw)
4463 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4464 double precision,
intent(out) :: f(ixi^s,nwflux)
4466 double precision :: vhall(ixi^s,1:
ndir)
4467 double precision :: adiabs(ixi^s), gammas(ixi^s)
4480 {
do ix^db=ixomin^db,ixomax^db\}
4486 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+)
4491 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4492 {
do ix^db=ixomin^db,ixomax^db\}
4494 ^
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))\
4498 {
do ix^db=ixomin^db,ixomax^db\}
4499 f(ix^d,mag(idim))=w(ix^d,
psi_)
4501 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4505 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4509 {
do ix^db=ixomin^db,ixomax^db\}
4513 end subroutine mhd_get_flux_noe
4516 subroutine mhd_get_flux_hde(wC,w,x,ixI^L,ixO^L,idim,f)
4520 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4522 double precision,
intent(in) :: wc(ixi^s,nw)
4524 double precision,
intent(in) :: w(ixi^s,nw)
4525 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4526 double precision,
intent(out) :: f(ixi^s,nwflux)
4528 double precision :: vhall(ixi^s,1:
ndir)
4529 double precision :: nperp(ixi^s,1:
ndir)
4530 double precision :: bunit_tc(
ndir)
4533 {
do ix^db=ixomin^db,ixomax^db\}
4546 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4547 {
do ix^db=ixomin^db,ixomax^db\}
4549 ^
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))\
4553 {
do ix^db=ixomin^db,ixomax^db\}
4554 f(ix^d,mag(idim))=w(ix^d,
psi_)
4556 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4560 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4564 {
do ix^db=ixomin^db,ixomax^db\}
4570 {
do ix^db=ixomin^db,ixomax^db\}
4571 bunit_tc=b_unit_vector(w(ix^d,mag(1:ndir)))
4572 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*bunit_tc(idim)
4576 call mhd_get_hyperbolic_tc_nperp(w,x,ixi^l,ixo^l,w(ixi^s,mag(1:ndir)),nperp)
4577 {
do ix^db=ixomin^db,ixomax^db\}
4578 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4584 end subroutine mhd_get_flux_hde
4591 subroutine mhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
4595 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4597 double precision,
intent(in) :: wc(ixi^s,nw)
4599 double precision,
intent(in) :: w(ixi^s,nw)
4600 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4601 double precision,
intent(out) :: f(ixi^s,nwflux)
4603 double precision :: vhall(ixi^s,1:
ndir)
4604 double precision :: ptotal, btotal(ixo^s,1:
ndir)
4605 double precision :: nperp(ixi^s,1:
ndir)
4606 double precision :: uawsom_zeta(ixi^s), uawsom_radius(ixi^s)
4607 double precision :: uawsom_lperp(ixi^s), uawsom_denom
4608 double precision :: uawsom_pwave, uawsom_bi
4609 double precision :: bunit_tc(
ndir)
4610 logical :: use_perp_flux
4613 if(
mhd_uawsom)
call mhd_uawsom_get_coefficients(w,x,ixi^
l,ixo^
l,.true.,&
4614 uawsom_zeta,uawsom_radius,uawsom_lperp)
4616 {
do ix^db=ixomin^db,ixomax^db\}
4624 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
4628 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
4632 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
4633 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
4635 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
4639 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
4643 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+uawsom_pwave
4646 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
4653 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
4654 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
4656 uawsom_denom=dsqrt(w(ix^
d,
rho_)*(uawsom_zeta(ix^
d)+one)/&
4659 uawsom_bi=btotal(ix^
d,idim)
4660 f(ix^
d,
e_)=f(ix^
d,
e_)+w(ix^
d,
mom(idim))*uawsom_pwave+uawsom_bi*(&
4668 {
do ix^db=ixomin^db,ixomax^db\}
4669 f(ix^d,mag(idim))=w(ix^d,
psi_)
4671 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4676 {
do ix^db=ixomin^db,ixomax^db\}
4677 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
4682 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4683 {
do ix^db=ixomin^db,ixomax^db\}
4685 ^
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)\
4686 if(total_energy)
then
4688 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)*btotal(ix^d,^
c)+)&
4689 -btotal(ix^d,idim)*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
4694 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4697 {
do ix^db=ixomin^db,ixomax^db\}
4698 uawsom_denom=dsqrt(w(ix^d,
rho_)*(uawsom_zeta(ix^d)+one)/&
4701 uawsom_bi=btotal(ix^d,idim)
4703 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4705 uawsom_bi/dsqrt(w(ix^d,
rho_)))
4712 {
do ix^db=ixomin^db,ixomax^db\}
4718 {
do ix^db=ixomin^db,ixomax^db\}
4719 bunit_tc=b_unit_vector(btotal(ix^d,1:ndir))
4720 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*bunit_tc(idim)
4724 call mhd_get_hyperbolic_tc_nperp(w,x,ixi^l,ixo^l,btotal,nperp)
4725 {
do ix^db=ixomin^db,ixomax^db\}
4726 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4732 end subroutine mhd_get_flux_split
4735 subroutine mhd_get_flux_semirelati(wC,w,x,ixI^L,ixO^L,idim,f)
4739 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4741 double precision,
intent(in) :: wc(ixi^s,nw)
4743 double precision,
intent(in) :: w(ixi^s,nw)
4744 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4745 double precision,
intent(out) :: f(ixi^s,nwflux)
4746 double precision :: sa(ixo^s,1:
ndir),e(ixo^s,1:
ndir),e2
4747 double precision :: btf(ixi^s,1:
ndir),b0sq,btsq
4748 double precision :: nperp(ixi^s,1:
ndir)
4749 double precision :: bunit_tc(
ndir)
4752 {
do ix^db=ixomin^db,ixomax^db\}
4763 e(ix^
d,1)=btf(ix^
d,2)*w(ix^
d,m3_)-btf(ix^
d,3)*w(ix^
d,m2_)
4764 e(ix^
d,2)=btf(ix^
d,3)*w(ix^
d,m1_)-btf(ix^
d,1)*w(ix^
d,m3_)
4765 e(ix^
d,3)=btf(ix^
d,1)*w(ix^
d,m2_)-btf(ix^
d,2)*w(ix^
d,m1_)
4770 e(ix^
d,2)=btf(ix^
d,1)*w(ix^
d,m2_)-btf(ix^
d,2)*w(ix^
d,m1_)
4775 e2=(^
c&e(ix^
d,^
c)**2+)
4782 sa(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
4783 sa(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
4784 sa(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
4787 sa(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
4788 sa(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
4798 -half*((^
c&w(ix^
d,
b^
c_)**2+)+e2*inv_squared_c)&
4799 +w(ix^
d,
p_))+sa(ix^
d,idim)
4805 -btf(ix^
d,idim)*btf(ix^
d,^
c)+
block%B0(ix^
d,idim,idim)*
block%B0(ix^
d,^
c,idim)&
4806 -e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4807 b0sq=(^
c&
block%B0(ix^
d,^
c,idim)**2+)
4808 btsq=(^
c&btf(ix^
d,^
c)**2+)
4809 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+w(ix^
d,
p_)+half*(btsq-b0sq+e2*inv_squared_c)
4812 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4814 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)
4818 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btf(ix^
d,^
c)-btf(ix^
d,idim)*w(ix^
d,
m^
c_)\
4822 {
do ix^db=ixomin^db,ixomax^db\}
4823 f(ix^d,mag(idim))=w(ix^d,
psi_)
4825 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4829 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4833 {
do ix^db=ixomin^db,ixomax^db\}
4839 {
do ix^db=ixomin^db,ixomax^db\}
4840 bunit_tc=b_unit_vector(btf(ix^d,1:ndir))
4841 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*bunit_tc(idim)
4845 call mhd_get_hyperbolic_tc_nperp(w,x,ixi^l,ixo^l,btf,nperp)
4846 {
do ix^db=ixomin^db,ixomax^db\}
4847 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4852 end subroutine mhd_get_flux_semirelati
4854 subroutine mhd_get_flux_semirelati_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4859 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4861 double precision,
intent(in) :: wc(ixi^s,nw)
4863 double precision,
intent(in) :: w(ixi^s,nw)
4864 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4865 double precision,
intent(out) :: f(ixi^s,nwflux)
4867 double precision :: adiabs(ixi^s), gammas(ixi^s)
4868 double precision :: e(ixo^s,1:
ndir),e2
4881 {
do ix^db=ixomin^db,ixomax^db\}
4886 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4887 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4888 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4889 e2=(^
c&e(ix^
d,^
c)**2+)
4894 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4904 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4906 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)
4913 {
do ix^db=ixomin^db,ixomax^db\}
4914 f(ix^d,mag(idim))=w(ix^d,
psi_)
4916 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4920 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4924 {
do ix^db=ixomin^db,ixomax^db\}
4928 end subroutine mhd_get_flux_semirelati_noe
4936 subroutine add_source_ambipolar_internal_energy(qdt,ixI^L,ixO^L,wCT,w,x)
4938 integer,
intent(in) :: ixi^
l, ixo^
l
4939 double precision,
intent(in) :: qdt
4940 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
4941 double precision,
intent(inout) :: w(ixi^s,1:nw)
4943 double precision :: tmp(ixi^s),btot2(ixi^s)
4944 double precision :: jxbxb(ixi^s,1:3)
4946 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,jxbxb)
4949 where (btot2(ixo^s)>smalldouble )
4950 tmp(ixo^s) = sum(jxbxb(ixo^s,1:3)**2,dim=
ndim+1) / btot2(ixo^s)
4957 w(ixo^s,
e_)=w(ixo^s,
e_)- qdt*tmp(ixo^s)
4959 end subroutine add_source_ambipolar_internal_energy
4962 subroutine mhd_get_jxbxb(w,x,ixI^L,ixO^L,res)
4965 integer,
intent(in) :: ixi^
l, ixo^
l
4966 double precision,
intent(in) :: w(ixi^s,nw)
4967 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4968 double precision,
intent(out) :: res(ixi^s,1:3)
4970 double precision :: btot(ixi^s,1:3)
4971 double precision :: current(ixi^s,7-2*
ndir:3)
4972 double precision :: tmp(ixi^s),b2(ixi^s)
4973 integer :: idir, idirmin
4983 btot(ixo^s, idir) = w(ixo^s,mag(idir)) +
block%B0(ixo^s,idir,
b0i)
4987 btot(ixo^s, idir) = w(ixo^s,mag(idir))
4991 tmp(ixo^s)= sum(current(ixo^s,idirmin:3)*btot(ixo^s,idirmin:3),dim=
ndim+1)
4992 b2(ixo^s) = sum(btot(ixo^s,1:3)**2,dim=
ndim+1)
4994 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s)
4997 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s) - current(ixo^s,idir) * b2(ixo^s)
5002 where (b2(ixo^s)<smalldouble )
5003 res(ixo^s,idir) = zero
5006 end subroutine mhd_get_jxbxb
5012 subroutine sts_set_source_ambipolar(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
5016 integer,
intent(in) :: ixi^
l,ixo^
l,igrid,nflux
5017 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5018 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
5019 double precision,
intent(in) :: my_dt
5020 logical,
intent(in) :: fix_conserve_at_step
5022 double precision,
dimension(ixI^S,1:3) :: tmp,ff
5023 double precision :: fluxall(ixi^s,1:nflux,1:
ndim)
5024 double precision :: fe(ixi^s,
sdim:3)
5025 double precision :: btot(ixi^s,1:3),tmp2(ixi^s)
5026 integer :: i, ixa^
l, ie_
5033 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,tmp)
5050 btot(ixa^s,1:3) = 0.d0
5052 btot(ixa^s,1:
ndir) = w(ixa^s,mag(1:
ndir))
5056 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5057 if(fix_conserve_at_step) fluxall(ixi^s,1,1:
ndim)=ff(ixi^s,1:
ndim)
5059 wres(ixo^s,
e_)=-tmp2(ixo^s)
5066 ff(ixa^s,1) = tmp(ixa^s,2)
5067 ff(ixa^s,2) = -tmp(ixa^s,1)
5069 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5070 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
5071 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
5074 call update_faces_ambipolar(ixi^
l,ixo^
l,w,x,tmp,fe,btot)
5076 ixamin^
d=ixomin^
d-1;
5077 wres(ixa^s,mag(1:
ndim))=-btot(ixa^s,1:
ndim)
5087 ff(ixa^s,2) = tmp(ixa^s,3)
5088 ff(ixa^s,3) = -tmp(ixa^s,2)
5089 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5090 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
5092 wres(ixo^s,mag(1))=-tmp2(ixo^s)
5095 ff(ixa^s,1) = -tmp(ixa^s,3)
5097 ff(ixa^s,3) = tmp(ixa^s,1)
5098 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5099 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
5100 wres(ixo^s,mag(2))=-tmp2(ixo^s)
5106 ff(ixa^s,2) = tmp(ixa^s,3)
5107 ff(ixa^s,3) = -tmp(ixa^s,2)
5108 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5109 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
5111 wres(ixo^s,mag(1))=-tmp2(ixo^s)
5113 ff(ixa^s,1) = -tmp(ixa^s,3)
5115 ff(ixa^s,3) = tmp(ixa^s,1)
5116 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5117 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
5118 wres(ixo^s,mag(2))=-tmp2(ixo^s)
5123 ff(ixa^s,1) = tmp(ixa^s,2)
5124 ff(ixa^s,2) = -tmp(ixa^s,1)
5126 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
5127 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
5128 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
5133 if(fix_conserve_at_step)
then
5134 fluxall=my_dt*fluxall
5141 end subroutine sts_set_source_ambipolar
5144 subroutine update_faces_ambipolar(ixI^L,ixO^L,w,x,ECC,fE,circ)
5147 integer,
intent(in) :: ixi^
l, ixo^
l
5148 double precision,
intent(in) :: w(ixi^s,1:nw)
5149 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5151 double precision,
intent(in) :: ecc(ixi^s,1:3)
5152 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
5153 double precision,
intent(out) :: circ(ixi^s,1:
ndim)
5155 integer :: hxc^
l,ixc^
l,ixa^
l
5156 integer :: idim1,idim2,idir,ix^
d
5162 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
5164 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
5165 ixamin^
d=ixcmin^
d+ix^
d;
5166 ixamax^
d=ixcmax^
d+ix^
d;
5167 fe(ixc^s,idir)=fe(ixc^s,idir)+ecc(ixa^s,idir)
5169 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0*block%dsC(ixc^s,idir)
5175 ixcmin^d=ixomin^d-1;
5182 hxc^l=ixc^l-kr(idim2,^d);
5184 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
5185 +lvc(idim1,idim2,idir)&
5190 circ(ixc^s,idim1)=circ(ixc^s,idim1)/block%surfaceC(ixc^s,idim1)
5193 end subroutine update_faces_ambipolar
5199 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
5202 integer,
intent(in) :: ixi^
l, ixo^
l
5203 double precision,
dimension(ixI^S,1:3),
intent(inout) :: ff
5204 double precision,
intent(out) :: src(ixi^s)
5206 double precision :: ffc(ixi^s,1:
ndim)
5207 double precision :: dxinv(
ndim)
5208 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
5216 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
5218 ixbmin^
d=ixcmin^
d+ix^
d;
5219 ixbmax^
d=ixcmax^
d+ix^
d;
5222 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
5224 call mpistop(
"to generalize using volume averaging")
5227 ff(ixi^s,1:ndim)=0.d0
5229 ixb^l=ixo^l-kr(idims,^d);
5230 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
5232 if({ ix^d==0 .and. ^d==idims | .or.})
then
5233 ixbmin^d=ixcmin^d-ix^d;
5234 ixbmax^d=ixcmax^d-ix^d;
5235 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
5238 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
5241 if(slab_uniform)
then
5243 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
5244 ixb^l=ixo^l-kr(idims,^d);
5245 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
5249 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
5250 ixb^l=ixo^l-kr(idims,^d);
5251 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
5253 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
5255 end subroutine get_flux_on_cell_face
5259 function get_ambipolar_dt(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
5262 integer,
intent(in) :: ixi^
l, ixo^
l
5263 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
5264 double precision,
intent(in) :: w(ixi^s,1:nw)
5265 double precision :: dtnew
5267 double precision :: coef
5268 double precision :: dxarr(
ndim)
5269 double precision :: tmp(ixi^s)
5275 coef = maxval(dabs(tmp(ixo^s)))
5282 dtnew=minval(dxarr(1:
ndim))**2.0d0*coef
5284 dtnew=minval(
block%ds(ixo^s,1:
ndim))**2.0d0*coef
5287 end function get_ambipolar_dt
5295 integer,
intent(in) :: ixi^
l, ixo^
l
5296 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
5297 double precision,
intent(inout) :: res(ixi^s)
5298 double precision :: tmp(ixi^s)
5299 double precision :: rho(ixi^s)
5306 res(ixo^s) = tmp(ixo^s) * res(ixo^s)
5311 subroutine mhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
5318 integer,
intent(in) :: ixi^
l, ixo^
l
5319 double precision,
intent(in) :: qdt,dtfactor
5320 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
5321 double precision,
intent(inout) :: w(ixi^s,1:nw)
5322 logical,
intent(in) :: qsourcesplit
5323 logical,
intent(inout) :: active
5330 if (.not. qsourcesplit)
then
5333 call mhd_add_source_uawsom(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x)
5338 call add_source_internal_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5342 call add_equi_terms(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
5348 call add_source_hyperbolic_tc(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5357 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
5361 if (abs(
mhd_eta)>smalldouble)
then
5363 call add_source_res_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
5368 call add_source_ambi_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
5373 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
5379 call add_source_hydrodynamic_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5383 call add_source_semirelativistic(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5390 select case (type_divb)
5395 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5398 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
5401 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5402 case (divb_janhunen)
5404 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5405 case (divb_lindejanhunen)
5407 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5408 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5409 case (divb_lindepowel)
5411 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5412 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5413 case (divb_lindeglm)
5415 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5416 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
5417 case (divb_multigrid)
5422 call mpistop(
'Unknown divB fix')
5429 w,x,qsourcesplit,active,
rc_fl)
5445 w,x,gravity_energy,qsourcesplit,active)
5454 call mhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x,qsourcesplit,active)
5457 end subroutine mhd_add_source
5459 subroutine mhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
5465 integer,
intent(in) :: ixi^
l, ixo^
l
5466 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
5467 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw)
5468 double precision,
intent(inout) :: w(ixi^s,1:nw)
5469 logical,
intent(in) :: qsourcesplit
5470 logical,
intent(inout) :: active
5476 end subroutine mhd_add_radiation_source
5479 subroutine add_equi_terms(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
5484 integer,
intent(in) :: ixi^
l, ixo^
l
5485 double precision,
intent(in) :: qdt,dtfactor
5486 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5487 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5488 double precision,
intent(inout) :: w(ixi^s,1:nw)
5490 double precision :: divv(ixi^s)
5491 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
5492 double precision :: gravity_field(ixi^s,1:
ndim)
5504 divv(ixo^s)=divv(ixo^s)*eos%gamma*eos%inv_gamma_minus_1
5515 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
5524 a(ixo^s,idir)=
block%J0(ixo^s,idir)
5529 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*axb(ixo^s,idir)*eos%inv_gamma_minus_1
5535 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
5544 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
5548 end subroutine add_equi_terms
5554 pure function b_unit_vector(B)
result(bunit)
5557 double precision,
intent(in) ::
b(:)
5558 double precision :: bunit(^nc), maxm, scaled_norm
5564 ^
c&bunit(^
c)=
b(^
c)/maxm\
5565 scaled_norm=dsqrt(^
c&bunit(^
c)**2+)
5567 ^
c&bunit(^
c)=bunit(^
c)/scaled_norm\
5569 end function b_unit_vector
5571 subroutine mhd_get_hyperbolic_tc_nperp(w,x,ixI^L,ixO^L,Bvec,nperp)
5574 integer,
intent(in) :: ixi^
l,ixo^
l
5575 double precision,
intent(in) :: w(ixi^s,nw)
5576 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5577 double precision,
intent(in) :: bvec(ixi^s,1:
ndir)
5578 double precision,
intent(out) :: nperp(ixi^s,1:
ndir)
5580 double precision :: r(ixi^s), te(ixi^s), bgradt
5581 double precision :: bunitvec(
ndir), gradt(ixi^s,
ndir), gradt_perp(
ndir)
5582 integer :: ix^
d, idir
5585 call eos%get_Rfactor(w,x,ixi^
l,ixi^
l,r)
5586 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*r(ixi^s))
5589 call gradient(te,ixi^
l,ixo^
l,idir,gradt(ixi^s,idir))
5595 do ix2=ixomin2,ixomax2
5596 do ix1=ixomin1,ixomax1
5597 bunitvec=b_unit_vector(bvec(ix^
d,1:
ndir))
5599 gradt(ix^
d,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)
5600 gradt(ix^
d,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)
5604 bgradt=(^
c&bunitvec(^
c)*gradt(ix^
d,^
c)+)
5605 {^
c& gradt_perp(^
c)=gradt(ix^
d,^
c)-bgradt*bunitvec(^
c)\}
5606 nperp(ix^
d,1:
ndir)=b_unit_vector(gradt_perp(1:
ndir))
5611 do ix3=ixomin3,ixomax3
5612 do ix2=ixomin2,ixomax2
5613 do ix1=ixomin1,ixomax1
5614 bunitvec=b_unit_vector(bvec(ix^
d,1:
ndir))
5617 gradt(ix^
d,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)
5618 gradt(ix^
d,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)
5619 gradt(ix^
d,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)
5622 bgradt=(^
c&bunitvec(^
c)*gradt(ix^
d,^
c)+)
5623 {^
c& gradt_perp(^
c)=gradt(ix^
d,^
c)-bgradt*bunitvec(^
c)\}
5624 nperp(ix^
d,1:
ndir)=b_unit_vector(gradt_perp(1:
ndir))
5629 end subroutine mhd_get_hyperbolic_tc_nperp
5631 subroutine mhd_get_hyperbolic_tc_geometry(ixI^L,ixO^L,Te,Bvec,bgradT,gradTperp_mag,nperp)
5634 integer,
intent(in) :: ixi^
l,ixo^
l
5635 double precision,
intent(in) :: te(ixi^s)
5636 double precision,
intent(in) :: bvec(ixi^s,1:
ndir)
5637 double precision,
intent(out) :: bgradt(ixi^s), gradtperp_mag(ixi^s)
5638 double precision,
intent(out) :: nperp(ixi^s,1:
ndir)
5640 double precision :: bunitvec(
ndir), gradt(ixi^s,
ndir), gradt_perp(
ndir)
5641 double precision :: maxm
5642 integer :: ix^
d, idir
5646 call gradient(te,ixi^
l,ixo^
l,idir,gradt(ixi^s,idir))
5652 do ix2=ixomin2,ixomax2
5653 do ix1=ixomin1,ixomax1
5654 bunitvec=b_unit_vector(bvec(ix^
d,1:
ndir))
5656 gradt(ix^
d,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)
5657 gradt(ix^
d,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)
5658 if(
ndir>2) gradt(ix^
d,3)=zero
5661 bgradt(ix^
d)=(^
c&bunitvec(^
c)*gradt(ix^
d,^
c)+)
5662 {^
c& gradt_perp(^
c)=gradt(ix^
d,^
c)-bgradt(ix^
d)*bunitvec(^
c)\}
5663 maxm=maxval(abs(gradt_perp))
5665 gradtperp_mag(ix^
d)=zero
5666 {^
c& nperp(ix^
d,^
c)=zero\}
5668 ^
c&nperp(ix^
d,^
c)=gradt_perp(^
c)/maxm\
5669 gradtperp_mag(ix^
d)=dsqrt(^
c&nperp(ix^
d,^
c)**2+)
5670 ^
c&nperp(ix^
d,^
c)=nperp(ix^
d,^
c)/gradtperp_mag(ix^
d)\
5671 gradtperp_mag(ix^
d)=gradtperp_mag(ix^
d)*maxm
5677 do ix3=ixomin3,ixomax3
5678 do ix2=ixomin2,ixomax2
5679 do ix1=ixomin1,ixomax1
5680 bunitvec=b_unit_vector(bvec(ix^
d,1:
ndir))
5683 gradt(ix^
d,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)
5684 gradt(ix^
d,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)
5685 gradt(ix^
d,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)
5688 bgradt(ix^
d)=(^
c&bunitvec(^
c)*gradt(ix^
d,^
c)+)
5689 {^
c& gradt_perp(^
c)=gradt(ix^
d,^
c)-bgradt(ix^
d)*bunitvec(^
c)\}
5690 maxm=maxval(abs(gradt_perp))
5692 gradtperp_mag(ix^
d)=zero
5693 {^
c& nperp(ix^
d,^
c)=zero\}
5695 ^
c&nperp(ix^
d,^
c)=gradt_perp(^
c)/maxm\
5696 gradtperp_mag(ix^
d)=dsqrt(^
c&nperp(ix^
d,^
c)**2+)
5697 ^
c&nperp(ix^
d,^
c)=nperp(ix^
d,^
c)/gradtperp_mag(ix^
d)\
5698 gradtperp_mag(ix^
d)=gradtperp_mag(ix^
d)*maxm
5704 end subroutine mhd_get_hyperbolic_tc_geometry
5706 subroutine add_source_hyperbolic_tc(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5709 integer,
intent(in) :: ixi^
l,ixo^
l
5710 double precision,
intent(in) :: qdt
5711 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
5712 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
5713 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
5715 double precision,
dimension(ixI^S) :: r,te,rho_loc,pth_loc,cs2_loc
5716 double precision,
dimension(ixI^S) :: ne_loc,nh_dummy
5717 double precision,
dimension(ixI^S,1:ndir) :: bvec
5718 double precision,
dimension(ixI^S) :: bgradt, gradtperp_mag
5719 double precision,
dimension(ixI^S,1:ndir) :: nperp
5720 double precision,
dimension(ixI^S) :: gradt_geom
5721 double precision,
parameter :: xe_prefac_cgs = 4.753567596681522d6
5722 double precision :: kappa_t5,kappa_t5_perp,kappa_t5_perp_eff
5723 double precision :: kappa_t7,f_sat,kappat5_bgradt,kappat5_gradtperp,tau,b2,fb,gradt1
5724 double precision :: bunit_tc(
ndir)
5725 double precision :: qclass_diss
5726 double precision :: bmag_loc,tloc,tcond,nloc_code,cchi,chi
5727 double precision :: cmax(
ndim),c2,cfast2,avmincs2(
ndim),inv_rho
5728 logical :: use_perp_source
5729 integer :: ix^
d,idir
5735 if(htc_perp_mode_id==htc_perp_electron)
then
5745 if (eos%eos_type ==
'LTE' .or. eos%eos_type ==
'PI')
then
5746 te(ixi^s) = wct(ixi^s,
te_)
5748 call eos%get_Rfactor(wct,x,ixi^
l,ixi^
l,r)
5749 {
do ix^db=iximin^db,iximax^db\}
5754 rho_loc(ix^
d)=wctprim(ix^
d,
rho_)
5755 pth_loc(ix^
d)=wctprim(ix^
d,
p_)
5757 te(ix^
d)=pth_loc(ix^
d)/(r(ix^
d)*rho_loc(ix^
d))
5762 cs2_loc(ixi^s)=eos%gamma*pth_loc(ixi^s)/rho_loc(ixi^s)
5764 call eos%get_csound2(wctprim,x,ixi^l,ixi^l,cs2_loc)
5770 if(htc_perp_mode_id==htc_perp_electron)
then
5771 if(eos%eos_type==
'LTE')
then
5772 call eos%get_ne_nH(ixi^l,ixi^l,wct, x,ne_loc,nh_dummy)
5773 else if(eos%eos_type==
'PI')
then
5774 ne_loc(ixi^s)=rho_loc(ixi^s)*max(r(ixi^s)*(2.d0+3.d0*eos%He_abundance) &
5775 -(1.d0+eos%He_abundance),smalldouble)
5777 ne_loc(ixi^s)=rho_loc(ixi^s)*(1.d0+2.d0*eos%He_abundance)
5782 {
do ix^db=ixomin^db,ixomax^db\}
5783 {^
c& bvec(ix^d,^
c)=wct(ix^d,mag(^
c))+block%B0(ix^d,^
c,0)\}
5786 {
do ix^db=ixomin^db,ixomax^db\}
5787 {^
c& bvec(ix^d,^
c)=wct(ix^d,mag(^
c))\}
5791 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
5795 if(.not.slab_uniform)
then
5796 call gradient(te,ixi^l,ixo^l,1,gradt_geom)
5798 do ix1=ixomin1,ixomax1
5801 kappa_t7=kappa_t5*te(ix1)
5805 tcond = max(tcond, block%wextra(ix1,
tcoff_))
5808 kappa_t7=kappa_t5*tcond
5810 if(slab_uniform)
then
5811 gradt1=((8.d0*(te(ix1+1)-te(ix1-1))-te(ix1+2)+te(ix1-2))/12.d0)/block%ds(ix1,1)
5813 gradt1=gradt_geom(ix1)
5816 {^
c& b2=b2+bvec(ix1,^
c)**2\}
5817 bunit_tc=b_unit_vector(bvec(ix1,1:ndir))
5818 bgradt(ix1)=bunit_tc(1)*gradt1
5819 kappat5_bgradt=kappa_t5*bgradt(ix1)
5820 inv_rho=1.d0/rho_loc(ix1)
5822 cfast2 = b2*inv_rho + c2
5823 avmincs2(1) = cfast2**2 - 4.0d0*c2*bvec(ix1,1)**2*inv_rho
5824 cmax(1) = sqrt(half*(cfast2 + sqrt(dabs(avmincs2(1)))))
5826 f_sat=one/(one+dabs(kappat5_bgradt)/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5827 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*cmax(1)**2))
5828 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5831 max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*cmax(1)**2))
5836 do ix2=ixomin2,ixomax2
5837 do ix1=ixomin1,ixomax1
5840 kappa_t7=kappa_t5*te(ix^d)
5844 tcond=max(tcond, block%wextra(ix^d,
tcoff_))
5847 kappa_t7 = kappa_t5*tcond
5849 kappat5_bgradt=kappa_t5*bgradt(ix^d)
5851 {^
c& b2 = b2 + bvec(ix^d,^
c)**2\}
5852 if(use_perp_source)
then
5853 select case(htc_perp_mode_id)
5854 case(htc_perp_fixed)
5856 case(htc_perp_weak_field)
5862 kappa_t5_perp_eff=(one-fb)*kappa_t5
5863 kappa_t5_perp=kappa_t5_perp_eff
5864 case(htc_perp_electron)
5865 bmag_loc = dsqrt(b2)
5866 tloc = max(te(ix^d), smalldouble)
5867 nloc_code = max(ne_loc(ix^d), smalldouble)
5868 chi = cchi*bmag_loc*tloc**1.5d0/nloc_code
5869 kappa_t5_perp_eff = kappa_t5/(one+chi**2)
5870 kappa_t5_perp = kappa_t5_perp_eff
5874 kappat5_gradtperp=kappa_t5_perp*gradtperp_mag(ix^d)
5876 inv_rho=1.d0/rho_loc(ix^d)
5878 cfast2 = b2*inv_rho + c2
5879 {avmincs2(^d)=cfast2**2-4.0d0*c2*bvec(ix^dd,^d)**2*inv_rho; cmax(^d)=sqrt(half*(cfast2+sqrt(dabs(avmincs2(^d)))))\}
5881 qclass_diss=dabs(kappat5_bgradt)
5882 if(use_perp_source) &
5883 qclass_diss=dsqrt(kappat5_bgradt**2+kappat5_gradtperp**2)
5884 f_sat=one/(one+qclass_diss/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5885 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5886 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5887 if(use_perp_source)
then
5891 tau=max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5893 if(use_perp_source)
then
5901 do ix3=ixomin3,ixomax3
5902 do ix2=ixomin2,ixomax2
5903 do ix1=ixomin1,ixomax1
5906 kappa_t7=kappa_t5*te(ix^d)
5910 tcond=max(tcond, block%wextra(ix^d,
tcoff_))
5913 kappa_t7 = kappa_t5*tcond
5915 kappat5_bgradt=kappa_t5*bgradt(ix^d)
5917 {^
c& b2 = b2 + bvec(ix^d,^
c)**2\}
5918 if(use_perp_source)
then
5919 select case(htc_perp_mode_id)
5920 case(htc_perp_fixed)
5922 case(htc_perp_weak_field)
5928 kappa_t5_perp_eff=(one-fb)*kappa_t5
5929 kappa_t5_perp=kappa_t5_perp_eff
5930 case(htc_perp_electron)
5931 bmag_loc = dsqrt(b2)
5932 tloc = max(te(ix^d), smalldouble)
5933 nloc_code = max(ne_loc(ix^d), smalldouble)
5934 chi = cchi*bmag_loc*tloc**1.5d0/nloc_code
5935 kappa_t5_perp_eff = kappa_t5/(one+chi**2)
5936 kappa_t5_perp = kappa_t5_perp_eff
5940 kappat5_gradtperp=kappa_t5_perp*gradtperp_mag(ix^d)
5942 inv_rho=1.d0/rho_loc(ix^d)
5944 cfast2 = b2*inv_rho + c2
5945 {avmincs2(^d)=cfast2**2-4.0d0*c2*bvec(ix^dd,^d)**2*inv_rho; cmax(^d)=sqrt(half*(cfast2+sqrt(dabs(avmincs2(^d)))))\}
5947 qclass_diss=dabs(kappat5_bgradt)
5948 if(use_perp_source) &
5949 qclass_diss=dsqrt(kappat5_bgradt**2+kappat5_gradtperp**2)
5950 f_sat=one/(one+qclass_diss/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5951 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5952 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5953 if(use_perp_source)
then
5957 tau=max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5959 if(use_perp_source)
then
5967 end subroutine add_source_hyperbolic_tc
5971 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
5973 integer,
intent(in) :: ixi^
l, ixo^
l
5974 double precision,
intent(in) :: w(ixi^s,1:nw)
5975 double precision,
intent(inout) :: jxb(ixi^s,3)
5976 double precision :: a(ixi^s,3),
b(ixi^s,3)
5978 double precision :: current(ixi^s,7-2*
ndir:3)
5979 integer :: idir, idirmin
5984 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
5988 b(ixo^s, idir) = w(ixo^s,mag(idir))
5997 a(ixo^s,idir)=current(ixo^s,idir)
6001 end subroutine get_lorentz_force
6005 integer,
intent(in) :: ixi^
l, ixo^
l
6006 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
6007 double precision,
intent(out) :: rho(ixi^s)
6012 rho(ixo^s) = w(ixo^s,
rho_)
6018 subroutine mhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
6021 integer,
intent(in) :: ixi^
l,ixo^
l, ie
6022 double precision,
intent(inout) :: w(ixi^s,1:nw)
6023 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6024 character(len=*),
intent(in) :: subname
6026 double precision :: rho(ixi^s)
6028 logical :: flag(ixi^s,1:nw)
6033 flag(ixo^s,ie)=.true.
6035 where(w(ixo^s,ie)<
small_e) flag(ixo^s,ie)=.true.
6037 if(any(flag(ixo^s,ie)))
then
6041 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e - &
6044 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e
6050 w(ixo^s,
e_)=w(ixo^s,
e_)*eos%gamma_minus_1
6053 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
6059 end subroutine mhd_handle_small_ei
6063 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
6066 integer,
intent(in) :: ixi^
l, ixo^
l
6067 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6068 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
6069 double precision,
intent(inout) :: w(ixi^s,1:nw)
6071 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
6083 a(ixo^s,idir)=
block%J0(ixo^s,idir)
6088 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
6091 axb(ixo^s,:)=axb(ixo^s,:)*qdt
6097 if(total_energy)
then
6100 b(ixo^s,:)=wctprim(ixo^s,mag(:))
6109 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
6112 axb(ixo^s,:)=axb(ixo^s,:)*qdt
6117 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
6121 call mhd_getv_hall(wct,x,ixi^
l,ixo^
l,a,.true.)
6126 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
6129 axb(ixo^s,:)=axb(ixo^s,:)*qdt
6133 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
6141 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,axb)
6146 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*axb(ixo^s,idir)*
block%J0(ixo^s,idir)
6152 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
6154 end subroutine add_source_b0split
6157 subroutine add_source_semirelativistic(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
6161 integer,
intent(in) :: ixi^
l, ixo^
l
6162 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6163 double precision,
intent(inout) :: w(ixi^s,1:nw)
6164 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
6166 double precision :: e(ixi^s,1:3),curle(ixi^s,1:3),dive(ixi^s),btot(1:3)
6167 integer :: idir, idirmin, ix^
d
6171 {
do ix^db=iximin^db,iximax^db\}
6173 ^
c&btot(^
c)=wct(ix^
d,
b^
c_)\
6177 e(ix^
d,1)=btot(2)*wctprim(ix^
d,m3_)-btot(3)*wctprim(ix^
d,m2_)
6178 e(ix^
d,2)=btot(3)*wctprim(ix^
d,m1_)-btot(1)*wctprim(ix^
d,m3_)
6179 e(ix^
d,3)=btot(1)*wctprim(ix^
d,m2_)-btot(2)*wctprim(ix^
d,m1_)
6181 call divvector(e,ixi^l,ixo^l,dive)
6183 call curlvector(e,ixi^l,ixo^l,curle,idirmin,1,3)
6190 {
do ix^db=ixomin^db,ixomax^db\}
6191 w(ix^d,m1_)=w(ix^d,m1_)+qdt*(inv_squared_c0-inv_squared_c)*&
6192 (e(ix^d,1)*dive(ix^d)-e(ix^d,2)*curle(ix^d,3)+e(ix^d,3)*curle(ix^d,2))
6193 w(ix^d,m2_)=w(ix^d,m2_)+qdt*(inv_squared_c0-inv_squared_c)*&
6194 (e(ix^d,2)*dive(ix^d)-e(ix^d,3)*curle(ix^d,1)+e(ix^d,1)*curle(ix^d,3))
6195 w(ix^d,m3_)=w(ix^d,m3_)+qdt*(inv_squared_c0-inv_squared_c)*&
6196 (e(ix^d,3)*dive(ix^d)-e(ix^d,1)*curle(ix^d,2)+e(ix^d,2)*curle(ix^d,1) )
6200 end subroutine add_source_semirelativistic
6203 subroutine add_source_internal_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
6207 integer,
intent(in) :: ixi^
l, ixo^
l
6208 double precision,
intent(in) :: qdt
6209 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6210 double precision,
intent(inout) :: w(ixi^s,1:nw)
6211 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
6213 double precision :: divv(ixi^s), tmp
6225 {
do ix^db=ixomin^db,ixomax^db\}
6227 w(ix^
d,
e_)=w(ix^
d,
e_)-qdt*wctprim(ix^
d,
p_)*divv(ix^
d)
6233 call add_source_ambipolar_internal_energy(qdt,ixi^l,ixo^l,wct,w,x)
6236 if(fix_small_values)
then
6237 call mhd_handle_small_ei(w,x,ixi^l,ixo^l,
e_,
'add_source_internal_e')
6239 end subroutine add_source_internal_e
6242 subroutine add_source_hydrodynamic_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
6247 integer,
intent(in) :: ixi^
l, ixo^
l
6248 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6249 double precision,
intent(inout) :: w(ixi^s,1:nw)
6250 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
6252 double precision ::
b(ixi^s,3), j(ixi^s,3), jxb(ixi^s,3)
6253 double precision :: current(ixi^s,7-2*
ndir:3)
6254 double precision :: bu(ixo^s,1:
ndir), tmp(ixo^s), b2(ixo^s)
6255 double precision :: gravity_field(ixi^s,1:
ndir), vaoc
6256 integer :: idir, idirmin, idims, ix^
d
6261 b(ixo^s, idir) = wct(ixo^s,mag(idir))
6273 j(ixo^s,idir)=current(ixo^s,idir)
6352 call add_source_ambipolar_internal_energy(qdt,ixi^
l,ixo^
l,wct,w,x)
6355 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_hydrodynamic_e')
6357 end subroutine add_source_hydrodynamic_e
6363 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
6368 integer,
intent(in) :: ixi^
l, ixo^
l
6369 double precision,
intent(in) :: qdt
6370 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6371 double precision,
intent(inout) :: w(ixi^s,1:nw)
6373 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim
6374 double precision :: tmp(ixi^s),tmp2(ixi^s)
6377 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
6378 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
6379 double precision :: lapl_vec(ixi^s,1:
ndir)
6385 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6386 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
6393 gradeta(ixo^s,1:
ndim)=zero
6398 gradeta(ixo^s,idim)=tmp(ixo^s)
6405 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
6412 tmp(ixo^s)=lapl_vec(ixo^s,idir)*eta(ixo^s)
6416 do jdir=1,
ndim;
do kdir=idirmin,3
6417 if (
lvc(idir,jdir,kdir)/=0)
then
6418 if (
lvc(idir,jdir,kdir)==1)
then
6419 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
6421 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
6428 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
6429 if(total_energy)
then
6430 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
6436 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
6439 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
6441 end subroutine add_source_res1
6445 subroutine add_source_res_exp(qdt,ixI^L,ixO^L,wCT,w,x)
6450 integer,
intent(in) :: ixi^
l, ixo^
l
6451 double precision,
intent(in) :: qdt
6452 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6453 double precision,
intent(inout) :: w(ixi^s,1:nw)
6456 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
6457 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
6458 integer :: ixa^
l,idir,idirmin,idirmin1
6462 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6463 call mpistop(
"Error in add_source_res_exp: Non-conforming input limits")
6473 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
mhd_eta
6478 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
6487 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
6490 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
6495 tmp(ixo^s)=qdt*
mhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
6497 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
6499 if(total_energy)
then
6502 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
6503 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
6506 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
6510 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res_exp')
6511 end subroutine add_source_res_exp
6516 subroutine add_source_ambi_exp(qdt,ixI^L,ixO^L,wCT,w,x)
6521 integer,
intent(in) :: ixi^
l, ixo^
l
6522 double precision,
intent(in) :: qdt
6523 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6524 double precision,
intent(inout) :: w(ixi^s,1:nw)
6526 double precision :: current(ixi^s,1:3),curlj(ixi^s,1:3)
6527 double precision :: tmpvec(ixi^s,1:3),tmp(ixi^s),btot2(ixi^s)
6528 integer :: ixa^
l,idir,idirmin1
6532 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6533 call mpistop(
"Error in add_source_ambi_exp: Non-conforming input limits")
6537 call mhd_get_jxbxb(wct,x,ixi^
l,ixa^
l,current)
6551 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
6554 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
6561 where (btot2(ixa^s)>smalldouble )
6562 tmp(ixa^s) = sum(current(ixa^s,1:3)**2,dim=
ndim+1) / btot2(ixa^s)
6569 tmp(ixo^s)=-qdt*tmp(ixo^s)
6570 if(total_energy)
then
6573 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
6574 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
6577 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
6581 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_ambi_exp')
6582 end subroutine add_source_ambi_exp
6586 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
6590 integer,
intent(in) :: ixi^
l, ixo^
l
6591 double precision,
intent(in) :: qdt
6592 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6593 double precision,
intent(inout) :: w(ixi^s,1:nw)
6595 double precision :: current(ixi^s,7-2*
ndir:3)
6596 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
6597 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
6600 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6601 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
6604 tmpvec(ixa^s,1:
ndir)=zero
6606 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
6610 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
6613 tmpvec(ixa^s,1:
ndir)=zero
6614 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
6618 tmpvec2(ixa^s,1:
ndir)=zero
6619 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
6622 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
6625 if(total_energy)
then
6628 tmpvec2(ixa^s,1:
ndir)=zero
6629 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
6630 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
6631 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
6632 end do;
end do;
end do
6634 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
6635 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
6638 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
6640 end subroutine add_source_hyperres
6642 subroutine add_source_glm(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), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
6674 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
6677 if(total_energy)
then
6686 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*wct(ixo^s,mag(idir))*gradpsi(ixo^s)
6695 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
6699 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
6701 end subroutine add_source_glm
6704 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
6707 integer,
intent(in) :: ixi^
l, ixo^
l
6708 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6709 double precision,
intent(inout) :: w(ixi^s,1:nw)
6711 double precision :: divb(ixi^s), ba(1:
ndir)
6712 integer :: idir, ix^
d
6718 {
do ix^db=ixomin^db,ixomax^db\}
6723 if (total_energy)
then
6729 {
do ix^db=ixomin^db,ixomax^db\}
6731 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
6733 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
6734 if (total_energy)
then
6736 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
6741 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
6743 end subroutine add_source_powel
6745 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
6750 integer,
intent(in) :: ixi^
l, ixo^
l
6751 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6752 double precision,
intent(inout) :: w(ixi^s,1:nw)
6754 double precision :: divb(ixi^s)
6755 integer :: idir, ix^
d
6760 {
do ix^db=ixomin^db,ixomax^db\}
6765 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
6767 end subroutine add_source_janhunen
6769 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
6774 integer,
intent(in) :: ixi^
l, ixo^
l
6775 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6776 double precision,
intent(inout) :: w(ixi^s,1:nw)
6778 double precision :: divb(ixi^s),graddivb(ixi^s)
6779 integer :: idim, idir, ixp^
l, i^
d, iside
6780 logical,
dimension(-1:1^D&) :: leveljump
6788 if(i^
d==0|.and.) cycle
6789 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
6790 leveljump(i^
d)=.true.
6792 leveljump(i^
d)=.false.
6801 i^dd=kr(^dd,^d)*(2*iside-3);
6802 if (leveljump(i^dd))
then
6804 ixpmin^d=ixomin^d-i^d
6806 ixpmax^d=ixomax^d-i^d
6817 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
6819 {
do i^db=ixpmin^db,ixpmax^db\}
6821 graddivb(i^d)=graddivb(i^d)*
divbdiff/(^d&1.0d0/block%ds({i^d},^d)**2+)
6823 w(i^d,mag(idim))=w(i^d,mag(idim))+graddivb(i^d)
6825 if (typedivbdiff==
'all' .and. total_energy)
then
6828 w(i^d,
e_)=w(i^d,
e_)+wct(i^d,mag(idim))*graddivb(i^d)
6833 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
6835 end subroutine add_source_linde
6842 integer,
intent(in) :: ixi^
l, ixo^
l
6843 double precision,
intent(in) :: w(ixi^s,1:nw)
6844 double precision :: divb(ixi^s), dsurface(ixi^s)
6846 double precision :: invb(ixo^s)
6847 integer :: ixa^
l,idims
6849 call get_divb(w,ixi^
l,ixo^
l,divb)
6851 where(invb(ixo^s)/=0.d0)
6852 invb(ixo^s)=1.d0/invb(ixo^s)
6855 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
6857 ixamin^
d=ixomin^
d-1;
6858 ixamax^
d=ixomax^
d-1;
6859 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
6861 ixa^
l=ixo^
l-
kr(idims,^
d);
6862 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
6864 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
6865 block%dvolume(ixo^s)/dsurface(ixo^s)
6876 integer,
intent(in) :: ixo^
l, ixi^
l
6877 double precision,
intent(in) :: w(ixi^s,1:nw)
6878 integer,
intent(out) :: idirmin
6881 double precision :: current(ixi^s,7-2*
ndir:3)
6882 integer :: idir, idirmin0
6888 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
6889 block%J0(ixo^s,idirmin0:3)
6893 subroutine mhd_get_dt(wprim,ixI^L,ixO^L,dtnew,dx^D,x)
6901 integer,
intent(in) :: ixi^
l, ixo^
l
6902 double precision,
intent(inout) :: dtnew
6903 double precision,
intent(in) ::
dx^
d
6904 double precision,
intent(in) :: wprim(ixi^s,1:nw)
6905 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6907 double precision :: dxarr(
ndim)
6908 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
6909 integer :: idirmin,idim
6927 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
6930 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
6952 dtnew=min(
dtdiffpar*get_ambipolar_dt(wprim,ixi^
l,ixo^
l,
dx^
d,x),dtnew)
6963 end subroutine mhd_get_dt
6968 subroutine mhd_fld_implicit_update(dtfactor,qdt,qtC,psa,psb)
6973 double precision,
intent(in) :: qdt
6974 double precision,
intent(in) :: qtc
6975 double precision,
intent(in) :: dtfactor
6978 end subroutine mhd_fld_implicit_update
6980 subroutine mhd_fld_evaluate_implicit(qtC,psa)
6984 double precision,
intent(in) :: qtc
6987 end subroutine mhd_fld_evaluate_implicit
6994 subroutine mhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
7000 integer,
intent(in) :: ixi^
l, ixo^
l
7001 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
7002 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
7004 double precision :: adiabs(ixi^s), gammas(ixi^s)
7005 double precision :: tmp,tmp1,invr,cot
7007 integer :: mr_,mphi_
7008 integer :: br_,bphi_
7011 br_=mag(1); bphi_=mag(1)-1+
phi_
7028 {
do ix^db=ixomin^db,ixomax^db\}
7031 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
7036 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
7038 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
7041 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
7042 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
7043 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
7044 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
7045 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
7047 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7048 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
7049 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
7052 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
7057 {
do ix^db=ixomin^db,ixomax^db\}
7059 if(local_timestep)
then
7060 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
7065 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
7067 tmp1=adiabs(ix^d)*wprim(ix^d,
rho_)**gammas(ix^d)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
7071 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
7074 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
7075 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
7079 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
7085 cot=1.d0/tan(x(ix^d,2))
7089 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7090 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
7092 if(.not.stagger_grid)
then
7093 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7095 tmp=tmp+wprim(ix^d,
psi_)*cot
7097 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7102 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7103 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
7104 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
7106 if(.not.stagger_grid)
then
7107 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7109 tmp=tmp+wprim(ix^d,
psi_)*cot
7111 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7114 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
7115 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
7116 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7117 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
7118 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
7120 if(.not.stagger_grid)
then
7121 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
7122 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7123 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7124 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7125 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
7132 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
7135 end subroutine mhd_add_source_geom
7142 subroutine mhd_add_source_geom_semirelati(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
7148 integer,
intent(in) :: ixi^
l, ixo^
l
7149 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
7150 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
7152 double precision :: adiabs(ixi^s), gammas(ixi^s)
7153 double precision :: tmp,tmp1,tmp2,invr,cot,ef(ixo^s,1:
ndir)
7155 integer :: mr_,mphi_
7156 integer :: br_,bphi_
7159 br_=mag(1); bphi_=mag(1)-1+
phi_
7176 {
do ix^db=ixomin^db,ixomax^db\}
7179 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
7186 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)
7190 ef(ix^
d,1)=wprim(ix^
d,b2_)*wprim(ix^
d,m3_)-wprim(ix^
d,b3_)*wprim(ix^
d,m2_)
7191 ef(ix^
d,2)=wprim(ix^
d,b3_)*wprim(ix^
d,m1_)-wprim(ix^
d,b1_)*wprim(ix^
d,m3_)
7192 ef(ix^
d,3)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
7197 ef(ix^
d,2)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
7203 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+&
7204 half*((^
c&wprim(ix^
d,
b^
c_)**2+)+(^
c&ef(ix^
d,^
c)**2+)*inv_squared_c) -&
7205 wprim(ix^
d,bphi_)**2+wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)**2)
7206 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
7207 -wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)*wprim(ix^
d,mr_) &
7208 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_)+ef(ix^
d,
phi_)*ef(ix^
d,1)*inv_squared_c)
7210 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7211 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
7212 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
7215 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+half*((^
c&wprim(ix^
d,
b^
c_)**2+)+&
7216 (^
c&ef(ix^
d,^
c)**2+)*inv_squared_c))
7221 {
do ix^db=ixomin^db,ixomax^db\}
7223 if(local_timestep)
then
7224 invr=block%dt(ix^d)*dtfactor/x(ix^d,1)
7230 ef(ix^d,1)=wprim(ix^d,b2_)*wprim(ix^d,m3_)-wprim(ix^d,b3_)*wprim(ix^d,m2_)
7231 ef(ix^d,2)=wprim(ix^d,b3_)*wprim(ix^d,m1_)-wprim(ix^d,b1_)*wprim(ix^d,m3_)
7232 ef(ix^d,3)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
7236 ef(ix^d,1)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
7243 tmp1=wprim(ix^d,
p_)+half*((^
c&wprim(ix^d,
b^
c_)**2+)+(^
c&ef(ix^d,^
c)**2+)*inv_squared_c)
7245 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)
7249 w(ix^d,m1_)=w(ix^d,m1_)+two*tmp1*invr
7252 w(ix^d,m1_)=w(ix^d,m1_)+invr*&
7253 (two*tmp1+(^ce&wprim(ix^d,
rho_)*wprim(ix^d,
m^ce_)**2-&
7254 wprim(ix^d,
b^ce_)**2-ef(ix^d,^ce)**2*inv_squared_c+))
7258 w(ix^d,b1_)=w(ix^d,b1_)+invr*2.0d0*wprim(ix^d,
psi_)
7264 cot=1.d0/tan(x(ix^d,2))
7268 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_)&
7269 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c)
7271 if(.not.stagger_grid)
then
7272 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7274 tmp=tmp+wprim(ix^d,
psi_)*cot
7276 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
7282 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_) &
7283 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c&
7284 +(wprim(ix^d,
rho_)*wprim(ix^d,m3_)**2&
7285 -wprim(ix^d,b3_)**2-ef(ix^d,3)**2*inv_squared_c)*cot)
7287 if(.not.stagger_grid)
then
7288 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7290 tmp=tmp+wprim(ix^d,
psi_)*cot
7292 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
7295 w(ix^d,m3_)=w(ix^d,m3_)+invr*&
7296 (-wprim(ix^d,m3_)*wprim(ix^d,m1_)*wprim(ix^d,
rho_) &
7297 +wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7298 +ef(ix^d,3)*ef(ix^d,1)*inv_squared_c&
7299 +(-wprim(ix^d,m2_)*wprim(ix^d,m3_)*wprim(ix^d,
rho_) &
7300 +wprim(ix^d,b2_)*wprim(ix^d,b3_)&
7301 +ef(ix^d,2)*ef(ix^d,3)*inv_squared_c)*cot)
7303 if(.not.stagger_grid)
then
7304 w(ix^d,b3_)=w(ix^d,b3_)+invr*&
7305 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7306 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7307 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7308 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
7315 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
7318 end subroutine mhd_add_source_geom_semirelati
7327 subroutine mhd_add_source_geom_split(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
7333 integer,
intent(in) :: ixi^
l, ixo^
l
7334 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
7335 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
7337 double precision :: tmp,tmp1,tmp2,invr,cot
7338 double precision :: adiabs(ixi^s), gammas(ixi^s)
7340 integer :: mr_,mphi_
7341 integer :: br_,bphi_
7357 br_=mag(1); bphi_=mag(1)-1+
phi_
7362 {
do ix^db=ixomin^db,ixomax^db\}
7365 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
7370 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
7372 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
7376 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
7377 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
7381 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
7382 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
7383 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
7385 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))
7388 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7389 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
7390 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
7392 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
7398 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
7403 {
do ix^db=ixomin^db,ixomax^db\}
7405 if(local_timestep)
then
7406 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
7410 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
7411 if(b0field) tmp2=(^
c&block%B0(ix^d,^
c,0)*wprim(ix^d,
b^
c_)+)
7414 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
7415 if(b0field) w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp2*invr
7419 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
7420 (two*(tmp1+tmp2)+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+)- &
7421 (^ce&two*block%B0(ix^d,^ce,0)*wprim(ix^d,
b^ce_)+))
7423 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
7424 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
7429 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
7435 cot=1.d0/tan(x(ix^d,2))
7440 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7441 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
7442 +wprim(ix^d,b1_)*block%B0(ix^d,2,0))
7444 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7445 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
7448 if(.not.stagger_grid)
then
7450 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
7451 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
7453 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7456 tmp=tmp+wprim(ix^d,
psi_)*cot
7458 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7464 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7465 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
7466 +wprim(ix^d,b1_)*block%B0(ix^d,2,0)&
7467 +(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)
7469 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
7470 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
7471 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
7474 if(.not.stagger_grid)
then
7476 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
7477 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
7479 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
7482 tmp=tmp+wprim(ix^d,
psi_)*cot
7484 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
7488 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
7489 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
7490 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7491 +block%B0(ix^d,1,0)*wprim(ix^d,b3_) &
7492 +wprim(ix^d,b1_)*block%B0(ix^d,3,0) &
7493 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
7494 -wprim(ix^d,b2_)*wprim(ix^d,b3_) &
7495 +block%B0(ix^d,2,0)*wprim(ix^d,b3_) &
7496 +wprim(ix^d,b2_)*block%B0(ix^d,3,0))*cot)
7498 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
7499 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
7500 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
7501 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
7502 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
7505 if(.not.stagger_grid)
then
7507 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
7508 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7509 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7510 +wprim(ix^d,m1_)*block%B0(ix^d,3,0) &
7511 -wprim(ix^d,m3_)*block%B0(ix^d,1,0) &
7512 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7513 -wprim(ix^d,m2_)*wprim(ix^d,b3_) &
7514 +wprim(ix^d,m3_)*block%B0(ix^d,2,0) &
7515 -wprim(ix^d,m2_)*block%B0(ix^d,3,0))*cot)
7517 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
7518 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
7519 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
7520 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
7521 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
7529 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
7532 end subroutine mhd_add_source_geom_split
7537 integer,
intent(in) :: ixi^
l, ixo^
l
7538 double precision,
intent(in) :: w(ixi^s, nw)
7539 double precision :: mge(ixo^s)
7542 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
7544 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
7548 subroutine mhd_getv_hall(w,x,ixI^L,ixO^L,vHall,partial)
7552 integer,
intent(in) :: ixi^
l, ixo^
l
7553 double precision,
intent(in) :: w(ixi^s,nw)
7554 double precision,
intent(in) :: x(ixi^s,1:
ndim)
7555 double precision,
intent(inout) :: vhall(ixi^s,1:
ndir)
7556 logical,
intent(in),
optional :: partial
7558 double precision :: current(ixi^s,7-2*
ndir:3)
7559 double precision :: rho(ixi^s)
7560 integer :: idir, idirmin, ix^
d
7561 logical :: use_partial
7564 if(
present(partial)) use_partial=partial
7566 if(.not.use_partial)
then
7577 do idir = idirmin,
ndir
7578 {
do ix^db=ixomin^db,ixomax^db\}
7579 vhall(ix^
d,idir)=-
mhd_etah*current(ix^
d,idir)/rho(ix^
d)
7583 end subroutine mhd_getv_hall
7585 subroutine mhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
7588 integer,
intent(in) :: ixi^
l, ixo^
l, idir
7589 double precision,
intent(in) :: qt
7590 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
7591 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
7594 double precision :: db(ixo^s), dpsi(ixo^s)
7595 integer :: ix^
d, saved_b0i
7598 {
do ix^db=ixomin^db,ixomax^db\}
7599 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7600 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7601 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7602 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
7611 {
do ix^db=ixomin^db,ixomax^db\}
7612 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
7613 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
7614 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
7615 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
7616 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7619 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
7620 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
7622 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7624 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7628 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
7629 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
7639 wlc(ixo^s,1:nw)=wlp(ixo^s,1:nw)
7640 wrc(ixo^s,1:nw)=wrp(ixo^s,1:nw)
7641 call phys_to_conserved(ixi^l,ixo^l,wlc,s%x)
7642 call phys_to_conserved(ixi^l,ixo^l,wrc,s%x)
7648 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
7650 end subroutine mhd_modify_wlr
7652 subroutine mhd_boundary_adjust(igrid,psb)
7654 integer,
intent(in) :: igrid
7657 integer :: ib, idims, iside, ixo^
l, i^
d
7666 i^
d=
kr(^
d,idims)*(2*iside-3);
7667 if (neighbor_type(i^
d,igrid)/=1) cycle
7668 ib=(idims-1)*2+iside
7686 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
7691 end subroutine mhd_boundary_adjust
7693 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
7696 integer,
intent(in) :: ixg^
l,ixo^
l,ib
7697 double precision,
intent(inout) :: w(ixg^s,1:nw)
7698 double precision,
intent(in) :: x(ixg^s,1:
ndim)
7700 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
7701 integer :: ix^
d,ixf^
l
7707 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7715 do ix1=ixfmax1,ixfmin1,-1
7716 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
7717 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7718 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7721 do ix1=ixfmax1,ixfmin1,-1
7722 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
7723 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
7724 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7725 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7726 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7727 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7728 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7742 do ix1=ixfmax1,ixfmin1,-1
7743 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7744 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7745 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7746 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7747 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7748 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7751 do ix1=ixfmax1,ixfmin1,-1
7752 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7753 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7754 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7755 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7756 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7757 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7758 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7759 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7760 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7761 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7762 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7763 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7764 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7765 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7766 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7767 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7768 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7769 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7774 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7777 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7785 do ix1=ixfmin1,ixfmax1
7786 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
7787 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7788 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7791 do ix1=ixfmin1,ixfmax1
7792 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
7793 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
7794 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7795 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7796 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7797 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7798 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7812 do ix1=ixfmin1,ixfmax1
7813 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7814 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7815 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7816 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7817 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7818 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7821 do ix1=ixfmin1,ixfmax1
7822 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7823 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7824 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7825 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7826 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7827 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7828 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7829 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7830 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7831 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7832 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7833 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7834 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7835 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7836 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7837 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7838 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7839 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7844 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7847 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7855 do ix2=ixfmax2,ixfmin2,-1
7856 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
7857 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7858 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7861 do ix2=ixfmax2,ixfmin2,-1
7862 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
7863 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
7864 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7865 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7866 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7867 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7868 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7882 do ix2=ixfmax2,ixfmin2,-1
7883 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7884 ix2+1,ixfmin3:ixfmax3,mag(2)) &
7885 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7886 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7887 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7888 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7891 do ix2=ixfmax2,ixfmin2,-1
7892 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
7893 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
7894 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7895 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
7896 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7897 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7898 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7899 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7900 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7901 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7902 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7903 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7904 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7905 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7906 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7907 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7908 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
7909 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7914 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7917 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7925 do ix2=ixfmin2,ixfmax2
7926 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
7927 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7928 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7931 do ix2=ixfmin2,ixfmax2
7932 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
7933 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
7934 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7935 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7936 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7937 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7938 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7952 do ix2=ixfmin2,ixfmax2
7953 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7954 ix2-1,ixfmin3:ixfmax3,mag(2)) &
7955 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7956 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7957 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7958 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7961 do ix2=ixfmin2,ixfmax2
7962 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
7963 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
7964 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7965 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
7966 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7967 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7968 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7969 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7970 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7971 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7972 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7973 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7974 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7975 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7976 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7977 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7978 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
7979 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7984 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7988 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7998 do ix3=ixfmax3,ixfmin3,-1
7999 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
8000 ixfmin2:ixfmax2,ix3+1,mag(3)) &
8001 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
8002 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
8003 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
8004 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
8007 do ix3=ixfmax3,ixfmin3,-1
8008 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
8009 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
8010 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
8011 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
8012 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
8013 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
8014 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
8015 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
8016 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
8017 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
8018 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
8019 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
8020 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
8021 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
8022 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
8023 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
8024 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
8025 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
8029 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
8032 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
8042 do ix3=ixfmin3,ixfmax3
8043 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
8044 ixfmin2:ixfmax2,ix3-1,mag(3)) &
8045 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
8046 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
8047 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
8048 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
8051 do ix3=ixfmin3,ixfmax3
8052 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
8053 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
8054 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
8055 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
8056 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
8057 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
8058 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
8059 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
8060 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
8061 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
8062 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
8063 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
8064 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
8065 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
8066 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
8067 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
8068 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
8069 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
8073 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
8076 call mpistop(
"Special boundary is not defined for this region")
8079 end subroutine fixdivb_boundary
8088 double precision,
intent(in) :: qdt
8089 double precision,
intent(in) :: qt
8090 logical,
intent(inout) :: active
8093 integer,
parameter :: max_its = 50
8094 double precision :: residual_it(max_its), max_divb
8095 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
8096 double precision :: res
8097 double precision,
parameter :: max_residual = 1
d-3
8098 double precision,
parameter :: residual_reduction = 1
d-10
8099 integer :: iigrid, igrid
8100 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
8103 mg%operator_type = mg_laplacian
8111 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8112 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8115 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
8116 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8118 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8119 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8122 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8123 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8127 write(*,*)
"mhd_clean_divb_multigrid warning: unknown boundary type"
8128 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
8129 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
8137 do iigrid = 1, igridstail
8138 igrid = igrids(iigrid);
8141 lvl =
mg%boxes(id)%lvl
8142 nc =
mg%box_size_lvl(lvl)
8148 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
8150 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
8151 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
8156 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
8159 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
8160 if (
mype == 0) print *,
"iteration vs residual"
8163 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
8164 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
8165 if (residual_it(n) < residual_reduction * max_divb)
exit
8167 if (
mype == 0 .and. n > max_its)
then
8168 print *,
"divb_multigrid warning: not fully converged"
8169 print *,
"current amplitude of divb: ", residual_it(max_its)
8170 print *,
"multigrid smallest grid: ", &
8171 mg%domain_size_lvl(:,
mg%lowest_lvl)
8172 print *,
"note: smallest grid ideally has <= 8 cells"
8173 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
8174 print *,
"note: dx/dy/dz should be similar"
8178 call mg_fas_vcycle(
mg, max_res=res)
8179 if (res < max_residual)
exit
8181 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
8186 do iigrid = 1, igridstail
8187 igrid = igrids(iigrid);
8196 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
8200 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
8202 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
8204 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
8217 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
8218 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
8221 if(total_energy)
then
8223 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
8226 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
8236 subroutine mhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
8240 integer,
intent(in) :: ixi^
l, ixo^
l
8241 double precision,
intent(in) :: qt,qdt
8243 double precision,
intent(in) :: wp(ixi^s,1:nw)
8244 type(state) :: sct, s
8245 type(ct_velocity) :: vcts
8246 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
8247 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
8249 double precision :: circ(ixi^s,1:
ndim)
8251 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
8252 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
8253 integer :: idim1,idim2,idir,iwdim1,iwdim2
8255 associate(bfaces=>s%ws,x=>s%x)
8262 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8269 i1kr^
d=
kr(idim1,^
d);
8272 i2kr^
d=
kr(idim2,^
d);
8275 if (
lvc(idim1,idim2,idir)==1)
then
8277 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8279 {
do ix^db=ixcmin^db,ixcmax^db\}
8280 fe(ix^
d,idir)=quarter*&
8281 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
8282 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
8284 if(
mhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
8289 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
8297 if(
associated(usr_set_electric_field)) &
8298 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
8300 circ(ixi^s,1:ndim)=zero
8305 ixcmin^d=ixomin^d-kr(idim1,^d);
8307 ixa^l=ixc^l-kr(idim2,^d);
8310 if(lvc(idim1,idim2,idir)==1)
then
8312 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8315 else if(lvc(idim1,idim2,idir)==-1)
then
8317 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8323 {
do ix^db=ixcmin^db,ixcmax^db\}
8325 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
8327 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
8334 end subroutine mhd_update_faces_average
8337 subroutine mhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
8342 integer,
intent(in) :: ixi^
l, ixo^
l
8343 double precision,
intent(in) :: qt, qdt
8345 double precision,
intent(in) :: wp(ixi^s,1:nw)
8346 type(state) :: sct, s
8347 type(ct_velocity) :: vcts
8348 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
8349 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
8351 double precision :: circ(ixi^s,1:
ndim)
8353 double precision :: ecc(ixi^s,
sdim:3)
8354 double precision :: ein(ixi^s,
sdim:3)
8356 double precision :: el(ixi^s),er(ixi^s)
8358 double precision :: elc,erc
8360 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
8362 double precision :: jce(ixi^s,
sdim:3)
8364 double precision :: xs(ixgs^t,1:
ndim)
8365 double precision :: gradi(ixgs^t)
8366 double precision :: resis_heat
8367 integer :: ixc^
l,ixa^
l
8368 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
8370 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
8373 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8379 {
do ix^db=iximin^db,iximax^db\}
8382 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_)
8383 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_)
8384 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_)
8387 ecc(ix^
d,3)=(wp(ix^
d,b1_)+
block%B0(ix^
d,1,0))*wp(ix^
d,m2_) &
8388 -(wp(ix^
d,b2_)+
block%B0(ix^
d,2,0))*wp(ix^
d,m1_)
8395 {
do ix^db=iximin^db,iximax^db\}
8398 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
8399 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
8400 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
8403 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
8417 i1kr^d=kr(idim1,^d);
8420 i2kr^d=kr(idim2,^d);
8423 if (lvc(idim1,idim2,idir)==1)
then
8425 ixcmin^d=ixomin^d+kr(idir,^d)-1;
8428 {
do ix^db=ixcmin^db,ixcmax^db\}
8429 fe(ix^d,idir)=quarter*&
8430 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
8431 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
8436 ixamax^d=ixcmax^d+i1kr^d;
8437 {
do ix^db=ixamin^db,ixamax^db\}
8438 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
8439 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
8442 do ix^db=ixcmin^db,ixcmax^db\}
8443 if(vnorm(ix^d,idim1)>0.d0)
then
8445 else if(vnorm(ix^d,idim1)<0.d0)
then
8446 elc=el({ix^d+i1kr^d})
8448 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
8450 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
8452 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
8453 erc=er({ix^d+i1kr^d})
8455 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
8457 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
8462 ixamax^d=ixcmax^d+i2kr^d;
8463 {
do ix^db=ixamin^db,ixamax^db\}
8464 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
8465 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
8468 do ix^db=ixcmin^db,ixcmax^db\}
8469 if(vnorm(ix^d,idim2)>0.d0)
then
8471 else if(vnorm(ix^d,idim2)<0.d0)
then
8472 elc=el({ix^d+i2kr^d})
8474 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
8476 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
8478 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
8479 erc=er({ix^d+i2kr^d})
8481 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
8483 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
8487 if(
mhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
8492 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
8506 if (lvc(idim1,idim2,idir)==0) cycle
8508 ixcmin^d=ixomin^d+kr(idir,^d)-1;
8509 ixamax^d=ixcmax^d-kr(idir,^d)+1;
8512 xs(ixa^s,:)=x(ixa^s,:)
8513 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
8514 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
8515 if (lvc(idim1,idim2,idir)==1)
then
8516 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
8518 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
8524 {
do ix^db=ixomin^db,ixomax^db\}
8525 resis_heat=0.25d0*(ein(ix^d,1)*jce(ix^d,1)+ein(ix1,ix2-1,ix3,1)*jce(ix1,ix2-1,ix3,1)&
8526 +ein(ix1,ix2,ix3-1,1)*jce(ix1,ix2,ix3-1,1)+ein(ix1,ix2-1,ix3-1,1)*jce(ix1,ix2-1,ix3-1,1))&
8527 +0.25d0*(ein(ix^d,2)*jce(ix^d,2)+ein(ix1-1,ix2,ix3,2)*jce(ix1-1,ix2,ix3,2)&
8528 +ein(ix1,ix2,ix3-1,2)*jce(ix1,ix2,ix3-1,2)+ein(ix1-1,ix2,ix3-1,2)*jce(ix1-1,ix2,ix3-1,2))&
8529 +0.25d0*(ein(ix^d,3)*jce(ix^d,3)+ein(ix1-1,ix2,ix3,3)*jce(ix1-1,ix2,ix3,3)&
8530 +ein(ix1,ix2-1,ix3,3)*jce(ix1,ix2-1,ix3,3)+ein(ix1-1,ix2-1,ix3,3)*jce(ix1-1,ix2-1,ix3,3))
8531 if(resis_heat<0.d0) resis_heat=0.d0
8532 w(ix^d,
e_)=w(ix^d,
e_)+qdt*resis_heat
8537 {
do ix^db=ixomin^db,ixomax^db\}
8538 resis_heat=0.25d0*(ein(ix^d,3)*jce(ix^d,3)+ein(ix1-1,ix2,3)*jce(ix1-1,ix2,3)&
8539 +ein(ix1,ix2-1,3)*jce(ix1,ix2-1,3)+ein(ix1-1,ix2-1,3)*jce(ix1-1,ix2-1,3))
8540 if(resis_heat<0.d0) resis_heat=0.d0
8541 w(ix^d,
e_)=w(ix^d,
e_)+qdt*resis_heat
8548 if(
associated(usr_set_electric_field)) &
8549 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
8551 circ(ixi^s,1:ndim)=zero
8556 ixcmin^d=ixomin^d-kr(idim1,^d);
8558 ixa^l=ixc^l-kr(idim2,^d);
8561 if(lvc(idim1,idim2,idir)==1)
then
8563 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8566 else if(lvc(idim1,idim2,idir)==-1)
then
8568 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8574 {
do ix^db=ixcmin^db,ixcmax^db\}
8576 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
8578 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
8585 end subroutine mhd_update_faces_contact
8588 subroutine mhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
8593 integer,
intent(in) :: ixi^
l, ixo^
l
8594 double precision,
intent(in) :: qt, qdt
8596 double precision,
intent(in) :: wp(ixi^s,1:nw)
8597 type(state) :: sct, s
8598 type(ct_velocity) :: vcts
8599 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
8600 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
8602 double precision :: vtill(ixi^s,2)
8603 double precision :: vtilr(ixi^s,2)
8604 double precision :: bfacetot(ixi^s,
ndim)
8605 double precision :: btill(ixi^s,
ndim)
8606 double precision :: btilr(ixi^s,
ndim)
8607 double precision :: cp(ixi^s,2)
8608 double precision :: cm(ixi^s,2)
8609 double precision :: circ(ixi^s,1:
ndim)
8611 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
8612 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
8613 integer :: idim1,idim2,idir,ix^
d
8615 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
8616 cbarmax=>vcts%cbarmax)
8629 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8645 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
8649 idim2=mod(idir+1,3)+1
8651 jxc^
l=ixc^
l+
kr(idim1,^
d);
8652 ixcp^
l=ixc^
l+
kr(idim2,^
d);
8656 vtill(ixi^s,2),vtilr(ixi^s,2))
8659 vtill(ixi^s,1),vtilr(ixi^s,1))
8665 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
8666 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
8668 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
8669 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
8672 btill(ixi^s,idim1),btilr(ixi^s,idim1))
8675 btill(ixi^s,idim2),btilr(ixi^s,idim2))
8679 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
8680 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
8682 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
8683 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
8687 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
8688 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
8689 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
8690 /(cp(ixc^s,1)+cm(ixc^s,1)) &
8691 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
8692 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
8693 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
8694 /(cp(ixc^s,2)+cm(ixc^s,2))
8697 if(
mhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
8701 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
8715 circ(ixi^s,1:
ndim)=zero
8720 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
8724 if(
lvc(idim1,idim2,idir)/=0)
then
8725 hxc^
l=ixc^
l-
kr(idim2,^
d);
8727 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8728 +
lvc(idim1,idim2,idir)&
8734 {
do ix^db=ixcmin^db,ixcmax^db\}
8736 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
8738 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
8744 end subroutine mhd_update_faces_hll
8747 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
8752 integer,
intent(in) :: ixi^
l, ixo^
l
8754 double precision,
intent(in) :: wp(ixi^s,1:nw)
8755 type(state),
intent(in) :: sct, s
8757 double precision :: jce(ixi^s,
sdim:3)
8760 double precision :: jcc(ixi^s,7-2*
ndir:3)
8762 double precision :: xs(ixgs^t,1:
ndim)
8764 double precision :: eta(ixi^s)
8765 double precision :: gradi(ixgs^t)
8766 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
8768 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
8774 if (
lvc(idim1,idim2,idir)==0) cycle
8776 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8777 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
8780 xs(ixb^s,:)=x(ixb^s,:)
8781 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
8782 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
8783 if (
lvc(idim1,idim2,idir)==1)
then
8784 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
8786 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
8793 jce(ixi^s,:)=jce(ixi^s,:)*
mhd_eta
8801 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8802 jcc(ixc^s,idir)=0.d0
8804 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8805 ixamin^
d=ixcmin^
d+ix^
d;
8806 ixamax^
d=ixcmax^
d+ix^
d;
8807 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
8809 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
8810 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
8815 end subroutine get_resistive_electric_field
8818 subroutine get_ambipolar_electric_field(ixI^L,ixO^L,w,x,fE)
8821 integer,
intent(in) :: ixi^
l, ixo^
l
8822 double precision,
intent(in) :: w(ixi^s,1:nw)
8823 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8824 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
8826 double precision :: jxbxb(ixi^s,1:3)
8827 integer :: idir,ixa^
l,ixc^
l,ix^
d
8830 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,jxbxb)
8837 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8840 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8841 ixamin^
d=ixcmin^
d+ix^
d;
8842 ixamax^
d=ixcmax^
d+ix^
d;
8843 fe(ixc^s,idir)=fe(ixc^s,idir)+jxbxb(ixa^s,idir)
8845 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0
8848 end subroutine get_ambipolar_electric_field
8854 integer,
intent(in) :: ixo^
l
8864 do ix^db=ixomin^db,ixomax^db\}
8866 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8867 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
8868 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8869 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
8870 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
8871 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
8874 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8875 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
8876 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8877 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
8920 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
8921 double precision,
intent(inout) :: ws(ixis^s,1:nws)
8922 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8924 double precision :: adummy(ixis^s,1:3)
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine, public 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 cak_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine, public cak_init(phys_gamma)
Initialize the module.
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)
EoS state container – the single thermodynamic authority for AMRVAC.
integer, parameter, public eos_type_pi
type(eos_container), allocatable, public eos
The single EoS state object, allocated in eos_init and shared (read-mostly) across all EoS sub-module...
integer, parameter, public eos_type_lte
LTE (Saha-table) EoS kernels and finalise for the eos% family.
double precision function, public lte_eint_from_p(pres, nh_val, log_nh_val, rho_val)
LTE internal energy from pressure in one cell: FI bypass, else eint(nH, p).
double precision function, public lte_p_from_eint(eint_val, nh_val, log_nh_val, inv_rho)
LTE pressure from internal energy in one cell: ideal without ionE, else the table floor,...
PI (partial-ionisation) ionisation-degree backend for the eos% family.
PI (partial-ionisation, eos_type='PI') arm of the eos% family.
subroutine, public eint_from_rho_p_pi(rho, p, eint)
Primitive pressure -> GAS internal energy (prim -> conserved direction): invert (rho,...
subroutine, public state_from_eint_pi(rho, eint, t, p, rfactor, iz_h, iz_he)
Conserved gas internal energy -> temperature, thermal pressure, R. Inverse of p_eint_from_rho_T_PI....
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(gas_eos_type, gas_ion_energy, gas_pi_table)
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.
logical h_correction
If true, do H-correction to fix the carbuncle problem at grid-aligned shocks.
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.
logical b0fieldalloccoarse
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
double precision function, public mhd_semirelati_eint(p, rho)
Internal energy from thermal pressure in one cell, the inverse of mhd_semirelati_p.
subroutine, public get_normalized_divb(w, ixil, ixol, divb)
get dimensionless div B = |divB| * volume / area / |B|
integer, public, protected mhd_uawsom_height_dim
Enable conservative kink-wave reflection from the kink-speed gradient Cartesian direction used for th...
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).
double precision, public, protected mhd_squared_c
squared reduced speed of light c
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.
logical, public, protected mhd_radiative_transfer
Whether the short-characteristics radiative transfer is used, with its settings in &rt_list.
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.
subroutine, public mhd_semirelati_vel_emech(w, ixil, ixol, vel, emech)
Velocity from the semirelativistic momentum (Gombosi et al. 2002 eqs 15-16) and emech,...
procedure(mask_subroutine), pointer, public usr_mask_ambipolar
logical, public, protected mhd_semirelati_curl_e
Keep E x curl(E) in the semirelativistic source: eq (26) of Gombosi et al. 2002 keeps it,...
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
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: Enable/disable with mhd_hyperbolic_tc_use_perp,...
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).
double precision function, public mhd_semirelati_p(eint, rho)
Thermal pressure from internal energy in one cell for the active EoS.
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.
Public face of the short-characteristics (SC) radiative transfer and its coupling to the (M)HD.
subroutine, public rt_sc_add_source(qdt, ixil, ixol, wct, w, x, thin_share, e_internal)
Unsplit heating source of one block and stage, e += qdt Q, with Q read from i_qrad,...
subroutine, public rt_sc_activate()
Switch the RT on. The physics module calls this from its initialisation when hd_radiative_transfer or...
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)
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.