22 double precision,
public ::
mhd_eta = 0.0d0
30 double precision,
protected :: small_e
43 double precision :: divbdiff = 0.8d0
48 double precision,
public,
protected ::
h_ion_fr=1d0
51 double precision,
public,
protected ::
he_ion_fr=1d0
58 double precision,
public,
protected ::
rr=1d0
60 double precision :: gamma_1, inv_gamma_1
62 double precision :: inv_squared_c0, inv_squared_c
69 integer,
public,
protected ::
rho_
71 integer,
allocatable,
public,
protected ::
mom(:)
73 integer,
public,
protected :: ^
c&m^C_
75 integer,
public,
protected ::
e_
77 integer,
public,
protected :: ^
c&b^C_
79 integer,
public,
protected ::
p_
81 integer,
public,
protected ::
q_
83 integer,
public,
protected ::
psi_
85 integer,
public,
protected ::
r_e
87 integer,
public,
protected ::
te_
92 integer,
allocatable,
public,
protected ::
tracer(:)
100 integer,
parameter :: divb_none = 0
101 integer,
parameter :: divb_multigrid = -1
102 integer,
parameter :: divb_glm = 1
103 integer,
parameter :: divb_powel = 2
104 integer,
parameter :: divb_janhunen = 3
105 integer,
parameter :: divb_linde = 4
106 integer,
parameter :: divb_lindejanhunen = 5
107 integer,
parameter :: divb_lindepowel = 6
108 integer,
parameter :: divb_lindeglm = 7
109 integer,
parameter :: divb_ct = 8
139 logical,
public,
protected ::
mhd_glm = .false.
186 logical :: total_energy = .true.
190 logical :: gravity_energy
192 character(len=std_len),
public,
protected ::
typedivbfix =
'linde'
194 character(len=std_len),
public,
protected ::
type_ct =
'uct_contact'
196 character(len=std_len) :: typedivbdiff =
'all'
207 subroutine mask_subroutine(ixI^L,ixO^L,w,x,res)
209 integer,
intent(in) :: ixi^
l, ixo^
l
210 double precision,
intent(in) :: x(ixi^s,1:
ndim)
211 double precision,
intent(in) :: w(ixi^s,1:nw)
212 double precision,
intent(inout) :: res(ixi^s)
213 end subroutine mask_subroutine
262 subroutine mhd_read_params(files)
265 character(len=*),
intent(in) :: files(:)
282 do n = 1,
size(files)
283 open(
unitpar, file=trim(files(n)), status=
"old")
284 read(
unitpar, mhd_list,
end=111)
288 end subroutine mhd_read_params
291 subroutine mhd_write_info(fh)
293 integer,
intent(in) :: fh
296 integer,
parameter :: n_par = 1
297 double precision :: values(n_par)
298 integer,
dimension(MPI_STATUS_SIZE) :: st
299 character(len=name_len) :: names(n_par)
301 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
305 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
306 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
307 end subroutine mhd_write_info
337 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_internal_e=T'
341 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_internal_e=T'
348 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_hydrodynamic_e=T'
352 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_hydrodynamic_e=T'
356 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_hydrodynamic_e=T'
363 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_semirelativistic=T'
367 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_semirelativistic=T'
371 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_semirelativistic=T'
378 if(
mype==0)
write(*,*)
'WARNING: set mhd_internal_e=F when mhd_energy=F'
382 if(
mype==0)
write(*,*)
'WARNING: set mhd_hydrodynamic_e=F when mhd_energy=F'
386 if(
mype==0)
write(*,*)
'WARNING: set mhd_thermal_conduction=F when mhd_energy=F'
390 if(
mype==0)
write(*,*)
'WARNING: set mhd_hyperbolic_thermal_conduction=F when mhd_energy=F'
394 if(
mype==0)
write(*,*)
'WARNING: set mhd_radiative_cooling=F when mhd_energy=F'
398 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac=F when mhd_energy=F'
402 if(
mype==0)
write(*,*)
'WARNING: set mhd_partial_ionization=F when mhd_energy=F'
406 if(
mype==0)
write(*,*)
'WARNING: set B0field=F when mhd_energy=F'
410 if(
mype==0)
write(*,*)
'WARNING: set has_equi_rho_and_p=F when mhd_energy=F'
416 if(
mype==0)
write(*,*)
'WARNING: set mhd_partial_ionization=F when eq_state_units=F'
422 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
426 if(
mype==0)
write(*,*)
'WARNING: turn off hyperbolic TC when using parabolic TC'
450 phys_total_energy=total_energy
453 gravity_energy=.false.
455 gravity_energy=.true.
458 gravity_energy=.false.
464 if(
mype==0)
write(*,*)
'WARNING: reset mhd_trac_type=1 for 1D simulation'
469 if(
mype==0)
write(*,*)
'WARNING: set mhd_trac_mask==bigdouble for global TRAC method'
477 type_divb = divb_none
480 type_divb = divb_multigrid
482 mg%operator_type = mg_laplacian
489 case (
'powel',
'powell')
490 type_divb = divb_powel
492 type_divb = divb_janhunen
494 type_divb = divb_linde
495 case (
'lindejanhunen')
496 type_divb = divb_lindejanhunen
498 type_divb = divb_lindepowel
502 type_divb = divb_lindeglm
507 call mpistop(
'Unknown divB fix')
512 allocate(start_indices(number_species),stop_indices(number_species))
519 mom(:) = var_set_momentum(
ndir)
525 e_ = var_set_energy()
534 mag(:) = var_set_bfield(
ndir)
538 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
554 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
560 write(*,*)
'Warning: CAK force addition together with FLD radiation'
565 write(*,*)
'Warning: Optically thin cooling together with FLD radiation'
569 call mpistop(
'using FLD implies the use of cgs units')
572 call mpistop(
'using FLD implies the use of an energy equation, set mhd_energy=T')
575 call mpistop(
'using FLD not yet with semirelativistic energy formalism')
578 call mpistop(
'using FLD not yet with hydrodynamic or internal energy formalism')
581 call mpistop(
'using FLD not yet with split off rho and p')
585 r_e = var_set_radiation_energy()
594 call mpistop(
'using anisotropic FLD implies multidimensional setup')
598 call mpistop(
'Radiation formalism unknown')
605 write(*,*)
'Warning: setting FLD specific flag to mhd_radiation_use_csrad=F'
613 te_ = var_set_auxvar(
'Te',
'Te')
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
705 phys_to_primitive => mhd_to_primitive_hde
707 phys_to_conserved => mhd_to_conserved_hde
711 phys_to_primitive => mhd_to_primitive_semirelati
713 phys_to_conserved => mhd_to_conserved_semirelati
716 phys_to_primitive => mhd_to_primitive_semirelati_noe
718 phys_to_conserved => mhd_to_conserved_semirelati_noe
723 phys_to_primitive => mhd_to_primitive_split_rho
725 phys_to_conserved => mhd_to_conserved_split_rho
728 phys_to_primitive => mhd_to_primitive_inte
730 phys_to_conserved => mhd_to_conserved_inte
733 phys_to_primitive => mhd_to_primitive_origin
735 phys_to_conserved => mhd_to_conserved_origin
738 phys_to_primitive => mhd_to_primitive_origin_noe
740 phys_to_conserved => mhd_to_conserved_origin_noe
745 phys_get_flux => mhd_get_flux_hde
748 phys_get_flux => mhd_get_flux_semirelati
750 phys_get_flux => mhd_get_flux_semirelati_noe
754 phys_get_flux => mhd_get_flux_split
756 phys_get_flux => mhd_get_flux
758 phys_get_flux => mhd_get_flux_noe
763 phys_add_source_geom => mhd_add_source_geom_semirelati
765 phys_add_source_geom => mhd_add_source_geom_split
767 phys_add_source_geom => mhd_add_source_geom
769 phys_add_source => mhd_add_source
770 phys_check_params => mhd_check_params
771 phys_write_info => mhd_write_info
774 phys_handle_small_values => mhd_handle_small_values_inte
775 mhd_handle_small_values => mhd_handle_small_values_inte
776 phys_check_w => mhd_check_w_inte
778 phys_handle_small_values => mhd_handle_small_values_hde
779 mhd_handle_small_values => mhd_handle_small_values_hde
780 phys_check_w => mhd_check_w_hde
782 phys_handle_small_values => mhd_handle_small_values_semirelati
783 mhd_handle_small_values => mhd_handle_small_values_semirelati
784 phys_check_w => mhd_check_w_semirelati
786 phys_handle_small_values => mhd_handle_small_values_split
787 mhd_handle_small_values => mhd_handle_small_values_split
788 phys_check_w => mhd_check_w_split
790 phys_handle_small_values => mhd_handle_small_values_origin
791 mhd_handle_small_values => mhd_handle_small_values_origin
792 phys_check_w => mhd_check_w_origin
794 phys_handle_small_values => mhd_handle_small_values_noe
795 mhd_handle_small_values => mhd_handle_small_values_noe
796 phys_check_w => mhd_check_w_noe
800 phys_get_pthermal => mhd_get_pthermal_inte
803 phys_get_pthermal => mhd_get_pthermal_hde
806 phys_get_pthermal => mhd_get_pthermal_semirelati
809 phys_get_pthermal => mhd_get_pthermal_origin
812 phys_get_pthermal => mhd_get_pthermal_noe
817 phys_set_equi_vars => set_equi_vars_grid
820 if(type_divb==divb_glm)
then
821 phys_modify_wlr => mhd_modify_wlr
827 phys_update_temperature => mhd_update_temperature
852 transverse_ghost_cells = 1
853 phys_get_ct_velocity => mhd_get_ct_velocity_average
854 phys_update_faces => mhd_update_faces_average
856 transverse_ghost_cells = 1
857 phys_get_ct_velocity => mhd_get_ct_velocity_contact
858 phys_update_faces => mhd_update_faces_contact
860 transverse_ghost_cells = 2
861 phys_get_ct_velocity => mhd_get_ct_velocity_hll
862 phys_update_faces => mhd_update_faces_hll
864 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
867 phys_modify_wlr => mhd_modify_wlr
869 phys_boundary_adjust => mhd_boundary_adjust
878 call mhd_physical_units()
893 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no splitting or total e in use'
896 if(
mype==0)
write(*,*)
'Will subtract thermal balance in TC or RC with mhd_equi_thermal=T'
899 if(
mype==0)
write(*,*)
'WARNING: turning mhd_equi_thermal=F as no TC or RC in use'
918 tc_fl%get_temperature_from_conserved => mhd_get_temperature_from_eint_with_equi
920 tc_fl%get_temperature_from_conserved => mhd_get_temperature_from_eint
926 tc_fl%get_temperature_from_eint => mhd_get_temperature_from_eint_with_equi
928 tc_fl%subtract_equi = .true.
929 tc_fl%get_temperature_equi => mhd_get_temperature_equi
930 tc_fl%get_rho_equi => mhd_get_rho_equi
932 tc_fl%subtract_equi = .false.
935 tc_fl%get_temperature_from_eint => mhd_get_temperature_from_eint
964 rc_fl%subtract_equi = .true.
965 rc_fl%get_rho_equi => mhd_get_rho_equi
966 rc_fl%get_pthermal_equi => mhd_get_pe_equi
967 rc_fl%get_temperature_equi => mhd_get_temperature_equi
969 rc_fl%subtract_equi = .false.
979 phys_te_images => mhd_te_images
985 write(*,*)
'*****Using hyperresistivity: with mhd_eta_hyper :',
mhd_eta_hyper
989 call mpistop(
"Must have B0field=F when using hyperresistivity")
993 call mpistop(
"Must have mhd_eta_hyper positive when using hyperresistivity")
1010 call mpistop(
"Must have has_equi_rho_and_p=F when mhd_rotating_frame=T")
1018 if (particles_eta < zero) particles_eta =
mhd_eta
1019 if (particles_etah < zero) particles_eta =
mhd_etah
1021 write(*,*)
'*****Using particles: with mhd_eta, mhd_etah :',
mhd_eta,
mhd_etah
1022 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
1034 call mpistop(
"Must have mhd_hall=F when mhd_semirelativistic=T")
1038 call mpistop(
"Must have Cartesian coordinates for Hall")
1042 phys_wider_stencil = 1
1049 call add_sts_method(get_ambipolar_dt,sts_set_source_ambipolar,mag(1),&
1060 phys_wider_stencil = 1
1070 call mpistop(
"CAK implementation not available in internal or semirelativistic variants")
1073 call mpistop(
"CAK force implementation not available for split off pressure and density")
1081 subroutine mhd_te_images
1086 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
1088 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
1090 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
1092 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
1095 call mpistop(
"Error in synthesize emission: Unknown convert_type")
1097 end subroutine mhd_te_images
1103 subroutine mhd_sts_set_source_tc_mhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1107 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1108 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1109 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1110 double precision,
intent(in) :: my_dt
1111 logical,
intent(in) :: fix_conserve_at_step
1113 end subroutine mhd_sts_set_source_tc_mhd
1115 subroutine mhd_sts_set_source_tc_hd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
1119 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
1120 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1121 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
1122 double precision,
intent(in) :: my_dt
1123 logical,
intent(in) :: fix_conserve_at_step
1125 end subroutine mhd_sts_set_source_tc_hd
1127 function mhd_get_tc_dt_mhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1134 integer,
intent(in) :: ixi^
l, ixo^
l
1135 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1136 double precision,
intent(in) :: w(ixi^s,1:nw)
1137 double precision :: dtnew
1140 end function mhd_get_tc_dt_mhd
1142 function mhd_get_tc_dt_hd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
1149 integer,
intent(in) :: ixi^
l, ixo^
l
1150 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
1151 double precision,
intent(in) :: w(ixi^s,1:nw)
1152 double precision :: dtnew
1155 end function mhd_get_tc_dt_hd
1157 subroutine mhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
1160 integer,
intent(in) :: ixi^
l,ixo^
l
1161 double precision,
intent(inout) :: w(ixi^s,1:nw)
1162 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1163 integer,
intent(in) :: step
1164 character(len=140) :: error_msg
1166 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
1167 call mhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
1168 end subroutine mhd_tc_handle_small_e
1171 subroutine tc_params_read_mhd(fl)
1173 type(tc_fluid),
intent(inout) :: fl
1175 double precision :: tc_k_para=0d0
1176 double precision :: tc_k_perp=0d0
1179 logical :: tc_perpendicular=.false.
1180 logical :: tc_saturate=.false.
1181 character(len=std_len) :: tc_slope_limiter=
"MC"
1183 namelist /tc_list/ tc_perpendicular, tc_saturate, tc_slope_limiter, tc_k_para, tc_k_perp
1187 read(
unitpar, tc_list,
end=111)
1191 fl%tc_perpendicular = tc_perpendicular
1192 fl%tc_saturate = tc_saturate
1193 fl%tc_k_para = tc_k_para
1194 fl%tc_k_perp = tc_k_perp
1195 select case(tc_slope_limiter)
1197 fl%tc_slope_limiter = 0
1200 fl%tc_slope_limiter = 1
1203 fl%tc_slope_limiter = 2
1206 fl%tc_slope_limiter = 3
1209 fl%tc_slope_limiter = 4
1212 fl%tc_slope_limiter = 5
1214 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod, superbee, koren, vanleer")
1216 end subroutine tc_params_read_mhd
1220 subroutine rc_params_read(fl)
1223 type(rc_fluid),
intent(inout) :: fl
1227 double precision :: rad_cut_hgt=0.5d0
1228 double precision :: rad_cut_dey=0.15d0
1231 integer :: ncool = 4000
1233 logical :: tfix=.false.
1235 logical :: rc_split=.false.
1236 logical :: rad_cut=.false.
1238 character(len=std_len) :: coolcurve=
'JCcorona'
1240 namelist /rc_list/ coolcurve, ncool, tlow, tfix, rc_split,rad_cut,rad_cut_hgt,rad_cut_dey
1244 read(
unitpar, rc_list,
end=111)
1249 fl%coolcurve=coolcurve
1252 fl%rc_split=rc_split
1254 fl%rad_cut_hgt=rad_cut_hgt
1255 fl%rad_cut_dey=rad_cut_dey
1256 end subroutine rc_params_read
1260 subroutine set_equi_vars_grid_faces(igrid,x,ixI^L,ixO^L)
1263 integer,
intent(in) :: igrid, ixi^
l, ixo^
l
1264 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1266 double precision :: delx(ixi^s,1:
ndim)
1267 double precision :: xc(ixi^s,1:
ndim),xshift^
d
1268 integer :: idims, ixc^
l, hxo^
l, ix, idims2
1274 delx(ixi^s,1:
ndim)=ps(igrid)%dx(ixi^s,1:
ndim)
1278 hxo^
l=ixo^
l-
kr(idims,^
d);
1284 ixcmax^
d=ixomax^
d; ixcmin^
d=hxomin^
d;
1287 xshift^
d=half*(one-
kr(^
d,idims));
1294 xc(ix^
d%ixC^s,^
d)=x(ix^
d%ixC^s,^
d)+(half-xshift^
d)*delx(ix^
d%ixC^s,^
d)
1298 call usr_set_equi_vars(ixi^l,ixc^l,xc,ps(igrid)%equi_vars(ixi^s,1:number_equi_vars,idims))
1301 end subroutine set_equi_vars_grid_faces
1304 subroutine set_equi_vars_grid(igrid)
1308 integer,
intent(in) :: igrid
1314 call set_equi_vars_grid_faces(igrid,ps(igrid)%x,ixg^
ll,
ixm^
ll)
1316 end subroutine set_equi_vars_grid
1319 function convert_vars_splitting(ixI^L,ixO^L, w, x, nwc)
result(wnew)
1321 integer,
intent(in) :: ixi^
l,ixo^
l, nwc
1322 double precision,
intent(in) :: w(ixi^s, 1:nw)
1323 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1324 double precision :: wnew(ixo^s, 1:nwc)
1331 wnew(ixo^s,
mom(:))=w(ixo^s,
mom(:))
1337 wnew(ixo^s,mag(1:
ndir))=w(ixo^s,mag(1:
ndir))
1341 wnew(ixo^s,
e_)=w(ixo^s,
e_)
1345 if(
b0field .and. total_energy)
then
1346 wnew(ixo^s,
e_)=wnew(ixo^s,
e_)+0.5d0*sum(
block%B0(ixo^s,:,0)**2,dim=
ndim+1) &
1347 + sum(w(ixo^s,mag(:))*
block%B0(ixo^s,:,0),dim=
ndim+1)
1351 end function convert_vars_splitting
1353 subroutine mhd_check_params
1361 if (
mhd_gamma <= 0.0d0)
call mpistop (
"Error: mhd_gamma <= 0")
1362 if (
mhd_adiab < 0.0d0)
call mpistop (
"Error: mhd_adiab < 0")
1366 call mpistop (
"Error: mhd_gamma <= 0 or mhd_gamma == 1")
1367 inv_gamma_1=1.d0/gamma_1
1373 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
1378 if(
mype .eq. 0) print*,
" add conversion method: split -> full "
1386 call mpistop(
'select IMEX scheme for FLD radiation use')
1391 call mpistop(
'multigrid must have BCs for IMEX and FLD radiation use')
1395 end subroutine mhd_check_params
1409 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
1410 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
1413 mg%bc(ib, mg_iphi)%bc_type = mg_bc_dirichlet
1414 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
1418 mg%bc(ib, mg_iphi)%bc_type = mg_bc_neumann
1419 mg%bc(ib, mg_iphi)%bc_value = 0.0_dp
1427 call mpistop(
"divE_multigrid warning: unknown b.c. ")
1432 subroutine mhd_physical_units()
1434 double precision :: mp,kb,miu0,c_lightspeed
1435 double precision :: a,
b
1446 c_lightspeed=const_c
1591 end subroutine mhd_physical_units
1593 subroutine mhd_check_w_semirelati(primitive,ixI^L,ixO^L,w,flag)
1596 logical,
intent(in) :: primitive
1597 logical,
intent(inout) :: flag(ixi^s,1:nw)
1598 integer,
intent(in) :: ixi^
l, ixo^
l
1599 double precision,
intent(in) :: w(ixi^s,nw)
1601 double precision :: tmp,
b(1:
ndir),v(1:
ndir),factor
1612 {
do ix^db=ixomin^db,ixomax^db \}
1613 if(w(ix^
d,
e_) < small_e) flag(ix^
d,
e_) = .true.
1616 {
do ix^db=ixomin^db,ixomax^db \}
1618 tmp=(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)*inv_squared_c
1619 factor=1.0d0/(w(ix^d,
rho_)*(w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+)*inv_squared_c))
1620 ^
c&v(^
c)=factor*(w(ix^d,
m^
c_)*w(ix^d,
rho_)+w(ix^d,
b^
c_)*tmp)\
1623 b(1)=w(ix^d,b2_)*v(3)-w(ix^d,b3_)*v(2)
1624 b(2)=w(ix^d,b3_)*v(1)-w(ix^d,b1_)*v(3)
1625 b(3)=w(ix^d,b1_)*v(2)-w(ix^d,b2_)*v(1)
1630 b(2)=w(ix^d,b1_)*v(2)-w(ix^d,b2_)*v(1)
1636 tmp=w(ix^d,
e_)-half*((^
c&v(^
c)**2+)*w(ix^d,
rho_)&
1637 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&
b(^
c)**2+)*inv_squared_c)
1638 if(tmp<small_e) flag(ix^d,
e_)=.true.
1644 end subroutine mhd_check_w_semirelati
1646 subroutine mhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
1649 logical,
intent(in) :: primitive
1650 integer,
intent(in) :: ixi^
l, ixo^
l
1651 double precision,
intent(in) :: w(ixi^s,nw)
1652 logical,
intent(inout) :: flag(ixi^s,1:nw)
1657 {
do ix^db=ixomin^db,ixomax^db\}
1663 (^
c&w(ix^
d,
b^
c_)**2+))<small_e) flag(ix^
d,
e_) = .true.
1670 end subroutine mhd_check_w_origin
1672 subroutine mhd_check_w_split(primitive,ixI^L,ixO^L,w,flag)
1675 logical,
intent(in) :: primitive
1676 integer,
intent(in) :: ixi^
l, ixo^
l
1677 double precision,
intent(in) :: w(ixi^s,nw)
1678 logical,
intent(inout) :: flag(ixi^s,1:nw)
1680 double precision :: tmp
1684 {
do ix^db=ixomin^db,ixomax^db\}
1690 tmp=w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/tmp+(^
c&w(ix^
d,
b^
c_)**2+))
1695 end subroutine mhd_check_w_split
1697 subroutine mhd_check_w_noe(primitive,ixI^L,ixO^L,w,flag)
1700 logical,
intent(in) :: primitive
1701 integer,
intent(in) :: ixi^
l, ixo^
l
1702 double precision,
intent(in) :: w(ixi^s,nw)
1703 logical,
intent(inout) :: flag(ixi^s,1:nw)
1708 {
do ix^db=ixomin^db,ixomax^db\}
1712 end subroutine mhd_check_w_noe
1714 subroutine mhd_check_w_inte(primitive,ixI^L,ixO^L,w,flag)
1717 logical,
intent(in) :: primitive
1718 integer,
intent(in) :: ixi^
l, ixo^
l
1719 double precision,
intent(in) :: w(ixi^s,nw)
1720 logical,
intent(inout) :: flag(ixi^s,1:nw)
1725 {
do ix^db=ixomin^db,ixomax^db\}
1730 if(w(ix^
d,
e_)<small_e) flag(ix^
d,
e_) = .true.
1734 end subroutine mhd_check_w_inte
1736 subroutine mhd_check_w_hde(primitive,ixI^L,ixO^L,w,flag)
1739 logical,
intent(in) :: primitive
1740 integer,
intent(in) :: ixi^
l, ixo^
l
1741 double precision,
intent(in) :: w(ixi^s,nw)
1742 logical,
intent(inout) :: flag(ixi^s,1:nw)
1747 {
do ix^db=ixomin^db,ixomax^db\}
1752 if(w(ix^
d,
e_)-half*(^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)<small_e) flag(ix^
d,
e_) = .true.
1756 end subroutine mhd_check_w_hde
1759 subroutine mhd_to_conserved_origin(ixI^L,ixO^L,w,x)
1761 integer,
intent(in) :: ixi^
l, ixo^
l
1762 double precision,
intent(inout) :: w(ixi^s, nw)
1763 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1767 {
do ix^db=ixomin^db,ixomax^db\}
1769 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1771 +(^
c&w(ix^
d,
b^
c_)**2+))
1776 end subroutine mhd_to_conserved_origin
1779 subroutine mhd_to_conserved_origin_noe(ixI^L,ixO^L,w,x)
1781 integer,
intent(in) :: ixi^
l, ixo^
l
1782 double precision,
intent(inout) :: w(ixi^s, nw)
1783 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1787 {
do ix^db=ixomin^db,ixomax^db\}
1792 end subroutine mhd_to_conserved_origin_noe
1795 subroutine mhd_to_conserved_hde(ixI^L,ixO^L,w,x)
1797 integer,
intent(in) :: ixi^
l, ixo^
l
1798 double precision,
intent(inout) :: w(ixi^s, nw)
1799 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1803 {
do ix^db=ixomin^db,ixomax^db\}
1805 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1811 end subroutine mhd_to_conserved_hde
1814 subroutine mhd_to_conserved_inte(ixI^L,ixO^L,w,x)
1816 integer,
intent(in) :: ixi^
l, ixo^
l
1817 double precision,
intent(inout) :: w(ixi^s, nw)
1818 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1822 {
do ix^db=ixomin^db,ixomax^db\}
1824 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1
1829 end subroutine mhd_to_conserved_inte
1832 subroutine mhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
1834 integer,
intent(in) :: ixi^
l, ixo^
l
1835 double precision,
intent(inout) :: w(ixi^s, nw)
1836 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1838 double precision :: rho
1841 {
do ix^db=ixomin^db,ixomax^db\}
1844 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1845 +half*((^
c&w(ix^
d,
m^
c_)**2+)*rho&
1846 +(^
c&w(ix^
d,
b^
c_)**2+))
1851 end subroutine mhd_to_conserved_split_rho
1854 subroutine mhd_to_conserved_semirelati(ixI^L,ixO^L,w,x)
1856 integer,
intent(in) :: ixi^
l, ixo^
l
1857 double precision,
intent(inout) :: w(ixi^s, nw)
1858 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1861 double precision :: ef(ixo^s,1:
ndir), s(ixo^s,1:
ndir)
1864 {
do ix^db=ixomin^db,ixomax^db\}
1866 ef(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
1867 ef(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
1868 ef(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
1869 s(ix^
d,1)=ef(ix^
d,2)*w(ix^
d,b3_)-ef(ix^
d,3)*w(ix^
d,b2_)
1870 s(ix^
d,2)=ef(ix^
d,3)*w(ix^
d,b1_)-ef(ix^
d,1)*w(ix^
d,b3_)
1871 s(ix^
d,3)=ef(ix^
d,1)*w(ix^
d,b2_)-ef(ix^
d,2)*w(ix^
d,b1_)
1876 ef(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
1877 s(ix^
d,1)=-ef(ix^
d,2)*w(ix^
d,b2_)
1878 s(ix^
d,2)=ef(ix^
d,2)*w(ix^
d,b1_)
1886 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1
1890 w(ix^
d,
e_)=w(ix^
d,
p_)*inv_gamma_1&
1892 +(^
c&w(ix^
d,
b^
c_)**2+)&
1893 +(^
c&ef(ix^
d,^
c)**2+)*inv_squared_c)
1901 end subroutine mhd_to_conserved_semirelati
1903 subroutine mhd_to_conserved_semirelati_noe(ixI^L,ixO^L,w,x)
1905 integer,
intent(in) :: ixi^
l, ixo^
l
1906 double precision,
intent(inout) :: w(ixi^s, nw)
1907 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1909 double precision :: e(ixo^s,1:
ndir), s(ixo^s,1:
ndir)
1912 {
do ix^db=ixomin^db,ixomax^db\}
1914 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
1915 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
1916 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
1917 s(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
1918 s(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
1919 s(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
1924 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
1925 s(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
1926 s(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
1936 end subroutine mhd_to_conserved_semirelati_noe
1939 subroutine mhd_to_primitive_origin(ixI^L,ixO^L,w,x)
1941 integer,
intent(in) :: ixi^
l, ixo^
l
1942 double precision,
intent(inout) :: w(ixi^s, nw)
1943 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1945 double precision :: inv_rho
1950 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_origin')
1953 {
do ix^db=ixomin^db,ixomax^db\}
1954 inv_rho = 1.d0/w(ix^
d,
rho_)
1958 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
1960 +(^
c&w(ix^
d,
b^
c_)**2+)))
1963 end subroutine mhd_to_primitive_origin
1966 subroutine mhd_to_primitive_origin_noe(ixI^L,ixO^L,w,x)
1968 integer,
intent(in) :: ixi^
l, ixo^
l
1969 double precision,
intent(inout) :: w(ixi^s, nw)
1970 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1972 double precision :: inv_rho
1977 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_origin_noe')
1980 {
do ix^db=ixomin^db,ixomax^db\}
1981 inv_rho = 1.d0/w(ix^
d,
rho_)
1986 end subroutine mhd_to_primitive_origin_noe
1989 subroutine mhd_to_primitive_hde(ixI^L,ixO^L,w,x)
1991 integer,
intent(in) :: ixi^
l, ixo^
l
1992 double precision,
intent(inout) :: w(ixi^s, nw)
1993 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1995 double precision :: inv_rho
2000 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_hde')
2003 {
do ix^db=ixomin^db,ixomax^db\}
2004 inv_rho = 1d0/w(ix^
d,
rho_)
2011 end subroutine mhd_to_primitive_hde
2014 subroutine mhd_to_primitive_inte(ixI^L,ixO^L,w,x)
2016 integer,
intent(in) :: ixi^
l, ixo^
l
2017 double precision,
intent(inout) :: w(ixi^s, nw)
2018 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2020 double precision :: inv_rho
2025 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_inte')
2028 {
do ix^db=ixomin^db,ixomax^db\}
2030 w(ix^
d,
p_)=w(ix^
d,
e_)*gamma_1
2032 inv_rho = 1.d0/w(ix^
d,
rho_)
2036 end subroutine mhd_to_primitive_inte
2039 subroutine mhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
2041 integer,
intent(in) :: ixi^
l, ixo^
l
2042 double precision,
intent(inout) :: w(ixi^s, nw)
2043 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2045 double precision :: inv_rho
2050 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_split_rho')
2053 {
do ix^db=ixomin^db,ixomax^db\}
2058 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
2060 (^
c&w(ix^
d,
m^
c_)**2+)+(^
c&w(ix^
d,
b^
c_)**2+)))
2063 end subroutine mhd_to_primitive_split_rho
2066 subroutine mhd_to_primitive_semirelati(ixI^L,ixO^L,w,x)
2068 integer,
intent(in) :: ixi^
l, ixo^
l
2069 double precision,
intent(inout) :: w(ixi^s, nw)
2070 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2072 double precision :: e(1:
ndir), tmp, factor
2077 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_semirelati')
2080 {
do ix^db=ixomin^db,ixomax^db\}
2082 tmp=(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)*inv_squared_c
2083 factor=1.0d0/(w(ix^
d,
rho_)*(w(ix^
d,
rho_)+(^
c&w(ix^
d,
b^
c_)**2+)*inv_squared_c))
2088 w(ix^
d,
p_)=gamma_1*w(ix^
d,
e_)
2092 e(1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
2093 e(2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
2094 e(3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
2098 e(2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
2104 w(ix^
d,
p_)=gamma_1*(w(ix^
d,
e_)&
2106 +(^
c&w(ix^
d,
b^
c_)**2+)&
2107 +(^
c&e(^
c)**2+)*inv_squared_c))
2111 end subroutine mhd_to_primitive_semirelati
2114 subroutine mhd_to_primitive_semirelati_noe(ixI^L,ixO^L,w,x)
2116 integer,
intent(in) :: ixi^
l, ixo^
l
2117 double precision,
intent(inout) :: w(ixi^s, nw)
2118 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2120 double precision :: tmp, factor
2125 call mhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_semirelati_noe')
2128 {
do ix^db=ixomin^db,ixomax^db\}
2130 tmp=(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)*inv_squared_c
2131 factor=1.0d0/(w(ix^
d,
rho_)*(w(ix^
d,
rho_)+(^
c&w(ix^
d,
b^
c_)**2+)*inv_squared_c))
2135 end subroutine mhd_to_primitive_semirelati_noe
2140 integer,
intent(in) :: ixi^
l, ixo^
l
2141 double precision,
intent(inout) :: w(ixi^s, nw)
2142 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2147 {
do ix^db=ixomin^db,ixomax^db\}
2150 +half*((^
c&w(ix^
d,
m^
c_)**2+)/&
2152 +(^
c&w(ix^
d,
b^
c_)**2+))
2155 {
do ix^db=ixomin^db,ixomax^db\}
2157 w(ix^d,
e_)=w(ix^d,
e_)&
2158 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
2159 +(^
c&w(ix^d,
b^
c_)**2+))
2166 subroutine mhd_ei_to_e_hde(ixI^L,ixO^L,w,x)
2168 integer,
intent(in) :: ixi^
l, ixo^
l
2169 double precision,
intent(inout) :: w(ixi^s, nw)
2170 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2174 {
do ix^db=ixomin^db,ixomax^db\}
2180 end subroutine mhd_ei_to_e_hde
2183 subroutine mhd_ei_to_e_semirelati(ixI^L,ixO^L,w,x)
2185 integer,
intent(in) :: ixi^
l, ixo^
l
2186 double precision,
intent(inout) :: w(ixi^s, nw)
2187 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2189 w(ixo^s,
p_)=w(ixo^s,
e_)*gamma_1
2190 call mhd_to_conserved_semirelati(ixi^
l,ixo^
l,w,x)
2192 end subroutine mhd_ei_to_e_semirelati
2197 integer,
intent(in) :: ixi^
l, ixo^
l
2198 double precision,
intent(inout) :: w(ixi^s, nw)
2199 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2204 {
do ix^db=ixomin^db,ixomax^db\}
2207 -half*((^
c&w(ix^
d,
m^
c_)**2+)/&
2209 +(^
c&w(ix^
d,
b^
c_)**2+))
2212 {
do ix^db=ixomin^db,ixomax^db\}
2214 w(ix^d,
e_)=w(ix^d,
e_)&
2215 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)&
2216 +(^
c&w(ix^d,
b^
c_)**2+))
2220 if(fix_small_values)
then
2221 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei')
2227 subroutine mhd_e_to_ei_hde(ixI^L,ixO^L,w,x)
2229 integer,
intent(in) :: ixi^
l, ixo^
l
2230 double precision,
intent(inout) :: w(ixi^s, nw)
2231 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2235 {
do ix^db=ixomin^db,ixomax^db\}
2241 if(fix_small_values)
then
2242 call mhd_handle_small_ei(w,x,ixi^l,ixi^l,
e_,
'mhd_e_to_ei_hde')
2245 end subroutine mhd_e_to_ei_hde
2248 subroutine mhd_e_to_ei_semirelati(ixI^L,ixO^L,w,x)
2250 integer,
intent(in) :: ixi^
l, ixo^
l
2251 double precision,
intent(inout) :: w(ixi^s, nw)
2252 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2254 call mhd_to_primitive_semirelati(ixi^
l,ixo^
l,w,x)
2255 w(ixo^s,
e_)=w(ixo^s,
p_)*inv_gamma_1
2257 end subroutine mhd_e_to_ei_semirelati
2259 subroutine mhd_handle_small_values_semirelati(primitive, w, x, ixI^L, ixO^L, subname)
2262 logical,
intent(in) :: primitive
2263 integer,
intent(in) :: ixi^
l,ixo^
l
2264 double precision,
intent(inout) :: w(ixi^s,1:nw)
2265 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2266 character(len=*),
intent(in) :: subname
2268 double precision :: e(ixi^s,1:
ndir), pressure(ixi^s), v(ixi^s,1:
ndir)
2269 double precision :: tmp, factor
2271 logical :: flag(ixi^s,1:nw)
2280 {
do ix^db=ixomin^db,ixomax^db\}
2282 tmp=(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)*inv_squared_c
2283 factor=1.0d0/(w(ix^
d,
rho_)*(w(ix^
d,
rho_)+(^
c&w(ix^
d,
b^
c_)**2+)*inv_squared_c))
2287 e(ix^
d,1)=w(ix^
d,b2_)*v(ix^
d,3)-w(ix^
d,b3_)*v(ix^
d,2)
2288 e(ix^
d,2)=w(ix^
d,b3_)*v(ix^
d,1)-w(ix^
d,b1_)*v(ix^
d,3)
2289 e(ix^
d,3)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
2293 e(ix^
d,2)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
2299 pressure(ix^
d)=gamma_1*(w(ix^
d,
e_)&
2300 -half*((^
c&v(ix^
d,^
c)**2+)*w(ix^
d,
rho_)&
2301 +(^
c&w(ix^
d,
b^
c_)**2+)+(^
c&e(ix^
d,^
c)**2+)*inv_squared_c))
2308 select case (small_values_method)
2310 {
do ix^db=ixomin^db,ixomax^db\}
2311 if(flag(ix^d,
rho_))
then
2312 w(ix^d,
rho_) = small_density
2313 ^
c&w(ix^d,
m^
c_)=0.d0\
2317 if(flag(ix^d,
e_)) w(ix^d,
p_) = small_pressure
2319 if(flag(ix^d,
e_))
then
2320 w(ix^d,
e_)=small_pressure*inv_gamma_1+half*((^
c&v(ix^d,^
c)**2+)*w(ix^d,
rho_)&
2321 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&e(ix^d,^
c)**2+)*inv_squared_c)
2328 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2331 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2333 w(ixo^s,
e_)=pressure(ixo^s)
2334 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2335 {
do ix^db=ixomin^db,ixomax^db\}
2336 w(ix^d,
e_)=w(ix^d,
p_)*inv_gamma_1+half*((^
c&v(ix^d,^
c)**2+)*w(ix^d,
rho_)&
2337 +(^
c&w(ix^d,
b^
c_)**2+)+(^
c&e(ix^d,^
c)**2+)*inv_squared_c)
2342 if(.not.primitive)
then
2344 w(ixo^s,
mom(1:ndir))=v(ixo^s,1:ndir)
2345 w(ixo^s,
e_)=pressure(ixo^s)
2347 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2351 end subroutine mhd_handle_small_values_semirelati
2353 subroutine mhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
2356 logical,
intent(in) :: primitive
2357 integer,
intent(in) :: ixi^
l,ixo^
l
2358 double precision,
intent(inout) :: w(ixi^s,1:nw)
2359 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2360 character(len=*),
intent(in) :: subname
2363 logical :: flag(ixi^s,1:nw)
2365 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2370 {
do ix^db=ixomin^db,ixomax^db\}
2374 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2391 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2393 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2396 {
do ix^db=iximin^db,iximax^db\}
2397 w(ix^d,
e_)=w(ix^d,
e_)&
2398 -half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))
2400 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2402 {
do ix^db=iximin^db,iximax^db\}
2403 w(ix^d,
e_)=w(ix^d,
e_)&
2404 +half*((^
c&w(ix^d,
m^
c_)**2+)/w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+))
2408 call small_values_average(ixi^l, ixo^l, w, x, flag,
r_e)
2411 if(.not.primitive)
then
2413 {
do ix^db=ixomin^db,ixomax^db\}
2415 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
2416 -half*((^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_)+(^
c&w(ix^d,
b^
c_)**2+)))
2419 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2423 end subroutine mhd_handle_small_values_origin
2425 subroutine mhd_handle_small_values_split(primitive, w, x, ixI^L, ixO^L, subname)
2428 logical,
intent(in) :: primitive
2429 integer,
intent(in) :: ixi^
l,ixo^
l
2430 double precision,
intent(inout) :: w(ixi^s,1:nw)
2431 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2432 character(len=*),
intent(in) :: subname
2434 double precision :: rho
2436 logical :: flag(ixi^s,1:nw)
2438 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2443 {
do ix^db=ixomin^db,ixomax^db\}
2448 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2455 w(ix^
d,
e_)=small_e+half*((^
c&w(ix^
d,
m^
c_)**2+)/rho+(^
c&w(ix^
d,
b^
c_)**2+))&
2461 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2463 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2466 {
do ix^db=iximin^db,iximax^db\}
2468 w(ix^d,
e_)=w(ix^d,
e_)&
2469 -half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2471 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2473 {
do ix^db=iximin^db,iximax^db\}
2475 w(ix^d,
e_)=w(ix^d,
e_)&
2476 +half*((^
c&w(ix^d,
m^
c_)**2+)/rho+(^
c&w(ix^d,
b^
c_)**2+))
2480 if(.not.primitive)
then
2482 {
do ix^db=ixomin^db,ixomax^db\}
2484 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)/rho\
2485 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)&
2486 -half*((^
c&w(ix^d,
m^
c_)**2+)*rho+(^
c&w(ix^d,
b^
c_)**2+)))
2489 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2493 end subroutine mhd_handle_small_values_split
2495 subroutine mhd_handle_small_values_inte(primitive, w, x, ixI^L, ixO^L, subname)
2498 logical,
intent(in) :: primitive
2499 integer,
intent(in) :: ixi^
l,ixo^
l
2500 double precision,
intent(inout) :: w(ixi^s,1:nw)
2501 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2502 character(len=*),
intent(in) :: subname
2505 logical :: flag(ixi^s,1:nw)
2507 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2512 {
do ix^db=ixomin^db,ixomax^db\}
2513 if(flag(ix^
d,
rho_))
then
2515 ^
c&w(ix^
d,
m^
c_)=0.d0\
2520 if(flag(ix^
d,
e_)) w(ix^
d,
e_)=small_e
2525 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2527 call small_values_average(ixi^l, ixo^l, w, x, flag,
p_)
2529 if(.not.primitive)
then
2531 {
do ix^db=ixomin^db,ixomax^db\}
2533 w(ix^d,
p_)=gamma_1*w(ix^d,
e_)
2536 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2540 end subroutine mhd_handle_small_values_inte
2542 subroutine mhd_handle_small_values_noe(primitive, w, x, ixI^L, ixO^L, subname)
2545 logical,
intent(in) :: primitive
2546 integer,
intent(in) :: ixi^
l,ixo^
l
2547 double precision,
intent(inout) :: w(ixi^s,1:nw)
2548 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2549 character(len=*),
intent(in) :: subname
2552 logical :: flag(ixi^s,1:nw)
2554 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2559 {
do ix^db=ixomin^db,ixomax^db\}
2563 if(flag({ix^
d},
rho_)) w({ix^
d},
m^
c_)=0.0d0
2569 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2571 if(.not.primitive)
then
2573 {
do ix^db=ixomin^db,ixomax^db\}
2577 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2581 end subroutine mhd_handle_small_values_noe
2583 subroutine mhd_handle_small_values_hde(primitive, w, x, ixI^L, ixO^L, subname)
2586 logical,
intent(in) :: primitive
2587 integer,
intent(in) :: ixi^
l,ixo^
l
2588 double precision,
intent(inout) :: w(ixi^s,1:nw)
2589 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2590 character(len=*),
intent(in) :: subname
2593 logical :: flag(ixi^s,1:nw)
2595 call phys_check_w(primitive, ixi^
l, ixo^
l, w, flag)
2600 {
do ix^db=ixomin^db,ixomax^db\}
2601 if(flag(ix^
d,
rho_))
then
2603 ^
c&w(ix^
d,
m^
c_)=0.d0\
2608 if(flag(ix^
d,
e_)) w(ix^
d,
e_)=small_e+half*(^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)
2613 call small_values_average(ixi^l, ixo^l, w, x, flag,
rho_)
2615 call small_values_average(ixi^l, ixo^l, w, x, flag,
e_)
2617 if(.not.primitive)
then
2619 {
do ix^db=ixomin^db,ixomax^db\}
2621 w(ix^d,
p_)=gamma_1*(w(ix^d,
e_)-half*(^
c&w(ix^d,
m^
c_)**2+)*w(ix^d,
rho_))
2624 call small_values_error(w, x, ixi^l, ixo^l, flag, subname)
2628 end subroutine mhd_handle_small_values_hde
2634 integer,
intent(in) :: ixi^
l, ixo^
l
2635 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
2636 double precision,
intent(out) :: v(ixi^s,
ndir)
2638 double precision :: rho(ixi^s)
2643 rho(ixo^s)=1.d0/rho(ixo^s)
2646 v(ixo^s, idir) = w(ixo^s,
mom(idir))*rho(ixo^s)
2652 subroutine mhd_get_csound2(w,x,ixI^L,ixO^L,cs2)
2655 integer,
intent(in) :: ixi^
l, ixo^
l
2656 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2657 double precision,
intent(inout) :: cs2(ixi^s)
2659 double precision :: rho, inv_rho, ploc
2662 {
do ix^db=ixomin^db,ixomax^db \}
2674 end subroutine mhd_get_csound2
2677 subroutine mhd_get_cmax_origin(w,x,ixI^L,ixO^L,idim,cmax)
2680 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2681 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2682 double precision,
intent(inout) :: cmax(ixi^s)
2684 double precision :: rho, inv_rho, ploc, cfast2, avmincs2, b2, kmax
2690 {
do ix^db=ixomin^db,ixomax^db \}
2703 cfast2=b2*inv_rho+cmax(ix^
d)
2704 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*(w(ix^
d,mag(idim))+
block%B0(ix^
d,idim,
b0i))**2*inv_rho
2705 if(avmincs2<zero) avmincs2=zero
2706 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2710 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2712 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
2715 {
do ix^db=ixomin^db,ixomax^db \}
2718 ploc=(w(ix^d,
p_)+block%equi_vars(ix^d,
equi_pe0_,b0i))
2727 b2=(^
c&w(ix^d,
b^
c_)**2+)
2728 cfast2=b2*inv_rho+cmax(ix^d)
2729 avmincs2=cfast2**2-4.0d0*cmax(ix^d)*w(ix^d,mag(idim))**2*inv_rho
2730 if(avmincs2<zero) avmincs2=zero
2731 cmax(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2735 cmax(ix^d)=max(cmax(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2737 cmax(ix^d)=abs(w(ix^d,
mom(idim)))+cmax(ix^d)
2741 end subroutine mhd_get_cmax_origin
2744 subroutine mhd_get_cmax_origin_noe(w,x,ixI^L,ixO^L,idim,cmax)
2748 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2749 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2750 double precision,
intent(inout) :: cmax(ixi^s)
2752 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
2753 double precision :: adiabs(ixo^s), gammas(ixo^s)
2768 {
do ix^db=ixomin^db,ixomax^db \}
2772 cmax(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*rho**(gammas(ix^
d)-1.d0)
2774 b2=(^
c&w(ix^
d,
b^
c_)**2+)
2775 cfast2=b2*inv_rho+cmax(ix^
d)
2776 avmincs2=cfast2**2-4.0d0*cmax(ix^
d)*w(ix^
d,mag(idim))**2*inv_rho
2777 if(avmincs2<zero) avmincs2=zero
2778 cmax(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
2782 cmax(ix^
d)=max(cmax(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
2784 cmax(ix^
d)=abs(w(ix^
d,
mom(idim)))+cmax(ix^
d)
2787 end subroutine mhd_get_cmax_origin_noe
2790 subroutine mhd_get_cmax_semirelati(w,x,ixI^L,ixO^L,idim,cmax)
2793 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2794 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2795 double precision,
intent(inout):: cmax(ixi^s)
2797 double precision :: csound, avmincs2, idim_alfven_speed2
2798 double precision :: inv_rho, alfven_speed2, gamma2
2801 {
do ix^db=ixomin^db,ixomax^db \}
2802 inv_rho=1.d0/w(ix^
d,
rho_)
2803 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
2804 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
2805 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
2808 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
2811 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
2812 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
2813 if(avmincs2<zero) avmincs2=zero
2815 csound = sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
2816 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+csound
2819 end subroutine mhd_get_cmax_semirelati
2822 subroutine mhd_get_cmax_semirelati_noe(w,x,ixI^L,ixO^L,idim,cmax)
2826 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2827 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
2828 double precision,
intent(inout):: cmax(ixi^s)
2830 double precision :: adiabs(ixo^s), gammas(ixo^s)
2831 double precision :: csound, avmincs2, idim_alfven_speed2
2832 double precision :: inv_rho, alfven_speed2, gamma2
2846 {
do ix^db=ixomin^db,ixomax^db \}
2847 inv_rho=1.d0/w(ix^
d,
rho_)
2848 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
2849 gamma2=1.0d0/(1.d0+alfven_speed2*inv_squared_c)
2850 cmax(ix^
d)=1.d0-gamma2*w(ix^
d,
mom(idim))**2*inv_squared_c
2851 csound=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
2852 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
2855 alfven_speed2=alfven_speed2*cmax(ix^
d)+csound*(1.d0+idim_alfven_speed2*inv_squared_c)
2856 avmincs2=(gamma2*alfven_speed2)**2-4.0d0*gamma2*csound*idim_alfven_speed2*cmax(ix^
d)
2857 if(avmincs2<zero) avmincs2=zero
2859 csound = sqrt(half*(gamma2*alfven_speed2+sqrt(avmincs2)))
2860 cmax(ix^
d)=gamma2*abs(w(ix^
d,
mom(idim)))+csound
2863 end subroutine mhd_get_cmax_semirelati_noe
2866 subroutine mhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
2869 integer,
intent(in) :: ixi^
l,ixo^
l
2870 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2872 double precision,
intent(inout) :: w(ixi^s,1:nw)
2873 double precision,
intent(out) :: tco_local,tmax_local
2875 double precision,
parameter :: trac_delta=0.25d0
2876 double precision :: te(ixi^s),lts(ixi^s)
2877 double precision,
dimension(1:ndim) :: bdir, bunitvec
2878 double precision,
dimension(ixI^S,1:ndim) :: gradt
2879 double precision :: ltrc,ltrp,altr
2880 integer :: idims,ix^
d,jxo^
l,hxo^
l,ixa^
d,ixb^
d
2881 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
2884 call mhd_get_temperature_from_te(w,x,ixi^
l,ixi^
l,te)
2887 te(ixi^s)=w(ixi^s,
p_)/(te(ixi^s)*w(ixi^s,
rho_))
2890 tmax_local=maxval(te(ixo^s))
2898 do ix1=ixomin1,ixomax1
2899 lts(ix1)=0.5d0*abs(te(ix1+1)-te(ix1-1))/te(ix1)
2900 if(lts(ix1)>trac_delta)
then
2901 tco_local=max(tco_local,te(ix1))
2913 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
2914 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
2915 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
2916 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
2918 call mpistop(
"mhd_trac_type not allowed for 1D simulation")
2929 call gradient(te,ixi^
l,ixo^
l,idims,gradt(ixi^s,idims))
2936 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
2941 ixb^d=(ixomin^d+ixomax^d-1)/2+ixa^d;
2942 bdir(1:ndim)=bdir(1:ndim)+w(ixb^d,iw_mag(1:ndim))
2946 if(bdir(1)/=0.d0)
then
2947 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
2949 block%special_values(3)=0.d0
2951 if(bdir(2)/=0.d0)
then
2952 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
2954 block%special_values(4)=0.d0
2958 if(bdir(1)/=0.d0)
then
2959 block%special_values(3)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+&
2960 (bdir(3)/bdir(1))**2)
2962 block%special_values(3)=0.d0
2964 if(bdir(2)/=0.d0)
then
2965 block%special_values(4)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+&
2966 (bdir(3)/bdir(2))**2)
2968 block%special_values(4)=0.d0
2970 if(bdir(3)/=0.d0)
then
2971 block%special_values(5)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+&
2972 (bdir(2)/bdir(3))**2)
2974 block%special_values(5)=0.d0
2979 block%special_values(1)=zero
2980 {
do ix^db=ixomin^db,ixomax^db\}
2982 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
2984 ^d&bdir(^d)=w({ix^d},iw_mag(^d))\
2987 if(bdir(1)/=0.d0)
then
2988 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
2992 if(bdir(2)/=0.d0)
then
2993 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
2998 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2))*&
2999 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3002 if(bdir(1)/=0.d0)
then
3003 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
3007 if(bdir(2)/=0.d0)
then
3008 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
3012 if(bdir(3)/=0.d0)
then
3013 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
3018 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2),block%ds(ix^d,3))*&
3019 abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3021 if(lts(ix^d)>trac_delta)
then
3022 block%special_values(1)=max(block%special_values(1),te(ix^d))
3025 block%special_values(2)=tmax_local
3044 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
3045 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
3046 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
3050 {
do ix^db=ixpmin^db,ixpmax^db\}
3051 ^d&bdir(^d)=w({ix^d},iw_mag(^d))+block%B0({ix^d},^d,0)\
3053 if(bdir(1)/=0.d0)
then
3054 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2)
3058 if(bdir(2)/=0.d0)
then
3059 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2)
3065 if(bdir(1)/=0.d0)
then
3066 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
3070 if(bdir(2)/=0.d0)
then
3071 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
3075 if(bdir(3)/=0.d0)
then
3076 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
3082 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3084 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
3085 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
3088 {
do ix^db=ixpmin^db,ixpmax^db\}
3090 if(w(ix^d,iw_mag(1))/=0.d0)
then
3091 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)
3095 if(w(ix^d,iw_mag(2))/=0.d0)
then
3096 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)
3102 if(w(ix^d,iw_mag(1))/=0.d0)
then
3103 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+&
3104 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(1)))**2)
3108 if(w(ix^d,iw_mag(2))/=0.d0)
then
3109 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+&
3110 (w(ix^d,iw_mag(3))/w(ix^d,iw_mag(2)))**2)
3114 if(w(ix^d,iw_mag(3))/=0.d0)
then
3115 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+&
3116 (w(ix^d,iw_mag(2))/w(ix^d,iw_mag(3)))**2)
3122 lts(ix^d)=abs(^d&gradt({ix^d},^d)*bunitvec(^d)+)/te(ix^d)
3124 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
3125 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
3131 {
do ix^db=ixpmin^db,ixpmax^db\}
3133 altr=0.25d0*((lts(ix1-1,ix2)+two*lts(ix^d)+lts(ix1+1,ix2))*bunitvec(1)**2+&
3134 (lts(ix1,ix2-1)+two*lts(ix^d)+lts(ix1,ix2+1))*bunitvec(2)**2)
3135 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
3138 altr=0.25d0*((lts(ix1-1,ix2,ix3)+two*lts(ix^d)+lts(ix1+1,ix2,ix3))*bunitvec(1)**2+&
3139 (lts(ix1,ix2-1,ix3)+two*lts(ix^d)+lts(ix1,ix2+1,ix3))*bunitvec(2)**2+&
3140 (lts(ix1,ix2,ix3-1)+two*lts(ix^d)+lts(ix1,ix2,ix3+1))*bunitvec(3)**2)
3141 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
3147 call mpistop(
"unknown mhd_trac_type")
3150 end subroutine mhd_get_tcutoff
3153 subroutine mhd_get_h_speed(wprim,x,ixI^L,ixO^L,idim,Hspeed)
3156 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3157 double precision,
intent(in) :: wprim(ixi^s, nw)
3158 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3159 double precision,
intent(out) :: hspeed(ixi^s,1:number_species)
3161 double precision :: csound(ixi^s,
ndim)
3162 double precision,
allocatable :: tmp(:^
d&)
3163 integer :: jxc^
l, ixc^
l, ixa^
l, id, ix^
d
3167 allocate(tmp(ixa^s))
3170 call mhd_get_csound_prim_split(wprim,x,ixi^
l,ixa^
l,id,tmp)
3172 call mhd_get_csound_prim(wprim,x,ixi^
l,ixa^
l,id,tmp)
3174 csound(ixa^s,id)=tmp(ixa^s)
3177 ixcmin^
d=ixomin^
d+
kr(idim,^
d)-1;
3178 jxcmax^
d=ixcmax^
d+
kr(idim,^
d);
3179 jxcmin^
d=ixcmin^
d+
kr(idim,^
d);
3180 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))
3184 ixamax^
d=ixcmax^
d+
kr(id,^
d);
3185 ixamin^
d=ixcmin^
d+
kr(id,^
d);
3186 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)))
3187 ixamax^
d=ixcmax^
d-
kr(id,^
d);
3188 ixamin^
d=ixcmin^
d-
kr(id,^
d);
3189 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)))
3194 ixamax^
d=jxcmax^
d+
kr(id,^
d);
3195 ixamin^
d=jxcmin^
d+
kr(id,^
d);
3196 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)))
3197 ixamax^
d=jxcmax^
d-
kr(id,^
d);
3198 ixamin^
d=jxcmin^
d-
kr(id,^
d);
3199 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)))
3203 end subroutine mhd_get_h_speed
3206 subroutine mhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3209 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3210 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3211 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3212 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3213 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3214 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3215 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3217 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3218 double precision :: umean, dmean, tmp1, tmp2, tmp3
3224 call mhd_get_csrad_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3225 call mhd_get_csrad_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3229 call mhd_get_csound_prim(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3230 call mhd_get_csound_prim(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3232 if(
present(cmin))
then
3233 {
do ix^db=ixomin^db,ixomax^db\}
3234 tmp1=sqrt(wlp(ix^
d,
rho_))
3235 tmp2=sqrt(wrp(ix^
d,
rho_))
3236 tmp3=1.d0/(tmp1+tmp2)
3237 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3238 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3239 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3240 cmin(ix^
d,1)=umean-dmean
3241 cmax(ix^
d,1)=umean+dmean
3243 if(h_correction)
then
3244 {
do ix^db=ixomin^db,ixomax^db\}
3245 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3246 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3250 {
do ix^db=ixomin^db,ixomax^db\}
3251 tmp1=sqrt(wlp(ix^d,
rho_))
3252 tmp2=sqrt(wrp(ix^d,
rho_))
3253 tmp3=1.d0/(tmp1+tmp2)
3254 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3255 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3256 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3257 cmax(ix^d,1)=abs(umean)+dmean
3261 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3263 call mhd_get_csrad_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
3265 call mhd_get_csound_prim(wmean,x,ixi^l,ixo^l,idim,csoundr)
3267 if(
present(cmin))
then
3268 {
do ix^db=ixomin^db,ixomax^db\}
3269 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3270 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3272 if(h_correction)
then
3273 {
do ix^db=ixomin^db,ixomax^db\}
3274 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3275 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3279 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3283 call mhd_get_csrad_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
3284 call mhd_get_csrad_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
3287 call mhd_get_csound_prim(wlp,x,ixi^l,ixo^l,idim,csoundl)
3288 call mhd_get_csound_prim(wrp,x,ixi^l,ixo^l,idim,csoundr)
3290 if(
present(cmin))
then
3291 {
do ix^db=ixomin^db,ixomax^db\}
3292 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3293 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3294 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3296 if(h_correction)
then
3297 {
do ix^db=ixomin^db,ixomax^db\}
3298 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3299 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3303 {
do ix^db=ixomin^db,ixomax^db\}
3304 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3305 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3310 end subroutine mhd_get_cbounds
3313 subroutine mhd_get_cbounds_semirelati(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3316 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3317 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3318 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3319 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3320 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3321 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3322 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3324 double precision,
dimension(ixO^S) :: csoundl, csoundr, gamma2l, gamma2r
3329 call mhd_get_csound_semirelati(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3330 call mhd_get_csound_semirelati(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3332 call mhd_get_csound_semirelati_noe(wlp,x,ixi^
l,ixo^
l,idim,csoundl,gamma2l)
3333 call mhd_get_csound_semirelati_noe(wrp,x,ixi^
l,ixo^
l,idim,csoundr,gamma2r)
3335 if(
present(cmin))
then
3336 {
do ix^db=ixomin^db,ixomax^db\}
3337 csoundl(ix^
d)=max(csoundl(ix^
d),csoundr(ix^
d))
3338 cmin(ix^
d,1)=min(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))-csoundl(ix^
d)
3339 cmax(ix^
d,1)=max(gamma2l(ix^
d)*wlp(ix^
d,
mom(idim)),gamma2r(ix^
d)*wrp(ix^
d,
mom(idim)))+csoundl(ix^
d)
3342 {
do ix^db=ixomin^db,ixomax^db\}
3343 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3344 cmax(ix^d,1)=max(gamma2l(ix^d)*wlp(ix^d,
mom(idim)),gamma2r(ix^d)*wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3348 end subroutine mhd_get_cbounds_semirelati
3351 subroutine mhd_get_cbounds_split_rho(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
3354 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3355 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
3356 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3357 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3358 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
3359 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
3360 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
3362 double precision :: wmean(ixi^s,nw), csoundl(ixo^s), csoundr(ixo^s)
3363 double precision :: umean, dmean, tmp1, tmp2, tmp3
3370 call mhd_get_csound_prim_split(wlp,x,ixi^
l,ixo^
l,idim,csoundl)
3371 call mhd_get_csound_prim_split(wrp,x,ixi^
l,ixo^
l,idim,csoundr)
3372 if(
present(cmin))
then
3373 {
do ix^db=ixomin^db,ixomax^db\}
3376 tmp3=1.d0/(tmp1+tmp2)
3377 umean=(wlp(ix^
d,
mom(idim))*tmp1+wrp(ix^
d,
mom(idim))*tmp2)*tmp3
3378 dmean=sqrt((tmp1*csoundl(ix^
d)**2+tmp2*csoundr(ix^
d)**2)*tmp3+&
3379 half*tmp1*tmp2*tmp3**2*(wrp(ix^
d,
mom(idim))-wlp(ix^
d,
mom(idim)))**2)
3380 cmin(ix^
d,1)=umean-dmean
3381 cmax(ix^
d,1)=umean+dmean
3383 if(h_correction)
then
3384 {
do ix^db=ixomin^db,ixomax^db\}
3385 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3386 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3390 {
do ix^db=ixomin^db,ixomax^db\}
3393 tmp3=1.d0/(tmp1+tmp2)
3394 umean=(wlp(ix^d,
mom(idim))*tmp1+wrp(ix^d,
mom(idim))*tmp2)*tmp3
3395 dmean=sqrt((tmp1*csoundl(ix^d)**2+tmp2*csoundr(ix^d)**2)*tmp3+&
3396 half*tmp1*tmp2*tmp3**2*(wrp(ix^d,
mom(idim))-wlp(ix^d,
mom(idim)))**2)
3397 cmax(ix^d,1)=abs(umean)+dmean
3401 wmean(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
3402 call mhd_get_csound_prim_split(wmean,x,ixi^l,ixo^l,idim,csoundr)
3403 if(
present(cmin))
then
3404 {
do ix^db=ixomin^db,ixomax^db\}
3405 cmax(ix^d,1)=max(wmean(ix^d,
mom(idim))+csoundr(ix^d),zero)
3406 cmin(ix^d,1)=min(wmean(ix^d,
mom(idim))-csoundr(ix^d),zero)
3408 if(h_correction)
then
3409 {
do ix^db=ixomin^db,ixomax^db\}
3410 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3411 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3415 cmax(ixo^s,1)=abs(wmean(ixo^s,
mom(idim)))+csoundr(ixo^s)
3419 call mhd_get_csound_prim_split(wlp,x,ixi^l,ixo^l,idim,csoundl)
3420 call mhd_get_csound_prim_split(wrp,x,ixi^l,ixo^l,idim,csoundr)
3421 if(
present(cmin))
then
3422 {
do ix^db=ixomin^db,ixomax^db\}
3423 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3424 cmin(ix^d,1)=min(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))-csoundl(ix^d)
3425 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3427 if(h_correction)
then
3428 {
do ix^db=ixomin^db,ixomax^db\}
3429 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
3430 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
3434 {
do ix^db=ixomin^db,ixomax^db\}
3435 csoundl(ix^d)=max(csoundl(ix^d),csoundr(ix^d))
3436 cmax(ix^d,1)=max(wlp(ix^d,
mom(idim)),wrp(ix^d,
mom(idim)))+csoundl(ix^d)
3441 end subroutine mhd_get_cbounds_split_rho
3444 subroutine mhd_get_ct_velocity_average(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3447 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3448 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3449 double precision,
intent(in) :: cmax(ixi^s)
3450 double precision,
intent(in),
optional :: cmin(ixi^s)
3451 type(ct_velocity),
intent(inout):: vcts
3453 end subroutine mhd_get_ct_velocity_average
3455 subroutine mhd_get_ct_velocity_contact(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3458 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3459 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3460 double precision,
intent(in) :: cmax(ixi^s)
3461 double precision,
intent(in),
optional :: cmin(ixi^s)
3462 type(ct_velocity),
intent(inout):: vcts
3464 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
3466 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
3468 end subroutine mhd_get_ct_velocity_contact
3470 subroutine mhd_get_ct_velocity_hll(vcts,wLp,wRp,ixI^L,ixO^L,idim,cmax,cmin)
3473 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3474 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
3475 double precision,
intent(in) :: cmax(ixi^s)
3476 double precision,
intent(in),
optional :: cmin(ixi^s)
3477 type(ct_velocity),
intent(inout):: vcts
3479 integer :: idime,idimn
3481 if(.not.
allocated(vcts%vbarC))
then
3482 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
3483 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
3486 if(
present(cmin))
then
3487 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
3488 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3490 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
3491 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
3494 idimn=mod(idim,
ndir)+1
3495 idime=mod(idim+1,
ndir)+1
3497 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
3498 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
3499 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
3500 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
3501 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3503 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
3504 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
3505 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
3506 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
3507 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
3509 end subroutine mhd_get_ct_velocity_hll
3513 subroutine mhd_get_csrad_prim(w,x,ixI^L,ixO^L,idim,csound)
3516 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3517 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3518 double precision,
intent(out):: csound(ixo^s)
3520 double precision :: adiabs(ixo^s), gammas(ixo^s)
3521 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
3522 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
3523 double precision :: prad_max(ixo^s)
3532 {
do ix^db=ixomin^db,ixomax^db \}
3533 inv_rho=1.d0/w(ix^
d,
rho_)
3534 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
3535 csound(ix^
d)=max(
mhd_gamma,4.d0/3.d0)*(w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
3537 cfast2=b2*inv_rho+csound(ix^
d)
3538 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
3540 if(avmincs2<zero) avmincs2=zero
3541 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3543 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3547 {
do ix^db=ixomin^db,ixomax^db \}
3548 inv_rho=1.d0/w(ix^d,
rho_)
3549 prad_max(ix^d) = maxval(prad_tensor(ix^d,:,:))
3550 csound(ix^d)=max(
mhd_gamma,4.d0/3.d0)*(w(ix^d,
p_)+prad_max(ix^d))*inv_rho
3551 b2=(^
c&w(ix^d,
b^
c_)**2+)
3552 cfast2=b2*inv_rho+csound(ix^d)
3553 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
3554 if(avmincs2<zero) avmincs2=zero
3555 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3557 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3562 end subroutine mhd_get_csrad_prim
3565 subroutine mhd_get_csound_prim(w,x,ixI^L,ixO^L,idim,csound)
3569 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3570 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3571 double precision,
intent(out):: csound(ixo^s)
3573 double precision :: adiabs(ixo^s), gammas(ixo^s)
3574 double precision :: inv_rho, cfast2, avmincs2, b2, kmax
3594 {
do ix^db=ixomin^db,ixomax^db \}
3595 inv_rho=1.d0/w(ix^
d,
rho_)
3599 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3602 cfast2=b2*inv_rho+csound(ix^
d)
3603 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
3605 if(avmincs2<zero) avmincs2=zero
3606 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3608 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3612 {
do ix^db=ixomin^db,ixomax^db \}
3613 inv_rho=1.d0/w(ix^d,
rho_)
3617 csound(ix^d)=gammas(ix^d)*adiabs(ix^d)*w(ix^d,
rho_)**(gammas(ix^d)-1.d0)
3619 b2=(^
c&w(ix^d,
b^
c_)**2+)
3620 cfast2=b2*inv_rho+csound(ix^d)
3621 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
3622 if(avmincs2<zero) avmincs2=zero
3623 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3625 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3630 end subroutine mhd_get_csound_prim
3634 subroutine mhd_get_csound_prim_split(w,x,ixI^L,ixO^L,idim,csound)
3637 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3638 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3639 double precision,
intent(out):: csound(ixo^s)
3641 double precision :: rho, inv_rho, cfast2, avmincs2, b2, kmax
3648 {
do ix^db=ixomin^db,ixomax^db \}
3653 cfast2=b2*inv_rho+csound(ix^
d)
3654 avmincs2=cfast2**2-4.0d0*csound(ix^
d)*(w(ix^
d,mag(idim))+&
3656 if(avmincs2<zero) avmincs2=zero
3657 csound(ix^
d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3659 csound(ix^
d)=max(csound(ix^
d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3663 {
do ix^db=ixomin^db,ixomax^db \}
3667 b2=(^
c&w(ix^d,
b^
c_)**2+)
3668 cfast2=b2*inv_rho+csound(ix^d)
3669 avmincs2=cfast2**2-4.0d0*csound(ix^d)*w(ix^d,mag(idim))**2*inv_rho
3670 if(avmincs2<zero) avmincs2=zero
3671 csound(ix^d)=sqrt(half*(cfast2+sqrt(avmincs2)))
3673 csound(ix^d)=max(csound(ix^d),
mhd_etah*sqrt(b2)*inv_rho*kmax)
3678 end subroutine mhd_get_csound_prim_split
3681 subroutine mhd_get_csound_semirelati(w,x,ixI^L,ixO^L,idim,csound,gamma2)
3684 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3686 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3687 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
3689 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
3692 {
do ix^db=ixomin^db,ixomax^db\}
3693 inv_rho = 1.d0/w(ix^
d,
rho_)
3696 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3697 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3698 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
3699 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3702 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
3703 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
3704 if(avmincs2<zero) avmincs2=zero
3706 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
3709 end subroutine mhd_get_csound_semirelati
3712 subroutine mhd_get_csound_semirelati_noe(w,x,ixI^L,ixO^L,idim,csound,gamma2)
3716 integer,
intent(in) :: ixi^
l, ixo^
l, idim
3718 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
3719 double precision,
intent(out):: csound(ixo^s), gamma2(ixo^s)
3721 double precision :: adiabs(ixo^s), gammas(ixo^s)
3722 double precision :: avmincs2, inv_rho, alfven_speed2, idim_alfven_speed2
3735 {
do ix^db=ixomin^db,ixomax^db\}
3736 inv_rho = 1.d0/w(ix^
d,
rho_)
3738 csound(ix^
d)=gammas(ix^
d)*adiabs(ix^
d)*w(ix^
d,
rho_)**(gammas(ix^
d)-1.d0)
3739 alfven_speed2=(^
c&w(ix^
d,
b^
c_)**2+)*inv_rho
3740 gamma2(ix^
d) = 1.0d0/(1.d0+alfven_speed2*inv_squared_c)
3741 avmincs2=1.d0-gamma2(ix^
d)*w(ix^
d,
mom(idim))**2*inv_squared_c
3742 idim_alfven_speed2=w(ix^
d,mag(idim))**2*inv_rho
3745 alfven_speed2=alfven_speed2*avmincs2+csound(ix^
d)*(1.d0+idim_alfven_speed2*inv_squared_c)
3746 avmincs2=(gamma2(ix^
d)*alfven_speed2)**2-4.0d0*gamma2(ix^
d)*csound(ix^
d)*idim_alfven_speed2*avmincs2
3747 if(avmincs2<zero) avmincs2=zero
3749 csound(ix^
d) = sqrt(half*(gamma2(ix^
d)*alfven_speed2+sqrt(avmincs2)))
3752 end subroutine mhd_get_csound_semirelati_noe
3755 subroutine mhd_get_pthermal_noe(w,x,ixI^L,ixO^L,pth)
3759 integer,
intent(in) :: ixi^
l, ixo^
l
3760 double precision,
intent(in) :: w(ixi^s,nw)
3761 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3762 double precision,
intent(out):: pth(ixi^s)
3764 double precision :: adiabs(ixo^s), gammas(ixo^s)
3777 {
do ix^db=ixomin^db,ixomax^db\}
3778 pth(ix^
d)=adiabs(ix^
d)*w(ix^
d,
rho_)**gammas(ix^
d)
3781 end subroutine mhd_get_pthermal_noe
3784 subroutine mhd_get_pthermal_inte(w,x,ixI^L,ixO^L,pth)
3788 integer,
intent(in) :: ixi^
l, ixo^
l
3789 double precision,
intent(in) :: w(ixi^s,nw)
3790 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3791 double precision,
intent(out):: pth(ixi^s)
3795 {
do ix^db= ixomin^db,ixomax^db\}
3796 pth(ix^
d)=gamma_1*w(ix^
d,
e_)
3800 if(check_small_values.and..not.fix_small_values)
then
3801 {
do ix^db= ixomin^db,ixomax^db\}
3802 if(pth(ix^d)<small_pressure)
then
3803 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
3804 " encountered when call mhd_get_pthermal_inte"
3805 write(*,*)
"Iteration: ", it,
" Time: ", global_time
3806 write(*,*)
"Location: ", x(ix^d,:)
3807 write(*,*)
"Cell number: ", ix^d
3809 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
3812 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
3813 write(*,*)
"Saving status at the previous time step"
3819 end subroutine mhd_get_pthermal_inte
3822 subroutine mhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
3826 integer,
intent(in) :: ixi^
l, ixo^
l
3827 double precision,
intent(in) :: w(ixi^s,nw)
3828 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3829 double precision,
intent(out):: pth(ixi^s)
3833 {
do ix^db=ixomin^db,ixomax^db\}
3838 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)&
3839 +(^
c&w(ix^
d,
b^
c_)**2+)))
3844 if(check_small_values.and..not.fix_small_values)
then
3845 {
do ix^db=ixomin^db,ixomax^db\}
3846 if(pth(ix^d)<small_pressure)
then
3847 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
3848 " encountered when call mhd_get_pthermal"
3849 write(*,*)
"Iteration: ", it,
" Time: ", global_time
3850 write(*,*)
"Location: ", x(ix^d,:)
3851 write(*,*)
"Cell number: ", ix^d
3853 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
3856 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
3857 write(*,*)
"Saving status at the previous time step"
3863 end subroutine mhd_get_pthermal_origin
3866 subroutine mhd_get_pthermal_semirelati(w,x,ixI^L,ixO^L,pth)
3870 integer,
intent(in) :: ixi^
l, ixo^
l
3871 double precision,
intent(in) :: w(ixi^s,nw)
3872 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3873 double precision,
intent(out):: pth(ixi^s)
3875 double precision :: e(1:
ndir), v(1:
ndir), tmp, factor
3878 {
do ix^db=ixomin^db,ixomax^db\}
3880 tmp=(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)*inv_squared_c
3881 factor=1.0d0/(w(ix^
d,
rho_)*(w(ix^
d,
rho_)+(^
c&w(ix^
d,
b^
c_)**2+)*inv_squared_c))
3886 e(1)=w(ix^
d,b2_)*v(3)-w(ix^
d,b3_)*v(2)
3887 e(2)=w(ix^
d,b3_)*v(1)-w(ix^
d,b1_)*v(3)
3888 e(3)=w(ix^
d,b1_)*v(2)-w(ix^
d,b2_)*v(1)
3892 e(2)=w(ix^
d,b1_)*v(2)-w(ix^
d,b2_)*v(1)
3898 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)&
3899 -half*((^
c&v(^
c)**2+)*w(ix^
d,
rho_)&
3900 +(^
c&w(ix^
d,
b^
c_)**2+)+(^
c&e(^
c)**2+)*inv_squared_c))
3904 if(check_small_values.and..not.fix_small_values)
then
3905 {
do ix^db=ixomin^db,ixomax^db\}
3906 if(pth(ix^d)<small_pressure)
then
3907 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
3908 " encountered when call mhd_get_pthermal_semirelati"
3909 write(*,*)
"Iteration: ", it,
" Time: ", global_time
3910 write(*,*)
"Location: ", x(ix^d,:)
3911 write(*,*)
"Cell number: ", ix^d
3913 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
3916 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
3917 write(*,*)
"Saving status at the previous time step"
3923 end subroutine mhd_get_pthermal_semirelati
3926 subroutine mhd_get_pthermal_hde(w,x,ixI^L,ixO^L,pth)
3930 integer,
intent(in) :: ixi^
l, ixo^
l
3931 double precision,
intent(in) :: w(ixi^s,nw)
3932 double precision,
intent(in) :: x(ixi^s,1:
ndim)
3933 double precision,
intent(out):: pth(ixi^s)
3937 {
do ix^db= ixomin^db,ixomax^db\}
3938 pth(ix^
d)=gamma_1*(w(ix^
d,
e_)-half*((^
c&w(ix^
d,
m^
c_)**2+)/w(ix^
d,
rho_)))
3941 if(check_small_values.and..not.fix_small_values)
then
3942 {
do ix^db= ixomin^db,ixomax^db\}
3943 if(pth(ix^d)<small_pressure)
then
3944 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
3945 " encountered when call mhd_get_pthermal_hde"
3946 write(*,*)
"Iteration: ", it,
" Time: ", global_time
3947 write(*,*)
"Location: ", x(ix^d,:)
3948 write(*,*)
"Cell number: ", ix^d
3950 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
3953 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
3954 write(*,*)
"Saving status at the previous time step"
3960 end subroutine mhd_get_pthermal_hde
3963 subroutine mhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
3965 integer,
intent(in) :: ixi^
l, ixo^
l
3966 double precision,
intent(in) :: w(ixi^s, 1:nw)
3967 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
3968 double precision,
intent(out):: res(ixi^s)
3969 res(ixo^s) = w(ixo^s,
te_)
3970 end subroutine mhd_get_temperature_from_te
3973 subroutine mhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
3975 integer,
intent(in) :: ixi^
l, ixo^
l
3976 double precision,
intent(in) :: w(ixi^s, 1:nw)
3977 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
3978 double precision,
intent(out):: res(ixi^s)
3980 double precision :: r(ixi^s)
3983 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
3984 end subroutine mhd_get_temperature_from_eint
3989 integer,
intent(in) :: ixi^
l, ixo^
l
3990 double precision,
intent(in) :: w(ixi^s, 1:nw)
3991 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
3992 double precision,
intent(out):: res(ixi^s)
3994 double precision :: r(ixi^s),rho(ixi^s)
3999 res(ixo^s)=res(ixo^s)/(r(ixo^s)*rho(ixo^s))
4003 subroutine mhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
4005 integer,
intent(in) :: ixi^
l, ixo^
l
4006 double precision,
intent(in) :: w(ixi^s, 1:nw)
4007 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4008 double precision,
intent(out):: res(ixi^s)
4010 double precision :: r(ixi^s)
4016 end subroutine mhd_get_temperature_from_eint_with_equi
4018 subroutine mhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
4020 integer,
intent(in) :: ixi^
l, ixo^
l
4021 double precision,
intent(in) :: w(ixi^s, 1:nw)
4022 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4023 double precision,
intent(out):: res(ixi^s)
4025 double precision :: r(ixi^s)
4031 end subroutine mhd_get_temperature_equi
4033 subroutine mhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
4035 integer,
intent(in) :: ixi^
l, ixo^
l
4036 double precision,
intent(in) :: w(ixi^s, 1:nw)
4037 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4038 double precision,
intent(out):: res(ixi^s)
4040 end subroutine mhd_get_rho_equi
4042 subroutine mhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
4044 integer,
intent(in) :: ixi^
l, ixo^
l
4045 double precision,
intent(in) :: w(ixi^s, 1:nw)
4046 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4047 double precision,
intent(out):: res(ixi^s)
4049 end subroutine mhd_get_pe_equi
4056 integer,
intent(in) :: ixi^
l, ixo^
l, nth
4057 double precision,
intent(in) :: w(ixi^s, 1:nw)
4058 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4059 double precision,
intent(out):: prad(ixo^s, 1:
ndim, 1:
ndim)
4067 call mpistop(
'Radiation formalism unknown')
4074 integer,
intent(in) :: ixi^
l, ixo^
l
4075 double precision,
intent(in) :: w(ixi^s, 1:nw)
4076 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4077 double precision,
intent(out) :: pth_plus_prad(ixi^s)
4079 double precision :: wprim(ixi^s, 1:nw)
4080 double precision :: prad_tensor(ixo^s, 1:
ndim, 1:
ndim)
4081 double precision :: prad_max(ixo^s)
4084 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
4087 {
do ix^
d = ixomin^
d,ixomax^
d\}
4088 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
4090 pth_plus_prad(ixo^s) = wprim(ixo^s,
p_) + prad_max(ixo^s)
4099 integer,
intent(in) :: ixi^
l, ixo^
l
4100 double precision,
intent(in) :: w(ixi^s, 1:nw)
4101 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
4102 double precision,
intent(out):: trad(ixi^s)
4110 subroutine mhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
4114 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4116 double precision,
intent(in) :: wc(ixi^s,nw)
4118 double precision,
intent(in) :: w(ixi^s,nw)
4119 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4120 double precision,
intent(out) :: f(ixi^s,nwflux)
4122 double precision :: vhall(ixi^s,1:
ndir)
4123 double precision :: ptotal
4127 {
do ix^db=ixomin^db,ixomax^db\}
4140 {
do ix^db=ixomin^db,ixomax^db\}
4144 ^
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_)\
4145 ptotal=w(ix^d,
p_)+half*(^
c&w(ix^d,
b^
c_)**2+)
4147 f(ix^d,
mom(idim))=f(ix^d,
mom(idim))+ptotal
4150 f(ix^d,
e_)=w(ix^d,
mom(idim))*(wc(ix^d,
e_)+ptotal)&
4151 -w(ix^d,mag(idim))*(^
c&w(ix^d,
b^
c_)*w(ix^d,
m^
c_)+)
4153 ^
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_)\
4157 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4158 {
do ix^db=ixomin^db,ixomax^db\}
4159 if(total_energy)
then
4161 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)**2+)&
4162 -w(ix^d,mag(idim))*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
4165 ^
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))\
4170 {
do ix^db=ixomin^db,ixomax^db\}
4171 f(ix^d,mag(idim))=w(ix^d,
psi_)
4173 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4178 {
do ix^db=ixomin^db,ixomax^db\}
4179 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
4185 {
do ix^db=ixomin^db,ixomax^db\}
4191 {
do ix^db=ixomin^db,ixomax^db\}
4192 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^
c&w({ix^d},
b^
c_)**2+)+smalldouble)
4197 end subroutine mhd_get_flux
4201 subroutine mhd_get_flux_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4206 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4208 double precision,
intent(in) :: wc(ixi^s,nw)
4210 double precision,
intent(in) :: w(ixi^s,nw)
4211 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4212 double precision,
intent(out) :: f(ixi^s,nwflux)
4214 double precision :: vhall(ixi^s,1:
ndir)
4215 double precision :: adiabs(ixo^s), gammas(ixo^s)
4228 {
do ix^db=ixomin^db,ixomax^db\}
4234 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+)
4239 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4240 {
do ix^db=ixomin^db,ixomax^db\}
4242 ^
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))\
4246 {
do ix^db=ixomin^db,ixomax^db\}
4247 f(ix^d,mag(idim))=w(ix^d,
psi_)
4249 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4254 {
do ix^db=ixomin^db,ixomax^db\}
4259 end subroutine mhd_get_flux_noe
4262 subroutine mhd_get_flux_hde(wC,w,x,ixI^L,ixO^L,idim,f)
4266 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4268 double precision,
intent(in) :: wc(ixi^s,nw)
4270 double precision,
intent(in) :: w(ixi^s,nw)
4271 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4272 double precision,
intent(out) :: f(ixi^s,nwflux)
4274 double precision :: vhall(ixi^s,1:
ndir)
4277 {
do ix^db=ixomin^db,ixomax^db\}
4290 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4291 {
do ix^db=ixomin^db,ixomax^db\}
4293 ^
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))\
4297 {
do ix^db=ixomin^db,ixomax^db\}
4298 f(ix^d,mag(idim))=w(ix^d,
psi_)
4300 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4305 {
do ix^db=ixomin^db,ixomax^db\}
4311 {
do ix^db=ixomin^db,ixomax^db\}
4312 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^
c&w({ix^d},
b^
c_)**2+)+smalldouble)
4317 end subroutine mhd_get_flux_hde
4324 subroutine mhd_get_flux_split(wC,w,x,ixI^L,ixO^L,idim,f)
4328 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4330 double precision,
intent(in) :: wc(ixi^s,nw)
4332 double precision,
intent(in) :: w(ixi^s,nw)
4333 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4334 double precision,
intent(out) :: f(ixi^s,nwflux)
4336 double precision :: vhall(ixi^s,1:
ndir)
4337 double precision :: ptotal, btotal(ixo^s,1:
ndir)
4340 {
do ix^db=ixomin^db,ixomax^db\}
4348 ptotal=w(ix^
d,
p_)+half*(^
c&w(ix^
d,
b^
c_)**2+)
4352 ptotal=ptotal+(^
c&w(ix^
d,
b^
c_)*
block%B0(ix^
d,^
c,idim)+)
4356 btotal(ix^
d,idim)*w(ix^
d,
b^
c_)-w(ix^
d,mag(idim))*
block%B0(ix^
d,^
c,idim)\
4357 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
4359 ^
c&btotal(ix^
d,^
c)=w(ix^
d,
b^
c_)\
4363 f(ix^
d,
mom(idim))=f(ix^
d,
mom(idim))+ptotal
4366 ^
c&f(ix^
d,
b^
c_)=w(ix^
d,
mom(idim))*btotal(ix^
d,^
c)-btotal(ix^
d,idim)*w(ix^
d,
m^
c_)\
4373 f(ix^
d,
e_)=w(ix^
d,
mom(idim))*(wc(ix^
d,
e_)+ptotal)&
4374 -btotal(ix^
d,idim)*(^
c&w(ix^
d,
b^
c_)*w(ix^
d,
m^
c_)+)
4379 {
do ix^db=ixomin^db,ixomax^db\}
4380 f(ix^d,mag(idim))=w(ix^d,
psi_)
4382 f(ix^d,
psi_) = cmax_global**2*w(ix^d,mag(idim))
4387 {
do ix^db=ixomin^db,ixomax^db\}
4388 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
4393 call mhd_getv_hall(w,x,ixi^l,ixo^l,vhall)
4394 {
do ix^db=ixomin^db,ixomax^db\}
4396 ^
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)\
4397 if(total_energy)
then
4399 f(ix^d,
e_)=f(ix^d,
e_)+vhall(ix^d,idim)*(^
c&w(ix^d,
b^
c_)*btotal(ix^d,^
c)+)&
4400 -btotal(ix^d,idim)*(^
c&vhall(ix^d,^
c)*w(ix^d,
b^
c_)+)
4406 {
do ix^db=ixomin^db,ixomax^db\}
4411 {
do ix^db=ixomin^db,ixomax^db\}
4412 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*btotal(ix^d,idim)/(dsqrt(^
c&btotal({ix^d},^
c)**2+)+smalldouble)
4417 end subroutine mhd_get_flux_split
4420 subroutine mhd_get_flux_semirelati(wC,w,x,ixI^L,ixO^L,idim,f)
4424 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4426 double precision,
intent(in) :: wc(ixi^s,nw)
4428 double precision,
intent(in) :: w(ixi^s,nw)
4429 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4430 double precision,
intent(out) :: f(ixi^s,nwflux)
4432 double precision :: sa(ixo^s,1:
ndir),e(ixo^s,1:
ndir),e2
4435 {
do ix^db=ixomin^db,ixomax^db\}
4440 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4441 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4442 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4447 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4452 e2=(^
c&e(ix^
d,^
c)**2+)
4459 sa(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
4460 sa(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
4461 sa(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
4464 sa(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
4465 sa(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
4478 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4480 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)
4487 {
do ix^db=ixomin^db,ixomax^db\}
4488 f(ix^d,mag(idim))=w(ix^d,
psi_)
4490 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4495 {
do ix^db=ixomin^db,ixomax^db\}
4500 {
do ix^db=ixomin^db,ixomax^db\}
4501 f(ix^d,
e_)=f(ix^d,
e_)+w(ix^d,
q_)*w(ix^d,mag(idim))/(dsqrt(^
c&w({ix^d},
b^
c_)**2+)+smalldouble)
4506 end subroutine mhd_get_flux_semirelati
4508 subroutine mhd_get_flux_semirelati_noe(wC,w,x,ixI^L,ixO^L,idim,f)
4513 integer,
intent(in) :: ixi^
l, ixo^
l, idim
4515 double precision,
intent(in) :: wc(ixi^s,nw)
4517 double precision,
intent(in) :: w(ixi^s,nw)
4518 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4519 double precision,
intent(out) :: f(ixi^s,nwflux)
4521 double precision :: adiabs(ixo^s), gammas(ixo^s)
4522 double precision :: e(ixo^s,1:
ndir),e2
4535 {
do ix^db=ixomin^db,ixomax^db\}
4540 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
4541 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
4542 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4543 e2=(^
c&e(ix^
d,^
c)**2+)
4548 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
4558 -w(ix^
d,mag(idim))*w(ix^
d,
b^
c_)-e(ix^
d,idim)*e(ix^
d,^
c)*inv_squared_c\
4560 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)
4567 {
do ix^db=ixomin^db,ixomax^db\}
4568 f(ix^d,mag(idim))=w(ix^d,
psi_)
4570 f(ix^d,
psi_)=cmax_global**2*w(ix^d,mag(idim))
4575 {
do ix^db=ixomin^db,ixomax^db\}
4580 end subroutine mhd_get_flux_semirelati_noe
4588 subroutine add_source_ambipolar_internal_energy(qdt,ixI^L,ixO^L,wCT,w,x)
4590 integer,
intent(in) :: ixi^
l, ixo^
l
4591 double precision,
intent(in) :: qdt
4592 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
4593 double precision,
intent(inout) :: w(ixi^s,1:nw)
4595 double precision :: tmp(ixi^s),btot2(ixi^s)
4596 double precision :: jxbxb(ixi^s,1:3)
4598 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,jxbxb)
4601 where (btot2(ixo^s)>smalldouble )
4602 tmp(ixo^s) = sum(jxbxb(ixo^s,1:3)**2,dim=
ndim+1) / btot2(ixo^s)
4609 w(ixo^s,
e_)=w(ixo^s,
e_)- qdt*tmp(ixo^s)
4611 end subroutine add_source_ambipolar_internal_energy
4614 subroutine mhd_get_jxbxb(w,x,ixI^L,ixO^L,res)
4617 integer,
intent(in) :: ixi^
l, ixo^
l
4618 double precision,
intent(in) :: w(ixi^s,nw)
4619 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4620 double precision,
intent(out) :: res(ixi^s,1:3)
4622 double precision :: btot(ixi^s,1:3)
4623 double precision :: current(ixi^s,7-2*
ndir:3)
4624 double precision :: tmp(ixi^s),b2(ixi^s)
4625 integer :: idir, idirmin
4635 btot(ixo^s, idir) = w(ixo^s,mag(idir)) +
block%B0(ixo^s,idir,
b0i)
4639 btot(ixo^s, idir) = w(ixo^s,mag(idir))
4643 tmp(ixo^s)= sum(current(ixo^s,idirmin:3)*btot(ixo^s,idirmin:3),dim=
ndim+1)
4644 b2(ixo^s) = sum(btot(ixo^s,1:3)**2,dim=
ndim+1)
4646 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s)
4649 res(ixo^s,idir) = btot(ixo^s,idir) * tmp(ixo^s) - current(ixo^s,idir) * b2(ixo^s)
4654 where (b2(ixo^s)<smalldouble )
4655 res(ixo^s,idir) = zero
4658 end subroutine mhd_get_jxbxb
4664 subroutine sts_set_source_ambipolar(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
4668 integer,
intent(in) :: ixi^
l,ixo^
l,igrid,nflux
4669 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4670 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
4671 double precision,
intent(in) :: my_dt
4672 logical,
intent(in) :: fix_conserve_at_step
4674 double precision,
dimension(ixI^S,1:3) :: tmp,ff
4675 double precision :: fluxall(ixi^s,1:nflux,1:
ndim)
4676 double precision :: fe(ixi^s,
sdim:3)
4677 double precision :: btot(ixi^s,1:3),tmp2(ixi^s)
4678 integer :: i, ixa^
l, ie_
4685 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,tmp)
4702 btot(ixa^s,1:3) = 0.d0
4704 btot(ixa^s,1:
ndir) = w(ixa^s,mag(1:
ndir))
4708 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4709 if(fix_conserve_at_step) fluxall(ixi^s,1,1:
ndim)=ff(ixi^s,1:
ndim)
4711 wres(ixo^s,
e_)=-tmp2(ixo^s)
4718 ff(ixa^s,1) = tmp(ixa^s,2)
4719 ff(ixa^s,2) = -tmp(ixa^s,1)
4721 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4722 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
4723 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
4726 call update_faces_ambipolar(ixi^
l,ixo^
l,w,x,tmp,fe,btot)
4728 ixamin^
d=ixomin^
d-1;
4729 wres(ixa^s,mag(1:
ndim))=-btot(ixa^s,1:
ndim)
4739 ff(ixa^s,2) = tmp(ixa^s,3)
4740 ff(ixa^s,3) = -tmp(ixa^s,2)
4741 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4742 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
4744 wres(ixo^s,mag(1))=-tmp2(ixo^s)
4747 ff(ixa^s,1) = -tmp(ixa^s,3)
4749 ff(ixa^s,3) = tmp(ixa^s,1)
4750 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4751 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
4752 wres(ixo^s,mag(2))=-tmp2(ixo^s)
4758 ff(ixa^s,2) = tmp(ixa^s,3)
4759 ff(ixa^s,3) = -tmp(ixa^s,2)
4760 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4761 if(fix_conserve_at_step) fluxall(ixi^s,2,1:
ndim)=ff(ixi^s,1:
ndim)
4763 wres(ixo^s,mag(1))=-tmp2(ixo^s)
4765 ff(ixa^s,1) = -tmp(ixa^s,3)
4767 ff(ixa^s,3) = tmp(ixa^s,1)
4768 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4769 if(fix_conserve_at_step) fluxall(ixi^s,3,1:
ndim)=ff(ixi^s,1:
ndim)
4770 wres(ixo^s,mag(2))=-tmp2(ixo^s)
4775 ff(ixa^s,1) = tmp(ixa^s,2)
4776 ff(ixa^s,2) = -tmp(ixa^s,1)
4778 call get_flux_on_cell_face(ixi^
l,ixo^
l,ff,tmp2)
4779 if(fix_conserve_at_step) fluxall(ixi^s,1+
ndir,1:
ndim)=ff(ixi^s,1:
ndim)
4780 wres(ixo^s,mag(
ndir))=-tmp2(ixo^s)
4785 if(fix_conserve_at_step)
then
4786 fluxall=my_dt*fluxall
4793 end subroutine sts_set_source_ambipolar
4796 subroutine update_faces_ambipolar(ixI^L,ixO^L,w,x,ECC,fE,circ)
4799 integer,
intent(in) :: ixi^
l, ixo^
l
4800 double precision,
intent(in) :: w(ixi^s,1:nw)
4801 double precision,
intent(in) :: x(ixi^s,1:
ndim)
4803 double precision,
intent(in) :: ecc(ixi^s,1:3)
4804 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
4805 double precision,
intent(out) :: circ(ixi^s,1:
ndim)
4807 integer :: hxc^
l,ixc^
l,ixa^
l
4808 integer :: idim1,idim2,idir,ix^
d
4814 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
4816 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
4817 ixamin^
d=ixcmin^
d+ix^
d;
4818 ixamax^
d=ixcmax^
d+ix^
d;
4819 fe(ixc^s,idir)=fe(ixc^s,idir)+ecc(ixa^s,idir)
4821 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0*block%dsC(ixc^s,idir)
4827 ixcmin^d=ixomin^d-1;
4834 hxc^l=ixc^l-kr(idim2,^d);
4836 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
4837 +lvc(idim1,idim2,idir)&
4842 circ(ixc^s,idim1)=circ(ixc^s,idim1)/block%surfaceC(ixc^s,idim1)
4845 end subroutine update_faces_ambipolar
4851 subroutine get_flux_on_cell_face(ixI^L,ixO^L,ff,src)
4854 integer,
intent(in) :: ixi^
l, ixo^
l
4855 double precision,
dimension(ixI^S,1:3),
intent(inout) :: ff
4856 double precision,
intent(out) :: src(ixi^s)
4858 double precision :: ffc(ixi^s,1:
ndim)
4859 double precision :: dxinv(
ndim)
4860 integer :: idims, ix^
d, ixa^
l, ixb^
l, ixc^
l
4868 ixcmax^
d=ixomax^
d; ixcmin^
d=ixomin^
d-1;
4870 ixbmin^
d=ixcmin^
d+ix^
d;
4871 ixbmax^
d=ixcmax^
d+ix^
d;
4874 ffc(ixc^s,1:ndim)=0.5d0**ndim*ffc(ixc^s,1:ndim)
4876 call mpistop(
"to generalize using volume averaging")
4879 ff(ixi^s,1:ndim)=0.d0
4881 ixb^l=ixo^l-kr(idims,^d);
4882 ixcmax^d=ixomax^d; ixcmin^d=ixbmin^d;
4884 if({ ix^d==0 .and. ^d==idims | .or.})
then
4885 ixbmin^d=ixcmin^d-ix^d;
4886 ixbmax^d=ixcmax^d-ix^d;
4887 ff(ixc^s,idims)=ff(ixc^s,idims)+ffc(ixb^s,idims)
4890 ff(ixc^s,idims)=ff(ixc^s,idims)*0.5d0**(ndim-1)
4893 if(slab_uniform)
then
4895 ff(ixa^s,idims)=dxinv(idims)*ff(ixa^s,idims)
4896 ixb^l=ixo^l-kr(idims,^d);
4897 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
4901 ff(ixa^s,idims)=ff(ixa^s,idims)*block%surfaceC(ixa^s,idims)
4902 ixb^l=ixo^l-kr(idims,^d);
4903 src(ixo^s)=src(ixo^s)+ff(ixo^s,idims)-ff(ixb^s,idims)
4905 src(ixo^s)=src(ixo^s)/block%dvolume(ixo^s)
4907 end subroutine get_flux_on_cell_face
4911 function get_ambipolar_dt(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
4914 integer,
intent(in) :: ixi^
l, ixo^
l
4915 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
4916 double precision,
intent(in) :: w(ixi^s,1:nw)
4917 double precision :: dtnew
4919 double precision :: coef
4920 double precision :: dxarr(
ndim)
4921 double precision :: tmp(ixi^s)
4927 coef = maxval(dabs(tmp(ixo^s)))
4934 dtnew=minval(dxarr(1:
ndim))**2.0d0*coef
4936 dtnew=minval(
block%ds(ixo^s,1:
ndim))**2.0d0*coef
4939 end function get_ambipolar_dt
4947 integer,
intent(in) :: ixi^
l, ixo^
l
4948 double precision,
intent(in) :: w(ixi^s,1:nw), x(ixi^s,1:
ndim)
4949 double precision,
intent(inout) :: res(ixi^s)
4950 double precision :: tmp(ixi^s)
4951 double precision :: rho(ixi^s)
4958 res(ixo^s) = tmp(ixo^s) * res(ixo^s)
4963 subroutine mhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
4970 integer,
intent(in) :: ixi^
l, ixo^
l
4971 double precision,
intent(in) :: qdt,dtfactor
4972 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
4973 double precision,
intent(inout) :: w(ixi^s,1:nw)
4974 logical,
intent(in) :: qsourcesplit
4975 logical,
intent(inout) :: active
4982 if (.not. qsourcesplit)
then
4986 call add_source_internal_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
4990 call add_equi_terms(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
4996 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5005 call add_source_b0split(qdt,dtfactor,ixi^
l,ixo^
l,wct,w,x,wctprim)
5009 if (abs(
mhd_eta)>smalldouble)
then
5011 call add_source_res_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
5016 call add_source_ambi_exp(qdt,ixi^
l,ixo^
l,wct,w,x)
5021 call add_source_hyperres(qdt,ixi^
l,ixo^
l,wct,w,x)
5027 call add_source_hydrodynamic_e(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5031 call add_source_semirelativistic(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
5038 select case (type_divb)
5043 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5046 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
5049 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5050 case (divb_janhunen)
5052 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5053 case (divb_lindejanhunen)
5055 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5056 call add_source_janhunen(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5057 case (divb_lindepowel)
5059 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5060 call add_source_powel(qdt,ixi^
l,ixo^
l,wctprim,w,x)
5061 case (divb_lindeglm)
5063 call add_source_linde(qdt,ixi^
l,ixo^
l,wct,w,x)
5064 call add_source_glm(qdt,ixi^
l,ixo^
l,wct,w,x)
5065 case (divb_multigrid)
5070 call mpistop(
'Unknown divB fix')
5077 w,x,qsourcesplit,active,
rc_fl)
5087 w,x,gravity_energy,qsourcesplit,active)
5096 call mhd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x,qsourcesplit,active)
5101 if(.not.qsourcesplit)
then
5103 call mhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
5107 end subroutine mhd_add_source
5109 subroutine mhd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
5116 integer,
intent(in) :: ixi^
l, ixo^
l
5117 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
5118 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw)
5119 double precision,
intent(inout) :: w(ixi^s,1:nw)
5120 logical,
intent(in) :: qsourcesplit
5121 logical,
intent(inout) :: active
5122 double precision :: cmax(ixi^s)
5130 call mhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'fld_add_radiation')
5136 call mhd_handle_small_values(.true., w, x, ixi^
l, ixo^
l,
'afld_add_radiation')
5141 call mpistop(
'Radiation formalism unknown')
5144 end subroutine mhd_add_radiation_source
5147 subroutine add_equi_terms(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
5152 integer,
intent(in) :: ixi^
l, ixo^
l
5153 double precision,
intent(in) :: qdt,dtfactor
5154 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5155 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5156 double precision,
intent(inout) :: w(ixi^s,1:nw)
5158 double precision :: divv(ixi^s)
5159 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
5160 double precision :: gravity_field(ixi^s,1:
ndim)
5172 divv(ixo^s)=divv(ixo^s)*
mhd_gamma*inv_gamma_1
5183 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)*inv_gamma_1
5192 a(ixo^s,idir)=
block%J0(ixo^s,idir)
5197 w(ixo^s,
e_)=w(ixo^s,
e_)-qdt*wctprim(ixo^s,
mom(idir))*axb(ixo^s,idir)*inv_gamma_1
5203 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)*inv_gamma_1
5212 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)*inv_gamma_1
5216 end subroutine add_equi_terms
5218 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5220 integer,
intent(in) :: ixi^
l,ixo^
l
5221 double precision,
intent(in) :: qdt
5222 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
5223 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
5224 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
5226 double precision :: r(ixi^s),te(ixi^s),rho_loc(ixi^s),pth_loc(ixi^s)
5227 double precision :: sigma_t5,sigma_t7,f_sat,sigmat5_bgradt,tau,bdir(
ndir),bunitvec(
ndim)
5231 {
do ix^db=iximin^db,iximax^db\}
5236 rho_loc(ix^
d)=wctprim(ix^
d,
rho_)
5237 pth_loc(ix^
d)=wctprim(ix^
d,
p_)
5239 te(ix^
d)=pth_loc(ix^
d)/(r(ix^
d)*rho_loc(ix^
d))
5245 do ix1=ixomin1,ixomax1
5247 if(te(ix^d)<block%wextra(ix^d,
tcoff_))
then
5249 sigma_t7=sigma_t5*block%wextra(ix^d,
tcoff_)
5252 sigma_t7=sigma_t5*te(ix^d)
5256 sigma_t7=sigma_t5*te(ix^d)
5258 sigmat5_bgradt=sigma_t5*(8.d0*(te(ix1+1)-te(ix1-1))-te(ix1+2)+te(ix1-2))/12.d0/block%ds(ix^d,1)
5261 f_sat=one/(one+dabs(sigmat5_bgradt)/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5262 tau=max(4.d0*dt, f_sat*sigma_t7*courantpar**2/(pth_loc(ix^d)*inv_gamma_1*cmax_global**2))
5263 w(ix^d,
q_)=w(ix^d,
q_)-qdt*(f_sat*sigmat5_bgradt+wct(ix^d,
q_))/tau
5265 w(ix^d,
q_)=w(ix^d,
q_)-qdt*(sigmat5_bgradt+wct(ix^d,
q_))/&
5266 max(4.d0*dt, sigma_t7*courantpar**2/(pth_loc(ix^d)*inv_gamma_1*cmax_global**2))
5271 do ix2=ixomin2,ixomax2
5272 do ix1=ixomin1,ixomax1
5274 if(te(ix^d)<block%wextra(ix^d,
tcoff_))
then
5276 sigma_t7=sigma_t5*block%wextra(ix^d,
tcoff_)
5279 sigma_t7=sigma_t5*te(ix^d)
5283 sigma_t7=sigma_t5*te(ix^d)
5286 ^
c&bdir(^
c)=wct({ix^d},mag(^
c))+block%B0({ix^d},^
c,0)\
5288 ^
c&bdir(^
c)=wct({ix^d},mag(^
c))\
5290 if(bdir(1)/=0.d0)
then
5291 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(^ce&(bdir(^ce)/bdir(1))**2+))
5295 if(bdir(2)/=0.d0)
then
5296 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(^cf&(bdir(^cf)/bdir(2))**2+))
5300 sigmat5_bgradt=sigma_t5*(&
5301 bunitvec(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)&
5302 +bunitvec(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))
5305 f_sat=one/(one+dabs(sigmat5_bgradt)/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5306 tau=max(4.d0*dt, f_sat*sigma_t7*courantpar**2/(pth_loc(ix^d)*inv_gamma_1*cmax_global**2))
5307 w(ix^d,
q_)=w(ix^d,
q_)-qdt*(f_sat*sigmat5_bgradt+wct(ix^d,
q_))/tau
5309 w(ix^d,
q_)=w(ix^d,
q_)-qdt*(sigmat5_bgradt+wct(ix^d,
q_))/&
5310 max(4.d0*dt, sigma_t7*courantpar**2/(pth_loc(ix^d)*inv_gamma_1*cmax_global**2))
5316 do ix3=ixomin3,ixomax3
5317 do ix2=ixomin2,ixomax2
5318 do ix1=ixomin1,ixomax1
5320 if(te(ix^d)<block%wextra(ix^d,
tcoff_))
then
5322 sigma_t7=sigma_t5*block%wextra(ix^d,
tcoff_)
5325 sigma_t7=sigma_t5*te(ix^d)
5329 sigma_t7=sigma_t5*te(ix^d)
5332 ^d&bdir(^d)=wct({ix^d},mag(^d))+block%B0({ix^d},^d,0)\
5334 ^d&bdir(^d)=wct({ix^d},mag(^d))\
5336 if(bdir(1)/=0.d0)
then
5337 bunitvec(1)=sign(1.d0,bdir(1))/dsqrt(1.d0+(bdir(2)/bdir(1))**2+(bdir(3)/bdir(1))**2)
5341 if(bdir(2)/=0.d0)
then
5342 bunitvec(2)=sign(1.d0,bdir(2))/dsqrt(1.d0+(bdir(1)/bdir(2))**2+(bdir(3)/bdir(2))**2)
5346 if(bdir(3)/=0.d0)
then
5347 bunitvec(3)=sign(1.d0,bdir(3))/dsqrt(1.d0+(bdir(1)/bdir(3))**2+(bdir(2)/bdir(3))**2)
5351 sigmat5_bgradt=sigma_t5*(&
5352 bunitvec(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)&
5353 +bunitvec(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)&
5354 +bunitvec(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))
5357 f_sat=one/(one+dabs(sigmat5_bgradt)/(1.5d0*rho_loc(ix^d)*(pth_loc(ix^d)/rho_loc(ix^d))**1.5d0))
5358 tau=max(4.d0*dt, f_sat*sigma_t7*courantpar**2/(pth_loc(ix^d)*inv_gamma_1*cmax_global**2))
5359 w(ix^d,
q_)=w(ix^d,
q_)-qdt*(f_sat*sigmat5_bgradt+wct(ix^d,
q_))/tau
5361 w(ix^d,
q_)=w(ix^d,
q_)-qdt*(sigmat5_bgradt+wct(ix^d,
q_))/&
5362 max(4.d0*dt, sigma_t7*courantpar**2/(pth_loc(ix^d)*inv_gamma_1*cmax_global**2))
5368 end subroutine add_hypertc_source
5372 subroutine get_lorentz_force(ixI^L,ixO^L,w,JxB)
5374 integer,
intent(in) :: ixi^
l, ixo^
l
5375 double precision,
intent(in) :: w(ixi^s,1:nw)
5376 double precision,
intent(inout) :: jxb(ixi^s,3)
5377 double precision :: a(ixi^s,3),
b(ixi^s,3)
5379 double precision :: current(ixi^s,7-2*
ndir:3)
5380 integer :: idir, idirmin
5385 b(ixo^s, idir) = w(ixo^s,mag(idir))+
block%B0(ixo^s,idir,0)
5389 b(ixo^s, idir) = w(ixo^s,mag(idir))
5398 a(ixo^s,idir)=current(ixo^s,idir)
5402 end subroutine get_lorentz_force
5406 integer,
intent(in) :: ixi^
l, ixo^
l
5407 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
5408 double precision,
intent(out) :: rho(ixi^s)
5413 rho(ixo^s) = w(ixo^s,
rho_)
5419 subroutine mhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
5422 integer,
intent(in) :: ixi^
l,ixo^
l, ie
5423 double precision,
intent(inout) :: w(ixi^s,1:nw)
5424 double precision,
intent(in) :: x(ixi^s,1:
ndim)
5425 character(len=*),
intent(in) :: subname
5427 double precision :: rho(ixi^s)
5429 logical :: flag(ixi^s,1:nw)
5433 where(w(ixo^s,ie)+
block%equi_vars(ixo^s,
equi_pe0_,0)*inv_gamma_1<small_e)&
5434 flag(ixo^s,ie)=.true.
5436 where(w(ixo^s,ie)<small_e) flag(ixo^s,ie)=.true.
5438 if(any(flag(ixo^s,ie)))
then
5442 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e - &
5445 where(flag(ixo^s,ie)) w(ixo^s,ie)=small_e
5451 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
5454 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/rho(ixo^s)
5460 end subroutine mhd_handle_small_ei
5462 subroutine mhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
5466 integer,
intent(in) :: ixi^
l, ixo^
l
5467 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5468 double precision,
intent(inout) :: w(ixi^s,1:nw)
5470 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
5479 end subroutine mhd_update_temperature
5482 subroutine add_source_b0split(qdt,dtfactor,ixI^L,ixO^L,wCT,w,x,wCTprim)
5485 integer,
intent(in) :: ixi^
l, ixo^
l
5486 double precision,
intent(in) :: qdt, dtfactor,wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5487 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5488 double precision,
intent(inout) :: w(ixi^s,1:nw)
5490 double precision :: a(ixi^s,3),
b(ixi^s,3), axb(ixi^s,3)
5502 a(ixo^s,idir)=
block%J0(ixo^s,idir)
5507 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5510 axb(ixo^s,:)=axb(ixo^s,:)*qdt
5516 if(total_energy)
then
5519 b(ixo^s,:)=wctprim(ixo^s,mag(:))
5528 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5531 axb(ixo^s,:)=axb(ixo^s,:)*qdt
5536 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
5540 call mhd_getv_hall(wct,x,ixi^
l,ixo^
l,a,.true.)
5545 axb(ixo^s,idir)=axb(ixo^s,idir)*
block%dt(ixo^s)*dtfactor
5548 axb(ixo^s,:)=axb(ixo^s,:)*qdt
5552 w(ixo^s,
e_)=w(ixo^s,
e_)-axb(ixo^s,idir)*
block%J0(ixo^s,idir)
5560 call mhd_get_jxbxb(wct,x,ixi^
l,ixo^
l,axb)
5565 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*axb(ixo^s,idir)*
block%J0(ixo^s,idir)
5571 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_B0')
5573 end subroutine add_source_b0split
5576 subroutine add_source_semirelativistic(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5580 integer,
intent(in) :: ixi^
l, ixo^
l
5581 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5582 double precision,
intent(inout) :: w(ixi^s,1:nw)
5583 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
5585 double precision :: e(ixi^s,1:3),curle(ixi^s,1:3),dive(ixi^s)
5586 integer :: idir, idirmin, ix^
d
5590 {
do ix^db=iximin^db,iximax^db\}
5592 e(ix^
d,1)=w(ix^
d,b2_)*wctprim(ix^
d,m3_)-w(ix^
d,b3_)*wctprim(ix^
d,m2_)
5593 e(ix^
d,2)=w(ix^
d,b3_)*wctprim(ix^
d,m1_)-w(ix^
d,b1_)*wctprim(ix^
d,m3_)
5594 e(ix^
d,3)=w(ix^
d,b1_)*wctprim(ix^
d,m2_)-w(ix^
d,b2_)*wctprim(ix^
d,m1_)
5596 call divvector(e,ixi^l,ixo^l,dive)
5598 call curlvector(e,ixi^l,ixo^l,curle,idirmin,1,3)
5601 {
do ix^db=ixomin^db,ixomax^db\}
5602 w(ix^d,m1_)=w(ix^d,m1_)+qdt*(inv_squared_c0-inv_squared_c)*&
5603 (e(ix^d,1)*dive(ix^d)-e(ix^d,2)*curle(ix^d,3)+e(ix^d,3)*curle(ix^d,2))
5604 w(ix^d,m2_)=w(ix^d,m2_)+qdt*(inv_squared_c0-inv_squared_c)*&
5605 (e(ix^d,2)*dive(ix^d)-e(ix^d,3)*curle(ix^d,1)+e(ix^d,1)*curle(ix^d,3))
5606 w(ix^d,m3_)=w(ix^d,m3_)+qdt*(inv_squared_c0-inv_squared_c)*&
5607 (e(ix^d,3)*dive(ix^d)-e(ix^d,1)*curle(ix^d,2)+e(ix^d,2)*curle(ix^d,1) )
5611 end subroutine add_source_semirelativistic
5614 subroutine add_source_internal_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5618 integer,
intent(in) :: ixi^
l, ixo^
l
5619 double precision,
intent(in) :: qdt
5620 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5621 double precision,
intent(inout) :: w(ixi^s,1:nw)
5622 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
5624 double precision :: divv(ixi^s), tmp
5636 {
do ix^db=ixomin^db,ixomax^db\}
5638 w(ix^
d,
e_)=w(ix^
d,
e_)-qdt*wctprim(ix^
d,
p_)*divv(ix^
d)
5639 if(w(ix^
d,
e_)<small_e)
then
5644 call add_source_ambipolar_internal_energy(qdt,ixi^l,ixo^l,wct,w,x)
5647 if(fix_small_values)
then
5648 call mhd_handle_small_ei(w,x,ixi^l,ixo^l,
e_,
'add_source_internal_e')
5650 end subroutine add_source_internal_e
5653 subroutine add_source_hydrodynamic_e(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
5658 integer,
intent(in) :: ixi^
l, ixo^
l
5659 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5660 double precision,
intent(inout) :: w(ixi^s,1:nw)
5661 double precision,
intent(in),
optional :: wctprim(ixi^s,1:nw)
5663 double precision ::
b(ixi^s,3), j(ixi^s,3), jxb(ixi^s,3)
5664 double precision :: current(ixi^s,7-2*
ndir:3)
5665 double precision :: bu(ixo^s,1:
ndir), tmp(ixo^s), b2(ixo^s)
5666 double precision :: gravity_field(ixi^s,1:
ndir), vaoc
5667 integer :: idir, idirmin, idims, ix^
d
5672 b(ixo^s, idir) = wct(ixo^s,mag(idir))
5684 j(ixo^s,idir)=current(ixo^s,idir)
5763 call add_source_ambipolar_internal_energy(qdt,ixi^
l,ixo^
l,wct,w,x)
5766 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_hydrodynamic_e')
5768 end subroutine add_source_hydrodynamic_e
5774 subroutine add_source_res1(qdt,ixI^L,ixO^L,wCT,w,x)
5779 integer,
intent(in) :: ixi^
l, ixo^
l
5780 double precision,
intent(in) :: qdt
5781 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5782 double precision,
intent(inout) :: w(ixi^s,1:nw)
5784 integer :: ixa^
l,idir,jdir,kdir,idirmin,idim
5785 double precision :: tmp(ixi^s),tmp2(ixi^s)
5788 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
5789 double precision :: gradeta(ixi^s,1:
ndim), bf(ixi^s,1:
ndir)
5790 double precision :: lapl_vec(ixi^s,1:
ndir)
5796 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5797 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
5804 gradeta(ixo^s,1:
ndim)=zero
5809 gradeta(ixo^s,idim)=tmp(ixo^s)
5816 bf(ixi^s,1:
ndir)=wct(ixi^s,mag(1:
ndir))
5823 tmp(ixo^s)=lapl_vec(ixo^s,idir)*eta(ixo^s)
5827 do jdir=1,
ndim;
do kdir=idirmin,3
5828 if (
lvc(idir,jdir,kdir)/=0)
then
5829 if (
lvc(idir,jdir,kdir)==1)
then
5830 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
5832 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
5839 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
5840 if(total_energy)
then
5841 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*tmp(ixo^s)*bf(ixo^s,idir)
5847 w(ixo^s,
e_)=w(ixo^s,
e_)+qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=ndim+1)
5850 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_res1')
5852 end subroutine add_source_res1
5856 subroutine add_source_res_exp(qdt,ixI^L,ixO^L,wCT,w,x)
5861 integer,
intent(in) :: ixi^
l, ixo^
l
5862 double precision,
intent(in) :: qdt
5863 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5864 double precision,
intent(inout) :: w(ixi^s,1:nw)
5867 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s),curlj(ixi^s,1:3)
5868 double precision :: tmpvec(ixi^s,1:3),tmp(ixo^s)
5869 integer :: ixa^
l,idir,idirmin,idirmin1
5873 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5874 call mpistop(
"Error in add_source_res_exp: Non-conforming input limits")
5884 tmpvec(ixa^s,idir)=current(ixa^s,idir)*
mhd_eta
5889 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
5898 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
5901 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
5906 tmp(ixo^s)=qdt*
mhd_eta*sum(current(ixo^s,:)**2,dim=
ndim+1)
5908 tmp(ixo^s)=qdt*eta(ixo^s)*sum(current(ixo^s,:)**2,dim=
ndim+1)
5910 if(total_energy)
then
5913 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
5914 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
5917 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
5921 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_res_exp')
5922 end subroutine add_source_res_exp
5927 subroutine add_source_ambi_exp(qdt,ixI^L,ixO^L,wCT,w,x)
5932 integer,
intent(in) :: ixi^
l, ixo^
l
5933 double precision,
intent(in) :: qdt
5934 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
5935 double precision,
intent(inout) :: w(ixi^s,1:nw)
5937 double precision :: current(ixi^s,1:3),curlj(ixi^s,1:3)
5938 double precision :: tmpvec(ixi^s,1:3),tmp(ixi^s),btot2(ixi^s)
5939 integer :: ixa^
l,idir,idirmin1
5943 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
5944 call mpistop(
"Error in add_source_ambi_exp: Non-conforming input limits")
5948 call mhd_get_jxbxb(wct,x,ixi^
l,ixa^
l,current)
5962 w(ixo^s,mag(
ndir)) = w(ixo^s,mag(
ndir))-qdt*curlj(ixo^s,
ndir)
5965 w(ixo^s,mag(1:
ndir)) = w(ixo^s,mag(1:
ndir))-qdt*curlj(ixo^s,1:
ndir)
5972 where (btot2(ixa^s)>smalldouble )
5973 tmp(ixa^s) = sum(current(ixa^s,1:3)**2,dim=
ndim+1) / btot2(ixa^s)
5980 tmp(ixo^s)=-qdt*tmp(ixo^s)
5981 if(total_energy)
then
5984 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)-&
5985 qdt*sum(wct(ixo^s,mag(1:
ndir))*curlj(ixo^s,1:
ndir),dim=
ndim+1)
5988 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)
5992 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_ambi_exp')
5993 end subroutine add_source_ambi_exp
5997 subroutine add_source_hyperres(qdt,ixI^L,ixO^L,wCT,w,x)
6001 integer,
intent(in) :: ixi^
l, ixo^
l
6002 double precision,
intent(in) :: qdt
6003 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6004 double precision,
intent(inout) :: w(ixi^s,1:nw)
6006 double precision :: current(ixi^s,7-2*
ndir:3)
6007 double precision :: tmpvec(ixi^s,1:3),tmpvec2(ixi^s,1:3),tmp(ixi^s),ehyper(ixi^s,1:3)
6008 integer :: ixa^
l,idir,jdir,kdir,idirmin,idirmin1
6011 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
6012 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
6015 tmpvec(ixa^s,1:
ndir)=zero
6017 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
6021 call curlvector(tmpvec,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
6024 tmpvec(ixa^s,1:
ndir)=zero
6025 call curlvector(tmpvec2,ixi^
l,ixa^
l,tmpvec,idirmin1,1,3)
6029 tmpvec2(ixa^s,1:
ndir)=zero
6030 call curlvector(ehyper,ixi^
l,ixa^
l,tmpvec2,idirmin1,1,3)
6033 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
6036 if(total_energy)
then
6039 tmpvec2(ixa^s,1:
ndir)=zero
6040 do idir=1,
ndir;
do jdir=1,
ndir;
do kdir=idirmin,3
6041 tmpvec2(ixa^s,idir) = tmpvec(ixa^s,idir)&
6042 +
lvc(idir,jdir,kdir)*wct(ixa^s,mag(jdir))*ehyper(ixa^s,kdir)
6043 end do;
end do;
end do
6045 call divvector(tmpvec2,ixi^l,ixo^l,tmp)
6046 w(ixo^s,
e_)=w(ixo^s,
e_)+tmp(ixo^s)*qdt
6049 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_hyperres')
6051 end subroutine add_source_hyperres
6053 subroutine add_source_glm(qdt,ixI^L,ixO^L,wCT,w,x)
6060 integer,
intent(in) :: ixi^
l, ixo^
l
6061 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6062 double precision,
intent(inout) :: w(ixi^s,1:nw)
6064 double precision:: divb(ixi^s), gradpsi(ixi^s), ba(ixo^s,1:
ndir)
6085 ba(ixo^s,1:
ndir)=wct(ixo^s,mag(1:
ndir))
6088 if(total_energy)
then
6097 w(ixo^s,
e_) = w(ixo^s,
e_)-qdt*ba(ixo^s,idir)*gradpsi(ixo^s)
6106 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-qdt*ba(ixo^s,idir)*divb(ixo^s)
6110 if (
fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^
l,ixo^
l,
'add_source_glm')
6112 end subroutine add_source_glm
6115 subroutine add_source_powel(qdt,ixI^L,ixO^L,wCT,w,x)
6118 integer,
intent(in) :: ixi^
l, ixo^
l
6119 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6120 double precision,
intent(inout) :: w(ixi^s,1:nw)
6122 double precision :: divb(ixi^s), ba(1:
ndir)
6123 integer :: idir, ix^
d
6129 {
do ix^db=ixomin^db,ixomax^db\}
6134 if (total_energy)
then
6140 {
do ix^db=ixomin^db,ixomax^db\}
6142 ^
c&w(ix^d,
b^
c_)=w(ix^d,
b^
c_)-qdt*wct(ix^d,
m^
c_)*divb(ix^d)\
6144 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)-qdt*wct(ix^d,
b^
c_)*divb(ix^d)\
6145 if (total_energy)
then
6147 w(ix^d,
e_)=w(ix^d,
e_)-qdt*(^
c&wct(ix^d,
m^
c_)*wct(ix^d,
b^
c_)+)*divb(ix^d)
6152 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_powel')
6154 end subroutine add_source_powel
6156 subroutine add_source_janhunen(qdt,ixI^L,ixO^L,wCT,w,x)
6161 integer,
intent(in) :: ixi^
l, ixo^
l
6162 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6163 double precision,
intent(inout) :: w(ixi^s,1:nw)
6165 double precision :: divb(ixi^s)
6166 integer :: idir, ix^
d
6171 {
do ix^db=ixomin^db,ixomax^db\}
6176 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_janhunen')
6178 end subroutine add_source_janhunen
6180 subroutine add_source_linde(qdt,ixI^L,ixO^L,wCT,w,x)
6185 integer,
intent(in) :: ixi^
l, ixo^
l
6186 double precision,
intent(in) :: qdt, wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
6187 double precision,
intent(inout) :: w(ixi^s,1:nw)
6189 double precision :: divb(ixi^s),graddivb(ixi^s)
6190 integer :: idim, idir, ixp^
l, i^
d, iside
6191 logical,
dimension(-1:1^D&) :: leveljump
6199 if(i^
d==0|.and.) cycle
6200 if(neighbor_type(i^
d,
block%igrid)==2 .or. neighbor_type(i^
d,
block%igrid)==4)
then
6201 leveljump(i^
d)=.true.
6203 leveljump(i^
d)=.false.
6212 i^dd=kr(^dd,^d)*(2*iside-3);
6213 if (leveljump(i^dd))
then
6215 ixpmin^d=ixomin^d-i^d
6217 ixpmax^d=ixomax^d-i^d
6228 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
6230 {
do i^db=ixpmin^db,ixpmax^db\}
6232 graddivb(i^d)=graddivb(i^d)*divbdiff/(^d&1.0d0/block%ds({i^d},^d)**2+)
6234 w(i^d,mag(idim))=w(i^d,mag(idim))+graddivb(i^d)
6236 if (typedivbdiff==
'all' .and. total_energy)
then
6238 w(i^d,
e_)=w(i^d,
e_)+wct(i^d,mag(idim))*graddivb(i^d)
6243 if (fix_small_values)
call mhd_handle_small_values(.false.,w,x,ixi^l,ixo^l,
'add_source_linde')
6245 end subroutine add_source_linde
6252 integer,
intent(in) :: ixi^
l, ixo^
l
6253 double precision,
intent(in) :: w(ixi^s,1:nw)
6254 double precision :: divb(ixi^s), dsurface(ixi^s)
6256 double precision :: invb(ixo^s)
6257 integer :: ixa^
l,idims
6259 call get_divb(w,ixi^
l,ixo^
l,divb)
6261 where(invb(ixo^s)/=0.d0)
6262 invb(ixo^s)=1.d0/invb(ixo^s)
6265 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
6267 ixamin^
d=ixomin^
d-1;
6268 ixamax^
d=ixomax^
d-1;
6269 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
6271 ixa^
l=ixo^
l-
kr(idims,^
d);
6272 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
6274 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
6275 block%dvolume(ixo^s)/dsurface(ixo^s)
6286 integer,
intent(in) :: ixo^
l, ixi^
l
6287 double precision,
intent(in) :: w(ixi^s,1:nw)
6288 integer,
intent(out) :: idirmin
6291 double precision :: current(ixi^s,7-2*
ndir:3)
6292 integer :: idir, idirmin0
6298 if(
b0field) current(ixo^s,idirmin0:3)=current(ixo^s,idirmin0:3)+&
6299 block%J0(ixo^s,idirmin0:3)
6303 subroutine mhd_get_dt(wprim,ixI^L,ixO^L,dtnew,dx^D,x)
6312 integer,
intent(in) :: ixi^
l, ixo^
l
6313 double precision,
intent(inout) :: dtnew
6314 double precision,
intent(in) ::
dx^
d
6315 double precision,
intent(in) :: wprim(ixi^s,1:nw)
6316 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6318 double precision :: dxarr(
ndim)
6319 double precision :: current(ixi^s,7-2*
ndir:3),eta(ixi^s)
6320 integer :: idirmin,idim
6338 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
6341 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
6363 dtnew=min(
dtdiffpar*get_ambipolar_dt(wprim,ixi^
l,ixo^
l,
dx^
d,x),dtnew)
6377 call mpistop(
'Radiation formalism unknown')
6381 end subroutine mhd_get_dt
6388 subroutine mhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6394 integer,
intent(in) :: ixi^
l, ixo^
l
6395 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6396 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6398 double precision :: adiabs(ixo^s), gammas(ixo^s)
6399 double precision :: tmp,tmp1,invr,cot
6401 integer :: mr_,mphi_
6402 integer :: br_,bphi_
6405 br_=mag(1); bphi_=mag(1)-1+
phi_
6422 {
do ix^db=ixomin^db,ixomax^db\}
6425 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6430 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6432 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6435 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
6436 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
6437 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6438 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6439 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
6441 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6442 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6443 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6446 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
6451 {
do ix^db=ixomin^db,ixomax^db\}
6453 if(local_timestep)
then
6454 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
6459 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6461 tmp1=adiabs(ix^d)*wprim(ix^d,
rho_)**gammas(ix^d)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6465 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
6468 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6469 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
6473 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
6479 cot=1.d0/tan(x(ix^d,2))
6483 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6484 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
6486 if(.not.stagger_grid)
then
6487 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6489 tmp=tmp+wprim(ix^d,
psi_)*cot
6491 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6496 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6497 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
6498 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
6500 if(.not.stagger_grid)
then
6501 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6503 tmp=tmp+wprim(ix^d,
psi_)*cot
6505 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6508 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
6509 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
6510 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6511 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
6512 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
6514 if(.not.stagger_grid)
then
6515 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
6516 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6517 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6518 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6519 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
6526 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
6529 end subroutine mhd_add_source_geom
6536 subroutine mhd_add_source_geom_semirelati(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6542 integer,
intent(in) :: ixi^
l, ixo^
l
6543 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6544 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6546 double precision :: adiabs(ixo^s), gammas(ixo^s)
6547 double precision :: tmp,tmp1,tmp2,invr,cot,ef(ixo^s,1:
ndir)
6549 integer :: mr_,mphi_
6550 integer :: br_,bphi_
6553 br_=mag(1); bphi_=mag(1)-1+
phi_
6570 {
do ix^db=ixomin^db,ixomax^db\}
6573 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6580 tmp=adiabs(ix^
d)*wprim(ix^
d,
rho_)**gammas(ix^
d)
6584 ef(ix^
d,1)=wprim(ix^
d,b2_)*wprim(ix^
d,m3_)-wprim(ix^
d,b3_)*wprim(ix^
d,m2_)
6585 ef(ix^
d,2)=wprim(ix^
d,b3_)*wprim(ix^
d,m1_)-wprim(ix^
d,b1_)*wprim(ix^
d,m3_)
6586 ef(ix^
d,3)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
6591 ef(ix^
d,2)=wprim(ix^
d,b1_)*wprim(ix^
d,m2_)-wprim(ix^
d,b2_)*wprim(ix^
d,m1_)
6597 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+&
6598 half*((^
c&wprim(ix^
d,
b^
c_)**2+)+(^
c&ef(ix^
d,^
c)**2+)*inv_squared_c) -&
6599 wprim(ix^
d,bphi_)**2+wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)**2)
6600 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6601 -wprim(ix^
d,
rho_)*wprim(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6602 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_)+ef(ix^
d,
phi_)*ef(ix^
d,1)*inv_squared_c)
6604 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6605 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6606 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6609 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp+half*((^
c&wprim(ix^
d,
b^
c_)**2+)+&
6610 (^
c&ef(ix^
d,^
c)**2+)*inv_squared_c))
6615 {
do ix^db=ixomin^db,ixomax^db\}
6617 if(local_timestep)
then
6618 invr=block%dt(ix^d)*dtfactor/x(ix^d,1)
6624 ef(ix^d,1)=wprim(ix^d,b2_)*wprim(ix^d,m3_)-wprim(ix^d,b3_)*wprim(ix^d,m2_)
6625 ef(ix^d,2)=wprim(ix^d,b3_)*wprim(ix^d,m1_)-wprim(ix^d,b1_)*wprim(ix^d,m3_)
6626 ef(ix^d,3)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
6630 ef(ix^d,1)=wprim(ix^d,b1_)*wprim(ix^d,m2_)-wprim(ix^d,b2_)*wprim(ix^d,m1_)
6637 tmp1=wprim(ix^d,
p_)+half*((^
c&wprim(ix^d,
b^
c_)**2+)+(^
c&ef(ix^d,^
c)**2+)*inv_squared_c)
6639 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)
6643 w(ix^d,m1_)=w(ix^d,m1_)+two*tmp1*invr
6646 w(ix^d,m1_)=w(ix^d,m1_)+invr*&
6647 (two*tmp1+(^ce&wprim(ix^d,
rho_)*wprim(ix^d,
m^ce_)**2-&
6648 wprim(ix^d,
b^ce_)**2-ef(ix^d,^ce)**2*inv_squared_c+))
6652 w(ix^d,b1_)=w(ix^d,b1_)+invr*2.0d0*wprim(ix^d,
psi_)
6658 cot=1.d0/tan(x(ix^d,2))
6662 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_)&
6663 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c)
6665 if(.not.stagger_grid)
then
6666 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6668 tmp=tmp+wprim(ix^d,
psi_)*cot
6670 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
6676 w(ix^d,m2_)=w(ix^d,m2_)+invr*(tmp1*cot-wprim(ix^d,
rho_)*wprim(ix^d,m1_)*wprim(ix^d,m2_) &
6677 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+ef(ix^d,1)*ef(ix^d,2)*inv_squared_c&
6678 +(wprim(ix^d,
rho_)*wprim(ix^d,m3_)**2&
6679 -wprim(ix^d,b3_)**2-ef(ix^d,3)**2*inv_squared_c)*cot)
6681 if(.not.stagger_grid)
then
6682 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6684 tmp=tmp+wprim(ix^d,
psi_)*cot
6686 w(ix^d,b2_)=w(ix^d,b2_)+tmp*invr
6689 w(ix^d,m3_)=w(ix^d,m3_)+invr*&
6690 (-wprim(ix^d,m3_)*wprim(ix^d,m1_)*wprim(ix^d,
rho_) &
6691 +wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6692 +ef(ix^d,3)*ef(ix^d,1)*inv_squared_c&
6693 +(-wprim(ix^d,m2_)*wprim(ix^d,m3_)*wprim(ix^d,
rho_) &
6694 +wprim(ix^d,b2_)*wprim(ix^d,b3_)&
6695 +ef(ix^d,2)*ef(ix^d,3)*inv_squared_c)*cot)
6697 if(.not.stagger_grid)
then
6698 w(ix^d,b3_)=w(ix^d,b3_)+invr*&
6699 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6700 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6701 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6702 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
6709 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
6712 end subroutine mhd_add_source_geom_semirelati
6721 subroutine mhd_add_source_geom_split(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
6726 integer,
intent(in) :: ixi^
l, ixo^
l
6727 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
6728 double precision,
intent(inout) :: wct(ixi^s,1:nw),wprim(ixi^s,1:nw),w(ixi^s,1:nw)
6730 double precision :: tmp,tmp1,tmp2,invr,cot
6732 integer :: mr_,mphi_
6733 integer :: br_,bphi_
6736 br_=mag(1); bphi_=mag(1)-1+
phi_
6741 {
do ix^db=ixomin^db,ixomax^db\}
6744 invr=
block%dt(ix^
d) * dtfactor/x(ix^
d,1)
6748 tmp=wprim(ix^
d,
p_)+half*(^
c&wprim(ix^
d,
b^
c_)**2+)
6751 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*(tmp-&
6752 wprim(ix^
d,bphi_)**2+wprim(ix^
d,mphi_)*wct(ix^
d,mphi_))
6756 w(ix^
d,mphi_)=w(ix^
d,mphi_)+invr*(&
6757 -wct(ix^
d,mphi_)*wprim(ix^
d,mr_) &
6758 +wprim(ix^
d,bphi_)*wprim(ix^
d,br_))
6760 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))
6763 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6764 (wprim(ix^
d,bphi_)*wprim(ix^
d,mr_) &
6765 -wprim(ix^
d,br_)*wprim(ix^
d,mphi_))
6767 w(ix^
d,bphi_)=w(ix^
d,bphi_)+invr*&
6773 w(ix^
d,mr_)=w(ix^
d,mr_)+invr*tmp
6778 {
do ix^db=ixomin^db,ixomax^db\}
6780 if(local_timestep)
then
6781 invr=block%dt(ix^d) * dtfactor/x(ix^d,1)
6785 tmp1=wprim(ix^d,
p_)+half*(^
c&wprim(ix^d,
b^
c_)**2+)
6786 if(b0field) tmp2=(^
c&block%B0(ix^d,^
c,0)*wprim(ix^d,
b^
c_)+)
6789 w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp1*invr
6790 if(b0field) w(ix^d,
mom(1))=w(ix^d,
mom(1))+two*tmp2*invr
6794 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6795 (two*(tmp1+tmp2)+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+)- &
6796 (^ce&two*block%B0(ix^d,^ce,0)*wprim(ix^d,
b^ce_)+))
6798 w(ix^d,
mom(1))=w(ix^d,
mom(1))+invr*&
6799 (two*tmp1+(^ce&wprim(ix^d,
m^ce_)*wct(ix^d,
m^ce_)-wprim(ix^d,
b^ce_)**2+))
6804 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wprim(ix^d,
psi_)
6810 cot=1.d0/tan(x(ix^d,2))
6815 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6816 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
6817 +wprim(ix^d,b1_)*block%B0(ix^d,2,0))
6819 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6820 +wprim(ix^d,b1_)*wprim(ix^d,b2_))
6823 if(.not.stagger_grid)
then
6825 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
6826 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
6828 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6831 tmp=tmp+wprim(ix^d,
psi_)*cot
6833 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6839 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*((tmp1+tmp2)*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6840 +wprim(ix^d,b1_)*wprim(ix^d,b2_)+block%B0(ix^d,1,0)*wprim(ix^d,b2_)&
6841 +wprim(ix^d,b1_)*block%B0(ix^d,2,0)&
6842 +(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)
6844 w(ix^d,
mom(2))=w(ix^d,
mom(2))+invr*(tmp1*cot-wprim(ix^d,m1_)*wct(ix^d,m2_)&
6845 +wprim(ix^d,b1_)*wprim(ix^d,b2_)&
6846 +(wprim(ix^d,m3_)*wct(ix^d,m3_)-wprim(ix^d,b3_)**2)*cot)
6849 if(.not.stagger_grid)
then
6851 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)&
6852 +wprim(ix^d,m1_)*block%B0(ix^d,2,0)-wprim(ix^d,m2_)*block%B0(ix^d,1,0)
6854 tmp=wprim(ix^d,m1_)*wprim(ix^d,b2_)-wprim(ix^d,m2_)*wprim(ix^d,b1_)
6857 tmp=tmp+wprim(ix^d,
psi_)*cot
6859 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
6863 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
6864 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
6865 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6866 +block%B0(ix^d,1,0)*wprim(ix^d,b3_) &
6867 +wprim(ix^d,b1_)*block%B0(ix^d,3,0) &
6868 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
6869 -wprim(ix^d,b2_)*wprim(ix^d,b3_) &
6870 +block%B0(ix^d,2,0)*wprim(ix^d,b3_) &
6871 +wprim(ix^d,b2_)*block%B0(ix^d,3,0))*cot)
6873 w(ix^d,
mom(3))=w(ix^d,
mom(3))-invr*&
6874 (wprim(ix^d,m3_)*wct(ix^d,m1_) &
6875 -wprim(ix^d,b3_)*wprim(ix^d,b1_) &
6876 +(wprim(ix^d,m2_)*wct(ix^d,m3_) &
6877 -wprim(ix^d,b2_)*wprim(ix^d,b3_))*cot)
6880 if(.not.stagger_grid)
then
6882 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
6883 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6884 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6885 +wprim(ix^d,m1_)*block%B0(ix^d,3,0) &
6886 -wprim(ix^d,m3_)*block%B0(ix^d,1,0) &
6887 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6888 -wprim(ix^d,m2_)*wprim(ix^d,b3_) &
6889 +wprim(ix^d,m3_)*block%B0(ix^d,2,0) &
6890 -wprim(ix^d,m2_)*block%B0(ix^d,3,0))*cot)
6892 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
6893 (wprim(ix^d,m1_)*wprim(ix^d,b3_) &
6894 -wprim(ix^d,m3_)*wprim(ix^d,b1_) &
6895 -(wprim(ix^d,m3_)*wprim(ix^d,b2_) &
6896 -wprim(ix^d,m2_)*wprim(ix^d,b3_))*cot)
6904 call rotating_frame_add_source(qdt,dtfactor,ixi^l,ixo^l,wprim,w,x)
6907 end subroutine mhd_add_source_geom_split
6912 integer,
intent(in) :: ixi^
l, ixo^
l
6913 double precision,
intent(in) :: w(ixi^s, nw)
6914 double precision :: mge(ixo^s)
6917 mge = sum((w(ixo^s, mag(:))+
block%B0(ixo^s,:,
b0i))**2, dim=
ndim+1)
6919 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
6923 subroutine mhd_getv_hall(w,x,ixI^L,ixO^L,vHall,partial)
6927 integer,
intent(in) :: ixi^
l, ixo^
l
6928 double precision,
intent(in) :: w(ixi^s,nw)
6929 double precision,
intent(in) :: x(ixi^s,1:
ndim)
6930 double precision,
intent(inout) :: vhall(ixi^s,1:
ndir)
6931 logical,
intent(in),
optional :: partial
6933 double precision :: current(ixi^s,7-2*
ndir:3)
6934 double precision :: rho(ixi^s)
6935 integer :: idir, idirmin, ix^
d
6936 logical :: use_partial
6939 if(
present(partial)) use_partial=partial
6941 if(.not.use_partial)
then
6952 do idir = idirmin,
ndir
6953 {
do ix^db=ixomin^db,ixomax^db\}
6954 vhall(ix^
d,idir)=-
mhd_etah*current(ix^
d,idir)/rho(ix^
d)
6958 end subroutine mhd_getv_hall
6960 subroutine mhd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
6963 integer,
intent(in) :: ixi^
l, ixo^
l, idir
6964 double precision,
intent(in) :: qt
6965 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
6966 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
6969 double precision :: db(ixo^s), dpsi(ixo^s)
6973 {
do ix^db=ixomin^db,ixomax^db\}
6974 wlc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6975 wrc(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6976 wlp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6977 wrp(ix^
d,mag(idir))=s%ws(ix^
d,idir)
6986 {
do ix^db=ixomin^db,ixomax^db\}
6987 db(ix^d)=wrp(ix^d,mag(idir))-wlp(ix^d,mag(idir))
6988 dpsi(ix^d)=wrp(ix^d,
psi_)-wlp(ix^d,
psi_)
6989 wlp(ix^d,mag(idir))=half*(wrp(ix^d,mag(idir))+wlp(ix^d,mag(idir))-dpsi(ix^d)/cmax_global)
6990 wlp(ix^d,
psi_)=half*(wrp(ix^d,
psi_)+wlp(ix^d,
psi_)-db(ix^d)*cmax_global)
6991 wrp(ix^d,mag(idir))=wlp(ix^d,mag(idir))
6993 if(total_energy)
then
6994 wrc(ix^d,
e_)=wrc(ix^d,
e_)-half*wrc(ix^d,mag(idir))**2
6995 wlc(ix^d,
e_)=wlc(ix^d,
e_)-half*wlc(ix^d,mag(idir))**2
6997 wrc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
6999 wlc(ix^d,mag(idir))=wlp(ix^d,mag(idir))
7002 if(total_energy)
then
7003 wrc(ix^d,
e_)=wrc(ix^d,
e_)+half*wrc(ix^d,mag(idir))**2
7004 wlc(ix^d,
e_)=wlc(ix^d,
e_)+half*wlc(ix^d,mag(idir))**2
7009 if(
associated(usr_set_wlr))
call usr_set_wlr(ixi^l,ixo^l,qt,wlc,wrc,wlp,wrp,s,idir)
7011 end subroutine mhd_modify_wlr
7013 subroutine mhd_boundary_adjust(igrid,psb)
7015 integer,
intent(in) :: igrid
7018 integer :: ib, idims, iside, ixo^
l, i^
d
7027 i^
d=
kr(^
d,idims)*(2*iside-3);
7028 if (neighbor_type(i^
d,igrid)/=1) cycle
7029 ib=(idims-1)*2+iside
7047 call fixdivb_boundary(ixg^
ll,ixo^
l,psb(igrid)%w,psb(igrid)%x,ib)
7052 end subroutine mhd_boundary_adjust
7054 subroutine fixdivb_boundary(ixG^L,ixO^L,w,x,iB)
7057 integer,
intent(in) :: ixg^
l,ixo^
l,ib
7058 double precision,
intent(inout) :: w(ixg^s,1:nw)
7059 double precision,
intent(in) :: x(ixg^s,1:
ndim)
7061 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
7062 integer :: ix^
d,ixf^
l
7075 do ix1=ixfmax1,ixfmin1,-1
7076 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
7077 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7078 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7081 do ix1=ixfmax1,ixfmin1,-1
7082 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
7083 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
7084 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7085 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7086 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7087 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7088 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7102 do ix1=ixfmax1,ixfmin1,-1
7103 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7104 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7105 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7106 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7107 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7108 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7111 do ix1=ixfmax1,ixfmin1,-1
7112 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7113 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7114 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7115 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7116 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7117 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7118 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7119 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7120 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7121 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7122 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7123 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7124 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7125 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7126 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7127 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7128 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7129 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7143 do ix1=ixfmin1,ixfmax1
7144 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
7145 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
7146 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
7149 do ix1=ixfmin1,ixfmax1
7150 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
7151 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
7152 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
7153 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
7154 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
7155 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
7156 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
7170 do ix1=ixfmin1,ixfmax1
7171 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7172 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
7173 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
7174 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
7175 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
7176 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
7179 do ix1=ixfmin1,ixfmax1
7180 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
7181 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
7182 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
7183 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
7184 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
7185 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
7186 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
7187 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
7188 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
7189 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
7190 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
7191 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
7192 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
7193 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
7194 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7195 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
7196 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
7197 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
7211 do ix2=ixfmax2,ixfmin2,-1
7212 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
7213 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7214 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7217 do ix2=ixfmax2,ixfmin2,-1
7218 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
7219 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
7220 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7221 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7222 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7223 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7224 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7238 do ix2=ixfmax2,ixfmin2,-1
7239 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7240 ix2+1,ixfmin3:ixfmax3,mag(2)) &
7241 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7242 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7243 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7244 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7247 do ix2=ixfmax2,ixfmin2,-1
7248 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
7249 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
7250 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7251 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
7252 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7253 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7254 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7255 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7256 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7257 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7258 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7259 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7260 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7261 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7262 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7263 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7264 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
7265 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7279 do ix2=ixfmin2,ixfmax2
7280 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
7281 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
7282 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
7285 do ix2=ixfmin2,ixfmax2
7286 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
7287 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
7288 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
7289 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
7290 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
7291 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
7292 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
7306 do ix2=ixfmin2,ixfmax2
7307 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
7308 ix2-1,ixfmin3:ixfmax3,mag(2)) &
7309 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
7310 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
7311 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
7312 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
7315 do ix2=ixfmin2,ixfmax2
7316 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
7317 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
7318 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
7319 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
7320 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
7321 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7322 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
7323 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
7324 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
7325 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
7326 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
7327 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
7328 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
7329 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
7330 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
7331 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
7332 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
7333 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
7350 do ix3=ixfmax3,ixfmin3,-1
7351 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
7352 ixfmin2:ixfmax2,ix3+1,mag(3)) &
7353 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
7354 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
7355 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
7356 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
7359 do ix3=ixfmax3,ixfmin3,-1
7360 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
7361 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
7362 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
7363 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
7364 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
7365 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7366 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
7367 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
7368 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7369 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
7370 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
7371 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
7372 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
7373 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
7374 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
7375 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
7376 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
7377 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
7392 do ix3=ixfmin3,ixfmax3
7393 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
7394 ixfmin2:ixfmax2,ix3-1,mag(3)) &
7395 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
7396 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
7397 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
7398 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
7401 do ix3=ixfmin3,ixfmax3
7402 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
7403 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
7404 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
7405 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
7406 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
7407 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7408 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
7409 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
7410 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
7411 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
7412 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
7413 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
7414 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
7415 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
7416 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
7417 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
7418 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
7419 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
7425 call mpistop(
"Special boundary is not defined for this region")
7428 end subroutine fixdivb_boundary
7437 double precision,
intent(in) :: qdt
7438 double precision,
intent(in) :: qt
7439 logical,
intent(inout) :: active
7442 integer,
parameter :: max_its = 50
7443 double precision :: residual_it(max_its), max_divb
7444 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
7445 double precision :: res
7446 double precision,
parameter :: max_residual = 1
d-3
7447 double precision,
parameter :: residual_reduction = 1
d-10
7448 integer :: iigrid, igrid
7449 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
7452 mg%operator_type = mg_laplacian
7460 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7461 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7464 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
7465 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7467 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7468 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7471 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7472 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7476 write(*,*)
"mhd_clean_divb_multigrid warning: unknown boundary type"
7477 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
7478 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
7486 do iigrid = 1, igridstail
7487 igrid = igrids(iigrid);
7490 lvl =
mg%boxes(id)%lvl
7491 nc =
mg%box_size_lvl(lvl)
7497 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
7499 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
7500 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
7505 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
7508 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
7509 if (
mype == 0) print *,
"iteration vs residual"
7512 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
7513 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
7514 if (residual_it(n) < residual_reduction * max_divb)
exit
7516 if (
mype == 0 .and. n > max_its)
then
7517 print *,
"divb_multigrid warning: not fully converged"
7518 print *,
"current amplitude of divb: ", residual_it(max_its)
7519 print *,
"multigrid smallest grid: ", &
7520 mg%domain_size_lvl(:,
mg%lowest_lvl)
7521 print *,
"note: smallest grid ideally has <= 8 cells"
7522 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
7523 print *,
"note: dx/dy/dz should be similar"
7527 call mg_fas_vcycle(
mg, max_res=res)
7528 if (res < max_residual)
exit
7530 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
7535 do iigrid = 1, igridstail
7536 igrid = igrids(iigrid);
7545 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
7549 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
7551 call gradientf(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim))
7553 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
7566 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
7567 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
7570 if(total_energy)
then
7572 tmp(
ixm^t) = 0.5_dp * (sum(ps(igrid)%w(
ixm^t, &
7575 ps(igrid)%w(
ixm^t,
e_) = ps(igrid)%w(
ixm^t,
e_) + tmp(
ixm^t)
7585 subroutine mhd_update_faces_average(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
7589 integer,
intent(in) :: ixi^
l, ixo^
l
7590 double precision,
intent(in) :: qt,qdt
7592 double precision,
intent(in) :: wp(ixi^s,1:nw)
7593 type(state) :: sct, s
7594 type(ct_velocity) :: vcts
7595 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
7596 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
7598 double precision :: circ(ixi^s,1:
ndim)
7600 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
7601 integer :: ix^
d,ixc^
l,ixa^
l,i1kr^
d,i2kr^
d
7602 integer :: idim1,idim2,idir,iwdim1,iwdim2
7604 associate(bfaces=>s%ws,x=>s%x)
7611 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
7618 i1kr^
d=
kr(idim1,^
d);
7621 i2kr^
d=
kr(idim2,^
d);
7624 if (
lvc(idim1,idim2,idir)==1)
then
7626 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
7628 {
do ix^db=ixcmin^db,ixcmax^db\}
7629 fe(ix^
d,idir)=quarter*&
7630 (fc(ix^
d,iwdim1,idim2)+fc({ix^
d+i1kr^
d},iwdim1,idim2)&
7631 -fc(ix^
d,iwdim2,idim1)-fc({ix^
d+i2kr^
d},iwdim2,idim1))
7633 if(
mhd_eta/=zero) fe(ix^
d,idir)=fe(ix^
d,idir)+e_resi(ix^
d,idir)
7638 fe(ix^
d,idir)=fe(ix^
d,idir)*qdt*s%dsC(ix^
d,idir)
7646 if(
associated(usr_set_electric_field)) &
7647 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
7649 circ(ixi^s,1:ndim)=zero
7654 ixcmin^d=ixomin^d-kr(idim1,^d);
7656 ixa^l=ixc^l-kr(idim2,^d);
7659 if(lvc(idim1,idim2,idir)==1)
then
7661 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7664 else if(lvc(idim1,idim2,idir)==-1)
then
7666 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7672 {
do ix^db=ixcmin^db,ixcmax^db\}
7674 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
7676 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
7683 end subroutine mhd_update_faces_average
7686 subroutine mhd_update_faces_contact(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
7691 integer,
intent(in) :: ixi^
l, ixo^
l
7692 double precision,
intent(in) :: qt, qdt
7694 double precision,
intent(in) :: wp(ixi^s,1:nw)
7695 type(state) :: sct, s
7696 type(ct_velocity) :: vcts
7697 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
7698 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
7700 double precision :: circ(ixi^s,1:
ndim)
7702 double precision :: ecc(ixi^s,
sdim:3)
7703 double precision :: ein(ixi^s,
sdim:3)
7705 double precision :: el(ixi^s),er(ixi^s)
7707 double precision :: elc,erc
7709 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
7711 double precision :: jce(ixi^s,
sdim:3)
7713 double precision :: xs(ixgs^t,1:
ndim)
7714 double precision :: gradi(ixgs^t)
7715 integer :: ixc^
l,ixa^
l
7716 integer :: idim1,idim2,idir,iwdim1,iwdim2,ix^
d,i1kr^
d,i2kr^
d
7718 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm,wcts=>sct%ws)
7721 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
7727 {
do ix^db=iximin^db,iximax^db\}
7730 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_)
7731 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_)
7732 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_)
7735 ecc(ix^
d,3)=wp(ix^
d,b1_)*wp(ix^
d,m2_)-wp(ix^
d,b2_)*wp(ix^
d,m1_)
7742 {
do ix^db=iximin^db,iximax^db\}
7745 ecc(ix^d,1)=wp(ix^d,b2_)*wp(ix^d,m3_)-wp(ix^d,b3_)*wp(ix^d,m2_)
7746 ecc(ix^d,2)=wp(ix^d,b3_)*wp(ix^d,m1_)-wp(ix^d,b1_)*wp(ix^d,m3_)
7747 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
7750 ecc(ix^d,3)=wp(ix^d,b1_)*wp(ix^d,m2_)-wp(ix^d,b2_)*wp(ix^d,m1_)
7764 i1kr^d=kr(idim1,^d);
7767 i2kr^d=kr(idim2,^d);
7770 if (lvc(idim1,idim2,idir)==1)
then
7772 ixcmin^d=ixomin^d+kr(idir,^d)-1;
7775 {
do ix^db=ixcmin^db,ixcmax^db\}
7776 fe(ix^d,idir)=quarter*&
7777 (fc(ix^d,iwdim1,idim2)+fc({ix^d+i1kr^d},iwdim1,idim2)&
7778 -fc(ix^d,iwdim2,idim1)-fc({ix^d+i2kr^d},iwdim2,idim1))
7783 ixamax^d=ixcmax^d+i1kr^d;
7784 {
do ix^db=ixamin^db,ixamax^db\}
7785 el(ix^d)=fc(ix^d,iwdim1,idim2)-ecc(ix^d,idir)
7786 er(ix^d)=fc(ix^d,iwdim1,idim2)-ecc({ix^d+i2kr^d},idir)
7789 do ix^db=ixcmin^db,ixcmax^db\}
7790 if(vnorm(ix^d,idim1)>0.d0)
then
7792 else if(vnorm(ix^d,idim1)<0.d0)
then
7793 elc=el({ix^d+i1kr^d})
7795 elc=0.5d0*(el(ix^d)+el({ix^d+i1kr^d}))
7797 if(vnorm({ix^d+i2kr^d},idim1)>0.d0)
then
7799 else if(vnorm({ix^d+i2kr^d},idim1)<0.d0)
then
7800 erc=er({ix^d+i1kr^d})
7802 erc=0.5d0*(er(ix^d)+er({ix^d+i1kr^d}))
7804 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
7809 ixamax^d=ixcmax^d+i2kr^d;
7810 {
do ix^db=ixamin^db,ixamax^db\}
7811 el(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc(ix^d,idir)
7812 er(ix^d)=-fc(ix^d,iwdim2,idim1)-ecc({ix^d+i1kr^d},idir)
7815 do ix^db=ixcmin^db,ixcmax^db\}
7816 if(vnorm(ix^d,idim2)>0.d0)
then
7818 else if(vnorm(ix^d,idim2)<0.d0)
then
7819 elc=el({ix^d+i2kr^d})
7821 elc=0.5d0*(el(ix^d)+el({ix^d+i2kr^d}))
7823 if(vnorm({ix^d+i1kr^d},idim2)>0.d0)
then
7825 else if(vnorm({ix^d+i1kr^d},idim2)<0.d0)
then
7826 erc=er({ix^d+i2kr^d})
7828 erc=0.5d0*(er(ix^d)+er({ix^d+i2kr^d}))
7830 fe(ix^d,idir)=fe(ix^d,idir)+0.25d0*(elc+erc)
7834 if(
mhd_eta/=zero) fe(ix^d,idir)=fe(ix^d,idir)+e_resi(ix^d,idir)
7839 fe(ix^d,idir)=fe(ix^d,idir)*qdt*s%dsC(ix^d,idir)
7853 if (lvc(idim1,idim2,idir)==0) cycle
7855 ixcmin^d=ixomin^d+kr(idir,^d)-1;
7856 ixamax^d=ixcmax^d-kr(idir,^d)+1;
7859 xs(ixa^s,:)=x(ixa^s,:)
7860 xs(ixa^s,idim2)=x(ixa^s,idim2)+half*s%dx(ixa^s,idim2)
7861 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^ll,ixc^l,idim1,gradi)
7862 if (lvc(idim1,idim2,idir)==1)
then
7863 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
7865 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
7872 ixcmin^d=ixomin^d+kr(idir,^d)-1;
7874 ein(ixc^s,idir)=ein(ixc^s,idir)*jce(ixc^s,idir)
7878 {
do ix^db=ixomin^db,ixomax^db\}
7879 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1,ix2-1,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
7880 +ein(ix1,ix2-1,ix3-1,idir))
7881 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7882 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7884 else if(idir==2)
then
7885 {
do ix^db=ixomin^db,ixomax^db\}
7886 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2,ix3-1,idir)&
7887 +ein(ix1-1,ix2,ix3-1,idir))
7888 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7889 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7892 {
do ix^db=ixomin^db,ixomax^db\}
7893 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,ix3,idir)+ein(ix1,ix2-1,ix3,idir)&
7894 +ein(ix1-1,ix2-1,ix3,idir))
7895 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7896 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7902 {
do ix^db=ixomin^db,ixomax^db\}
7903 jce(ix^d,idir)=0.25d0*(ein(ix^d,idir)+ein(ix1-1,ix2,idir)+ein(ix1,ix2-1,idir)&
7904 +ein(ix1-1,ix2-1,idir))
7905 if(jce(ix^d,idir)<0.d0) jce(ix^d,idir)=0.d0
7906 w(ix^d,
e_)=w(ix^d,
e_)+qdt*jce(ix^d,idir)
7911 block%w(ixo^s,nw)=block%w(ixo^s,nw)+jce(ixo^s,idir)
7917 if(
associated(usr_set_electric_field)) &
7918 call usr_set_electric_field(ixi^l,ixo^l,qt,qdt,fe,sct)
7920 circ(ixi^s,1:ndim)=zero
7925 ixcmin^d=ixomin^d-kr(idim1,^d);
7927 ixa^l=ixc^l-kr(idim2,^d);
7930 if(lvc(idim1,idim2,idir)==1)
then
7932 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7935 else if(lvc(idim1,idim2,idir)==-1)
then
7937 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
7943 {
do ix^db=ixcmin^db,ixcmax^db\}
7945 if(s%surfaceC(ix^d,idim1) > smalldouble)
then
7947 bfaces(ix^d,idim1)=bfaces(ix^d,idim1)-circ(ix^d,idim1)/s%surfaceC(ix^d,idim1)
7954 end subroutine mhd_update_faces_contact
7957 subroutine mhd_update_faces_hll(ixI^L,ixO^L,qt,qdt,wp,fC,fE,sCT,s,vcts)
7962 integer,
intent(in) :: ixi^
l, ixo^
l
7963 double precision,
intent(in) :: qt, qdt
7965 double precision,
intent(in) :: wp(ixi^s,1:nw)
7966 type(state) :: sct, s
7967 type(ct_velocity) :: vcts
7968 double precision,
intent(in) :: fc(ixi^s,1:nwflux,1:
ndim)
7969 double precision,
intent(inout) :: fe(ixi^s,
sdim:3)
7971 double precision :: vtill(ixi^s,2)
7972 double precision :: vtilr(ixi^s,2)
7973 double precision :: bfacetot(ixi^s,
ndim)
7974 double precision :: btill(ixi^s,
ndim)
7975 double precision :: btilr(ixi^s,
ndim)
7976 double precision :: cp(ixi^s,2)
7977 double precision :: cm(ixi^s,2)
7978 double precision :: circ(ixi^s,1:
ndim)
7980 double precision,
dimension(ixI^S,sdim:3) :: e_resi, e_ambi
7981 integer :: hxc^
l,ixc^
l,ixcp^
l,jxc^
l,ixcm^
l
7982 integer :: idim1,idim2,idir,ix^
d
7984 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
7985 cbarmax=>vcts%cbarmax)
7998 if(
mhd_eta/=zero)
call get_resistive_electric_field(ixi^
l,ixo^
l,wp,sct,s,e_resi)
8014 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
8018 idim2=mod(idir+1,3)+1
8020 jxc^
l=ixc^
l+
kr(idim1,^
d);
8021 ixcp^
l=ixc^
l+
kr(idim2,^
d);
8025 vtill(ixi^s,2),vtilr(ixi^s,2))
8028 vtill(ixi^s,1),vtilr(ixi^s,1))
8034 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)+
block%B0(ixi^s,idim1,idim1)
8035 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)+
block%B0(ixi^s,idim2,idim2)
8037 bfacetot(ixi^s,idim1)=bfacesct(ixi^s,idim1)
8038 bfacetot(ixi^s,idim2)=bfacesct(ixi^s,idim2)
8041 btill(ixi^s,idim1),btilr(ixi^s,idim1))
8044 btill(ixi^s,idim2),btilr(ixi^s,idim2))
8048 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
8049 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
8051 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
8052 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
8056 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
8057 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
8058 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
8059 /(cp(ixc^s,1)+cm(ixc^s,1)) &
8060 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
8061 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
8062 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
8063 /(cp(ixc^s,2)+cm(ixc^s,2))
8066 if(
mhd_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+e_resi(ixc^s,idir)
8070 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
8084 circ(ixi^s,1:
ndim)=zero
8089 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
8093 if(
lvc(idim1,idim2,idir)/=0)
then
8094 hxc^
l=ixc^
l-
kr(idim2,^
d);
8096 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
8097 +
lvc(idim1,idim2,idir)&
8103 {
do ix^db=ixcmin^db,ixcmax^db\}
8105 if(s%surfaceC(ix^
d,idim1) > smalldouble)
then
8107 bfaces(ix^
d,idim1)=bfaces(ix^
d,idim1)-circ(ix^
d,idim1)/s%surfaceC(ix^
d,idim1)
8113 end subroutine mhd_update_faces_hll
8116 subroutine get_resistive_electric_field(ixI^L,ixO^L,wp,sCT,s,jce)
8121 integer,
intent(in) :: ixi^
l, ixo^
l
8123 double precision,
intent(in) :: wp(ixi^s,1:nw)
8124 type(state),
intent(in) :: sct, s
8126 double precision :: jce(ixi^s,
sdim:3)
8129 double precision :: jcc(ixi^s,7-2*
ndir:3)
8131 double precision :: xs(ixgs^t,1:
ndim)
8133 double precision :: eta(ixi^s)
8134 double precision :: gradi(ixgs^t)
8135 integer :: ix^
d,ixc^
l,ixa^
l,ixb^
l,idir,idirmin,idim1,idim2
8137 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
8143 if (
lvc(idim1,idim2,idir)==0) cycle
8145 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8146 ixbmax^
d=ixcmax^
d-
kr(idir,^
d)+1;
8149 xs(ixb^s,:)=x(ixb^s,:)
8150 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
8151 call gradientf(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^
l,idim1,gradi,2)
8152 if (
lvc(idim1,idim2,idir)==1)
then
8153 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
8155 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
8162 jce(ixi^s,:)=jce(ixi^s,:)*
mhd_eta
8170 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8171 jcc(ixc^s,idir)=0.d0
8173 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8174 ixamin^
d=ixcmin^
d+ix^
d;
8175 ixamax^
d=ixcmax^
d+ix^
d;
8176 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
8178 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
8179 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
8184 end subroutine get_resistive_electric_field
8187 subroutine get_ambipolar_electric_field(ixI^L,ixO^L,w,x,fE)
8190 integer,
intent(in) :: ixi^
l, ixo^
l
8191 double precision,
intent(in) :: w(ixi^s,1:nw)
8192 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8193 double precision,
intent(out) :: fe(ixi^s,
sdim:3)
8195 double precision :: jxbxb(ixi^s,1:3)
8196 integer :: idir,ixa^
l,ixc^
l,ix^
d
8199 call mhd_get_jxbxb(w,x,ixi^
l,ixa^
l,jxbxb)
8206 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
8209 if({ ix^
d==1 .and. ^
d==idir | .or.}) cycle
8210 ixamin^
d=ixcmin^
d+ix^
d;
8211 ixamax^
d=ixcmax^
d+ix^
d;
8212 fe(ixc^s,idir)=fe(ixc^s,idir)+jxbxb(ixa^s,idir)
8214 fe(ixc^s,idir)=fe(ixc^s,idir)*0.25d0
8217 end subroutine get_ambipolar_electric_field
8223 integer,
intent(in) :: ixo^
l
8233 do ix^db=ixomin^db,ixomax^db\}
8235 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8236 +s%ws(ix1-1,ix2,ix3,1)*s%surfaceC(ix1-1,ix2,ix3,1))
8237 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8238 +s%ws(ix1,ix2-1,ix3,2)*s%surfaceC(ix1,ix2-1,ix3,2))
8239 s%w(ix^
d,b3_)=half/s%surface(ix^
d,3)*(s%ws(ix^
d,3)*s%surfaceC(ix^
d,3)&
8240 +s%ws(ix1,ix2,ix3-1,3)*s%surfaceC(ix1,ix2,ix3-1,3))
8243 s%w(ix^
d,b1_)=half/s%surface(ix^
d,1)*(s%ws(ix^
d,1)*s%surfaceC(ix^
d,1)&
8244 +s%ws(ix1-1,ix2,1)*s%surfaceC(ix1-1,ix2,1))
8245 s%w(ix^
d,b2_)=half/s%surface(ix^
d,2)*(s%ws(ix^
d,2)*s%surfaceC(ix^
d,2)&
8246 +s%ws(ix1,ix2-1,2)*s%surfaceC(ix1,ix2-1,2))
8289 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
8290 double precision,
intent(inout) :: ws(ixis^s,1:nws)
8291 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8293 double precision :: adummy(ixis^s,1:3)
8299 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
8302 integer,
intent(in) :: ixi^
l, ixo^
l
8303 double precision,
intent(in) :: w(ixi^s,1:nw)
8304 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8305 double precision,
intent(out):: rfactor(ixi^s)
8307 double precision :: iz_h(ixo^s),iz_he(ixo^s)
8311 rfactor(ixo^s)=(1.d0+iz_h(ixo^s)+0.1d0*(1.d0+iz_he(ixo^s)*(1.d0+iz_he(ixo^s))))/(2.d0+3.d0*
he_abundance)
8313 end subroutine rfactor_from_temperature_ionization
8315 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
8317 integer,
intent(in) :: ixi^
l, ixo^
l
8318 double precision,
intent(in) :: w(ixi^s,1:nw)
8319 double precision,
intent(in) :: x(ixi^s,1:
ndim)
8320 double precision,
intent(out):: rfactor(ixi^s)
8324 end subroutine rfactor_from_constant_ionization
Module for including anisotropic flux limited diffusion (AFLD)-approximation in Radiation-hydrodynami...
subroutine afld_get_diffcoef_central(w, wct, wctprim, x, ixil, ixol, primitives_filled)
Calculates cell-centered diffusion coefficient to be used in multigrid.
subroutine, public add_afld_rad_force(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 This subroutine handles th...
subroutine, public afld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
get dt limit for radiation force: NOTE: only uniform cartesian here!
subroutine, public afld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor.
subroutine, public afld_init(he_abundance, afld_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine, public get_afld_energy_interact(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 This subroutine handles th...
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine cak_init(phys_gamma)
Initialize the module.
subroutine cak_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine cak_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter bigdouble
A very large real number.
double precision, parameter const_rad_a
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)
Module for flux conservation near refinement boundaries.
subroutine, public store_flux(igrid, fc, idimlim, nwfluxin)
subroutine, public store_edge(igrid, ixil, fe, idimlim)
Nicolas Moens with updates by RK (16/03/2026) Module for including flux limited diffusion (FLD)-appro...
subroutine, public fld_get_radpress(w, x, ixil, ixol, rad_pressure, nth)
Calculate Radiation Pressure Returns Radiation Pressure as tensor NOTE: w is primitive on entry.
subroutine, public fld_get_diffcoef_central(w, wct, wctprim, x, ixil, ixol, primitives_filled)
Calculates cell-centered diffusion coefficient to be used in multigrid.
subroutine, public add_fld_rad_force(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 This subroutine handles th...
subroutine, public fld_init(he_abundance, r_gamma)
Initialising FLD-module: Read opacities Initialise Multigrid adimensionalise kappa Add extra variable...
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x)
get dt limit for radiation force: NOTE: only uniform cartesian here!
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 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.
integer, parameter bc_noinflow
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 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.
double precision, dimension(:), allocatable, parameter d
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.
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 unit_velocity
Physical scaling factor for velocity.
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
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 ionization degree - get ionization degree for given temperature
subroutine ionization_degree_from_temperature(ixil, ixol, te, iz_h, iz_he)
subroutine ionization_degree_init()
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.
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.
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)
logical, public, protected mhd_hyperbolic_thermal_conduction
Whether thermal conduction is used.
character(len=8), public mhd_radiation_fld_formalism
Formalism to treat radiation: either fld or afld (anisotropic fld)
double precision, public, protected small_r_e
The smallest allowed radiation energy (when fld active)
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.
logical, public, protected mhd_radiation_use_csrad
Whether mixed gas-radiation sound speed is used for cbounds in FLD.
logical, public, protected mhd_partial_ionization
Whether plasma is partially ionized.
double precision, public mhd_eta_hyper
The MHD hyper-resistivity.
double precision, public, protected rr
double precision, public, protected h_ion_fr
Ionization fraction of H H_ion_fr = H+/(H+ + H)
double precision, public mhd_gamma
The adiabatic index.
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 q_
Index of the heat flux q.
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 CAK radiation line force is activated.
logical, public, protected source_split_divb
Whether divB cleaning sources are added splitting from fluid solver.
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.
double precision, public hypertc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
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 mhd_set_mg_bounds
Set the boundaries for the diffusion of E.
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.
procedure(sub_get_pthermal), pointer, public mhd_get_rfactor
double precision, public, protected mhd_reduced_c
Reduced speed of light for semirelativistic MHD: 2% of light speed.
logical, public, protected mhd_energy
Whether an energy equation is used.
logical, public, protected mhd_ambipolar_exp
Whether Ambipolar term is implemented explicitly.
logical, public, protected mhd_htc_sat
Whether saturation is considered for hyperbolic TC.
logical, public, protected mhd_glm
Whether GLM-MHD is used to control div B.
logical, public clean_initial_divb
clean initial divB
procedure(sub_convert), pointer, public mhd_to_conserved
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.
subroutine, public mhd_get_temperature_from_etot(w, x, ixil, ixol, res)
Calculate temperature=p/rho from total energy.
logical, public, protected mhd_thermal_conduction
Whether thermal conduction is used.
procedure(sub_get_pthermal), pointer, public mhd_get_temperature
integer, public equi_pe0_
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.
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
procedure(sub_convert), pointer, public mhd_to_primitive
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.
subroutine, public mhd_get_pradiation_from_prim(w, x, ixil, ixol, prad, nth)
Calculate radiation pressure within ixO^L.
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_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.
logical, public, protected eq_state_units
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.
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.
procedure(sub_get_pthermal), pointer, public mhd_get_pthermal
subroutine, public mhd_ei_to_e(ixil, ixol, w, x)
Transform internal energy to total energy.
integer, public, protected e_
Index of the energy density (-1 if not present)
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
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)
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method which can be used for multiple source terms in the governing equatio...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
double precision function, public get_tc_dt_mhd(w, ixil, ixol, dxd, x, fl)
Get the explicit timestep for the TC (mhd implementation) Note: for multi-D MHD (1D MHD will use HD f...
double precision function, public get_tc_dt_hd(w, ixil, ixol, dxd, x, fl)
Get the explicit timestep for the TC (hd implementation) Note: also used in 1D MHD (or for neutrals i...
subroutine tc_init_params(phys_gamma)
subroutine, public sts_set_source_tc_hd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
subroutine, public sts_set_source_tc_mhd(ixil, ixol, w, x, wres, fix_conserve_at_step, my_dt, igrid, nflux, fl)
anisotropic thermal conduction with slope limited symmetric scheme Sharma 2007 Journal of Computation...
subroutine, public tc_get_mhd_params(fl, read_mhd_params)
Init TC coefficients: MHD case.
subroutine get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_adiab), pointer usr_set_adiab
procedure(set_adiab), pointer usr_set_gamma
procedure(phys_gravity), pointer usr_gravity
procedure(set_equi_vars), pointer usr_set_equi_vars
procedure(special_mg_bc), pointer usr_special_mg_bc
procedure(set_electric_field), pointer usr_set_electric_field
The module add viscous source terms and check time step.
subroutine viscosity_init(phys_wider_stencil)
Initialize the module.
subroutine viscosity_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
procedure(sub_add_source), pointer, public viscosity_add_source
The data structure that contains information about a tree node/grid block.