22 double precision,
public ::
mhd_eta = 0.0d0
43 double precision,
public,
protected ::
h_ion_fr=1d0
46 double precision,
public,
protected ::
he_ion_fr=1d0
53 double precision,
public,
protected ::
rr=1d0
55 double precision :: inv_squared_c0=0.d0, inv_squared_c=0.d0
62 integer,
public,
protected ::
rho_
64 integer,
allocatable,
public,
protected ::
mom(:)
66 integer,
public,
protected :: ^
c&m^C_
68 integer,
public,
protected ::
e_
70 integer,
public,
protected :: ^
c&b^C_
72 integer,
public,
protected ::
p_
74 integer,
public,
protected ::
ne_
76 integer,
public,
protected ::
qpar_
80 integer,
public,
protected ::
psi_
82 integer,
public,
protected ::
r_e
84 integer,
public,
protected ::
te_
86 integer,
public,
protected ::
fip_ = -1
88 logical,
public,
protected ::
mhd_fip = .false.
93 integer,
allocatable,
public,
protected ::
tracer(:)
101 integer,
parameter :: divb_none = 0
102 integer,
parameter :: divb_multigrid = -1
103 integer,
parameter :: divb_glm = 1
104 integer,
parameter :: divb_powel = 2
105 integer,
parameter :: divb_janhunen = 3
106 integer,
parameter :: divb_linde = 4
107 integer,
parameter :: divb_lindejanhunen = 5
108 integer,
parameter :: divb_lindepowel = 6
109 integer,
parameter :: divb_lindeglm = 7
110 integer,
parameter :: divb_ct = 8
157 logical,
public,
protected ::
mhd_glm = .false.
197 logical :: total_energy = .true.
201 logical :: gravity_energy
203 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
205 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
207 character(len=std_len) :: typedivbdiff =
'all'
218 subroutine mask_subroutine(ixI^L,ixO^L,w,x,res)
220 integer,
intent(in) :: ixi^
l, ixo^
l
221 double precision,
intent(in) :: x(ixi^s,1:
ndim)
222 double precision,
intent(in) :: w(ixi^s,1:nw)
223 double precision,
intent(inout) :: res(ixi^s)
224 end subroutine mask_subroutine
267 subroutine mhd_read_params(files)
270 character(len=*),
intent(in) :: files(:)
290 do n = 1,
size(files)
291 open(
unitpar, file=trim(files(n)), status=
"old")
292 read(
unitpar, mhd_list,
end=111)
298 end subroutine mhd_read_params
301 subroutine mhd_write_info(fh)
303 integer,
intent(in) :: fh
306 integer,
parameter :: n_par = 1
307 double precision :: values(n_par)
308 integer,
dimension(MPI_STATUS_SIZE) :: st
309 character(len=name_len) :: names(n_par)
311 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
314 values(1) = eos%gamma
315 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
316 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
317 end subroutine mhd_write_info
345 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_internal_e=T'
349 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_internal_e=T'
356 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_hydrodynamic_e=T'
360 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_hydrodynamic_e=T'
364 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_hydrodynamic_e=T'
371 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_semirelativistic=T'
375 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_semirelativistic=T'
379 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_semirelativistic=T'
386 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_energy=F'
390 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_energy=F'
394 if(
mype==0)
write(*,*)
'WARNING: set mhd_thermal_conduction=F when mhd_energy=F'
398 if(
mype==0)
write(*,*)
'WARNING: set mhd_hyperbolic_tc=F when mhd_energy=F'
402 if(
mype==0)
write(*,*)
'WARNING: set mhd_radiative_cooling=F when mhd_energy=F'
406 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac=F when mhd_energy=F'
410 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_energy=F'
414 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_energy=F'
420 if(
mype==0)
write(*,*)
'WARNING: set either parabolic TC or hyperbolic TC to F'
421 if(
mype==0)
write(*,*)
'WARNING: defaulting to only mhd_hyperbolic_tc=T'
425 call mpistop(
"mhd_hyperbolic_tc_use_perp is not supported in 1D")
435 phys_gamma = eos%gamma
448 phys_total_energy=total_energy
451 gravity_energy=.false.
453 gravity_energy=.true.
456 gravity_energy=.false.
462 if(
mype==0)
write(*,*)
'WARNING: reset mhd_trac_type=1 for 1D simulation'
467 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac_mask==bigdouble for global TRAC method'
475 type_divb = divb_none
478 if(
mhd_radiation_fld)
call mpistop(
'To verify whether mg usage for FLD versus divB can be combined')
479 type_divb = divb_multigrid
481 mg%operator_type = mg_laplacian
488 case (
'powel',
'powell')
489 type_divb = divb_powel
491 type_divb = divb_janhunen
493 type_divb = divb_linde
494 case (
'lindejanhunen')
495 type_divb = divb_lindejanhunen
497 type_divb = divb_lindepowel
501 type_divb = divb_lindeglm
506 call mpistop(
'Unknown divB fix')
509 allocate(start_indices(number_species),stop_indices(number_species))
516 mom(:) = var_set_momentum(
ndir)
522 e_ = var_set_energy()
531 mag(:) = var_set_bfield(
ndir)
535 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
541 qpar_ = var_set_fluxvar(
'q',
'q', need_bc=.false.)
543 qperp_ = var_set_fluxvar(
'qperp',
'qperp', need_bc=.false.)
554 fip_ = var_set_fluxvar(
'rho_fip',
'fip', need_bc=.false.)
559 if (eos%eos_type ==
'LTE')
then
562 else if (eos%eos_type ==
'PI')
then
573 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
579 write(*,*)
'Warning: CAK force addition together with FLD radiation'
584 write(*,*)
'Warning: Optically thin cooling together with FLD radiation'
588 call mpistop(
'using FLD implies the use of an energy equation, set mhd_energy=T')
591 call mpistop(
'using FLD not yet with semirelativistic energy formalism')
594 call mpistop(
'using FLD not yet with hydrodynamic or internal energy formalism')
597 call mpistop(
'using FLD not yet with split off rho and p')
601 r_e = var_set_radiation_energy()
610 phys_implicit_update => mhd_fld_implicit_update
611 phys_evaluate_implicit => mhd_fld_evaluate_implicit
622 stop_indices(1)=nwflux
650 allocate(iw_vector(nvector))
651 iw_vector(1) =
mom(1) - 1
652 iw_vector(2) = mag(1) - 1
655 if (.not.
allocated(flux_type))
then
656 allocate(flux_type(
ndir, nwflux))
657 flux_type = flux_default
658 else if (any(shape(flux_type) /= [
ndir, nwflux]))
then
659 call mpistop(
"phys_check error: flux_type has wrong shape")
662 if(nwflux>mag(
ndir))
then
664 flux_type(:,mag(
ndir)+1:nwflux)=flux_hll
669 flux_type(:,
psi_)=flux_special
671 flux_type(idir,mag(idir))=flux_special
675 flux_type(idir,mag(idir))=flux_tvdlf
681 phys_get_dt => mhd_get_dt
684 phys_get_cmax => mhd_get_cmax_semirelati
686 phys_get_cmax => mhd_get_cmax_semirelati_noe
690 phys_get_cmax => mhd_get_cmax_origin
692 phys_get_cmax => mhd_get_cmax_origin_noe
695 phys_get_tcutoff => mhd_get_tcutoff
696 phys_get_h_speed => mhd_get_h_speed
698 phys_get_cbounds => mhd_get_cbounds_split_rho
700 phys_get_cbounds => mhd_get_cbounds_semirelati
702 phys_get_cbounds => mhd_get_cbounds
712 phys_get_flux => mhd_get_flux_hde
715 phys_get_flux => mhd_get_flux_semirelati
717 phys_get_flux => mhd_get_flux_semirelati_noe
721 phys_get_flux => mhd_get_flux_split
723 phys_get_flux => mhd_get_flux
725 phys_get_flux => mhd_get_flux_noe
730 phys_add_source_geom => mhd_add_source_geom_semirelati
732 phys_add_source_geom => mhd_add_source_geom_split
734 phys_add_source_geom => mhd_add_source_geom
736 phys_add_source => mhd_add_source
737 phys_check_params => mhd_check_params
738 phys_write_info => mhd_write_info
741 phys_handle_small_values => mhd_handle_small_values_inte
742 mhd_handle_small_values => mhd_handle_small_values_inte
743 phys_check_w => mhd_check_w_inte
745 phys_handle_small_values => mhd_handle_small_values_hde
746 mhd_handle_small_values => mhd_handle_small_values_hde
747 phys_check_w => mhd_check_w_hde
749 phys_handle_small_values => mhd_handle_small_values_semirelati
750 mhd_handle_small_values => mhd_handle_small_values_semirelati
751 phys_check_w => mhd_check_w_semirelati
753 phys_handle_small_values => mhd_handle_small_values_split
754 mhd_handle_small_values => mhd_handle_small_values_split
755 phys_check_w => mhd_check_w_split
757 phys_handle_small_values => mhd_handle_small_values_origin
758 mhd_handle_small_values => mhd_handle_small_values_origin
759 phys_check_w => mhd_check_w_origin
761 phys_handle_small_values => mhd_handle_small_values_noe
762 mhd_handle_small_values => mhd_handle_small_values_noe
763 phys_check_w => mhd_check_w_noe
769 phys_set_equi_vars => set_equi_vars_grid
772 if(type_divb==divb_glm)
then
773 phys_modify_wlr => mhd_modify_wlr
784 transverse_ghost_cells = 1
785 phys_get_ct_velocity => mhd_get_ct_velocity_average
786 phys_update_faces => mhd_update_faces_average
788 transverse_ghost_cells = 1
789 phys_get_ct_velocity => mhd_get_ct_velocity_contact
790 phys_update_faces => mhd_update_faces_contact
792 transverse_ghost_cells = 2
793 phys_get_ct_velocity => mhd_get_ct_velocity_hll
794 phys_update_faces => mhd_update_faces_hll
796 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
799 phys_modify_wlr => mhd_modify_wlr
801 phys_boundary_adjust => mhd_boundary_adjust
807 call mpistop(
'To verify whether mg usage for FLD versus divB can be combined')
812 call mhd_physical_units()
827 case(
'fixed_reference')
837 case(
'weak_field_isotropization')
841 case(
'electron_magnetization')
843 call mpistop(
"mhd_hyperbolic_tc_coulomb_log must be positive")
846 call mpistop(
"invalid mhd_hyperbolic_tc_perp_mode: "// &
852 call mpistop(
"thermal conduction needs mhd_energy=T")
855 call mpistop(
"hyperbolic thermal conduction needs mhd_energy=T")
858 call mpistop(
"radiative cooling needs mhd_energy=T")
863 iw_log_nh = var_set_wextra()
869 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no splitting or total e in use'
872 if(
mype==0)
write(*,*)
'Will subtract thermal balance in TC or RC with mhd_equi_thermal=T'
875 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no TC or RC in use'
899 phys_e_to_ei => mhd_e_to_ei_hde
900 phys_ei_to_e => mhd_ei_to_e_hde
903 phys_e_to_ei => mhd_e_to_ei_semirelati
904 phys_ei_to_e => mhd_ei_to_e_semirelati
906 if (iw_log_nh > 0)
then
923 phys_e_to_ei => mhd_e_to_ei_hde
924 phys_ei_to_e => mhd_ei_to_e_hde
926 phys_e_to_ei => mhd_e_to_ei_semirelati
927 phys_ei_to_e => mhd_ei_to_e_semirelati
950 phys_te_images => mhd_te_images
956 write(*,*)
'*****Using hyperresistivity: with mhd_eta_hyper :',
mhd_eta_hyper
960 call mpistop(
"Must have B0field=F when using hyperresistivity")
964 call mpistop(
"Must have mhd_eta_hyper positive when using hyperresistivity")
981 call mpistop(
"Must have has_equi_rho_and_p=F when mhd_rotating_frame=T")
995 call mpistop(
"Must have mhd_hall=F when mhd_semirelativistic=T")
999 call mpistop(
"Must have Cartesian coordinates for Hall")
1003 phys_wider_stencil = 1
1010 phys_wider_stencil=max(phys_wider_stencil,1)
1017 call add_sts_method(get_ambipolar_dt,sts_set_source_ambipolar,mag(1),&
1028 phys_wider_stencil = 1
1038 call mpistop(
"CAK implementation not available in internal or semirelativistic variants")
1041 call mpistop(
"CAK force implementation not available for split off pressure and density")
1049 subroutine mhd_te_images
1054 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
1056 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
1058 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
1060 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
1063 call mpistop(
"Error in synthesize emission: Unknown convert_type")
1065 end subroutine mhd_te_images
1071 subroutine mhd_sts_set_source_tc_mhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1075 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1076 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1077 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1078 double precision,
intent(in) :: my_dt
1079 logical,
intent(in) :: fix_conserve_at_step
1081 end subroutine mhd_sts_set_source_tc_mhd
1083 subroutine mhd_sts_set_source_tc_hd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1087 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1088 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1089 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1090 double precision,
intent(in) :: my_dt
1091 logical,
intent(in) :: fix_conserve_at_step
1093 end subroutine mhd_sts_set_source_tc_hd
1095 function mhd_get_tc_dt_mhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1102 integer,
intent(in) :: ixi^
l, ixo^
l
1103 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1104 double precision,
intent(in) :: w(ixi^s,1:nw)
1105 double precision :: dtnew
1108 end function mhd_get_tc_dt_mhd
1110 function mhd_get_tc_dt_hd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1117 integer,
intent(in) :: ixi^
l, ixo^
l
1118 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1119 double precision,
intent(in) :: w(ixi^s,1:nw)
1120 double precision :: dtnew
1123 end function mhd_get_tc_dt_hd
1125 subroutine mhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
1128 integer,
intent(in) :: ixi^
l,ixo^
l
1129 double precision,
intent(inout) :: w(ixi^s,1:nw)
1130 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1131 integer,
intent(in) :: step
1132 character(len=140) :: error_msg
1138 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
1139 call mhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
1140 end subroutine mhd_tc_handle_small_e
1143 subroutine tc_params_read_mhd(fl)
1145 type(tc_fluid),
intent(inout) :: fl
1147 double precision :: tc_k_para=0d0
1148 double precision :: tc_k_perp=0d0
1151 logical :: tc_perpendicular=.false.
1152 logical :: tc_saturate=.false.
1153 logical :: tc_patch_eint=.false.
1154 double precision :: trac_t_floor=0.d0
1155 character(len=std_len) :: tc_slope_limiter=
"MC"
1157 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp, tc_patch_eint, trac_t_floor
1161 read(
unitpar, tc_list,
end=111)
1165 fl%tc_perpendicular = tc_perpendicular
1166 fl%tc_saturate = tc_saturate
1167 fl%tc_patch_eint = tc_patch_eint
1168 fl%tc_k_para = tc_k_para
1169 fl%tc_k_perp = tc_k_perp
1170 fl%trac_T_floor = trac_t_floor / unit_temperature
1171 select case(tc_slope_limiter)
1173 fl%tc_slope_limiter = 0
1176 fl%tc_slope_limiter = 1
1179 fl%tc_slope_limiter = 2
1182 fl%tc_slope_limiter = 3
1185 fl%tc_slope_limiter = 4
1188 fl%tc_slope_limiter = 5
1190 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod, superbee, koren, vanleer")
1192 end subroutine tc_params_read_mhd
1196 subroutine rc_params_read(fl)
1199 type(rc_fluid),
intent(inout) :: fl
1203 double precision :: rad_damp_height=0.5d0
1204 double precision :: rad_damp_scale=0.15d0
1207 integer :: ncool = 4000
1209 logical :: tfix=.false.
1211 logical :: rc_split=.false.
1212 logical :: rad_damp=.false.
1214 character(len=std_len) :: coolcurve=
'JCcorona'
1215 logical :: rad_newton = .false.
1216 double precision :: rad_newton_trad = 0.006d0
1217 double precision :: rad_newton_rhosurf = 1.d4
1218 double precision :: rad_newton_pthick = 25.d0
1220 double precision :: cfrac=0.1d0
1221 double precision :: rad_cut_hgt=0.5d0
1222 double precision :: rad_cut_dey=0.15d0
1224 character(len=8) :: rc_y_mod_quadrature=
'boole'
1225 integer :: rc_y_mod_n_sub=16
1227 namelist /rc_list/ coolcurve, ncool, cfrac, tlow, tfix, rc_split, &
1228 rad_cut_hgt, rad_cut_dey, &
1229 rc_y_mod_quadrature, rc_y_mod_n_sub, &
1230 rad_newton, rad_newton_trad, rad_newton_rhosurf, &
1231 rad_newton_pthick, rad_damp, rad_damp_height, rad_damp_scale
1235 read(
unitpar, rc_list,
end=111)
1240 fl%coolcurve=coolcurve
1243 fl%rc_split=rc_split
1245 fl%rad_cut_hgt=rad_cut_hgt
1246 fl%rad_cut_dey=rad_cut_dey
1247 fl%Y_mod_quadrature=rc_y_mod_quadrature
1248 fl%Y_mod_N_sub=rc_y_mod_n_sub
1249 fl%rad_damp=rad_damp
1250 fl%rad_damp_height=rad_damp_height
1251 fl%rad_damp_scale=rad_damp_scale
1252 fl%rad_newton=rad_newton
1253 fl%rad_newton_trad=rad_newton_trad
1254 fl%rad_newton_rhosurf=rad_newton_rhosurf
1255 fl%rad_newton_pthick=rad_newton_pthick
1256 end subroutine rc_params_read
1259 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
1262 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
1263 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1265 double precision :: delx(ixi^s,1:
ndim)
1266 double precision :: xc(ixi^s,1:
ndim),xshift^
d
1267 integer :: idims, ixc^
l, hxo^
l, ix, idims2
1273 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
1277 hxo^
l=ixo^
l-
kr(idims,^
d);
1283 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
1286 xshift^
d=half*(one-
kr(^
d,idims));
1293 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
1297 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
1299 end subroutine set_equi_vars_grid_faces
1302 subroutine set_equi_vars_grid(igrid)
1306 integer,
intent(in) :: igrid
1312 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
1314 end subroutine set_equi_vars_grid
1317 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
1319 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
1320 double precision,
intent(in) :: w(ixi^s, 1:nw)
1321 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1322 double precision :: wnew(ixo^s, 1:nwc)
1329 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
1335 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
1339 wnew(ixo^s,
e_)=w(ixo^s,
e_)
1341 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+
block%equi_vars(ixo^s,
equi_pe0_,0)*eos%inv_gamma_minus_1
1343 if(
b0field .and. total_energy)
then
1344 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
1345 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
1349 end function convert_vars_splitting
1351 subroutine mhd_check_params
1358 ngridvars,num_particles,physics_type_particles
1361 double precision :: a,
b,xfrac,yfrac
1366 if (particles_eta < zero) particles_eta =
mhd_eta
1367 if (particles_etah < zero) particles_eta =
mhd_etah
1372 if (eos%gamma <= 0.0d0)
call mpistop (
"Error: gamma <= 0")
1373 if (
mhd_adiab < 0.0d0)
call mpistop (
"Error: mhd_adiab < 0")
1376 if (eos%gamma <= 0.0d0 .or. eos%gamma == 1.0d0) &
1377 call mpistop (
"Error: gamma <= 0 or gamma == 1")
1383 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
1388 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
1396 call mpistop(
'select IMEX scheme for FLD radiation use')
1399 call phys_set_mg_bounds()
1401 if(.not.
fld_no_mg)
call mpistop(
'multigrid must have BCs for IMEX and FLD radiation use')
1404 write(*,*)
'==FLD SETUP======================'
1405 write(*,*)
'Using FLD with settings:'
1410 write(*,*)
'Using FLD with settings: fld_kappa0=',
fld_kappa0
1411 write(*,*)
'Using FLD with settings: fld_opal_table=',
fld_opal_table
1413 write(*,*)
'Using FLD with settings: fld_bisect_tol=',
fld_bisect_tol
1414 write(*,*)
'Using FLD with settings: fld_diff_tol=',
fld_diff_tol
1418 print *,
'NORMALIZED arad_norm=',
arad_norm
1419 print *,
'NORMALIZED c_norm=',
c_norm
1426 print *,
'physical fld_kappa (in cgs or SI) =',
fld_kappa0
1429 write(*,*)
'===FLD SETUP====================='
1434 write(*,*)
'====MHD run with settings===================='
1435 write(*,*)
'Using mod_mhd_phys with settings:'
1437 write(*,*)
'Dimensionality :',
ndim
1438 write(*,*)
'vector components:',
ndir
1440 write(*,*)
'number of variables nw=',nw
1441 write(*,*)
' start index iwstart=',iwstart
1442 write(*,*)
'number of vector variables=',nvector
1443 write(*,*)
'number of stagger variables nws=',nws
1444 write(*,*)
'number of variables with BCs=',nwgc
1445 write(*,*)
'number of vars with fluxes=',nwflux
1446 write(*,*)
'number of vars with flux + BC=',nwfluxbc
1447 write(*,*)
'number of auxiliary variables=',nwaux
1448 write(*,*)
'number of extra vars without flux=',nwextra
1449 write(*,*)
'number of extra vars for wextra=',nw_extra
1450 write(*,*)
'number of auxiliary I/O variables=',
nwauxio
1452 write(*,*)
' mhd_energy=',
mhd_energy,
' with total_energy=',total_energy
1457 write(*,*)
' mhd_eta=',
mhd_eta,
' nonzero implies resistivity'
1471 write(*,*)
'*****Using particles: with mhd_eta, mhd_etah :',
mhd_eta,
mhd_etah
1472 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
1473 write(*,*)
'*****Using particles: npayload,ngridvars :', npayload,ngridvars
1474 write(*,*)
'*****Using particles: nusrpayload :', nusrpayload
1475 write(*,*)
'*****Using particles: num_particles :', num_particles
1476 write(*,*)
'*****Using particles: physics_type_particles=',physics_type_particles
1479 write(*,*)
'number due to phys_wider_stencil=',phys_wider_stencil
1480 write(*,*)
'==========================================='
1481 print *,
'========EOS and UNITS==========='
1483 print *,
'gamma=',eos%gamma
1484 print *,
'He_abundance =',eos%He_abundance
1486 print *,
'========EOS and UNITS==========='
1508 print *,
' compare this to ',mp_si*(1.d0+4.d0*eos%He_abundance)
1510 print *,
' compare this to ',mp_cgs*(1.d0+4.d0*eos%He_abundance)
1514 print *,
' compare this to ',kb_si*(2.d0+3.d0*eos%He_abundance)
1518 print *,
' compare this to ',kb_cgs*(2.d0+3.d0*eos%He_abundance)
1522 if(eos%eos_type /=
'LTE')
then
1523 print *,
'mean molecular weight mu is =',a/
b,
' = ', (1.d0+4.d0*eos%He_abundance)/(2.d0+3.d0*eos%He_abundance)
1525 yfrac=4.d0*eos%He_abundance/(1.d0+4.d0*eos%He_abundance)
1526 print *,
'mass fraction hydrogen X is =',1/a,
' and this equals ', 1.d0/(1.d0+4.d0*eos%He_abundance)
1527 print *,
'mass fraction helium Y is =',yfrac
1528 print *,
' check that 1/mu',
b/a,
' is equal to 2X+3Y/4=',2.d0*xfrac+3.d0*yfrac/4.d0
1529 print *,
' ratio n_e/n_p=',1.d0+2.0d0*eos%He_abundance
1531 print *,
'========UNITS==========='
1534 end subroutine mhd_check_params
1536 subroutine mhd_physical_units()
1538 double precision :: mp,kb,miu0,c_lightspeed,xfrac,sigma_telectron
1539 double precision :: a,
b
1547 sigma_telectron=sigma_te_si
1553 c_lightspeed=const_c
1554 sigma_telectron=sigma_te_cgs
1559 if (eos%eos_type ==
'LTE')
then
1563 eos%nH2rhoFactor = 1d0+4d0*eos%He_abundance
1564 rr=(2d0+3d0*eos%He_abundance) / (1d0+4d0*eos%He_abundance)
1565 xfrac=1.d0/(1.d0+4.d0*eos%He_abundance)
1569 a=1d0+4d0*eos%He_abundance
1570 if(eos%eos_type==
'PI')
then
1573 b=2d0+3d0*eos%He_abundance
1705 eos%inv_squared_c0 = inv_squared_c0
1706 eos%inv_squared_c = inv_squared_c
1722 end subroutine mhd_physical_units
1724 subroutine mhd_check_w_semirelati(primitive,ixI^L,ixO^L,w,flag)
1727 logical,
intent(in) :: primitive
1728 logical,
intent(inout) :: flag(ixi^s,1:nw)
1729 integer,
intent(in) :: ixi^
l, ixo^
l
1730 double precision,
intent(in) :: w(ixi^s,nw)
1732 double precision :: tmp,
b(1:
ndir),v(1:
ndir),factor
1743 {
do ix^db=ixomin^db,ixomax^db \}
1747 {
do ix^db=ixomin^db,ixomax^db \}
1749 tmp=(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)*inv_squared_c
1750 factor=1.0d0/(w(ix^d,
rho_)*(w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+)*inv_squared_c))
1751 ^
c&v(^
c)=factor*(w(ix^d,
m^
c_)*w(ix^d,
rho_)+w(ix^d,
b^
c_)*tmp)\
1754 b(1)=w(ix^d,b2_)*v(3)-w(ix^d,b3_)*v(2)
1755 b(2)=w(ix^d,b3_)*v(1)-w(ix^d,b1_)*v(3)
1756 b(3)=w(ix^d,b1_)*v(2)-w(ix^d,b2_)*v(1)
1761 b(2)=w(ix^d,b1_)*v(2)-w(ix^d,b2_)*v(1)
1767 tmp=w(ix^d,
e_)-half*((^
c&v(^
c)**2+)*w(ix^d,
rho_)&
1768 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&
b(^
c)**2+)*inv_squared_c)
1769 if(tmp<small_e) flag(ix^d,
e_)=.true.
1775 end subroutine mhd_check_w_semirelati
1777 subroutine mhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1780 logical,
intent(in) :: primitive
1781 integer,
intent(in) :: ixi^
l, ixo^
l
1782 double precision,
intent(in) :: w(ixi^s,nw)
1783 logical,
intent(inout) :: flag(ixi^s,1:nw)
1788 {
do ix^db=ixomin^db,ixomax^db\}
1801 end subroutine mhd_check_w_origin
1803 subroutine mhd_check_w_split(primitive,ixI^L,ixO^L,w,flag)
1806 logical,
intent(in) :: primitive
1807 integer,
intent(in) :: ixi^
l, ixo^
l
1808 double precision,
intent(in) :: w(ixi^s,nw)
1809 logical,
intent(inout) :: flag(ixi^s,1:nw)
1811 double precision :: tmp
1815 {
do ix^db=ixomin^db,ixomax^db\}
1821 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1826 end subroutine mhd_check_w_split
1828 subroutine mhd_check_w_noe(primitive,ixI^L,ixO^L,w,flag)
1831 logical,
intent(in) :: primitive
1832 integer,
intent(in) :: ixi^
l, ixo^
l
1833 double precision,
intent(in) :: w(ixi^s,nw)
1834 logical,
intent(inout) :: flag(ixi^s,1:nw)
1839 {
do ix^db=ixomin^db,ixomax^db\}
1843 end subroutine mhd_check_w_noe
1845 subroutine mhd_check_w_inte(primitive,ixI^L,ixO^L,w,flag)
1848 logical,
intent(in) :: primitive
1849 integer,
intent(in) :: ixi^
l, ixo^
l
1850 double precision,
intent(in) :: w(ixi^s,nw)
1851 logical,
intent(inout) :: flag(ixi^s,1:nw)
1856 {
do ix^db=ixomin^db,ixomax^db\}
1865 end subroutine mhd_check_w_inte
1867 subroutine mhd_check_w_hde(primitive,ixI^L,ixO^L,w,flag)
1870 logical,
intent(in) :: primitive
1871 integer,
intent(in) :: ixi^
l, ixo^
l
1872 double precision,
intent(in) :: w(ixi^s,nw)
1873 logical,
intent(inout) :: flag(ixi^s,1:nw)
1878 {
do ix^db=ixomin^db,ixomax^db\}
1887 end subroutine mhd_check_w_hde
1889 subroutine mhd_bound_fip(primitive, ixI^L, ixO^L, w)
1891 logical,
intent(in) :: primitive
1892 integer,
intent(in) :: ixi^
l, ixo^
l
1893 double precision,
intent(inout) :: w(ixi^s,1:nw)
1895 double precision :: rho_safe(ixi^s), fip_prim(ixi^s)
1907 fip_prim(ixo^s) = w(ixo^s,
fip_) / rho_safe(ixo^s)
1908 fip_prim(ixo^s) = min(
maxfip, max(
minfip, fip_prim(ixo^s)))
1909 w(ixo^s,
fip_) = rho_safe(ixo^s) * fip_prim(ixo^s)
1911 end subroutine mhd_bound_fip
1916 integer,
intent(in) :: ixi^
l, ixo^
l
1917 double precision,
intent(inout) :: w(ixi^s, nw)
1918 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1923 {
do ix^db=ixomin^db,ixomax^db\}
1926 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1928 +(^
c&w(ix^
d,
b^
c_)**2+))
1931 {
do ix^db=ixomin^db,ixomax^db\}
1933 w(ix^d,
e_)=w(ix^d,
e_)&
1934 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1935 +(^
c&w(ix^d,
b^
c_)**2+))
1941 subroutine mhd_ei_to_e_hde(ixI^L,ixO^L,w,x)
1943 integer,
intent(in) :: ixi^
l, ixo^
l
1944 double precision,
intent(inout) :: w(ixi^s, nw)
1945 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1949 {
do ix^db=ixomin^db,ixomax^db\}
1955 end subroutine mhd_ei_to_e_hde
1958 subroutine mhd_ei_to_e_semirelati(ixI^L,ixO^L,w,x)
1960 integer,
intent(in) :: ixi^
l, ixo^
l
1961 double precision,
intent(inout) :: w(ixi^s, nw)
1962 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1964 w(ixo^s,
p_)=w(ixo^s,
e_)*eos%gamma_minus_1
1966 call eos%to_conserved(ixi^
l,ixo^
l,w,x)
1968 end subroutine mhd_ei_to_e_semirelati
1973 integer,
intent(in) :: ixi^
l, ixo^
l
1974 double precision,
intent(inout) :: w(ixi^s, nw)
1975 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1980 {
do ix^db=ixomin^db,ixomax^db\}
1983 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
1985 +(^
c&w(ix^
d,
b^
c_)**2+))
1988 {
do ix^db=ixomin^db,ixomax^db\}
1990 w(ix^d,
e_)=w(ix^d,
e_)&
1991 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
1992 +(^
c&w(ix^d,
b^
c_)**2+))
1996 if(fix_small_values)
then
1997 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei')
2005 subroutine mhd_e_to_ei_and_cache_log_nh(ixI^L,ixO^L,w,x)
2007 integer,
intent(in) :: ixi^
l, ixo^
l
2008 double precision,
intent(inout) :: w(ixi^s, nw)
2009 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2012 block%wextra(ixo^s, iw_log_nh) = dlog10(w(ixo^s,
rho_) / eos%nH2rhoFactor)
2013 end subroutine mhd_e_to_ei_and_cache_log_nh
2016 subroutine mhd_e_to_ei_hde(ixI^L,ixO^L,w,x)
2018 integer,
intent(in) :: ixi^
l, ixo^
l
2019 double precision,
intent(inout) :: w(ixi^s, nw)
2020 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2024 {
do ix^db=ixomin^db,ixomax^db\}
2030 if(fix_small_values)
then
2031 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei_hde')
2034 end subroutine mhd_e_to_ei_hde
2037 subroutine mhd_e_to_ei_semirelati(ixI^L,ixO^L,w,x)
2039 integer,
intent(in) :: ixi^
l, ixo^
l
2040 double precision,
intent(inout) :: w(ixi^s, nw)
2041 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2043 call eos%to_primitive(ixi^
l,ixo^
l,w,x)
2044 w(ixo^s,
e_)=w(ixo^s,
p_)*eos%inv_gamma_minus_1
2046 end subroutine mhd_e_to_ei_semirelati
2048 subroutine mhd_handle_small_values_semirelati(primitive, w, x, ixI^L, ixO^L, subname)
2051 logical,
intent(in) :: primitive
2052 integer,
intent(in) :: ixi^
l,ixo^
l
2053 double precision,
intent(inout) :: w(ixi^s,1:nw)
2054 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2055 character(len=*),
intent(in) :: subname
2057 double precision :: e(ixi^s,1:
ndir), pressure(ixi^s), v(ixi^s,1:
ndir)
2058 double precision :: tmp, factor
2060 logical :: flag(ixi^s,1:nw)
2069 {
do ix^db=ixomin^db,ixomax^db\}
2071 tmp=(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)*inv_squared_c
2072 factor=1.0d0/(w(ix^
d,
rho_)*(w(ix^
d,
rho_)+(^
c&w(ix^
d,
b^
c_)**2+)*inv_squared_c))
2076 e(ix^
d,1)=w(ix^
d,b2_)*v(ix^
d,3)-w(ix^
d,b3_)*v(ix^
d,2)
2077 e(ix^
d,2)=w(ix^
d,b3_)*v(ix^
d,1)-w(ix^
d,b1_)*v(ix^
d,3)
2078 e(ix^
d,3)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
2082 e(ix^
d,2)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
2088 pressure(ix^
d)=eos%gamma_minus_1*(w(ix^
d,
e_)&
2089 -half*((^
c&v(ix^
d,^
c)**2+)*w(ix^
d,
rho_)&
2090 +(^
c&w(ix^
d,
b^
c_)**2+)+(^
c&e(ix^
d,^
c)**2+)*inv_squared_c))
2097 select case (small_values_method)
2099 {
do ix^db=ixomin^db,ixomax^db\}
2100 if(flag(ix^d,
rho_))
then
2101 w(ix^d,
rho_) = small_density
2102 ^
c&w(ix^d,
m^
c_)=0.d0\
2106 if(flag(ix^d,
e_)) w(ix^d,
p_) = small_pressure
2108 if(flag(ix^d,
e_))
then
2109 w(ix^d,
e_)=small_pressure*eos%inv_gamma_minus_1+half*((^
c&v(ix^d,^
c)**2+)*w(ix^d,
rho_)&
2110 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&e(ix^d,^
c)**2+)*inv_squared_c)
2117 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2120 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2122 w(ixo^s,
e_)=pressure(ixo^s)
2123 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2124 {
do ix^db=ixomin^db,ixomax^db\}
2125 w(ix^d,
e_)=w(ix^d,
p_)*eos%inv_gamma_minus_1+half*((^
c&v(ix^d,^
c)**2+)*w(ix^d,
rho_)&
2126 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&e(ix^d,^
c)**2+)*inv_squared_c)
2131 if(.not.primitive)
then
2133 w(ixo^s,
mom(1:ndir))=v(ixo^s,1:ndir)
2136 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2139 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2140 end subroutine mhd_handle_small_values_semirelati
2142 subroutine mhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
2145 logical,
intent(in) :: primitive
2146 integer,
intent(in) :: ixi^
l,ixo^
l
2147 double precision,
intent(inout) :: w(ixi^s,1:nw)
2148 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2149 character(len=*),
intent(in) :: subname
2152 logical :: flag(ixi^s,1:nw)
2154 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2159 {
do ix^db=ixomin^db,ixomax^db\}
2163 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2180 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2182 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2185 {
do ix^db=iximin^db,iximax^db\}
2186 w(ix^d,
e_)=w(ix^d,
e_)&
2187 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))
2189 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2191 {
do ix^db=iximin^db,iximax^db\}
2192 w(ix^d,
e_)=w(ix^d,
e_)&
2193 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))
2197 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
2200 if(.not.primitive)
then
2202 {
do ix^db=ixomin^db,ixomax^db\}
2204 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)&
2205 -half*((^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+)))
2208 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2211 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2212 end subroutine mhd_handle_small_values_origin
2214 subroutine mhd_handle_small_values_split(primitive, w, x, ixI^L, ixO^L, subname)
2217 logical,
intent(in) :: primitive
2218 integer,
intent(in) :: ixi^
l,ixo^
l
2219 double precision,
intent(inout) :: w(ixi^s,1:nw)
2220 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2221 character(len=*),
intent(in) :: subname
2223 double precision :: rho
2225 logical :: flag(ixi^s,1:nw)
2227 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2232 {
do ix^db=ixomin^db,ixomax^db\}
2237 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2250 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2252 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2255 {
do ix^db=iximin^db,iximax^db\}
2257 w(ix^d,
e_)=w(ix^d,
e_)&
2258 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2260 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2262 {
do ix^db=iximin^db,iximax^db\}
2264 w(ix^d,
e_)=w(ix^d,
e_)&
2265 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2269 if(.not.primitive)
then
2271 {
do ix^db=ixomin^db,ixomax^db\}
2273 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
2274 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)&
2275 -half*((^
c&w(ix^d,
m^
c_)**2+)*rho+(^
c&w(ix^d,
b^
c_)**2+)))
2278 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2281 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2282 end subroutine mhd_handle_small_values_split
2284 subroutine mhd_handle_small_values_inte(primitive, w, x, ixI^L, ixO^L, subname)
2287 logical,
intent(in) :: primitive
2288 integer,
intent(in) :: ixi^
l,ixo^
l
2289 double precision,
intent(inout) :: w(ixi^s,1:nw)
2290 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2291 character(len=*),
intent(in) :: subname
2294 logical :: flag(ixi^s,1:nw)
2296 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2301 {
do ix^db=ixomin^db,ixomax^db\}
2302 if(flag(ix^
d,
rho_))
then
2304 ^
c&w(ix^
d,
m^
c_)=0.d0\
2314 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2316 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2318 if(.not.primitive)
then
2320 {
do ix^db=ixomin^db,ixomax^db\}
2322 w(ix^d,
p_)=eos%gamma_minus_1*w(ix^d,
e_)
2325 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2328 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2329 end subroutine mhd_handle_small_values_inte
2331 subroutine mhd_handle_small_values_noe(primitive, w, x, ixI^L, ixO^L, subname)
2334 logical,
intent(in) :: primitive
2335 integer,
intent(in) :: ixi^
l,ixo^
l
2336 double precision,
intent(inout) :: w(ixi^s,1:nw)
2337 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2338 character(len=*),
intent(in) :: subname
2341 logical :: flag(ixi^s,1:nw)
2343 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2348 {
do ix^db=ixomin^db,ixomax^db\}
2352 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2358 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2360 if(.not.primitive)
then
2362 {
do ix^db=ixomin^db,ixomax^db\}
2366 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2369 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2370 end subroutine mhd_handle_small_values_noe
2372 subroutine mhd_handle_small_values_hde(primitive, w, x, ixI^L, ixO^L, subname)
2375 logical,
intent(in) :: primitive
2376 integer,
intent(in) :: ixi^
l,ixo^
l
2377 double precision,
intent(inout) :: w(ixi^s,1:nw)
2378 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2379 character(len=*),
intent(in) :: subname
2382 logical :: flag(ixi^s,1:nw)
2384 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2389 {
do ix^db=ixomin^db,ixomax^db\}
2390 if(flag(ix^
d,
rho_))
then
2392 ^
c&w(ix^
d,
m^
c_)=0.d0\
2402 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2404 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2406 if(.not.primitive)
then
2408 {
do ix^db=ixomin^db,ixomax^db\}
2410 w(ix^d,
p_)=eos%gamma_minus_1*(w(ix^d,
e_)-half*(^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_))
2413 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2416 if (
mhd_fip)
call mhd_bound_fip(primitive, ixi^l, ixo^l, w)
2417 end subroutine mhd_handle_small_values_hde
2423 integer,
intent(in) :: ixi^
l, ixo^
l
2424 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
2425 double precision,
intent(out) :: v(ixi^s,
ndir)
2427 double precision :: rho(ixi^s)
2432 rho(ixo^s)=1.d0/rho(ixo^s)
2435 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
2441 subroutine mhd_get_csound2(w,x,ixI^L,ixO^L,cs2)
2444 integer,
intent(in) :: ixi^
l, ixo^
l
2445 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2446 double precision,
intent(inout) :: cs2(ixi^s)
2448 double precision :: rho, inv_rho, ploc
2451 {
do ix^db=ixomin^db,ixomax^db \}
2461 cs2(ix^
d)=eos%gamma*ploc*inv_rho
2463 end subroutine mhd_get_csound2
2466 subroutine mhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
2469 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2470 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2471 double precision,
intent(inout) :: cmax(ixi^s)
2473 double precision :: rho, inv_rho, ploc, cfast2, avmincs2, b2, kmax
2474 double precision :: cs2(ixi^s)
2475 double precision,
allocatable :: w_eos(:^
d&,:)
2485 allocate(w_eos(ixi^s,nw))
2486 w_eos(ixo^s,:) = w(ixo^s,:)
2491 call eos%get_csound2(w_eos, x, ixi^
l, ixo^
l, cs2)
2494 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
2498 {
do ix^db=ixomin^db,ixomax^db \}
2507 cmax(ix^
d)=cs2(ix^
d)
2510 cfast2=b2*inv_rho+cmax(ix^
d)
2511 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
2512 if(avmincs2<zero) avmincs2=zero
2513 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2517 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2519 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
2522 {
do ix^db=ixomin^db,ixomax^db \}
2525 ploc=(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i))
2531 cmax(ix^d)=cs2(ix^d)
2533 b2=(^
c&w(ix^d,
b^
c_)**2+)
2534 cfast2=b2*inv_rho+cmax(ix^d)
2535 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2536 if(avmincs2<zero) avmincs2=zero
2537 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2541 cmax(ix^d)=max(cmax(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2543 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
2547 end subroutine mhd_get_cmax_origin
2550 subroutine mhd_get_cmax_origin_noe(w,x,ixI^L,ixO^L,idim,cmax)
2554 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2555 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2556 double precision,
intent(inout) :: cmax(ixi^s)
2558 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
2559 double precision :: adiabs(ixi^s), gammas(ixi^s)
2574 {
do ix^db=ixomin^db,ixomax^db \}
2578 cmax(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*rho**(gammas(ix^
d)-1.d0)
2580 b2=(^
c&w(ix^
d,
b^
c_)**2+)
2581 cfast2=b2*inv_rho+cmax(ix^
d)
2582 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*w(ix^
d,mag(idim))**2*inv_rho
2583 if(avmincs2<zero) avmincs2=zero
2584 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2588 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2590 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
2593 end subroutine mhd_get_cmax_origin_noe
2596 subroutine mhd_get_cmax_semirelati(w,x,ixI^L,ixO^L,idim,cmax)
2599 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2600 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2601 double precision,
intent(inout):: cmax(ixi^s)
2603 double precision :: csound, avmincs2, idim_alfven_speed2
2604 double precision :: inv_rho, alfven_speed2, gamma2
2607 {
do ix^db=ixomin^db,ixomax^db \}
2608 inv_rho=1.d0/w(ix^
d,
rho_)
2609 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
2610 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
2611 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
2613 csound=eos%gamma*w(ix^
d,
p_)*inv_rho
2614 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
2617 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
2618 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
2619 if(avmincs2<zero) avmincs2=zero
2621 csound = sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
2622 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+csound
2625 end subroutine mhd_get_cmax_semirelati
2628 subroutine mhd_get_cmax_semirelati_noe(w,x,ixI^L,ixO^L,idim,cmax)
2632 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2633 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2634 double precision,
intent(inout):: cmax(ixi^s)
2636 double precision :: adiabs(ixi^s), gammas(ixi^s)
2637 double precision :: csound, avmincs2, idim_alfven_speed2
2638 double precision :: inv_rho, alfven_speed2, gamma2
2652 {
do ix^db=ixomin^db,ixomax^db \}
2653 inv_rho=1.d0/w(ix^
d,
rho_)
2654 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
2655 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
2656 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
2657 csound=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
2658 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
2661 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
2662 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
2663 if(avmincs2<zero) avmincs2=zero
2665 csound = sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
2666 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+csound
2669 end subroutine mhd_get_cmax_semirelati_noe
2672 subroutine mhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
2675 integer,
intent(in) :: ixi^
l,ixo^
l
2676 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2678 double precision,
intent(inout) :: w(ixi^s,1:nw)
2679 double precision,
intent(out) :: tco_local,tmax_local
2681 double precision,
parameter :: trac_delta=0.25d0
2682 double precision :: te(ixi^s),lts(ixi^s)
2683 double precision,
dimension(1:ndim) :: bdir, bunitvec
2684 double precision,
dimension(ixI^S,1:ndim) :: gradt
2685 double precision :: ltrc,ltrp,altr
2686 integer :: idims,ix^
d,jxo^
l,hxo^
l,ixa^
d,ixb^
d
2687 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
2689 if (eos%eos_type ==
'LTE' .or. eos%eos_type ==
'PI')
then
2690 te(ixi^s) = w(ixi^s,
te_)
2692 call eos%get_Rfactor(w,x,ixi^
l,ixi^
l,te)
2693 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
2696 tmax_local=maxval(te(ixo^s))
2704 do ix1=ixomin1,ixomax1
2705 lts(ix1)=0.5d0*abs(te(ix1+1)-te(ix1-1))/te(ix1)
2706 if(lts(ix1)>trac_delta)
then
2707 tco_local=max(tco_local,te(ix1))
2719 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
2720 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
2721 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
2722 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
2724 call mpistop(
"mhd_trac_type not allowed for 1D simulation")
2735 call gradient(te,ixi^
l,ixo^
l,idims,gradt(ixi^s,idims))
2742 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
2747 ixb^d=(ixomin^d+ixomax^d-1)/2+ixa^d;
2748 bdir(1:ndim)=bdir(1:ndim)+w(ixb^d,iw_mag(1:ndim))
2752 if(bdir(1)/=0.d0)
then
2753 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
2755 block%special_values(3)=0.d0
2757 if(bdir(2)/=0.d0)
then
2758 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
2760 block%special_values(4)=0.d0
2764 if(bdir(1)/=0.d0)
then
2765 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+&
2766 (bdir(3)/bdir(1))**2)
2768 block%special_values(3)=0.d0
2770 if(bdir(2)/=0.d0)
then
2771 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+&
2772 (bdir(3)/bdir(2))**2)
2774 block%special_values(4)=0.d0
2776 if(bdir(3)/=0.d0)
then
2777 block%special_values(5)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+&
2778 (bdir(2)/bdir(3))**2)
2780 block%special_values(5)=0.d0
2785 block%special_values(1)=zero
2786 {
do ix^db=ixomin^db,ixomax^db\}
2788 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
2790 ^d&bdir(^d)=w({ix^d},iw_mag(^d))\
2793 if(bdir(1)/=0.d0)
then
2794 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
2798 if(bdir(2)/=0.d0)
then
2799 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
2804 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2))*&
2805 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
2808 if(bdir(1)/=0.d0)
then
2809 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
2813 if(bdir(2)/=0.d0)
then
2814 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
2818 if(bdir(3)/=0.d0)
then
2819 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
2824 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2),block%ds(ix^d,3))*&
2825 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
2827 if(lts(ix^d)>trac_delta)
then
2828 block%special_values(1)=max(block%special_values(1),te(ix^d))
2831 block%special_values(2)=tmax_local
2850 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
2851 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
2852 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
2856 {
do ix^db=ixpmin^db,ixpmax^db\}
2857 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
2859 if(bdir(1)/=0.d0)
then
2860 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
2864 if(bdir(2)/=0.d0)
then
2865 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
2871 if(bdir(1)/=0.d0)
then
2872 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
2876 if(bdir(2)/=0.d0)
then
2877 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
2881 if(bdir(3)/=0.d0)
then
2882 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
2888 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
2890 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
2891 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
2894 {
do ix^db=ixpmin^db,ixpmax^db\}
2896 if(w(ix^d,iw_mag(1))/=0.d0)
then
2897 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)
2901 if(w(ix^d,iw_mag(2))/=0.d0)
then
2902 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)
2908 if(w(ix^d,iw_mag(1))/=0.d0)
then
2909 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+&
2910 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(1)))**2)
2914 if(w(ix^d,iw_mag(2))/=0.d0)
then
2915 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+&
2916 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(2)))**2)
2920 if(w(ix^d,iw_mag(3))/=0.d0)
then
2921 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+&
2922 (w(ix^d,iw_mag(2))/w(ix^d,iw_mag(3)))**2)
2928 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
2930 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
2931 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
2937 {
do ix^db=ixpmin^db,ixpmax^db\}
2939 altr=0.25d0*((lts(ix1-1,ix2)+two*lts(ix^d)+lts(ix1+1,ix2))*bunitvec(1)**2+&
2940 (lts(ix1,ix2-1)+two*lts(ix^d)+lts(ix1,ix2+1))*bunitvec(2)**2)
2941 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
2944 altr=0.25d0*((lts(ix1-1,ix2,ix3)+two*lts(ix^d)+lts(ix1+1,ix2,ix3))*bunitvec(1)**2+&
2945 (lts(ix1,ix2-1,ix3)+two*lts(ix^d)+lts(ix1,ix2+1,ix3))*bunitvec(2)**2+&
2946 (lts(ix1,ix2,ix3-1)+two*lts(ix^d)+lts(ix1,ix2,ix3+1))*bunitvec(3)**2)
2947 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
2953 call mpistop(
"unknown mhd_trac_type")
2956 end subroutine mhd_get_tcutoff
2959 subroutine mhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
2962 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2963 double precision,
intent(in) :: wprim(ixi^s, nw)
2964 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2965 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
2967 double precision :: csound(ixi^s,
ndim)
2968 double precision,
allocatable :: tmp(:^
d&)
2969 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
2973 allocate(tmp(ixa^s))
2976 call mhd_get_csound_prim_split(wprim,x,ixi^
l,ixa^
l,id,tmp)
2978 call mhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
2980 csound(ixa^s,id)=tmp(ixa^s)
2983 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
2984 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
2985 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
2986 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))
2990 ixamax^
d=ixcmax^
d+
kr(id,^
d);
2991 ixamin^
d=ixcmin^
d+
kr(id,^
d);
2992 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)))
2993 ixamax^
d=ixcmax^
d-
kr(id,^
d);
2994 ixamin^
d=ixcmin^
d-
kr(id,^
d);
2995 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)))
3000 ixamax^
d=jxcmax^
d+
kr(id,^
d);
3001 ixamin^
d=jxcmin^
d+
kr(id,^
d);
3002 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)))
3003 ixamax^
d=jxcmax^
d-
kr(id,^
d);
3004 ixamin^
d=jxcmin^
d-
kr(id,^
d);
3005 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)))
3009 end subroutine mhd_get_h_speed
3012 subroutine mhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3015 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3016 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3017 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3018 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3019 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3020 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3021 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3023 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3024 double precision :: umean, dmean, tmp1, tmp2, tmp3
3031 call mhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3032 call mhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3033 if(
present(cmin))
then
3034 {
do ix^db=ixomin^db,ixomax^db\}
3035 tmp1=sqrt(wlp(ix^
d,
rho_))
3036 tmp2=sqrt(wrp(ix^
d,
rho_))
3037 tmp3=1.d0/(tmp1+tmp2)
3038 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3039 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3040 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3041 cmin(ix^
d,1)=umean-dmean
3042 cmax(ix^
d,1)=umean+dmean
3044 if(h_correction)
then
3045 {
do ix^db=ixomin^db,ixomax^db\}
3046 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3047 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3051 {
do ix^db=ixomin^db,ixomax^db\}
3052 tmp1=sqrt(wlp(ix^d,
rho_))
3053 tmp2=sqrt(wrp(ix^d,
rho_))
3054 tmp3=1.d0/(tmp1+tmp2)
3055 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3056 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3057 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3058 cmax(ix^d,1)=abs(umean)+dmean
3062 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3063 call mhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
3064 if(
present(cmin))
then
3065 {
do ix^db=ixomin^db,ixomax^db\}
3066 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3067 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3069 if(h_correction)
then
3070 {
do ix^db=ixomin^db,ixomax^db\}
3071 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3072 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3076 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3080 call mhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
3081 call mhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
3082 if(
present(cmin))
then
3083 {
do ix^db=ixomin^db,ixomax^db\}
3084 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3085 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3086 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3088 if(h_correction)
then
3089 {
do ix^db=ixomin^db,ixomax^db\}
3090 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3091 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3095 {
do ix^db=ixomin^db,ixomax^db\}
3096 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3097 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3102 end subroutine mhd_get_cbounds
3105 subroutine mhd_get_cbounds_semirelati(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3108 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3109 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3110 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3111 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3112 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3113 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3114 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3116 double precision,
dimension(ixO^S) :: csoundl, csoundr, gamma2l, gamma2r
3121 call mhd_get_csound_semirelati(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3122 call mhd_get_csound_semirelati(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3124 call mhd_get_csound_semirelati_noe(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3125 call mhd_get_csound_semirelati_noe(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3127 if(
present(cmin))
then
3128 {
do ix^db=ixomin^db,ixomax^db\}
3129 csoundl(ix^
d)=max(csoundl(ix^
d),csoundr(ix^
d))
3130 cmin(ix^
d,1)=min(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))-csoundl(ix^
d)
3131 cmax(ix^
d,1)=max(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))+csoundl(ix^
d)
3134 {
do ix^db=ixomin^db,ixomax^db\}
3135 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3136 cmax(ix^d,1)=max(gamma2l(ix^d)*wlp(ix^d,
mom(idim)),gamma2r(ix^d)*wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3140 end subroutine mhd_get_cbounds_semirelati
3143 subroutine mhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3146 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3147 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3148 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3149 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3150 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3151 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3152 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3154 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3155 double precision :: umean, dmean, tmp1, tmp2, tmp3
3162 call mhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3163 call mhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3164 if(
present(cmin))
then
3165 {
do ix^db=ixomin^db,ixomax^db\}
3168 tmp3=1.d0/(tmp1+tmp2)
3169 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3170 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3171 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3172 cmin(ix^
d,1)=umean-dmean
3173 cmax(ix^
d,1)=umean+dmean
3175 if(h_correction)
then
3176 {
do ix^db=ixomin^db,ixomax^db\}
3177 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3178 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3182 {
do ix^db=ixomin^db,ixomax^db\}
3185 tmp3=1.d0/(tmp1+tmp2)
3186 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3187 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3188 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3189 cmax(ix^d,1)=abs(umean)+dmean
3193 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3194 call mhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
3195 if(
present(cmin))
then
3196 {
do ix^db=ixomin^db,ixomax^db\}
3197 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3198 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3200 if(h_correction)
then
3201 {
do ix^db=ixomin^db,ixomax^db\}
3202 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3203 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3207 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3211 call mhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
3212 call mhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
3213 if(
present(cmin))
then
3214 {
do ix^db=ixomin^db,ixomax^db\}
3215 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3216 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3217 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3219 if(h_correction)
then
3220 {
do ix^db=ixomin^db,ixomax^db\}
3221 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3222 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3226 {
do ix^db=ixomin^db,ixomax^db\}
3227 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3228 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3233 end subroutine mhd_get_cbounds_split_rho
3236 subroutine mhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3239 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3240 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3241 double precision,
intent(in) :: cmax(ixi^s)
3242 double precision,
intent(in),
optional :: cmin(ixi^s)
3243 type(ct_velocity),
intent(inout):: vcts
3245 end subroutine mhd_get_ct_velocity_average
3247 subroutine mhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3250 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3251 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3252 double precision,
intent(in) :: cmax(ixi^s)
3253 double precision,
intent(in),
optional :: cmin(ixi^s)
3254 type(ct_velocity),
intent(inout):: vcts
3256 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
3258 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
3260 end subroutine mhd_get_ct_velocity_contact
3262 subroutine mhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3265 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3266 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3267 double precision,
intent(in) :: cmax(ixi^s)
3268 double precision,
intent(in),
optional :: cmin(ixi^s)
3269 type(ct_velocity),
intent(inout):: vcts
3271 integer :: idime,idimn
3273 if(.not.
allocated(vcts%vbarC))
then
3274 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
3275 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
3278 if(
present(cmin))
then
3279 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
3280 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3282 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3283 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
3286 idimn=mod(idim,
ndir)+1
3287 idime=mod(idim+1,
ndir)+1
3289 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
3290 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
3291 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
3292 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
3293 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3295 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
3296 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
3297 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
3298 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
3299 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3301 end subroutine mhd_get_ct_velocity_hll
3308 integer,
intent(in) :: ixi^
l, ixo^
l
3309 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3310 double precision,
intent(out):: csound(ixi^s)
3312 double precision :: wprim(ixi^s, nw)
3314 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
3315 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
3327 integer,
intent(in) :: ixi^
l, ixo^
l
3328 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3329 double precision,
intent(out):: csound(ixi^s)
3331 double precision :: inv_rho, b2
3332 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
3333 double precision :: prad_max(ixi^s)
3339 {
do ix^db=ixomin^db,ixomax^db \}
3340 inv_rho=1.d0/w(ix^
d,
rho_)
3341 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
3343 csound(ix^
d)=(eos%gamma*w(ix^
d,
p_)+b2+prad_max(ix^
d))*inv_rho
3346 {
do ix^db=ixomin^db,ixomax^db \}
3347 inv_rho=1.d0/w(ix^d,
rho_)
3348 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
3349 b2=(^
c&w(ix^d,
b^
c_)**2+)
3350 csound(ix^d)=(eos%gamma*w(ix^d,
p_)+b2+prad_max(ix^d))*inv_rho
3354 if(minval(csound(ixo^s))<smalldouble)
then
3355 print *,
'issue with squared speed and rad pressure'
3356 print *,minval(csound(ixo^s))
3357 print *,minval(prad_max(ixo^s))
3358 call mpistop(
"negative squared speed in get_csrad2 for dt")
3364 subroutine mhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
3368 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3369 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3370 double precision,
intent(out):: csound(ixo^s)
3372 double precision :: adiabs(ixi^s), gammas(ixi^s)
3373 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
3374 double precision :: cs2(ixi^s)
3394 call eos%get_csound2(w, x, ixi^
l, ixo^
l, cs2)
3399 {
do ix^db=ixomin^db,ixomax^db \}
3400 inv_rho=1.d0/w(ix^
d,
rho_)
3402 csound(ix^
d)=cs2(ix^
d)
3404 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3407 cfast2=b2*inv_rho+csound(ix^
d)
3408 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
3410 if(avmincs2<zero) avmincs2=zero
3411 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3413 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3417 {
do ix^db=ixomin^db,ixomax^db \}
3418 inv_rho=1.d0/w(ix^d,
rho_)
3420 csound(ix^d)=cs2(ix^d)
3422 csound(ix^d)=gammas(ix^d)*adiabs(ix^d)*w(ix^d,
rho_)**(gammas(ix^d)-1.d0)
3424 b2=(^
c&w(ix^d,
b^
c_)**2+)
3425 cfast2=b2*inv_rho+csound(ix^d)
3426 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
3427 if(avmincs2<zero) avmincs2=zero
3428 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3430 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3435 end subroutine mhd_get_csound_prim
3439 subroutine mhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
3442 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3443 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3444 double precision,
intent(out):: csound(ixo^s)
3446 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
3453 {
do ix^db=ixomin^db,ixomax^db \}
3458 cfast2=b2*inv_rho+csound(ix^
d)
3459 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
3461 if(avmincs2<zero) avmincs2=zero
3462 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3464 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3468 {
do ix^db=ixomin^db,ixomax^db \}
3471 csound(ix^d)=eos%gamma*(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i))*inv_rho
3472 b2=(^
c&w(ix^d,
b^
c_)**2+)
3473 cfast2=b2*inv_rho+csound(ix^d)
3474 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
3475 if(avmincs2<zero) avmincs2=zero
3476 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3478 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3483 end subroutine mhd_get_csound_prim_split
3486 subroutine mhd_get_csound_semirelati(w,x,ixI^L,ixO^L,idim,csound,gamma2)
3489 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3491 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3492 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
3494 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
3497 {
do ix^db=ixomin^db,ixomax^db\}
3498 inv_rho = 1.d0/w(ix^
d,
rho_)
3500 csound(ix^
d)=eos%gamma*w(ix^
d,
p_)*inv_rho
3501 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3502 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3503 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
3504 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3507 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
3508 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
3509 if(avmincs2<zero) avmincs2=zero
3511 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
3514 end subroutine mhd_get_csound_semirelati
3517 subroutine mhd_get_csound_semirelati_noe(w,x,ixI^L,ixO^L,idim,csound,gamma2)
3521 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3523 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3524 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
3526 double precision :: adiabs(ixi^s), gammas(ixi^s)
3527 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
3540 {
do ix^db=ixomin^db,ixomax^db\}
3541 inv_rho = 1.d0/w(ix^
d,
rho_)
3543 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3544 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3545 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3546 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
3547 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3550 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
3551 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
3552 if(avmincs2<zero) avmincs2=zero
3554 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
3557 end subroutine mhd_get_csound_semirelati_noe
3570 integer,
intent(in) :: ixi^
l, ixo^
l
3571 double precision,
intent(in) :: w(ixi^s, 1:nw)
3572 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
3573 double precision,
intent(out):: prad(ixi^s, 1:
ndim, 1:
ndim)
3582 integer,
intent(in) :: ixi^
l, ixo^
l
3583 double precision,
intent(in) :: w(ixi^s, 1:nw)
3584 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
3585 double precision,
intent(out) :: pth_plus_prad(ixi^s)
3587 double precision :: wprim(ixi^s, 1:nw)
3588 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
3589 double precision :: prad_max(ixi^s)
3592 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
3593 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
3595 {
do ix^
d = ixomin^
d,ixomax^
d\}
3596 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
3598 pth_plus_prad(ixo^s) = wprim(ixo^s,
p_) + prad_max(ixo^s)
3606 integer,
intent(in) :: ixi^
l, ixo^
l
3607 double precision,
intent(in) :: w(ixi^s, 1:nw)
3608 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
3609 double precision,
intent(out):: trad(ixi^s)
3616 subroutine mhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
3620 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3622 double precision,
intent(in) :: wc(ixi^s,nw)
3624 double precision,
intent(in) :: w(ixi^s,nw)
3625 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3626 double precision,
intent(out) :: f(ixi^s,nwflux)
3628 double precision :: vhall(ixi^s,1:
ndir)
3629 double precision :: ptotal
3630 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
3631 double precision :: bvec(ixi^s,1:
ndir)
3632 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
3633 double precision :: nperp(ixi^s,1:
ndir)
3634 logical :: use_perp_flux
3635 integer :: iw, ix^
d, idir
3638 {
do ix^db=ixomin^db,ixomax^db\}
3651 {
do ix^db=ixomin^db,ixomax^db\}
3655 ^
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_)\
3656 ptotal=w(ix^d,
p_)+half*(^
c&w(ix^d,
b^
c_)**2+)
3658 f(ix^d,
mom(idim))=f(ix^d,
mom(idim))+ptotal
3661 f(ix^d,
e_)=w(ix^d,
mom(idim))*(wc(ix^d,
e_)+ptotal)&
3662 -w(ix^d,mag(idim))*(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)
3664 ^
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_)\
3668 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
3669 {
do ix^db=ixomin^db,ixomax^db\}
3670 if(total_energy)
then
3672 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)**2+)&
3673 -w(ix^d,mag(idim))*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
3676 ^
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))\
3681 {
do ix^db=ixomin^db,ixomax^db\}
3682 f(ix^d,mag(idim))=w(ix^d,
psi_)
3684 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
3689 {
do ix^db=ixomin^db,ixomax^db\}
3690 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
3695 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
3699 {
do ix^db=ixomin^db,ixomax^db\}
3706 if(use_perp_flux)
then
3708 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
3710 te(ixi^s)=(w(ixi^s,
p_)+block%equi_vars(ixi^s,
equi_pe0_,b0i)) / &
3711 (r(ixi^s)*rho_loc(ixi^s))
3713 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
3715 {
do ix^db=ixomin^db,ixomax^db\}
3717 bvec(ix^d,idir)=w(ix^d,mag(idir))
3720 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
3724 {
do ix^db=ixomin^db,ixomax^db\}
3725 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*w(ix^d,mag(idim))/(dsqrt(^
c&w(ix^d,
b^
c_)**2+)+smalldouble)
3727 if(use_perp_flux)
then
3728 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
3733 end subroutine mhd_get_flux
3737 subroutine mhd_get_flux_noe(wC,w,x,ixI^L,ixO^L,idim,f)
3742 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3744 double precision,
intent(in) :: wc(ixi^s,nw)
3746 double precision,
intent(in) :: w(ixi^s,nw)
3747 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3748 double precision,
intent(out) :: f(ixi^s,nwflux)
3750 double precision :: vhall(ixi^s,1:
ndir)
3751 double precision :: adiabs(ixi^s), gammas(ixi^s)
3764 {
do ix^db=ixomin^db,ixomax^db\}
3770 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+)
3775 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
3776 {
do ix^db=ixomin^db,ixomax^db\}
3778 ^
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))\
3782 {
do ix^db=ixomin^db,ixomax^db\}
3783 f(ix^d,mag(idim))=w(ix^d,
psi_)
3785 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
3789 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
3793 {
do ix^db=ixomin^db,ixomax^db\}
3797 end subroutine mhd_get_flux_noe
3800 subroutine mhd_get_flux_hde(wC,w,x,ixI^L,ixO^L,idim,f)
3804 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3806 double precision,
intent(in) :: wc(ixi^s,nw)
3808 double precision,
intent(in) :: w(ixi^s,nw)
3809 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3810 double precision,
intent(out) :: f(ixi^s,nwflux)
3812 double precision :: vhall(ixi^s,1:
ndir)
3813 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
3814 double precision :: bvec(ixi^s,1:
ndir)
3815 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
3816 double precision :: nperp(ixi^s,1:
ndir)
3817 logical :: use_perp_flux
3818 integer :: iw, ix^
d, idir
3820 {
do ix^db=ixomin^db,ixomax^db\}
3833 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
3834 {
do ix^db=ixomin^db,ixomax^db\}
3836 ^
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))\
3840 {
do ix^db=ixomin^db,ixomax^db\}
3841 f(ix^d,mag(idim))=w(ix^d,
psi_)
3843 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
3847 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
3851 {
do ix^db=ixomin^db,ixomax^db\}
3857 if(use_perp_flux)
then
3859 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
3860 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
3861 {
do ix^db=ixomin^db,ixomax^db\}
3863 bvec(ix^d,idir)=w(ix^d,mag(idir))
3866 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
3869 {
do ix^db=ixomin^db,ixomax^db\}
3870 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*w(ix^d,mag(idim))/(dsqrt(^
c&w(ix^d,
b^
c_)**2+)+smalldouble)
3872 if(use_perp_flux)
then
3873 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
3878 end subroutine mhd_get_flux_hde
3885 subroutine mhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
3889 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3891 double precision,
intent(in) :: wc(ixi^s,nw)
3893 double precision,
intent(in) :: w(ixi^s,nw)
3894 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3895 double precision,
intent(out) :: f(ixi^s,nwflux)
3897 double precision :: vhall(ixi^s,1:
ndir)
3898 double precision :: ptotal, btotal(ixo^s,1:
ndir)
3899 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
3900 double precision :: bvec(ixi^s,1:
ndir)
3901 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
3902 double precision :: nperp(ixi^s,1:
ndir)
3903 logical :: use_perp_flux
3904 integer :: iw, ix^
d, idir
3906 {
do ix^db=ixomin^db,ixomax^db\}
3914 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
3918 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
3922 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
3923 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
3925 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
3929 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
3932 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
3939 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
3940 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
3945 {
do ix^db=ixomin^db,ixomax^db\}
3946 f(ix^d,mag(idim))=w(ix^d,
psi_)
3948 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
3953 {
do ix^db=ixomin^db,ixomax^db\}
3954 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
3959 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
3960 {
do ix^db=ixomin^db,ixomax^db\}
3962 ^
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)\
3963 if(total_energy)
then
3965 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)*btotal(ix^d,^
c)+)&
3966 -btotal(ix^d,idim)*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
3971 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
3975 {
do ix^db=ixomin^db,ixomax^db\}
3981 if(use_perp_flux)
then
3983 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
3985 te(ixi^s)=(w(ixi^s,
p_)+block%equi_vars(ixi^s,
equi_pe0_,b0i)) / &
3986 (r(ixi^s)*rho_loc(ixi^s))
3988 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
3990 {
do ix^db=ixomin^db,ixomax^db\}
3992 bvec(ix^d,idir)=btotal(ix^d,idir)
3995 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
3998 {
do ix^db=ixomin^db,ixomax^db\}
3999 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal(ix^d,^
c)**2+)+smalldouble)
4001 if(use_perp_flux)
then
4002 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4007 end subroutine mhd_get_flux_split
4010 subroutine mhd_get_flux_semirelati(wC,w,x,ixI^L,ixO^L,idim,f)
4014 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4016 double precision,
intent(in) :: wc(ixi^s,nw)
4018 double precision,
intent(in) :: w(ixi^s,nw)
4019 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4020 double precision,
intent(out) :: f(ixi^s,nwflux)
4021 double precision :: sa(ixo^s,1:
ndir),e(ixo^s,1:
ndir),e2
4022 double precision :: r(ixi^s), te(ixi^s), rho_loc(ixi^s)
4023 double precision :: bvec(ixi^s,1:
ndir)
4024 double precision :: bgradt(ixi^s), gradtperp_mag(ixi^s)
4025 double precision :: nperp(ixi^s,1:
ndir)
4026 logical :: use_perp_flux
4027 integer :: iw, ix^
d, idir
4029 {
do ix^db=ixomin^db,ixomax^db\}
4034 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4035 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4036 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4041 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4046 e2=(^
c&e(ix^
d,^
c)**2+)
4053 sa(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
4054 sa(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
4055 sa(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
4058 sa(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
4059 sa(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
4068 eos%gamma*w(ix^
d,
p_)*eos%inv_gamma_minus_1)+sa(ix^
d,idim)
4072 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4074 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)
4081 {
do ix^db=ixomin^db,ixomax^db\}
4082 f(ix^d,mag(idim))=w(ix^d,
psi_)
4084 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4088 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4092 {
do ix^db=ixomin^db,ixomax^db\}
4098 if(use_perp_flux)
then
4100 call eos%get_Rfactor(w,x,ixi^l,ixi^l,r)
4101 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*rho_loc(ixi^s))
4102 {
do ix^db=ixomin^db,ixomax^db\}
4104 bvec(ix^d,idir)=w(ix^d,mag(idir))
4107 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
4110 {
do ix^db=ixomin^db,ixomax^db\}
4111 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qpar_)*w(ix^d,mag(idim))/(dsqrt(^
c&w(ix^d,
b^
c_)**2+)+smalldouble)
4113 if(use_perp_flux)
then
4114 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
qperp_)*nperp(ix^d,idim)
4119 end subroutine mhd_get_flux_semirelati
4121 subroutine mhd_get_flux_semirelati_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4126 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4128 double precision,
intent(in) :: wc(ixi^s,nw)
4130 double precision,
intent(in) :: w(ixi^s,nw)
4131 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4132 double precision,
intent(out) :: f(ixi^s,nwflux)
4134 double precision :: adiabs(ixi^s), gammas(ixi^s)
4135 double precision :: e(ixo^s,1:
ndir),e2
4148 {
do ix^db=ixomin^db,ixomax^db\}
4153 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4154 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4155 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4156 e2=(^
c&e(ix^
d,^
c)**2+)
4161 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4171 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4173 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)
4180 {
do ix^db=ixomin^db,ixomax^db\}
4181 f(ix^d,mag(idim))=w(ix^d,
psi_)
4183 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4187 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
4191 {
do ix^db=ixomin^db,ixomax^db\}
4195 end subroutine mhd_get_flux_semirelati_noe
4203 subroutine add_source_ambipolar_internal_energy(qdt,ixI^L,ixO^L,wCT,w,x)
4205 integer,
intent(in) :: ixi^
l, ixo^
l
4206 double precision,
intent(in) :: qdt
4207 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
4208 double precision,
intent(inout) :: w(ixi^s,1:nw)
4210 double precision :: tmp(ixi^s),btot2(ixi^s)
4211 double precision :: jxbxb(ixi^s,1:3)
4213 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,jxbxb)
4216 where (btot2(ixo^s)>smalldouble )
4217 tmp(ixo^s) = sum(jxbxb(ixo^s,1:3)**2,dim=
ndim+1) / btot2(ixo^s)
4224 w(ixo^s,
e_)=w(ixo^s,
e_)- qdt*tmp(ixo^s)
4226 end subroutine add_source_ambipolar_internal_energy
4229 subroutine mhd_get_jxbxb(w,x,ixI^L,ixO^L,res)
4232 integer,
intent(in) :: ixi^
l, ixo^
l
4233 double precision,
intent(in) :: w(ixi^s,nw)
4234 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4235 double precision,
intent(out) :: res(ixi^s,1:3)
4237 double precision :: btot(ixi^s,1:3)
4238 double precision :: current(ixi^s,7-2*
ndir:3)
4239 double precision :: tmp(ixi^s),b2(ixi^s)
4240 integer :: idir, idirmin
4250 btot(ixo^s, idir) = w(ixo^s,mag(idir)) +
block%B0(ixo^s,idir,
b0i)
4254 btot(ixo^s, idir) = w(ixo^s,mag(idir))
4258 tmp(ixo^s)= sum(current(ixo^s,idirmin:3)*btot(ixo^s,idirmin:3),dim=
ndim+1)
4259 b2(ixo^s) = sum(btot(ixo^s,1:3)**2,dim=
ndim+1)
4261 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s)
4264 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s) - current(ixo^s,idir) * b2(ixo^s)
4269 where (b2(ixo^s)<smalldouble )
4270 res(ixo^s,idir) = zero
4273 end subroutine mhd_get_jxbxb
4279 subroutine sts_set_source_ambipolar(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
4283 integer,
intent(in) :: ixi^
l,ixo^
l,igrid,nflux
4284 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4285 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
4286 double precision,
intent(in) :: my_dt
4287 logical,
intent(in) :: fix_conserve_at_step
4289 double precision,
dimension(ixI^S,1:3) :: tmp,ff
4290 double precision :: fluxall(ixi^s,1:nflux,1:
ndim)
4291 double precision :: fe(ixi^s,
sdim:3)
4292 double precision :: btot(ixi^s,1:3),tmp2(ixi^s)
4293 integer :: i, ixa^
l, ie_
4300 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,tmp)
4317 btot(ixa^s,1:3) = 0.d0
4319 btot(ixa^s,1:
ndir) = w(ixa^s,mag(1:
ndir))
4323 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4324 if(fix_conserve_at_step) fluxall(ixi^s,1,1:
ndim)=ff(ixi^s,1:
ndim)
4326 wres(ixo^s,
e_)=-tmp2(ixo^s)
4333 ff(ixa^s,1) = tmp(ixa^s,2)
4334 ff(ixa^s,2) = -tmp(ixa^s,1)
4336 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4337 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
4338 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
4341 call update_faces_ambipolar(ixi^
l,ixo^
l,w,x,tmp,fe,btot)
4343 ixamin^
d=ixomin^
d-1;
4344 wres(ixa^s,mag(1:
ndim))=-btot(ixa^s,1:
ndim)
4354 ff(ixa^s,2) = tmp(ixa^s,3)
4355 ff(ixa^s,3) = -tmp(ixa^s,2)
4356 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4357 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
4359 wres(ixo^s,mag(1))=-tmp2(ixo^s)
4362 ff(ixa^s,1) = -tmp(ixa^s,3)
4364 ff(ixa^s,3) = tmp(ixa^s,1)
4365 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4366 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
4367 wres(ixo^s,mag(2))=-tmp2(ixo^s)
4373 ff(ixa^s,2) = tmp(ixa^s,3)
4374 ff(ixa^s,3) = -tmp(ixa^s,2)
4375 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4376 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
4378 wres(ixo^s,mag(1))=-tmp2(ixo^s)
4380 ff(ixa^s,1) = -tmp(ixa^s,3)
4382 ff(ixa^s,3) = tmp(ixa^s,1)
4383 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4384 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
4385 wres(ixo^s,mag(2))=-tmp2(ixo^s)
4390 ff(ixa^s,1) = tmp(ixa^s,2)
4391 ff(ixa^s,2) = -tmp(ixa^s,1)
4393 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4394 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
4395 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
4400 if(fix_conserve_at_step)
then
4401 fluxall=my_dt*fluxall
4408 end subroutine sts_set_source_ambipolar
4411 subroutine update_faces_ambipolar(ixI^L,ixO^L,w,x,ECC,fE,circ)
4414 integer,
intent(in) :: ixi^
l, ixo^
l
4415 double precision,
intent(in) :: w(ixi^s,1:nw)
4416 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4418 double precision,
intent(in) :: ecc(ixi^s,1:3)
4419 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
4420 double precision,
intent(out) :: circ(ixi^s,1:
ndim)
4422 integer :: hxc^
l,ixc^
l,ixa^
l
4423 integer :: idim1,idim2,idir,ix^
d
4429 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4431 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4432 ixamin^
d=ixcmin^
d+ix^
d;
4433 ixamax^
d=ixcmax^
d+ix^
d;
4434 fe(ixc^s,idir)=fe(ixc^s,idir)+ecc(ixa^s,idir)
4436 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0*block%dsC(ixc^s,idir)
4442 ixcmin^d=ixomin^d-1;
4449 hxc^l=ixc^l-kr(idim2,^d);
4451 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4452 +lvc(idim1,idim2,idir)&
4457 circ(ixc^s,idim1)=circ(ixc^s,idim1)/block%surfaceC(ixc^s,idim1)
4460 end subroutine update_faces_ambipolar
4466 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
4469 integer,
intent(in) :: ixi^
l, ixo^
l
4470 double precision,
dimension(ixI^S,1:3),
intent(inout) :: ff
4471 double precision,
intent(out) :: src(ixi^s)
4473 double precision :: ffc(ixi^s,1:
ndim)
4474 double precision :: dxinv(
ndim)
4475 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
4483 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
4485 ixbmin^
d=ixcmin^
d+ix^
d;
4486 ixbmax^
d=ixcmax^
d+ix^
d;
4489 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
4491 call mpistop(
"to generalize using volume averaging")
4494 ff(ixi^s,1:ndim)=0.d0
4496 ixb^l=ixo^l-kr(idims,^d);
4497 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
4499 if({ ix^d==0 .and. ^d==idims | .or.})
then
4500 ixbmin^d=ixcmin^d-ix^d;
4501 ixbmax^d=ixcmax^d-ix^d;
4502 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
4505 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
4508 if(slab_uniform)
then
4510 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
4511 ixb^l=ixo^l-kr(idims,^d);
4512 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
4516 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
4517 ixb^l=ixo^l-kr(idims,^d);
4518 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
4520 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
4522 end subroutine get_flux_on_cell_face
4526 function get_ambipolar_dt(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
4529 integer,
intent(in) :: ixi^
l, ixo^
l
4530 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
4531 double precision,
intent(in) :: w(ixi^s,1:nw)
4532 double precision :: dtnew
4534 double precision :: coef
4535 double precision :: dxarr(
ndim)
4536 double precision :: tmp(ixi^s)
4542 coef = maxval(dabs(tmp(ixo^s)))
4549 dtnew=minval(dxarr(1:
ndim))**2.0d0*coef
4551 dtnew=minval(
block%ds(ixo^s,1:
ndim))**2.0d0*coef
4554 end function get_ambipolar_dt
4562 integer,
intent(in) :: ixi^
l, ixo^
l
4563 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
4564 double precision,
intent(inout) :: res(ixi^s)
4565 double precision :: tmp(ixi^s)
4566 double precision :: rho(ixi^s)
4573 res(ixo^s) = tmp(ixo^s) * res(ixo^s)
4578 subroutine mhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
4586 integer,
intent(in) :: ixi^
l, ixo^
l
4587 double precision,
intent(in) :: qdt,dtfactor
4588 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
4589 double precision,
intent(inout) :: w(ixi^s,1:nw)
4590 logical,
intent(in) :: qsourcesplit
4591 logical,
intent(inout) :: active
4598 if (.not. qsourcesplit)
then
4602 call add_source_internal_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
4606 call add_equi_terms(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
4612 call add_hyperbolic_tc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
4621 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
4625 if (abs(
mhd_eta)>smalldouble)
then
4627 call add_source_res_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
4632 call add_source_ambi_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
4637 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
4643 call add_source_hydrodynamic_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
4647 call add_source_semirelativistic(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
4654 select case (type_divb)
4659 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
4662 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
4665 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
4666 case (divb_janhunen)
4668 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
4669 case (divb_lindejanhunen)
4671 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
4672 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
4673 case (divb_lindepowel)
4675 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
4676 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
4677 case (divb_lindeglm)
4679 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
4680 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
4681 case (divb_multigrid)
4686 call mpistop(
'Unknown divB fix')
4693 w,x,qsourcesplit,active,
rc_fl)
4703 w,x,gravity_energy,qsourcesplit,active)
4712 call mhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x,qsourcesplit,active)
4716 if(eos%eos_type ==
'PI')
then
4717 if(.not.qsourcesplit)
then
4719 call eos%update_eos(ixi^
l,ixo^
l,w,x)
4723 end subroutine mhd_add_source
4725 subroutine mhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
4731 integer,
intent(in) :: ixi^
l, ixo^
l
4732 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
4733 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw)
4734 double precision,
intent(inout) :: w(ixi^s,1:nw)
4735 logical,
intent(in) :: qsourcesplit
4736 logical,
intent(inout) :: active
4742 end subroutine mhd_add_radiation_source
4745 subroutine add_equi_terms(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
4750 integer,
intent(in) :: ixi^
l, ixo^
l
4751 double precision,
intent(in) :: qdt,dtfactor
4752 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
4753 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
4754 double precision,
intent(inout) :: w(ixi^s,1:nw)
4756 double precision :: divv(ixi^s)
4757 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
4758 double precision :: gravity_field(ixi^s,1:
ndim)
4770 divv(ixo^s)=divv(ixo^s)*eos%gamma*eos%inv_gamma_minus_1
4781 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
4790 a(ixo^s,idir)=
block%J0(ixo^s,idir)
4795 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*axb(ixo^s,idir)*eos%inv_gamma_minus_1
4801 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
4810 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
4814 end subroutine add_equi_terms
4816 subroutine mhd_get_hyperbolic_tc_geometry(ixI^L,ixO^L,Te,Bvec,bgradT,gradTperp_mag,nperp)
4819 integer,
intent(in) :: ixi^
l,ixo^
l
4820 double precision,
intent(in) :: te(ixi^s)
4821 double precision,
intent(in) :: bvec(ixi^s,1:
ndir)
4822 double precision,
intent(out) :: bgradt(ixi^s), gradtperp_mag(ixi^s)
4823 double precision,
intent(out) :: nperp(ixi^s,1:
ndir)
4825 double precision :: bmag, bunitvec(
ndir), gradt(
ndir), gradt_perp(
ndir)
4826 double precision :: gradt_cell(ixi^s,1:
ndir)
4827 integer :: ix^
d, idir
4832 call gradient(te,ixi^
l,ixo^
l,idir,gradt_cell(ixi^s,idir))
4837 do ix2=ixomin2,ixomax2
4838 do ix1=ixomin1,ixomax1
4841 bmag=bmag+bvec(ix^
d,idir)**2
4845 if(bmag>smalldouble)
then
4847 bunitvec(idir)=bvec(ix^
d,idir)/bmag
4855 gradt(1)=((8.d0*(te(ix1+1,ix2)-te(ix1-1,ix2))-te(ix1+2,ix2)+te(ix1-2,ix2))/12.d0)/
block%ds(ix^
d,1)
4856 gradt(2)=((8.d0*(te(ix1,ix2+1)-te(ix1,ix2-1))-te(ix1,ix2+2)+te(ix1,ix2-2))/12.d0)/
block%ds(ix^
d,2)
4857 if(
ndir>2) gradt(3)=zero
4860 gradt(idir)=gradt_cell(ix^
d,idir)
4866 bgradt(ix^
d)=bgradt(ix^
d)+bunitvec(idir)*gradt(idir)
4870 gradt_perp(idir)=gradt(idir)-bgradt(ix^
d)*bunitvec(idir)
4873 gradtperp_mag(ix^
d)=zero
4875 gradtperp_mag(ix^
d)=gradtperp_mag(ix^
d)+gradt_perp(idir)**2
4877 gradtperp_mag(ix^
d)=dsqrt(gradtperp_mag(ix^
d))
4879 if(gradtperp_mag(ix^
d)>smalldouble)
then
4881 nperp(ix^
d,idir)=gradt_perp(idir)/gradtperp_mag(ix^
d)
4884 gradtperp_mag(ix^
d)=zero
4886 nperp(ix^
d,idir)=zero
4893 do ix3=ixomin3,ixomax3
4894 do ix2=ixomin2,ixomax2
4895 do ix1=ixomin1,ixomax1
4896 bmag=dsqrt(bvec(ix^
d,1)**2+bvec(ix^
d,2)**2+bvec(ix^
d,3)**2)
4897 if(bmag>smalldouble)
then
4898 bunitvec(1)=bvec(ix^
d,1)/bmag
4899 bunitvec(2)=bvec(ix^
d,2)/bmag
4900 bunitvec(3)=bvec(ix^
d,3)/bmag
4908 gradt(1)=((8.d0*(te(ix1+1,ix2,ix3)-te(ix1-1,ix2,ix3))-te(ix1+2,ix2,ix3)+te(ix1-2,ix2,ix3))/12.d0)/
block%ds(ix^
d,1)
4909 gradt(2)=((8.d0*(te(ix1,ix2+1,ix3)-te(ix1,ix2-1,ix3))-te(ix1,ix2+2,ix3)+te(ix1,ix2-2,ix3))/12.d0)/
block%ds(ix^
d,2)
4910 gradt(3)=((8.d0*(te(ix1,ix2,ix3+1)-te(ix1,ix2,ix3-1))-te(ix1,ix2,ix3+2)+te(ix1,ix2,ix3-2))/12.d0)/
block%ds(ix^
d,3)
4913 gradt(idir)=gradt_cell(ix^
d,idir)
4919 bgradt(ix^
d)=bgradt(ix^
d)+bunitvec(idir)*gradt(idir)
4923 gradt_perp(idir)=gradt(idir)-bgradt(ix^
d)*bunitvec(idir)
4926 gradtperp_mag(ix^
d)=dsqrt(gradt_perp(1)**2+gradt_perp(2)**2+gradt_perp(3)**2)
4927 if(gradtperp_mag(ix^
d)>smalldouble)
then
4929 nperp(ix^
d,idir)=gradt_perp(idir)/gradtperp_mag(ix^
d)
4932 gradtperp_mag(ix^
d)=zero
4934 nperp(ix^
d,idir)=zero
4941 end subroutine mhd_get_hyperbolic_tc_geometry
4943 subroutine add_hyperbolic_tc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
4946 integer,
intent(in) :: ixi^
l,ixo^
l
4947 double precision,
intent(in) :: qdt
4948 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
4949 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
4950 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
4952 double precision,
dimension(ixI^S) :: r,te,rho_loc,pth_loc
4953 double precision,
dimension(ixI^S) :: ne_loc,nh_dummy
4954 double precision,
dimension(ixI^S,1:ndir) :: bvec
4955 double precision,
dimension(ixI^S) :: bgradt, gradtperp_mag
4956 double precision,
dimension(ixI^S,1:ndir) :: nperp
4957 double precision,
dimension(ixI^S) :: gradt_geom
4958 double precision,
parameter :: xe_prefac_cgs = 4.753567596681522d6
4959 double precision :: kappa_t5,kappa_t5_perp,kappa_t5_perp_eff
4960 double precision :: kappa_t7,f_sat,kappat5_bgradt,kappat5_gradtperp,tau,b2,fb,gradt1
4961 double precision :: qclass_diss
4962 double precision :: bmag_loc,tloc,tcond,nloc_code,cchi,chi
4963 double precision :: cmax(
ndim),c2,cfast2,avmincs2(
ndim),inv_rho
4964 logical :: use_perp_source
4965 integer :: ix^
d,idir
4981 call eos%get_Rfactor(wct,x,ixi^
l,ixi^
l,r)
4982 {
do ix^db=iximin^db,iximax^db\}
4987 rho_loc(ix^
d)=wctprim(ix^
d,
rho_)
4988 pth_loc(ix^
d)=wctprim(ix^
d,
p_)
4990 te(ix^
d)=pth_loc(ix^
d)/(r(ix^
d)*rho_loc(ix^
d))
4997 if(eos%eos_type==
'LTE')
then
4998 call eos%get_ne_nH(ixi^l,ixi^l,wct,ne_loc,nh_dummy)
4999 else if(eos%eos_type==
'PI')
then
5000 ne_loc(ixi^s)=rho_loc(ixi^s)*max(r(ixi^s)*(2.d0+3.d0*eos%He_abundance) &
5001 -(1.d0+eos%He_abundance),smalldouble)
5003 ne_loc(ixi^s)=rho_loc(ixi^s)*(1.d0+2.d0*eos%He_abundance)
5009 {
do ix^db=ixomin^db,ixomax^db\}
5011 bvec(ix^d,idir)=wct(ix^d,mag(idir))+block%B0(ix^d,idir,0)
5015 {
do ix^db=ixomin^db,ixomax^db\}
5017 bvec(ix^d,idir)=wct(ix^d,mag(idir))
5022 call mhd_get_hyperbolic_tc_geometry(ixi^l,ixo^l,te,bvec,bgradt,gradtperp_mag,nperp)
5026 if(.not.slab_uniform)
then
5027 call gradient(te,ixi^l,ixo^l,1,gradt_geom)
5029 do ix1=ixomin1,ixomax1
5032 kappa_t7=kappa_t5*te(ix1)
5036 tcond = max(tcond, block%wextra(ix1,
tcoff_))
5039 kappa_t7=kappa_t5*tcond
5041 if(slab_uniform)
then
5042 gradt1=((8.d0*(te(ix1+1)-te(ix1-1))-te(ix1+2)+te(ix1-2))/12.d0)/block%ds(ix1,1)
5044 gradt1=gradt_geom(ix1)
5048 b2=b2+bvec(ix1,idir)**2
5050 if(b2>smalldouble**2)
then
5051 bgradt(ix1)=bvec(ix1,1)*gradt1/dsqrt(b2)
5055 kappat5_bgradt=kappa_t5*bgradt(ix1)
5056 inv_rho=1.d0/rho_loc(ix1)
5057 c2=eos%gamma*pth_loc(ix1)*inv_rho
5058 cfast2 = b2*inv_rho + c2
5059 avmincs2(1) = cfast2**2 - 4.0d0*c2*bvec(ix1,1)**2*inv_rho
5060 cmax(1) = sqrt(half*(cfast2 + sqrt(dabs(avmincs2(1)))))
5062 f_sat=one/(one+dabs(kappat5_bgradt)/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5063 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*cmax(1)**2))
5064 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5067 max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*cmax(1)**2))
5072 do ix2=ixomin2,ixomax2
5073 do ix1=ixomin1,ixomax1
5076 kappa_t7=kappa_t5*te(ix^d)
5080 tcond=max(tcond, block%wextra(ix^d,
tcoff_))
5083 kappa_t7 = kappa_t5*tcond
5085 kappat5_bgradt=kappa_t5*bgradt(ix^d)
5088 b2 = b2 + bvec(ix^d,idir)**2
5090 if(use_perp_source)
then
5092 case(
'fixed_reference')
5094 case(
'weak_field_isotropization')
5100 kappa_t5_perp_eff=(one-fb)*kappa_t5
5101 kappa_t5_perp=kappa_t5_perp_eff
5102 case(
'electron_magnetization')
5103 bmag_loc = dsqrt(b2)
5104 tloc = max(te(ix^d), smalldouble)
5105 nloc_code = max(ne_loc(ix^d), smalldouble)
5106 chi = cchi*bmag_loc*tloc**1.5d0/nloc_code
5107 kappa_t5_perp_eff = kappa_t5/(one+chi**2)
5108 kappa_t5_perp = kappa_t5_perp_eff
5112 kappat5_gradtperp=kappa_t5_perp*gradtperp_mag(ix^d)
5114 inv_rho=1.d0/rho_loc(ix^d)
5115 c2=eos%gamma*pth_loc(ix^d)*inv_rho
5116 cfast2 = b2*inv_rho + c2
5118 avmincs2(idir)=cfast2**2-4.0d0*c2*bvec(ix^d,idir)**2*inv_rho
5119 cmax(idir)=sqrt(half*(cfast2+sqrt(dabs(avmincs2(idir)))))\
5122 qclass_diss=dabs(kappat5_bgradt)
5123 if(use_perp_source) &
5124 qclass_diss=dsqrt(kappat5_bgradt**2+kappat5_gradtperp**2)
5125 f_sat=one/(one+qclass_diss/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5126 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5127 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5128 if(use_perp_source)
then
5132 tau=max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5134 if(use_perp_source)
then
5142 do ix3=ixomin3,ixomax3
5143 do ix2=ixomin2,ixomax2
5144 do ix1=ixomin1,ixomax1
5147 kappa_t7=kappa_t5*te(ix^d)
5151 tcond=max(tcond, block%wextra(ix^d,
tcoff_))
5154 kappa_t7 = kappa_t5*tcond
5156 kappat5_bgradt=kappa_t5*bgradt(ix^d)
5159 b2 = b2 + bvec(ix^d,idir)**2
5161 if(use_perp_source)
then
5163 case(
'fixed_reference')
5165 case(
'weak_field_isotropization')
5171 kappa_t5_perp_eff=(one-fb)*kappa_t5
5172 kappa_t5_perp=kappa_t5_perp_eff
5173 case(
'electron_magnetization')
5174 bmag_loc = dsqrt(b2)
5175 tloc = max(te(ix^d), smalldouble)
5176 nloc_code = max(ne_loc(ix^d), smalldouble)
5177 chi = cchi*bmag_loc*tloc**1.5d0/nloc_code
5178 kappa_t5_perp_eff = kappa_t5/(one+chi**2)
5179 kappa_t5_perp = kappa_t5_perp_eff
5183 kappat5_gradtperp=kappa_t5_perp*gradtperp_mag(ix^d)
5185 inv_rho=1.d0/rho_loc(ix^d)
5186 c2=eos%gamma*pth_loc(ix^d)*inv_rho
5187 cfast2 = b2*inv_rho + c2
5189 avmincs2(idir)=cfast2**2-4.0d0*c2*bvec(ix^d,idir)**2*inv_rho
5190 cmax(idir)=sqrt(half*(cfast2+sqrt(dabs(avmincs2(idir)))))\
5193 qclass_diss=dabs(kappat5_bgradt)
5194 if(use_perp_source) &
5195 qclass_diss=dsqrt(kappat5_bgradt**2+kappat5_gradtperp**2)
5196 f_sat=one/(one+qclass_diss/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5197 tau=max(4.d0*dt, f_sat*kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5198 w(ix^d,
qpar_)=w(ix^d,
qpar_)-qdt*(f_sat*kappat5_bgradt+wct(ix^d,
qpar_))/tau
5199 if(use_perp_source)
then
5203 tau=max(4.d0*dt, kappa_t7*courantpar**2/(pth_loc(ix^d)*eos%inv_gamma_minus_1*maxval(cmax(:))**2))
5205 if(use_perp_source)
then
5213 end subroutine add_hyperbolic_tc_source
5217 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
5219 integer,
intent(in) :: ixi^
l, ixo^
l
5220 double precision,
intent(in) :: w(ixi^s,1:nw)
5221 double precision,
intent(inout) :: jxb(ixi^s,3)
5222 double precision :: a(ixi^s,3),
b(ixi^s,3)
5224 double precision :: current(ixi^s,7-2*
ndir:3)
5225 integer :: idir, idirmin
5230 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
5234 b(ixo^s, idir) = w(ixo^s,mag(idir))
5243 a(ixo^s,idir)=current(ixo^s,idir)
5247 end subroutine get_lorentz_force
5251 integer,
intent(in) :: ixi^
l, ixo^
l
5252 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
5253 double precision,
intent(out) :: rho(ixi^s)
5258 rho(ixo^s) = w(ixo^s,
rho_)
5264 subroutine mhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
5267 integer,
intent(in) :: ixi^
l,ixo^
l, ie
5268 double precision,
intent(inout) :: w(ixi^s,1:nw)
5269 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5270 character(len=*),
intent(in) :: subname
5272 double precision :: rho(ixi^s)
5274 logical :: flag(ixi^s,1:nw)
5279 flag(ixo^s,ie)=.true.
5281 where(w(ixo^s,ie)<
small_e) flag(ixo^s,ie)=.true.
5283 if(any(flag(ixo^s,ie)))
then
5287 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e - &
5290 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e
5296 w(ixo^s,
e_)=w(ixo^s,
e_)*eos%gamma_minus_1
5299 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
5305 end subroutine mhd_handle_small_ei
5309 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
5312 integer,
intent(in) :: ixi^
l, ixo^
l
5313 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5314 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5315 double precision,
intent(inout) :: w(ixi^s,1:nw)
5317 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
5329 a(ixo^s,idir)=
block%J0(ixo^s,idir)
5334 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5337 axb(ixo^s,:)=axb(ixo^s,:)*qdt
5343 if(total_energy)
then
5346 b(ixo^s,:)=wctprim(ixo^s,mag(:))
5355 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5358 axb(ixo^s,:)=axb(ixo^s,:)*qdt
5363 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
5367 call mhd_getv_hall(wct,x,ixi^
l,ixo^
l,a,.true.)
5372 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5375 axb(ixo^s,:)=axb(ixo^s,:)*qdt
5379 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
5387 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,axb)
5392 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*axb(ixo^s,idir)*
block%J0(ixo^s,idir)
5398 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
5400 end subroutine add_source_b0split
5403 subroutine add_source_semirelativistic(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5407 integer,
intent(in) :: ixi^
l, ixo^
l
5408 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5409 double precision,
intent(inout) :: w(ixi^s,1:nw)
5410 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
5412 double precision :: e(ixi^s,1:3),curle(ixi^s,1:3),dive(ixi^s)
5413 integer :: idir, idirmin, ix^
d
5417 {
do ix^db=iximin^db,iximax^db\}
5419 e(ix^
d,1)=w(ix^
d,b2_)*wctprim(ix^
d,m3_)-w(ix^
d,b3_)*wctprim(ix^
d,m2_)
5420 e(ix^
d,2)=w(ix^
d,b3_)*wctprim(ix^
d,m1_)-w(ix^
d,b1_)*wctprim(ix^
d,m3_)
5421 e(ix^
d,3)=w(ix^
d,b1_)*wctprim(ix^
d,m2_)-w(ix^
d,b2_)*wctprim(ix^
d,m1_)
5423 call divvector(e,ixi^l,ixo^l,dive)
5425 call curlvector(e,ixi^l,ixo^l,curle,idirmin,1,3)
5428 {
do ix^db=ixomin^db,ixomax^db\}
5429 w(ix^d,m1_)=w(ix^d,m1_)+qdt*(inv_squared_c0-inv_squared_c)*&
5430 (e(ix^d,1)*dive(ix^d)-e(ix^d,2)*curle(ix^d,3)+e(ix^d,3)*curle(ix^d,2))
5431 w(ix^d,m2_)=w(ix^d,m2_)+qdt*(inv_squared_c0-inv_squared_c)*&
5432 (e(ix^d,2)*dive(ix^d)-e(ix^d,3)*curle(ix^d,1)+e(ix^d,1)*curle(ix^d,3))
5433 w(ix^d,m3_)=w(ix^d,m3_)+qdt*(inv_squared_c0-inv_squared_c)*&
5434 (e(ix^d,3)*dive(ix^d)-e(ix^d,1)*curle(ix^d,2)+e(ix^d,2)*curle(ix^d,1) )
5438 end subroutine add_source_semirelativistic
5441 subroutine add_source_internal_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5445 integer,
intent(in) :: ixi^
l, ixo^
l
5446 double precision,
intent(in) :: qdt
5447 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5448 double precision,
intent(inout) :: w(ixi^s,1:nw)
5449 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5451 double precision :: divv(ixi^s), tmp
5463 {
do ix^db=ixomin^db,ixomax^db\}
5465 w(ix^
d,
e_)=w(ix^
d,
e_)-qdt*wctprim(ix^
d,
p_)*divv(ix^
d)
5471 call add_source_ambipolar_internal_energy(qdt,ixi^l,ixo^l,wct,w,x)
5474 if(fix_small_values)
then
5475 call mhd_handle_small_ei(w,x,ixi^l,ixo^l,
e_,
'add_source_internal_e')
5477 end subroutine add_source_internal_e
5480 subroutine add_source_hydrodynamic_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5485 integer,
intent(in) :: ixi^
l, ixo^
l
5486 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5487 double precision,
intent(inout) :: w(ixi^s,1:nw)
5488 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
5490 double precision ::
b(ixi^s,3), j(ixi^s,3), jxb(ixi^s,3)
5491 double precision :: current(ixi^s,7-2*
ndir:3)
5492 double precision :: bu(ixo^s,1:
ndir), tmp(ixo^s), b2(ixo^s)
5493 double precision :: gravity_field(ixi^s,1:
ndir), vaoc
5494 integer :: idir, idirmin, idims, ix^
d
5499 b(ixo^s, idir) = wct(ixo^s,mag(idir))
5511 j(ixo^s,idir)=current(ixo^s,idir)
5590 call add_source_ambipolar_internal_energy(qdt,ixi^
l,ixo^
l,wct,w,x)
5593 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_hydrodynamic_e')
5595 end subroutine add_source_hydrodynamic_e
5601 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
5606 integer,
intent(in) :: ixi^
l, ixo^
l
5607 double precision,
intent(in) :: qdt
5608 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5609 double precision,
intent(inout) :: w(ixi^s,1:nw)
5611 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim
5612 double precision :: tmp(ixi^s),tmp2(ixi^s)
5615 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
5616 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
5617 double precision :: lapl_vec(ixi^s,1:
ndir)
5623 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5624 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
5631 gradeta(ixo^s,1:
ndim)=zero
5636 gradeta(ixo^s,idim)=tmp(ixo^s)
5643 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
5650 tmp(ixo^s)=lapl_vec(ixo^s,idir)*eta(ixo^s)
5654 do jdir=1,
ndim;
do kdir=idirmin,3
5655 if (
lvc(idir,jdir,kdir)/=0)
then
5656 if (
lvc(idir,jdir,kdir)==1)
then
5657 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
5659 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
5666 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
5667 if(total_energy)
then
5668 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
5674 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
5677 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
5679 end subroutine add_source_res1
5683 subroutine add_source_res_exp(qdt,ixI^L,ixO^L,wCT,w,x)
5688 integer,
intent(in) :: ixi^
l, ixo^
l
5689 double precision,
intent(in) :: qdt
5690 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5691 double precision,
intent(inout) :: w(ixi^s,1:nw)
5694 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
5695 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
5696 integer :: ixa^
l,idir,idirmin,idirmin1
5700 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5701 call mpistop(
"Error in add_source_res_exp: Non-conforming input limits")
5711 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
mhd_eta
5716 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
5725 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
5728 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
5733 tmp(ixo^s)=qdt*
mhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
5735 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
5737 if(total_energy)
then
5740 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
5741 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
5744 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
5748 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res_exp')
5749 end subroutine add_source_res_exp
5754 subroutine add_source_ambi_exp(qdt,ixI^L,ixO^L,wCT,w,x)
5759 integer,
intent(in) :: ixi^
l, ixo^
l
5760 double precision,
intent(in) :: qdt
5761 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5762 double precision,
intent(inout) :: w(ixi^s,1:nw)
5764 double precision :: current(ixi^s,1:3),curlj(ixi^s,1:3)
5765 double precision :: tmpvec(ixi^s,1:3),tmp(ixi^s),btot2(ixi^s)
5766 integer :: ixa^
l,idir,idirmin1
5770 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5771 call mpistop(
"Error in add_source_ambi_exp: Non-conforming input limits")
5775 call mhd_get_jxbxb(wct,x,ixi^
l,ixa^
l,current)
5789 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
5792 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
5799 where (btot2(ixa^s)>smalldouble )
5800 tmp(ixa^s) = sum(current(ixa^s,1:3)**2,dim=
ndim+1) / btot2(ixa^s)
5807 tmp(ixo^s)=-qdt*tmp(ixo^s)
5808 if(total_energy)
then
5811 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
5812 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
5815 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
5819 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_ambi_exp')
5820 end subroutine add_source_ambi_exp
5824 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
5828 integer,
intent(in) :: ixi^
l, ixo^
l
5829 double precision,
intent(in) :: qdt
5830 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5831 double precision,
intent(inout) :: w(ixi^s,1:nw)
5833 double precision :: current(ixi^s,7-2*
ndir:3)
5834 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
5835 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
5838 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5839 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
5842 tmpvec(ixa^s,1:
ndir)=zero
5844 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
5848 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
5851 tmpvec(ixa^s,1:
ndir)=zero
5852 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
5856 tmpvec2(ixa^s,1:
ndir)=zero
5857 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
5860 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
5863 if(total_energy)
then
5866 tmpvec2(ixa^s,1:
ndir)=zero
5867 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
5868 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
5869 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
5870 end do;
end do;
end do
5872 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
5873 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
5876 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
5878 end subroutine add_source_hyperres
5880 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
5887 integer,
intent(in) :: ixi^
l, ixo^
l
5888 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5889 double precision,
intent(inout) :: w(ixi^s,1:nw)
5891 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
5912 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
5915 if(total_energy)
then
5924 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
5933 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
5937 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
5939 end subroutine add_source_glm
5942 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
5945 integer,
intent(in) :: ixi^
l, ixo^
l
5946 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5947 double precision,
intent(inout) :: w(ixi^s,1:nw)
5949 double precision :: divb(ixi^s), ba(1:
ndir)
5950 integer :: idir, ix^
d
5956 {
do ix^db=ixomin^db,ixomax^db\}
5961 if (total_energy)
then
5967 {
do ix^db=ixomin^db,ixomax^db\}
5969 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
5971 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
5972 if (total_energy)
then
5974 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
5979 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
5981 end subroutine add_source_powel
5983 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
5988 integer,
intent(in) :: ixi^
l, ixo^
l
5989 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5990 double precision,
intent(inout) :: w(ixi^s,1:nw)
5992 double precision :: divb(ixi^s)
5993 integer :: idir, ix^
d
5998 {
do ix^db=ixomin^db,ixomax^db\}
6003 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
6005 end subroutine add_source_janhunen
6007 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
6012 integer,
intent(in) :: ixi^
l, ixo^
l
6013 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6014 double precision,
intent(inout) :: w(ixi^s,1:nw)
6016 double precision :: divb(ixi^s),graddivb(ixi^s)
6017 integer :: idim, idir, ixp^
l, i^
d, iside
6018 logical,
dimension(-1:1^D&) :: leveljump
6026 if(i^
d==0|.and.) cycle
6027 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
6028 leveljump(i^
d)=.true.
6030 leveljump(i^
d)=.false.
6039 i^dd=kr(^dd,^d)*(2*iside-3);
6040 if (leveljump(i^dd))
then
6042 ixpmin^d=ixomin^d-i^d
6044 ixpmax^d=ixomax^d-i^d
6055 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
6057 {
do i^db=ixpmin^db,ixpmax^db\}
6059 graddivb(i^d)=graddivb(i^d)*
divbdiff/(^d&1.0d0/block%ds({i^d},^d)**2+)
6061 w(i^d,mag(idim))=w(i^d,mag(idim))+graddivb(i^d)
6063 if (typedivbdiff==
'all' .and. total_energy)
then
6065 w(i^d,
e_)=w(i^d,
e_)+wct(i^d,mag(idim))*graddivb(i^d)
6070 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
6072 end subroutine add_source_linde
6079 integer,
intent(in) :: ixi^
l, ixo^
l
6080 double precision,
intent(in) :: w(ixi^s,1:nw)
6081 double precision :: divb(ixi^s), dsurface(ixi^s)
6083 double precision :: invb(ixo^s)
6084 integer :: ixa^
l,idims
6086 call get_divb(w,ixi^
l,ixo^
l,divb)
6088 where(invb(ixo^s)/=0.d0)
6089 invb(ixo^s)=1.d0/invb(ixo^s)
6092 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
6094 ixamin^
d=ixomin^
d-1;
6095 ixamax^
d=ixomax^
d-1;
6096 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
6098 ixa^
l=ixo^
l-
kr(idims,^
d);
6099 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
6101 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
6102 block%dvolume(ixo^s)/dsurface(ixo^s)
6113 integer,
intent(in) :: ixo^
l, ixi^
l
6114 double precision,
intent(in) :: w(ixi^s,1:nw)
6115 integer,
intent(out) :: idirmin
6118 double precision :: current(ixi^s,7-2*
ndir:3)
6119 integer :: idir, idirmin0
6125 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
6126 block%J0(ixo^s,idirmin0:3)
6130 subroutine mhd_get_dt(wprim,ixI^L,ixO^L,dtnew,dx^D,x)
6138 integer,
intent(in) :: ixi^
l, ixo^
l
6139 double precision,
intent(inout) :: dtnew
6140 double precision,
intent(in) ::
dx^
d
6141 double precision,
intent(in) :: wprim(ixi^s,1:nw)
6142 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6144 double precision :: dxarr(
ndim)
6145 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
6146 integer :: idirmin,idim
6164 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
6167 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
6189 dtnew=min(
dtdiffpar*get_ambipolar_dt(wprim,ixi^
l,ixo^
l,
dx^
d,x),dtnew)
6200 end subroutine mhd_get_dt
6205 subroutine mhd_fld_implicit_update(dtfactor,qdt,qtC,psa,psb)
6210 double precision,
intent(in) :: qdt
6211 double precision,
intent(in) :: qtc
6212 double precision,
intent(in) :: dtfactor
6215 end subroutine mhd_fld_implicit_update
6217 subroutine mhd_fld_evaluate_implicit(qtC,psa)
6221 double precision,
intent(in) :: qtc
6224 end subroutine mhd_fld_evaluate_implicit
6231 subroutine mhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6237 integer,
intent(in) :: ixi^
l, ixo^
l
6238 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6239 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6241 double precision :: adiabs(ixi^s), gammas(ixi^s)
6242 double precision :: tmp,tmp1,invr,cot
6244 integer :: mr_,mphi_
6245 integer :: br_,bphi_
6248 br_=mag(1); bphi_=mag(1)-1+
phi_
6265 {
do ix^db=ixomin^db,ixomax^db\}
6268 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6273 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6275 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6278 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
6279 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
6280 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6281 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6282 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
6284 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6285 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6286 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6289 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
6294 {
do ix^db=ixomin^db,ixomax^db\}
6296 if(local_timestep)
then
6297 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
6302 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6304 tmp1=adiabs(ix^d)*wprim(ix^d,
rho_)**gammas(ix^d)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6308 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
6311 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6312 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
6316 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
6322 cot=1.d0/tan(x(ix^d,2))
6326 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6327 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
6329 if(.not.stagger_grid)
then
6330 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6332 tmp=tmp+wprim(ix^d,
psi_)*cot
6334 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6339 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6340 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
6341 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
6343 if(.not.stagger_grid)
then
6344 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6346 tmp=tmp+wprim(ix^d,
psi_)*cot
6348 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6351 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
6352 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
6353 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6354 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
6355 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
6357 if(.not.stagger_grid)
then
6358 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
6359 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6360 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6361 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6362 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
6369 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
6372 end subroutine mhd_add_source_geom
6379 subroutine mhd_add_source_geom_semirelati(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6385 integer,
intent(in) :: ixi^
l, ixo^
l
6386 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6387 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6389 double precision :: adiabs(ixi^s), gammas(ixi^s)
6390 double precision :: tmp,tmp1,tmp2,invr,cot,ef(ixo^s,1:
ndir)
6392 integer :: mr_,mphi_
6393 integer :: br_,bphi_
6396 br_=mag(1); bphi_=mag(1)-1+
phi_
6413 {
do ix^db=ixomin^db,ixomax^db\}
6416 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6423 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)
6427 ef(ix^
d,1)=wprim(ix^
d,b2_)*wprim(ix^
d,m3_)-wprim(ix^
d,b3_)*wprim(ix^
d,m2_)
6428 ef(ix^
d,2)=wprim(ix^
d,b3_)*wprim(ix^
d,m1_)-wprim(ix^
d,b1_)*wprim(ix^
d,m3_)
6429 ef(ix^
d,3)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
6434 ef(ix^
d,2)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
6440 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+&
6441 half*((^
c&wprim(ix^
d,
b^
c_)**2+)+(^
c&ef(ix^
d,^
c)**2+)*inv_squared_c) -&
6442 wprim(ix^
d,bphi_)**2+wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)**2)
6443 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6444 -wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6445 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_)+ef(ix^
d,
phi_)*ef(ix^
d,1)*inv_squared_c)
6447 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6448 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6449 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6452 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+half*((^
c&wprim(ix^
d,
b^
c_)**2+)+&
6453 (^
c&ef(ix^
d,^
c)**2+)*inv_squared_c))
6458 {
do ix^db=ixomin^db,ixomax^db\}
6460 if(local_timestep)
then
6461 invr=block%dt(ix^d)*dtfactor/x(ix^d,1)
6467 ef(ix^d,1)=wprim(ix^d,b2_)*wprim(ix^d,m3_)-wprim(ix^d,b3_)*wprim(ix^d,m2_)
6468 ef(ix^d,2)=wprim(ix^d,b3_)*wprim(ix^d,m1_)-wprim(ix^d,b1_)*wprim(ix^d,m3_)
6469 ef(ix^d,3)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
6473 ef(ix^d,1)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
6480 tmp1=wprim(ix^d,
p_)+half*((^
c&wprim(ix^d,
b^
c_)**2+)+(^
c&ef(ix^d,^
c)**2+)*inv_squared_c)
6482 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)
6486 w(ix^d,m1_)=w(ix^d,m1_)+two*tmp1*invr
6489 w(ix^d,m1_)=w(ix^d,m1_)+invr*&
6490 (two*tmp1+(^ce&wprim(ix^d,
rho_)*wprim(ix^d,
m^ce_)**2-&
6491 wprim(ix^d,
b^ce_)**2-ef(ix^d,^ce)**2*inv_squared_c+))
6495 w(ix^d,b1_)=w(ix^d,b1_)+invr*2.0d0*wprim(ix^d,
psi_)
6501 cot=1.d0/tan(x(ix^d,2))
6505 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_)&
6506 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c)
6508 if(.not.stagger_grid)
then
6509 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6511 tmp=tmp+wprim(ix^d,
psi_)*cot
6513 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
6519 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_) &
6520 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c&
6521 +(wprim(ix^d,
rho_)*wprim(ix^d,m3_)**2&
6522 -wprim(ix^d,b3_)**2-ef(ix^d,3)**2*inv_squared_c)*cot)
6524 if(.not.stagger_grid)
then
6525 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6527 tmp=tmp+wprim(ix^d,
psi_)*cot
6529 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
6532 w(ix^d,m3_)=w(ix^d,m3_)+invr*&
6533 (-wprim(ix^d,m3_)*wprim(ix^d,m1_)*wprim(ix^d,
rho_) &
6534 +wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6535 +ef(ix^d,3)*ef(ix^d,1)*inv_squared_c&
6536 +(-wprim(ix^d,m2_)*wprim(ix^d,m3_)*wprim(ix^d,
rho_) &
6537 +wprim(ix^d,b2_)*wprim(ix^d,b3_)&
6538 +ef(ix^d,2)*ef(ix^d,3)*inv_squared_c)*cot)
6540 if(.not.stagger_grid)
then
6541 w(ix^d,b3_)=w(ix^d,b3_)+invr*&
6542 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6543 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6544 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6545 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
6552 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
6555 end subroutine mhd_add_source_geom_semirelati
6564 subroutine mhd_add_source_geom_split(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6570 integer,
intent(in) :: ixi^
l, ixo^
l
6571 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6572 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6574 double precision :: tmp,tmp1,tmp2,invr,cot
6575 double precision :: adiabs(ixi^s), gammas(ixi^s)
6577 integer :: mr_,mphi_
6578 integer :: br_,bphi_
6594 br_=mag(1); bphi_=mag(1)-1+
phi_
6599 {
do ix^db=ixomin^db,ixomax^db\}
6602 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6607 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6609 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6613 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
6614 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
6618 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6619 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6620 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
6622 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))
6625 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6626 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6627 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6629 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6635 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
6640 {
do ix^db=ixomin^db,ixomax^db\}
6642 if(local_timestep)
then
6643 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
6647 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6648 if(b0field) tmp2=(^
c&block%B0(ix^d,^
c,0)*wprim(ix^d,
b^
c_)+)
6651 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
6652 if(b0field) w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp2*invr
6656 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6657 (two*(tmp1+tmp2)+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+)- &
6658 (^ce&two*block%B0(ix^d,^ce,0)*wprim(ix^d,
b^ce_)+))
6660 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6661 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
6666 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
6672 cot=1.d0/tan(x(ix^d,2))
6677 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6678 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
6679 +wprim(ix^d,b1_)*block%B0(ix^d,2,0))
6681 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6682 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
6685 if(.not.stagger_grid)
then
6687 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
6688 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
6690 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6693 tmp=tmp+wprim(ix^d,
psi_)*cot
6695 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6701 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6702 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
6703 +wprim(ix^d,b1_)*block%B0(ix^d,2,0)&
6704 +(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)
6706 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6707 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
6708 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
6711 if(.not.stagger_grid)
then
6713 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
6714 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
6716 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6719 tmp=tmp+wprim(ix^d,
psi_)*cot
6721 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6725 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
6726 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
6727 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6728 +block%B0(ix^d,1,0)*wprim(ix^d,b3_) &
6729 +wprim(ix^d,b1_)*block%B0(ix^d,3,0) &
6730 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
6731 -wprim(ix^d,b2_)*wprim(ix^d,b3_) &
6732 +block%B0(ix^d,2,0)*wprim(ix^d,b3_) &
6733 +wprim(ix^d,b2_)*block%B0(ix^d,3,0))*cot)
6735 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
6736 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
6737 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6738 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
6739 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
6742 if(.not.stagger_grid)
then
6744 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
6745 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6746 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6747 +wprim(ix^d,m1_)*block%B0(ix^d,3,0) &
6748 -wprim(ix^d,m3_)*block%B0(ix^d,1,0) &
6749 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6750 -wprim(ix^d,m2_)*wprim(ix^d,b3_) &
6751 +wprim(ix^d,m3_)*block%B0(ix^d,2,0) &
6752 -wprim(ix^d,m2_)*block%B0(ix^d,3,0))*cot)
6754 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
6755 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6756 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6757 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6758 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
6766 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
6769 end subroutine mhd_add_source_geom_split
6774 integer,
intent(in) :: ixi^
l, ixo^
l
6775 double precision,
intent(in) :: w(ixi^s, nw)
6776 double precision :: mge(ixo^s)
6779 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
6781 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
6785 subroutine mhd_getv_hall(w,x,ixI^L,ixO^L,vHall,partial)
6789 integer,
intent(in) :: ixi^
l, ixo^
l
6790 double precision,
intent(in) :: w(ixi^s,nw)
6791 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6792 double precision,
intent(inout) :: vhall(ixi^s,1:
ndir)
6793 logical,
intent(in),
optional :: partial
6795 double precision :: current(ixi^s,7-2*
ndir:3)
6796 double precision :: rho(ixi^s)
6797 integer :: idir, idirmin, ix^
d
6798 logical :: use_partial
6801 if(
present(partial)) use_partial=partial
6803 if(.not.use_partial)
then
6814 do idir = idirmin,
ndir
6815 {
do ix^db=ixomin^db,ixomax^db\}
6816 vhall(ix^
d,idir)=-
mhd_etah*current(ix^
d,idir)/rho(ix^
d)
6820 end subroutine mhd_getv_hall
6822 subroutine mhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
6825 integer,
intent(in) :: ixi^
l, ixo^
l, idir
6826 double precision,
intent(in) :: qt
6827 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
6828 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
6831 double precision :: db(ixo^s), dpsi(ixo^s)
6835 {
do ix^db=ixomin^db,ixomax^db\}
6836 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6837 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6838 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6839 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6848 {
do ix^db=ixomin^db,ixomax^db\}
6849 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
6850 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
6851 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
6852 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
6853 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
6855 if(total_energy)
then
6856 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
6857 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
6859 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
6861 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
6864 if(total_energy)
then
6865 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
6866 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
6871 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
6873 end subroutine mhd_modify_wlr
6875 subroutine mhd_boundary_adjust(igrid,psb)
6877 integer,
intent(in) :: igrid
6880 integer :: ib, idims, iside, ixo^
l, i^
d
6889 i^
d=
kr(^
d,idims)*(2*iside-3);
6890 if (neighbor_type(i^
d,igrid)/=1) cycle
6891 ib=(idims-1)*2+iside
6909 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
6914 end subroutine mhd_boundary_adjust
6916 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
6919 integer,
intent(in) :: ixg^
l,ixo^
l,ib
6920 double precision,
intent(inout) :: w(ixg^s,1:nw)
6921 double precision,
intent(in) :: x(ixg^s,1:
ndim)
6923 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
6924 integer :: ix^
d,ixf^
l
6930 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
6938 do ix1=ixfmax1,ixfmin1,-1
6939 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
6940 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
6941 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
6944 do ix1=ixfmax1,ixfmin1,-1
6945 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
6946 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
6947 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
6948 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
6949 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
6950 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
6951 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
6965 do ix1=ixfmax1,ixfmin1,-1
6966 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
6967 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
6968 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
6969 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
6970 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
6971 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
6974 do ix1=ixfmax1,ixfmin1,-1
6975 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
6976 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
6977 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
6978 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
6979 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
6980 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
6981 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
6982 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
6983 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
6984 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
6985 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
6986 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
6987 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
6988 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
6989 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
6990 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
6991 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
6992 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
6997 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7000 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7008 do ix1=ixfmin1,ixfmax1
7009 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
7010 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7011 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7014 do ix1=ixfmin1,ixfmax1
7015 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
7016 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
7017 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7018 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7019 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7020 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7021 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7035 do ix1=ixfmin1,ixfmax1
7036 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7037 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7038 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7039 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7040 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7041 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7044 do ix1=ixfmin1,ixfmax1
7045 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7046 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7047 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7048 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7049 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7050 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7051 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7052 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7053 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7054 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7055 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7056 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7057 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7058 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7059 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7060 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7061 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7062 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7067 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7070 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7078 do ix2=ixfmax2,ixfmin2,-1
7079 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
7080 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7081 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7084 do ix2=ixfmax2,ixfmin2,-1
7085 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
7086 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
7087 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7088 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7089 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7090 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7091 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7105 do ix2=ixfmax2,ixfmin2,-1
7106 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7107 ix2+1,ixfmin3:ixfmax3,mag(2)) &
7108 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7109 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7110 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7111 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7114 do ix2=ixfmax2,ixfmin2,-1
7115 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
7116 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
7117 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7118 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
7119 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7120 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7121 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7122 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7123 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7124 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7125 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7126 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7127 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7128 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7129 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7130 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7131 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
7132 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7137 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7140 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7148 do ix2=ixfmin2,ixfmax2
7149 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
7150 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7151 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7154 do ix2=ixfmin2,ixfmax2
7155 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
7156 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
7157 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7158 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7159 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7160 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7161 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7175 do ix2=ixfmin2,ixfmax2
7176 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7177 ix2-1,ixfmin3:ixfmax3,mag(2)) &
7178 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7179 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7180 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7181 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7184 do ix2=ixfmin2,ixfmax2
7185 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
7186 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
7187 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7188 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
7189 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7190 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7191 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7192 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7193 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7194 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7195 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7196 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7197 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7198 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7199 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7200 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7201 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
7202 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7207 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7211 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7221 do ix3=ixfmax3,ixfmin3,-1
7222 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
7223 ixfmin2:ixfmax2,ix3+1,mag(3)) &
7224 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
7225 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
7226 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
7227 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
7230 do ix3=ixfmax3,ixfmin3,-1
7231 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
7232 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
7233 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
7234 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
7235 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
7236 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7237 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
7238 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
7239 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7240 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
7241 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
7242 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
7243 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
7244 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
7245 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
7246 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
7247 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
7248 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
7252 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7255 if(total_energy)
call eos%to_primitive(ixg^
l,ixo^
l,w,x)
7265 do ix3=ixfmin3,ixfmax3
7266 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
7267 ixfmin2:ixfmax2,ix3-1,mag(3)) &
7268 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
7269 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
7270 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
7271 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
7274 do ix3=ixfmin3,ixfmax3
7275 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
7276 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
7277 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
7278 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
7279 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
7280 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7281 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
7282 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
7283 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7284 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
7285 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
7286 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
7287 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
7288 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
7289 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
7290 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
7291 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
7292 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
7296 if(total_energy)
call eos%to_conserved(ixg^
l,ixo^
l,w,x)
7299 call mpistop(
"Special boundary is not defined for this region")
7302 end subroutine fixdivb_boundary
7311 double precision,
intent(in) :: qdt
7312 double precision,
intent(in) :: qt
7313 logical,
intent(inout) :: active
7316 integer,
parameter :: max_its = 50
7317 double precision :: residual_it(max_its), max_divb
7318 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
7319 double precision :: res
7320 double precision,
parameter :: max_residual = 1
d-3
7321 double precision,
parameter :: residual_reduction = 1
d-10
7322 integer :: iigrid, igrid
7323 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
7326 mg%operator_type = mg_laplacian
7334 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7335 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7338 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
7339 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7341 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7342 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7345 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7346 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7350 write(*,*)
"mhd_clean_divb_multigrid warning: unknown boundary type"
7351 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7352 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7360 do iigrid = 1, igridstail
7361 igrid = igrids(iigrid);
7364 lvl =
mg%boxes(id)%lvl
7365 nc =
mg%box_size_lvl(lvl)
7371 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
7373 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
7374 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
7379 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
7382 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
7383 if (
mype == 0) print *,
"iteration vs residual"
7386 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
7387 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
7388 if (residual_it(n) < residual_reduction * max_divb)
exit
7390 if (
mype == 0 .and. n > max_its)
then
7391 print *,
"divb_multigrid warning: not fully converged"
7392 print *,
"current amplitude of divb: ", residual_it(max_its)
7393 print *,
"multigrid smallest grid: ", &
7394 mg%domain_size_lvl(:,
mg%lowest_lvl)
7395 print *,
"note: smallest grid ideally has <= 8 cells"
7396 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
7397 print *,
"note: dx/dy/dz should be similar"
7401 call mg_fas_vcycle(
mg, max_res=res)
7402 if (res < max_residual)
exit
7404 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
7409 do iigrid = 1, igridstail
7410 igrid = igrids(iigrid);
7419 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
7423 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
7425 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
7427 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
7440 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
7441 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
7444 if(total_energy)
then
7446 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
7449 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
7459 subroutine mhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
7463 integer,
intent(in) :: ixi^
l, ixo^
l
7464 double precision,
intent(in) :: qt,qdt
7466 double precision,
intent(in) :: wp(ixi^s,1:nw)
7467 type(state) :: sct, s
7468 type(ct_velocity) :: vcts
7469 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
7470 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
7472 double precision :: circ(ixi^s,1:
ndim)
7474 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
7475 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
7476 integer :: idim1,idim2,idir,iwdim1,iwdim2
7478 associate(bfaces=>s%ws,x=>s%x)
7485 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
7492 i1kr^
d=
kr(idim1,^
d);
7495 i2kr^
d=
kr(idim2,^
d);
7498 if (
lvc(idim1,idim2,idir)==1)
then
7500 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
7502 {
do ix^db=ixcmin^db,ixcmax^db\}
7503 fe(ix^
d,idir)=quarter*&
7504 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
7505 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
7507 if(
mhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
7512 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
7520 if(
associated(usr_set_electric_field)) &
7521 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
7523 circ(ixi^s,1:ndim)=zero
7528 ixcmin^d=ixomin^d-kr(idim1,^d);
7530 ixa^l=ixc^l-kr(idim2,^d);
7533 if(lvc(idim1,idim2,idir)==1)
then
7535 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7538 else if(lvc(idim1,idim2,idir)==-1)
then
7540 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7546 {
do ix^db=ixcmin^db,ixcmax^db\}
7548 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
7550 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
7557 end subroutine mhd_update_faces_average
7560 subroutine mhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
7565 integer,
intent(in) :: ixi^
l, ixo^
l
7566 double precision,
intent(in) :: qt, qdt
7568 double precision,
intent(in) :: wp(ixi^s,1:nw)
7569 type(state) :: sct, s
7570 type(ct_velocity) :: vcts
7571 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
7572 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
7574 double precision :: circ(ixi^s,1:
ndim)
7576 double precision :: ecc(ixi^s,
sdim:3)
7577 double precision :: ein(ixi^s,
sdim:3)
7579 double precision :: el(ixi^s),er(ixi^s)
7581 double precision :: elc,erc
7583 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
7585 double precision :: jce(ixi^s,
sdim:3)
7587 double precision :: xs(ixgs^t,1:
ndim)
7588 double precision :: gradi(ixgs^t)
7589 integer :: ixc^
l,ixa^
l
7590 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
7592 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
7595 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
7601 {
do ix^db=iximin^db,iximax^db\}
7604 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_)
7605 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_)
7606 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_)
7609 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
7616 {
do ix^db=iximin^db,iximax^db\}
7619 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
7620 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
7621 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
7624 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
7638 i1kr^d=kr(idim1,^d);
7641 i2kr^d=kr(idim2,^d);
7644 if (lvc(idim1,idim2,idir)==1)
then
7646 ixcmin^d=ixomin^d+kr(idir,^d)-1;
7649 {
do ix^db=ixcmin^db,ixcmax^db\}
7650 fe(ix^d,idir)=quarter*&
7651 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
7652 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
7657 ixamax^d=ixcmax^d+i1kr^d;
7658 {
do ix^db=ixamin^db,ixamax^db\}
7659 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
7660 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
7663 do ix^db=ixcmin^db,ixcmax^db\}
7664 if(vnorm(ix^d,idim1)>0.d0)
then
7666 else if(vnorm(ix^d,idim1)<0.d0)
then
7667 elc=el({ix^d+i1kr^d})
7669 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
7671 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
7673 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
7674 erc=er({ix^d+i1kr^d})
7676 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
7678 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
7683 ixamax^d=ixcmax^d+i2kr^d;
7684 {
do ix^db=ixamin^db,ixamax^db\}
7685 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
7686 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
7689 do ix^db=ixcmin^db,ixcmax^db\}
7690 if(vnorm(ix^d,idim2)>0.d0)
then
7692 else if(vnorm(ix^d,idim2)<0.d0)
then
7693 elc=el({ix^d+i2kr^d})
7695 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
7697 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
7699 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
7700 erc=er({ix^d+i2kr^d})
7702 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
7704 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
7708 if(
mhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
7713 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
7727 if (lvc(idim1,idim2,idir)==0) cycle
7729 ixcmin^d=ixomin^d+kr(idir,^d)-1;
7730 ixamax^d=ixcmax^d-kr(idir,^d)+1;
7733 xs(ixa^s,:)=x(ixa^s,:)
7734 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
7735 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
7736 if (lvc(idim1,idim2,idir)==1)
then
7737 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
7739 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
7746 ixcmin^d=ixomin^d+kr(idir,^d)-1;
7748 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
7752 {
do ix^db=ixomin^db,ixomax^db\}
7753 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
7754 +ein(ix1,ix2-1,ix3-1,idir))
7755 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7756 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7758 else if(idir==2)
then
7759 {
do ix^db=ixomin^db,ixomax^db\}
7760 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
7761 +ein(ix1-1,ix2,ix3-1,idir))
7762 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7763 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7766 {
do ix^db=ixomin^db,ixomax^db\}
7767 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
7768 +ein(ix1-1,ix2-1,ix3,idir))
7769 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7770 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7776 {
do ix^db=ixomin^db,ixomax^db\}
7777 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
7778 +ein(ix1-1,ix2-1,idir))
7779 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7780 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7791 if(
associated(usr_set_electric_field)) &
7792 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
7794 circ(ixi^s,1:ndim)=zero
7799 ixcmin^d=ixomin^d-kr(idim1,^d);
7801 ixa^l=ixc^l-kr(idim2,^d);
7804 if(lvc(idim1,idim2,idir)==1)
then
7806 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7809 else if(lvc(idim1,idim2,idir)==-1)
then
7811 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7817 {
do ix^db=ixcmin^db,ixcmax^db\}
7819 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
7821 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
7828 end subroutine mhd_update_faces_contact
7831 subroutine mhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
7836 integer,
intent(in) :: ixi^
l, ixo^
l
7837 double precision,
intent(in) :: qt, qdt
7839 double precision,
intent(in) :: wp(ixi^s,1:nw)
7840 type(state) :: sct, s
7841 type(ct_velocity) :: vcts
7842 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
7843 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
7845 double precision :: vtill(ixi^s,2)
7846 double precision :: vtilr(ixi^s,2)
7847 double precision :: bfacetot(ixi^s,
ndim)
7848 double precision :: btill(ixi^s,
ndim)
7849 double precision :: btilr(ixi^s,
ndim)
7850 double precision :: cp(ixi^s,2)
7851 double precision :: cm(ixi^s,2)
7852 double precision :: circ(ixi^s,1:
ndim)
7854 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
7855 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
7856 integer :: idim1,idim2,idir,ix^
d
7858 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
7859 cbarmax=>vcts%cbarmax)
7872 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
7888 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
7892 idim2=mod(idir+1,3)+1
7894 jxc^
l=ixc^
l+
kr(idim1,^
d);
7895 ixcp^
l=ixc^
l+
kr(idim2,^
d);
7899 vtill(ixi^s,2),vtilr(ixi^s,2))
7902 vtill(ixi^s,1),vtilr(ixi^s,1))
7908 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
7909 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
7911 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
7912 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
7915 btill(ixi^s,idim1),btilr(ixi^s,idim1))
7918 btill(ixi^s,idim2),btilr(ixi^s,idim2))
7922 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
7923 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
7925 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
7926 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
7930 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
7931 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
7932 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
7933 /(cp(ixc^s,1)+cm(ixc^s,1)) &
7934 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
7935 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
7936 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
7937 /(cp(ixc^s,2)+cm(ixc^s,2))
7940 if(
mhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
7944 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
7958 circ(ixi^s,1:
ndim)=zero
7963 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
7967 if(
lvc(idim1,idim2,idir)/=0)
then
7968 hxc^
l=ixc^
l-
kr(idim2,^
d);
7970 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7971 +
lvc(idim1,idim2,idir)&
7977 {
do ix^db=ixcmin^db,ixcmax^db\}
7979 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
7981 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
7987 end subroutine mhd_update_faces_hll
7990 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
7995 integer,
intent(in) :: ixi^
l, ixo^
l
7997 double precision,
intent(in) :: wp(ixi^s,1:nw)
7998 type(state),
intent(in) :: sct, s
8000 double precision :: jce(ixi^s,
sdim:3)
8003 double precision :: jcc(ixi^s,7-2*
ndir:3)
8005 double precision :: xs(ixgs^t,1:
ndim)
8007 double precision :: eta(ixi^s)
8008 double precision :: gradi(ixgs^t)
8009 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
8011 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
8017 if (
lvc(idim1,idim2,idir)==0) cycle
8019 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8020 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
8023 xs(ixb^s,:)=x(ixb^s,:)
8024 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
8025 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
8026 if (
lvc(idim1,idim2,idir)==1)
then
8027 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
8029 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
8036 jce(ixi^s,:)=jce(ixi^s,:)*
mhd_eta
8044 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8045 jcc(ixc^s,idir)=0.d0
8047 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8048 ixamin^
d=ixcmin^
d+ix^
d;
8049 ixamax^
d=ixcmax^
d+ix^
d;
8050 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
8052 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
8053 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
8058 end subroutine get_resistive_electric_field
8061 subroutine get_ambipolar_electric_field(ixI^L,ixO^L,w,x,fE)
8064 integer,
intent(in) :: ixi^
l, ixo^
l
8065 double precision,
intent(in) :: w(ixi^s,1:nw)
8066 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8067 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
8069 double precision :: jxbxb(ixi^s,1:3)
8070 integer :: idir,ixa^
l,ixc^
l,ix^
d
8073 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,jxbxb)
8080 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8083 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8084 ixamin^
d=ixcmin^
d+ix^
d;
8085 ixamax^
d=ixcmax^
d+ix^
d;
8086 fe(ixc^s,idir)=fe(ixc^s,idir)+jxbxb(ixa^s,idir)
8088 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0
8091 end subroutine get_ambipolar_electric_field
8097 integer,
intent(in) :: ixo^
l
8107 do ix^db=ixomin^db,ixomax^db\}
8109 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8110 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
8111 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8112 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
8113 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
8114 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
8117 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8118 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
8119 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8120 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
8163 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
8164 double precision,
intent(inout) :: ws(ixis^s,1:nws)
8165 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8167 double precision :: adummy(ixis^s,1:3)
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine cak_init(phys_gamma)
Initialize the module.
subroutine cak_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine cak_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter bigdouble
A very large real number.
subroutine reconstruct(ixil, ixcl, idir, q, ql, qr)
Reconstruct scalar q within ixO^L to 1/2 dx in direction idir Return both left and right reconstructe...
subroutine b_from_vector_potentiala(ixisl, ixil, ixol, ws, x, a)
calculate magnetic field from vector potential A at cell edges
subroutine add_convert_method(phys_convert_vars, nwc, dataset_names, file_suffix)
PI (partial-ionisation) ionisation-degree backend for the eos% family.
Equation of state for AMRVAC, handled through a single eos_container object.
Module for flux conservation near refinement boundaries.
subroutine, public store_flux(igrid, fc, idimlim, nwfluxin)
subroutine, public store_edge(igrid, ixil, fe, idimlim)
Module for flux limited diffusion (FLD)-approximation in Radiation-(Magneto)hydrodynamics simulations...
double precision, public fld_bisect_tol
Tolerance for bisection method for Energy sourceterms This is a percentage of the minimum of gas- and...
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x, fl)
get dt limit for radiation force and FLD explicit source additions NOTE: w is primitive on entry
double precision, public fld_diff_tol
Tolerance for radiative Energy diffusion.
character(len=40) fld_fluxlimiter
flux limiter choice
character(len=40) fld_opal_table
double precision, public fld_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:
subroutine, public fld_implicit_update(dtfactor, qdt, qtc, psa, psb, fl)
Calling all subroutines to perform the multigrid method Communicates rad_e and diff_coeff to multigri...
subroutine, public fld_evaluate_implicit(qtc, psa, fl)
inplace update of psa==>F_im(psa)
subroutine, public fld_init()
Initialising FLD-module Read opacities Initialise Multigrid and adimensionalise kappa.
integer nth_for_diff_mg
diffusion coefficient stencil control
Module with basic grid data structures.
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
subroutine, public get_divb(w, ixil, ixol, divb, nth_in)
Calculate div B within ixO.
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
Module with geometry-related routines (e.g., divergence, curl)
subroutine divvector(qvec, ixil, ixol, divq, nth_in)
subroutine laplacian_of_vector(qvec, ixil, ixol, lapl_qvec)
integer, parameter cylindrical
subroutine curlvector(qvec, ixil, ixol, curlvec, idirmin, idirmin0, ndir0, fourthorder)
Calculate curl of a vector qvec within ixL Options to employ standard second order CD evaluations use...
subroutine gradient(q, ixil, ixol, idir, gradq, nth_in)
subroutine gradientf(q, x, ixil, ixol, idir, gradq, nth_in, pm_in)
subroutine gradientl(q, ixil, ixol, idir, gradq)
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
double precision const_kappae
double precision arad_norm
Normalised radiation constant.
double precision dtdiffpar
For resistive MHD, the time step is also limited by the diffusion time: .
character(len=std_len) typegrad
double precision unit_charge
Physical scaling factor for charge.
double precision small_pressure
integer ixghi
Upper index of grid block arrays.
pure subroutine cross_product(ixil, ixol, a, b, axb)
Cross product of two vectors.
integer, dimension(3, 3, 3) lvc
Levi-Civita tensor.
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
double precision unit_opacity
Physical scaling factor for Opacity.
integer, parameter unitpar
file handle for IO
integer, parameter bc_asymm
double precision unit_mass
Physical scaling factor for mass.
logical use_imex_scheme
whether IMEX in use or not
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision phys_trac_mask
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
double precision unit_numberdensity
Physical scaling factor for number density.
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.
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.
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 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.
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.
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)
integer, public, protected mhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
subroutine, public get_normalized_divb(w, ixil, ixol, divb)
get dimensionless div B = |divB| * volume / area / |B|
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.
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.
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)
logical, public, protected mhd_viscosity
Whether viscosity is added.
subroutine, public mhd_get_pradiation_from_prim(w, x, ixil, ixol, prad)
Calculate radiation pressure within ixO^L.
double precision, public, protected mhd_reduced_c
Reduced speed of light for semirelativistic MHD: 2% of light speed.
logical, public, protected mhd_energy
Whether an energy equation is used.
logical, public, protected mhd_ambipolar_exp
Whether Ambipolar term is implemented explicitly.
double precision, public mhd_hyperbolic_tc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
logical, public, protected mhd_glm
Whether GLM-MHD is used to control div B.
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_magnetofriction
Whether magnetofriction is added.
double precision, public, protected mhd_trac_mask
Height of the mask used in the TRAC method.
procedure(mask_subroutine), pointer, public usr_mask_ambipolar
character(len=std_len), public, protected typedivbfix
Method type to clean divergence of B.
logical, public, protected mhd_thermal_conduction
Whether thermal conduction is used.
integer, public equi_pe0_
subroutine, public mhd_get_csrad2_prim(w, x, ixil, ixol, csound)
Calculate modified squared fast wave speed for FLD NOTE: w is primitive on entry here!...
integer, public, protected qperp_
Index of the perpendicular heat flux q_perp.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
character(len=std_len), public, protected mhd_hyperbolic_tc_perp_mode
Perpendicular hyperbolic-TC closure mode: 'off' = disabled 'fixed_reference' = fixed classical ratio ...
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
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, 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)
logical, public, protected b0field_forcefree
B0 field is force-free.
integer, dimension(2 *^nd), public, protected boundary_divbfix_skip
To skip * layer of ghost cells during divB=0 fix for boundary.
integer, public, protected tweight_
logical, public, protected mhd_ambipolar_sts
Whether Ambipolar term is implemented using supertimestepping.
logical, public, protected mhd_hyperbolic_tc_use_perp
Whether the perpendicular hyperbolic-TC channel is enabled.
subroutine, public mhd_ei_to_e(ixil, ixol, w, x)
Transform internal energy to total energy.
integer, public, protected e_
Index of the energy density (-1 if not present)
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
subroutine, public mhd_get_rho(w, x, ixil, ixol, rho)
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 radiative_cooling_init(fl, read_params)
subroutine radiative_cooling_add_source(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
Module for including rotating frame in (magneto)hydrodynamics simulations The rotation vector is assu...
subroutine rotating_frame_add_source(qdt, dtfactor, ixil, ixol, wct, w, x)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine rotating_frame_init()
Initialize the module.
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method which can be used for multiple source terms in the governing equatio...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
double precision function, public get_tc_dt_mhd(w, ixil, ixol, dxd, x, fl)
Get the explicit timestep for the TC (mhd implementation) Note: for multi-D MHD (1D MHD will use HD f...
double precision function, public get_tc_dt_hd(w, ixil, ixol, dxd, x, fl)
Get the explicit timestep for the TC (hd implementation) Note: also used in 1D MHD (or for neutrals i...
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_hd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine, public tc_get_mhd_params(fl, read_mhd_params)
Init TC coefficients: MHD case.
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
double precision time_htc_total
double precision time_htc0
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_adiab), pointer usr_set_adiab
procedure(set_adiab), pointer usr_set_gamma
procedure(phys_gravity), pointer usr_gravity
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.