35 logical,
public,
protected ::
hd_dust = .false.
67 integer,
public,
protected ::
rho_
70 integer,
allocatable,
public,
protected ::
mom(:)
73 integer,
public,
protected :: ^
c&m^C_
76 integer,
allocatable,
public,
protected ::
tracer(:)
79 integer,
public,
protected ::
e_
82 integer,
public,
protected ::
p_
85 integer,
public,
protected ::
ne_
88 integer,
public,
protected ::
r_e
91 integer,
public,
protected ::
te_
94 integer,
public,
protected ::
fip_ = -1
97 logical,
public,
protected ::
hd_fip = .false.
103 integer,
public,
protected ::
q_
179 logical,
public,
protected ::
hd_trac = .false.
195 double precision,
public,
protected ::
h_ion_fr=1d0
205 double precision,
public,
protected ::
rr=1d0
236 subroutine hd_read_params(files)
238 character(len=*),
intent(in) :: files(:)
254 do n = 1,
size(files)
255 open(
unitpar, file=trim(files(n)), status=
"old")
256 read(
unitpar, hd_list,
end=111)
260 end subroutine hd_read_params
263 subroutine hd_write_info(fh)
265 integer,
intent(in) :: fh
266 integer,
parameter :: n_par = 1
267 double precision :: values(n_par)
268 character(len=name_len) :: names(n_par)
269 integer,
dimension(MPI_STATUS_SIZE) :: st
272 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
275 values(1) = eos%gamma
276 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
277 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
278 end subroutine hd_write_info
304 phys_internal_e = .false.
305 phys_gamma = eos%gamma
312 if(
mype==0)
write(*,*)
'WARNING: set hd_trac_type=1'
316 call mpistop(
"hd_trac_type=7 requires usr_get_heating to be set in mod_usr.t")
327 call mpistop(
"hd_trac_type=7 requires usr_get_heating to be set in mod_usr.t")
332 if(
mype==0)
write(*,*)
'WARNING: hd_trac disabled for ndim>=2 (only trac_type=7 supported)'
341 if(
mype==0)
write(*,*)
'WARNING: set hd_thermal_conduction=F when hd_energy=F'
345 if(
mype==0)
write(*,*)
'WARNING: set hd_hyperbolic_thermal_conduction=F when hd_energy=F'
349 if(
mype==0)
write(*,*)
'WARNING: set hd_radiative_cooling=F when hd_energy=F'
354 allocate(start_indices(number_species),stop_indices(number_species))
362 mom(:) = var_set_momentum(
ndir)
367 e_ = var_set_energy()
393 fip_ = var_set_fluxvar(
'rho_fip',
'fip', need_bc=.false.)
402 tracer(itr) = var_set_fluxvar(
"trc",
"trp", itr, need_bc=.false.)
405 if (eos%eos_type ==
'LTE')
then
408 else if (eos%eos_type ==
'PI')
then
419 if(.not.
hd_energy)
call mpistop(
"radiative transfer needs hd_energy=T")
420 call rt_sc_activate()
426 write(*,*)
'Warning: CAK force addition together with FLD radiation'
431 write(*,*)
'Warning: Optically thin cooling together with FLD radiation'
435 call mpistop(
'implicit dust addition not compatible with FLD radiation')
438 call mpistop(
'using FLD implies the use of an energy equation, set hd_energy=T')
441 r_e = var_set_radiation_energy()
446 call fld_init(eos%eos_type, eos%ionE, eos%pi_table)
450 phys_implicit_update => hd_fld_implicit_update
451 phys_evaluate_implicit => hd_fld_evaluate_implicit
458 phys_get_dt => hd_get_dt
459 phys_get_cmax => hd_get_cmax
460 phys_get_tcutoff => hd_get_tcutoff
461 phys_get_cbounds => hd_get_cbounds
462 phys_get_flux => hd_get_flux
463 phys_add_source_geom => hd_add_source_geom
464 phys_add_source => hd_add_source
465 phys_modify_wlr => hd_modify_wlr
469 phys_get_v => hd_get_v
471 phys_write_info => hd_write_info
475 phys_get_ei => hd_get_ei
478 call hd_physical_units()
508 if (iw_ne > 0) nwgc = max(nwgc, iw_ne)
509 if (iw_te > 0) nwgc = max(nwgc, iw_te)
512 stop_indices(1)=nwflux
523 iw_log_nh = var_set_wextra()
531 call mpistop(
"thermal conduction needs hd_energy=T")
539 if (iw_log_nh > 0)
then
569 call mpistop(
"radiative cooling needs hd_energy=T")
577 if (
rc_fl%rad_escape_prob)
then
587 phys_te_images => hd_te_images
599 if(
mype==0)
write(*,*)
'WARNING: set hd_well_balanced=F (requires hd_gravity=T)'
601 phys_wb_transform => hd_wb_transform
602 phys_wb_inverse => hd_wb_inverse
603 phys_wb_prolong => hd_wb_prolong
606 if (eos%ionE .and. eos%p2eint_method /=
'bisect')
then
607 eos%p2eint_method =
'bisect'
608 if(
mype==0)
write(*,*)
'WB + ionE: forcing p2eint_method = bisect'
610 if(
mype==0)
write(*,*)
'Well-balanced reconstruction enabled'
622 if (.not.
allocated(flux_type))
then
623 allocate(flux_type(
ndir, nw))
624 flux_type = flux_default
625 else if (any(shape(flux_type) /= [
ndir, nw]))
then
626 call mpistop(
"phys_check error: flux_type has wrong shape")
630 allocate(iw_vector(nvector))
631 iw_vector(1) =
mom(1) - 1
639 subroutine hd_modify_wlr(ixI^L,ixO^L,qt,wLC,wRC,wLp,wRp,s,idir)
642 integer,
intent(in) :: ixi^
l, ixo^
l, idir
643 double precision,
intent(in) :: qt
644 double precision,
intent(inout) :: wlc(ixi^s,1:nw), wrc(ixi^s,1:nw)
645 double precision,
intent(inout) :: wlp(ixi^s,1:nw), wrp(ixi^s,1:nw)
650 end subroutine hd_modify_wlr
653 subroutine hd_te_images
657 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
659 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
661 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
663 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
666 call mpistop(
"Error in synthesize emission: Unknown convert_type")
668 end subroutine hd_te_images
673 subroutine hd_sts_set_source_tc_hd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
677 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
678 double precision,
intent(in) :: x(ixi^s,1:
ndim)
679 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
680 double precision,
intent(in) :: my_dt
681 logical,
intent(in) :: fix_conserve_at_step
683 end subroutine hd_sts_set_source_tc_hd
685 function hd_get_tc_dt_hd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
691 integer,
intent(in) :: ixi^
l, ixo^
l
692 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
693 double precision,
intent(in) :: w(ixi^s,1:nw)
694 double precision :: dtnew
697 end function hd_get_tc_dt_hd
699 subroutine hd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
704 integer,
intent(in) :: ixi^
l,ixo^
l
705 double precision,
intent(inout) :: w(ixi^s,1:nw)
706 double precision,
intent(in) :: x(ixi^s,1:
ndim)
707 integer,
intent(in) :: step
710 logical :: flag(ixi^s,1:nw)
711 character(len=140) :: error_msg
715 if(any(flag(ixo^s,
e_)))
then
723 w(ixo^s,
e_)=w(ixo^s,
e_)*(eos%gamma - 1.0d0)
725 w(ixo^s, iw_mom(idir)) = w(ixo^s, iw_mom(idir))/w(ixo^s,
rho_)
727 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
731 end subroutine hd_tc_handle_small_e
734 subroutine tc_params_read_hd(fl)
736 type(tc_fluid),
intent(inout) :: fl
738 logical :: tc_saturate=.false.
739 logical :: tc_patch_eint=.false.
740 logical :: tc_frozen_ion=.true.
741 double precision :: tc_k_para=0d0
742 double precision :: trac_t_floor=0.d0
744 namelist /tc_list/ tc_saturate, tc_k_para, trac_t_floor, tc_patch_eint, tc_frozen_ion
748 read(
unitpar, tc_list,
end=111)
751 fl%tc_saturate = tc_saturate
752 fl%tc_patch_eint = tc_patch_eint
753 fl%frozen_ion = tc_frozen_ion
754 fl%tc_k_para = tc_k_para
755 fl%trac_T_floor = trac_t_floor / unit_temperature
757 end subroutine tc_params_read_hd
771 subroutine rc_params_read(fl)
775 type(rc_fluid),
intent(inout) :: fl
778 integer :: ncool = 4000
781 character(len=std_len) :: coolcurve=
'JCcorona'
784 logical :: tfix=.false.
790 logical :: rc_split=.false.
793 double precision :: cfrac=0.1d0
796 logical :: rad_modify=.false.
798 logical :: rad_modify_sym=.false.
800 double precision :: rad_cut_hgt=0.0d0
802 double precision :: rad_cut_dey=0.15d0
804 double precision :: rad_taper_rho=
bigdouble
806 double precision :: rad_taper_dey=0.0d0
809 double precision :: rad_suppress_temp=0.0d0
811 logical :: rad_escape_prob=.false.
813 double precision :: rad_kappa_eff=0.0d0
815 double precision :: rad_kappa_tcutoff=0.0d0
817 double precision :: rad_kappa_alpha=4.0d0
819 character(len=10) :: rad_escape_type=
'slab'
821 double precision :: rad_escape_tau_cutoff=0.0d0
823 double precision :: rad_escape_height=0.0d0
825 character(len=8) :: rc_y_mod_quadrature=
'boole'
826 integer :: rc_y_mod_n_sub=16
828 logical :: rad_damp=.false.
829 double precision :: rad_damp_height=0.5d0
830 double precision :: rad_damp_scale=0.15d0
832 logical :: rad_newton=.false.
833 double precision :: rad_newton_trad=0.006d0
834 double precision :: rad_newton_rhosurf=1.d4
835 double precision :: rad_newton_pthick=25.d0
837 namelist /rc_list/ coolcurve, ncool, cfrac, tlow, tfix, rc_split, &
838 rad_modify, rad_modify_sym, rad_suppress_temp, &
839 rad_cut_hgt, rad_cut_dey, rad_taper_rho, rad_taper_dey, &
840 rad_escape_prob, rad_kappa_eff, rad_kappa_tcutoff, rad_kappa_alpha, &
841 rad_escape_type, rad_escape_tau_cutoff, rad_escape_height, &
842 rc_y_mod_quadrature, rc_y_mod_n_sub, &
843 rad_damp, rad_damp_height, rad_damp_scale, &
844 rad_newton, rad_newton_trad, rad_newton_rhosurf, rad_newton_pthick
848 read(
unitpar, rc_list,
end=111)
853 fl%coolcurve=coolcurve
858 fl%rad_modify=rad_modify
859 fl%rad_modify_sym=rad_modify_sym
860 fl%rad_suppress_temp=rad_suppress_temp
861 fl%rad_cut_hgt=rad_cut_hgt
862 fl%rad_cut_dey=rad_cut_dey
863 fl%rad_taper_rho=rad_taper_rho
864 fl%rad_taper_dey=rad_taper_dey
865 fl%rad_escape_prob=rad_escape_prob
866 fl%rad_kappa_eff=rad_kappa_eff
867 fl%rad_kappa_Tcutoff=rad_kappa_tcutoff/unit_temperature
868 fl%rad_kappa_alpha=rad_kappa_alpha
869 fl%rad_escape_type=rad_escape_type
870 fl%rad_escape_tau_cutoff=rad_escape_tau_cutoff
871 fl%rad_escape_height=rad_escape_height/unit_length
872 fl%Y_mod_quadrature=rc_y_mod_quadrature
873 fl%Y_mod_N_sub=rc_y_mod_n_sub
874 fl%rad_damp = rad_damp
875 fl%rad_damp_height = rad_damp_height
876 fl%rad_damp_scale = rad_damp_scale
877 fl%rad_newton = rad_newton
878 fl%rad_newton_trad = rad_newton_trad
879 fl%rad_newton_rhosurf = rad_newton_rhosurf
880 fl%rad_newton_pthick = rad_newton_pthick
881 end subroutine rc_params_read
889 use mod_particles,
only: npayload,nusrpayload,ngridvars,num_particles,physics_type_particles
892 double precision :: a,b,xfrac,yfrac
902 if (eos%gamma <= 0.0d0)
call mpistop (
"Error: eos%gamma <= 0")
903 if (
hd_adiab < 0.0d0)
call mpistop (
"Error: hd_adiab < 0")
906 if (eos%gamma <= 0.0d0 .or. eos%gamma == 1.0d0) &
907 call mpistop (
"Error: eos%gamma <= 0 or eos%gamma == 1.0")
919 call mpistop(
'select IMEX scheme for implicit dust update')
931 call mpistop(
"hd_hyperbolic_thermal_conduction is implemented for ndim=1 only;" // &
932 " for ndim>1 use mod_ffhd or parabolic mod_thermal_conduction.")
935 call mpistop(
"hd_hyperbolic_thermal_conduction and hd_thermal_conduction are mutually exclusive;" // &
936 " choose one TC implementation.")
941 call mpistop(
'select IMEX scheme for FLD radiation use')
944 call phys_set_mg_bounds()
946 if(.not.
fld_no_mg)
call mpistop(
'multigrid must have BCs for IMEX and FLD radiation use')
949 write(*,*)
'==FLD SETUP======================'
950 write(*,*)
'Using FLD with settings:'
954 write(*,*)
'Using FLD with settings: fld_bound_diff=',
fld_bound_diff
957 write(*,*)
'Using FLD with settings: fld_kappa0=',
fld_kappa0
958 write(*,*)
'Using FLD with settings: fld_opal_table=',
fld_opal_table
960 write(*,*)
'Using FLD with settings: fld_bisect_tol=',
fld_bisect_tol
961 write(*,*)
'Using FLD with settings: fld_diff_tol=',
fld_diff_tol
964 write(*,*)
' FLD has fld_no_mg=',
fld_no_mg
966 print *,
'WARNING: cheating with FLD diffusion ***********************'
967 print *,
'WARNING: No MG-diffusion for radiative energy at all!!!!!!!'
968 print *,
'WARNING: cheating with FLD diffusion ***********************'
971 print *,
'NORMALIZED arad_norm=',
arad_norm
972 print *,
'NORMALIZED c_norm=',
c_norm
974 print *,
'WARNING: cheating with c_norm ***********************'
975 print *,
'WARNING: c_norm reset to=',
fld_cnorm
977 print *,
'WARNING: cheating with c_norm ***********************'
985 print *,
'physical fld_kappa (in cgs or SI) =',
fld_kappa0
988 write(*,*)
'===FLD SETUP====================='
992 write(*,*)
'====HD run with settings===================='
993 write(*,*)
'Using mod_hd_phys with settings:'
995 write(*,*)
'Dimensionality :',
ndim
996 write(*,*)
'vector components:',
ndir
998 write(*,*)
'number of variables nw=',nw
999 write(*,*)
' start index iwstart=',iwstart
1000 write(*,*)
'number of vector variables=',nvector
1001 write(*,*)
'number of stagger variables nws=',nws
1002 write(*,*)
'number of variables with BCs=',nwgc
1003 write(*,*)
'number of vars with fluxes=',nwflux
1004 write(*,*)
'number of vars with flux + BC=',nwfluxbc
1005 write(*,*)
'number of auxiliary variables=',nwaux
1006 write(*,*)
'number of extra vars without flux=',nwextra
1007 write(*,*)
'number of extra vars for wextra=',nw_extra
1008 write(*,*)
'number of auxiliary I/O variables=',
nwauxio
1023 write(*,*)
'*****Using particles: npayload,ngridvars :', npayload,ngridvars
1024 write(*,*)
'*****Using particles: nusrpayload :', nusrpayload
1025 write(*,*)
'*****Using particles: num_particles :', num_particles
1026 write(*,*)
'*****Using particles: physics_type_particles=',physics_type_particles
1029 write(*,*)
'number due to phys_wider_stencil=',phys_wider_stencil
1030 write(*,*)
'==========================================='
1031 print *,
'========EOS and UNITS==========='
1033 print *,
'gamma=',eos%gamma
1034 print *,
'He_abundance =',eos%He_abundance
1036 print *,
'========EOS and UNITS==========='
1052 print *,
' compare this to ',mp_si*(1.d0+4.d0*eos%He_abundance)
1054 print *,
' compare this to ',mp_cgs*(1.d0+4.d0*eos%He_abundance)
1058 print *,
' compare this to ',kb_si*(2.d0+3.d0*eos%He_abundance)
1062 print *,
' compare this to ',kb_cgs*(2.d0+3.d0*eos%He_abundance)
1066 if(eos%eos_type /=
'LTE')
then
1067 print *,
'mean molecular weight mu is =',a/b,
' = ', (1.d0+4.d0*eos%He_abundance)/(2.d0+3.d0*eos%He_abundance)
1069 yfrac=4.d0*eos%He_abundance/(1.d0+4.d0*eos%He_abundance)
1070 print *,
'mass fraction hydrogen X is =',1/a,
' and this equals ', 1.d0/(1.d0+4.d0*eos%He_abundance)
1071 print *,
'mass fraction helium Y is =',yfrac
1072 print *,
' check that 1/mu', b/a,
' is equal to 2X+3Y/4=',2.d0*xfrac+3.d0*yfrac/4.d0
1073 print *,
' ratio n_e/n_p=',1.d0+2.0d0*eos%He_abundance
1075 print *,
'========UNITS==========='
1080 subroutine hd_physical_units
1082 double precision :: mp,kb,c_lightspeed,xfrac,sigma_telectron
1083 double precision :: a,b
1090 sigma_telectron=sigma_te_si
1095 c_lightspeed=const_c
1096 sigma_telectron=sigma_te_cgs
1101 if (eos%eos_type ==
'LTE')
then
1105 eos%nH2rhoFactor = 1d0+4d0*eos%He_abundance
1106 rr=(2d0+3d0*eos%He_abundance) / (1d0+4d0*eos%He_abundance)
1107 xfrac=1.d0/(1.d0+4.d0*eos%He_abundance)
1111 a=1d0+4d0*eos%He_abundance
1112 if(eos%eos_type==
'PI')
then
1115 b=2d0+3d0*eos%He_abundance
1201 end subroutine hd_physical_units
1208 logical,
intent(in) :: primitive
1209 integer,
intent(in) :: ixi^
l, ixo^
l
1210 double precision,
intent(in) :: w(ixi^s, nw)
1211 logical,
intent(inout) :: flag(ixi^s,1:nw)
1213 double precision :: tmp(ixi^s)
1214 double precision :: x(ixi^s, 1:
ndim)
1225 tmp(ixo^s)=(eos%gamma-1.0d0)*(w(ixo^s,
e_)-&
1226 half*(^
c&w(ixo^s,
m^
c_)**2+)/w(ixo^s,
rho_))
1240 subroutine hd_bound_fip(primitive, ixI^L, ixO^L, w)
1242 logical,
intent(in) :: primitive
1243 integer,
intent(in) :: ixi^
l, ixo^
l
1244 double precision,
intent(inout) :: w(ixi^s,1:nw)
1246 double precision :: rho_safe(ixi^s), fip_prim(ixi^s)
1254 fip_prim(ixo^s) = w(ixo^s,
fip_) / rho_safe(ixo^s)
1255 fip_prim(ixo^s) = min(
maxfip, max(
minfip, fip_prim(ixo^s)))
1256 w(ixo^s,
fip_) = rho_safe(ixo^s) * fip_prim(ixo^s)
1258 end subroutine hd_bound_fip
1323 integer,
intent(in) :: ixi^
l, ixo^
l
1324 double precision,
intent(inout) :: w(ixi^s, nw)
1325 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1328 w(ixo^s,
e_)=w(ixo^s,
e_)+half*(^
c&w(ixo^s,
m^
c_)**2+)/w(ixo^s,
rho_)
1335 integer,
intent(in) :: ixi^
l, ixo^
l
1336 double precision,
intent(inout) :: w(ixi^s, nw)
1337 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1340 w(ixo^s,
e_)=w(ixo^s,
e_)-half*(^
c&w(ixo^s,
m^
c_)**2+)/w(ixo^s,
rho_)
1347 subroutine hd_e_to_ei_and_cache_log_nh(ixI^L,ixO^L,w,x)
1349 integer,
intent(in) :: ixi^
l, ixo^
l
1350 double precision,
intent(inout) :: w(ixi^s, nw)
1351 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1354 block%wextra(ixo^s, iw_log_nh) = dlog10(w(ixo^s,
rho_) / eos%nH2rhoFactor)
1355 end subroutine hd_e_to_ei_and_cache_log_nh
1358 function hd_get_ei(w, ixI^L, ixO^L)
result(ei)
1360 integer,
intent(in) :: ixi^
l, ixo^
l
1361 double precision,
intent(in) :: w(ixi^s, nw)
1362 double precision :: ei(ixo^s)
1365 ei(ixo^s) = w(ixo^s,
e_) - half*(^
c&w(ixo^s,
m^
c_)**2+)/w(ixo^s,
rho_)
1366 end function hd_get_ei
1369 subroutine hd_get_v_idim(w, x, ixI^L, ixO^L, idim, v)
1371 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1372 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s, 1:
ndim)
1373 double precision,
intent(out) :: v(ixi^s)
1375 v(ixo^s) = w(ixo^s,
mom(idim)) / w(ixo^s,
rho_)
1376 end subroutine hd_get_v_idim
1379 subroutine hd_get_v(w,x,ixI^L,ixO^L,v)
1382 integer,
intent(in) :: ixi^
l, ixo^
l
1383 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:^nd)
1384 double precision,
intent(out) :: v(ixi^s,1:
ndir)
1389 v(ixo^s,idir) = w(ixo^s,
mom(idir)) / w(ixo^s,
rho_)
1392 end subroutine hd_get_v
1395 subroutine hd_get_cmax(w, x, ixI^L, ixO^L, idim, cmax)
1400 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1402 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s, 1:
ndim)
1403 double precision,
intent(inout) :: cmax(ixi^s)
1404 double precision :: csound2(ixi^s)
1407 call eos%get_csound2(w, x, ixi^
l, ixo^
l, csound2)
1408 cmax(ixo^s)=dabs(w(ixo^s,
mom(idim)))+dsqrt(csound2(ixo^s))
1415 cmax(ixo^s)=dabs(w(ixo^s,
mom(idim)))+dsqrt(eos%gamma*cmax(ixo^s)/w(ixo^s,
rho_))
1421 end subroutine hd_get_cmax
1424 subroutine hd_get_tcutoff(ixI^L,ixO^L,w,x,tco_local,Tmax_local)
1430 integer,
intent(in) :: ixi^
l,ixo^
l
1431 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1433 double precision,
intent(inout) :: w(ixi^s,1:nw)
1434 double precision,
intent(out) :: tco_local, tmax_local
1436 double precision,
parameter :: trac_delta=0.25d0
1437 double precision :: tmp1(ixi^s),te(ixi^s),lts(ixi^s), r(ixi^s)
1438 double precision :: ltrc,ltrp
1439 integer :: jxo^
l,hxo^
l
1440 integer :: jxp^
l,hxp^
l,ixp^
l
1441 logical :: lrlt(ixi^s)
1443 double precision :: dtdx, l_t, a_coeff, l1, cooling, net_cool
1444 double precision :: kappa_par, disc, kappa_trac, kappa_eff, tcoff_eff
1445 double precision :: dx_over_delta, v_abs, v_n, gnorm, dl_eff
1446 double precision :: q_heat(ixi^s), ne(ixi^s), nh_arr(ixi^s)
1447 double precision :: gradtd(ixi^s,1:
ndim), nhat(1:
ndim)
1448 integer :: ix^
d, idims
1450 call eos%get_Rfactor(w,x,ixi^
l,ixi^
l,r)
1451 te(ixi^s)=w(ixi^s,
p_)/(r(ixi^s)*w(ixi^s,
rho_))
1453 if (eos%eos_type ==
'LTE')
then
1454 te(ixi^s) = w(ixi^s,
te_)
1458 tmax_local=maxval(te(ixo^s))
1468 lts(ixo^s)=0.5d0*dabs(te(jxo^s)-te(hxo^s))/te(ixo^s)
1470 where(lts(ixo^s) > trac_delta)
1473 if(any(lrlt(ixo^s)))
then
1474 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
1485 lts(ixp^s)=0.5d0*abs(te(jxp^s)-te(hxp^s))/te(ixp^s)
1486 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
1488 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
1489 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
1494 block%wextra(ixomin1-1,
tcoff_)=te(ixomin1-1)*lts(ixomin1-1)**0.4d0
1495 block%wextra(ixomax1+1,
tcoff_)=te(ixomax1+1)*lts(ixomax1+1)**0.4d0
1510 call eos%get_ne_nH(ixi^
l, ixp^
l, w, x, ne, nh_arr)
1516 do ix1=ixpmin1,ixpmax1
1518 dtdx = abs(te(ix1+1) - te(ix1-1)) / (2.d0 *
dxlevel(1))
1520 if(dtdx < smalldouble .or. te(ix1) <
tc_fl%trac_T_floor)
then
1524 l_t = te(ix1) / dtdx
1528 v_abs = abs(w(ix1,m1_))
1529 a_coeff = 2.5d0 * w(ix1,
p_) * v_abs / te(ix1)
1533 if(te(ix1) >
rc_fl%tcoolmin .and. te(ix1) <
rc_fl%tcoolmax)
then
1534 call findl(te(ix1), l1,
rc_fl); cooling = ne(ix1) * nh_arr(ix1) * l1
1535 else if(te(ix1) >=
rc_fl%tcoolmax)
then
1542 net_cool = abs(cooling - q_heat(ix1))
1545 kappa_par =
tc_fl%tc_k_para * te(ix1)**2.5d0
1548 disc = a_coeff**2 + 4.d0 *
tc_fl%tc_k_para * te(ix1)**1.5d0 * net_cool
1550 if(l_t <= 2.d0 * dx_over_delta)
then
1552 kappa_trac = (a_coeff + dsqrt(disc)) / (2.d0 / dx_over_delta)
1555 kappa_trac = dsqrt(4.d0 *
tc_fl%tc_k_para * te(ix1)**1.5d0 * net_cool) &
1556 / (2.d0 / dx_over_delta)
1560 kappa_eff = max(kappa_trac, kappa_par)
1563 tcoff_eff = (kappa_eff /
tc_fl%tc_k_para)**0.4d0
1566 block%wextra(ix1,
tcoff_) = max(te(ix1), tcoff_eff)
1574 call eos%get_ne_nH(ixi^
l, ixo^
l, w, x, ne, nh_arr)
1578 call gradient(te,ixi^
l,ixo^
l,idims,gradtd(ixi^s,idims))
1580 {
do ix^db=ixomin^db,ixomax^db\}
1581 gnorm = dsqrt(^
d&gradtd({ix^
d},^
d)**2+ )
1582 if(gnorm < smalldouble .or. te(ix^
d) <
tc_fl%trac_T_floor)
then
1586 ^
d&nhat(^
d)=gradtd({ix^
d},^
d)/gnorm\
1588 dl_eff = 1.d0/dsqrt(^
d&(nhat(^
d)/
block%ds({ix^
d},^
d))**2+ )
1589 l_t = te(ix^
d)/gnorm
1591 v_n = ^
d&w({ix^
d},
mom(^
d))*nhat(^
d)+
1592 a_coeff = 2.5d0*w(ix^
d,
p_)*dabs(v_n)/te(ix^
d)
1596 if(te(ix^
d) >
rc_fl%tcoolmin .and. te(ix^
d) <
rc_fl%tcoolmax)
then
1597 call findl(te(ix^
d),l1,
rc_fl); cooling = l1*ne(ix^
d)*nh_arr(ix^
d)
1598 else if(te(ix^
d) >=
rc_fl%tcoolmax)
then
1603 net_cool = dabs(cooling-q_heat(ix^
d))
1604 kappa_par =
tc_fl%tc_k_para*te(ix^
d)**2.5d0
1605 disc = a_coeff**2 + 4.d0*
tc_fl%tc_k_para*te(ix^
d)**1.5d0*net_cool
1607 if(l_t <= 2.d0*dx_over_delta)
then
1608 kappa_trac = (a_coeff+dsqrt(disc))/(2.d0/dx_over_delta)
1610 kappa_trac = dsqrt(4.d0*
tc_fl%tc_k_para*te(ix^
d)**1.5d0*net_cool)/(2.d0/dx_over_delta)
1612 kappa_eff = max(kappa_trac,kappa_par)
1613 tcoff_eff = (kappa_eff/
tc_fl%tc_k_para)**0.4d0
1619 call mpistop(
"hd_trac_type not allowed")
1621 end subroutine hd_get_tcutoff
1624 subroutine hd_get_cbounds(wLC, wRC, wLp, wRp, x, ixI^L, ixO^L, idim,Hspeed,cmax, cmin)
1630 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1632 double precision,
intent(in) :: wlc(ixi^s,
nw), wrc(ixi^s,
nw)
1634 double precision,
intent(in) :: wlp(ixi^s,
nw), wrp(ixi^s,
nw)
1635 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1637 double precision,
intent(inout),
optional :: cmin(ixi^s,1:
number_species)
1640 double precision :: wmean(ixi^s,
nw)
1641 double precision,
dimension(ixI^S) :: umean, dmean, csoundl, csoundr, tmp1,tmp2,tmp3
1649 tmp1(ixo^s)=dsqrt(wlp(ixo^s,
rho_))
1650 tmp2(ixo^s)=dsqrt(wrp(ixo^s,
rho_))
1651 tmp3(ixo^s)=1.d0/(tmp1(ixo^s)+tmp2(ixo^s))
1652 umean(ixo^s)=(wlp(ixo^s,
mom(idim))*tmp1(ixo^s)+wrp(ixo^s,
mom(idim))*tmp2(ixo^s))*tmp3(ixo^s)
1655 call eos%get_csound2(wlp, x, ixi^
l, ixo^
l, csoundl)
1656 call eos%get_csound2(wrp, x, ixi^
l, ixo^
l, csoundr)
1658 csoundl(ixo^s)=csoundl(ixo^s)+(4.0d0/9.0d0)*wlp(ixo^s,
r_e)/wlp(ixo^s,
rho_)
1659 csoundr(ixo^s)=csoundr(ixo^s)+(4.0d0/9.0d0)*wrp(ixo^s,
r_e)/wrp(ixo^s,
rho_)
1667 dmean(ixo^s) = (tmp1(ixo^s)*csoundl(ixo^s)+tmp2(ixo^s)*csoundr(ixo^s)) * &
1668 tmp3(ixo^s) + 0.5d0*tmp1(ixo^s)*tmp2(ixo^s)*tmp3(ixo^s)**2 * &
1669 (wrp(ixo^s,
mom(idim))-wlp(ixo^s,
mom(idim)))**2
1671 dmean(ixo^s)=dsqrt(dmean(ixo^s))
1672 if(
present(cmin))
then
1673 cmin(ixo^s,1)=umean(ixo^s)-dmean(ixo^s)
1674 cmax(ixo^s,1)=umean(ixo^s)+dmean(ixo^s)
1676 {
do ix^db=ixomin^db,ixomax^db\}
1677 cmin(ix^
d,1)=sign(one,cmin(ix^
d,1))*max(abs(cmin(ix^
d,1)),hspeed(ix^
d,1))
1678 cmax(ix^
d,1)=sign(one,cmax(ix^
d,1))*max(abs(cmax(ix^
d,1)),hspeed(ix^
d,1))
1682 cmax(ixo^s,1)=dabs(umean(ixo^s))+dmean(ixo^s)
1686 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1687 call dust_get_cmax(wmean, x, ixi^l, ixo^l, idim, cmax, cmin)
1698 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1699 tmp1(ixo^s)=wmean(ixo^s,
mom(idim))/wmean(ixo^s,
rho_)
1701 if(
hd_radiation_fld.and.fld_bound_diff)csoundr(ixo^s)=csoundr(ixo^s)+(4.0d0/9.0d0)*wmean(ixo^s,
r_e)/wmean(ixo^s,
rho_)
1703 csoundr(ixo^s) = dsqrt(csoundr(ixo^s))
1705 if(
present(cmin))
then
1706 cmax(ixo^s,1)=max(tmp1(ixo^s)+csoundr(ixo^s),zero)
1707 cmin(ixo^s,1)=min(tmp1(ixo^s)-csoundr(ixo^s),zero)
1708 if(h_correction)
then
1709 {
do ix^db=ixomin^db,ixomax^db\}
1710 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1711 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1715 cmax(ixo^s,1)=dabs(tmp1(ixo^s))+csoundr(ixo^s)
1719 call dust_get_cmax(wmean, x, ixi^l, ixo^l, idim, cmax, cmin)
1724 call eos%get_csound2(wlp, x, ixi^l, ixo^l, csoundl)
1725 call eos%get_csound2(wrp, x, ixi^l, ixo^l, csoundr)
1727 csoundl(ixo^s)=csoundl(ixo^s)+(4.0d0/9.0d0)*wlp(ixo^s,
r_e)/wlp(ixo^s,
rho_)
1728 csoundr(ixo^s)=csoundr(ixo^s)+(4.0d0/9.0d0)*wrp(ixo^s,
r_e)/wrp(ixo^s,
rho_)
1735 csoundl(ixo^s)=max(dsqrt(csoundl(ixo^s)),dsqrt(csoundr(ixo^s)))
1736 if(
present(cmin))
then
1737 cmin(ixo^s,1)=min(wlp(ixo^s,
mom(idim)),wrp(ixo^s,
mom(idim)))-csoundl(ixo^s)
1738 cmax(ixo^s,1)=max(wlp(ixo^s,
mom(idim)),wrp(ixo^s,
mom(idim)))+csoundl(ixo^s)
1739 if(h_correction)
then
1740 {
do ix^db=ixomin^db,ixomax^db\}
1741 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1742 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1746 cmax(ixo^s,1)=max(wlp(ixo^s,
mom(idim)),wrp(ixo^s,
mom(idim)))+csoundl(ixo^s)
1749 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1750 call dust_get_cmax(wmean, x, ixi^l, ixo^l, idim, cmax, cmin)
1759 call eos%get_csound2(wlp, x, ixi^l, ixo^l, csoundl)
1760 call eos%get_csound2(wrp, x, ixi^l, ixo^l, csoundr)
1762 csoundl(ixo^s)=csoundl(ixo^s)+(4.0d0/9.0d0)*wlp(ixo^s,
r_e)/wlp(ixo^s,
rho_)
1763 csoundr(ixo^s)=csoundr(ixo^s)+(4.0d0/9.0d0)*wrp(ixo^s,
r_e)/wrp(ixo^s,
rho_)
1769 csoundl(ixo^s) = dsqrt(csoundl(ixo^s))
1770 csoundr(ixo^s) = dsqrt(csoundr(ixo^s))
1771 if(
present(cmin))
then
1772 {
do ix^db=ixomin^db,ixomax^db\}
1775 tmp1(ix^d) = 0.25d0*(wlp(ix^d,
rho_)+wrp(ix^d,
rho_)) &
1776 *(csoundl(ix^d)+csoundr(ix^d))
1778 tmp2(ix^d) = max(zero, 0.5d0*(wlp(ix^d,
e_)+wrp(ix^d,
e_)) &
1779 + 0.5d0*(wlp(ix^d,
mom(idim))-wrp(ix^d,
mom(idim))) &
1782 if(tmp2(ix^d) > wlp(ix^d,
e_) .and. wlp(ix^d,
e_) > zero)
then
1784 tmp3(ix^d) = csoundl(ix^d)**2*wlp(ix^d,
rho_)/wlp(ix^d,
e_)
1785 dmean(ix^d) = dsqrt(1.0d0 + (tmp3(ix^d)+1.0d0) &
1786 /(2.0d0*tmp3(ix^d)) &
1787 *(tmp2(ix^d)/wlp(ix^d,
e_) - 1.0d0))
1792 cmin(ix^d,1) = wlp(ix^d,
mom(idim)) - csoundl(ix^d)*dmean(ix^d)
1794 if(tmp2(ix^d) > wrp(ix^d,
e_) .and. wrp(ix^d,
e_) > zero)
then
1796 tmp3(ix^d) = csoundr(ix^d)**2*wrp(ix^d,
rho_)/wrp(ix^d,
e_)
1797 dmean(ix^d) = dsqrt(1.0d0 + (tmp3(ix^d)+1.0d0) &
1798 /(2.0d0*tmp3(ix^d)) &
1799 *(tmp2(ix^d)/wrp(ix^d,
e_) - 1.0d0))
1804 cmax(ix^d,1) = wrp(ix^d,
mom(idim)) + csoundr(ix^d)*dmean(ix^d)
1806 if(h_correction)
then
1807 {
do ix^db=ixomin^db,ixomax^db\}
1808 cmin(ix^d,1)=sign(one,cmin(ix^d,1))*max(abs(cmin(ix^d,1)),hspeed(ix^d,1))
1809 cmax(ix^d,1)=sign(one,cmax(ix^d,1))*max(abs(cmax(ix^d,1)),hspeed(ix^d,1))
1813 {
do ix^db=ixomin^db,ixomax^db\}
1814 tmp1(ix^d) = 0.25d0*(wlp(ix^d,
rho_)+wrp(ix^d,
rho_)) &
1815 *(csoundl(ix^d)+csoundr(ix^d))
1816 tmp2(ix^d) = max(zero, 0.5d0*(wlp(ix^d,
e_)+wrp(ix^d,
e_)) &
1817 + 0.5d0*(wlp(ix^d,
mom(idim))-wrp(ix^d,
mom(idim))) &
1819 if(tmp2(ix^d) > wlp(ix^d,
e_) .and. wlp(ix^d,
e_) > zero)
then
1820 tmp3(ix^d) = csoundl(ix^d)**2*wlp(ix^d,
rho_)/wlp(ix^d,
e_)
1821 dmean(ix^d) = dsqrt(1.0d0 + (tmp3(ix^d)+1.0d0) &
1822 /(2.0d0*tmp3(ix^d)) &
1823 *(tmp2(ix^d)/wlp(ix^d,
e_) - 1.0d0))
1827 umean(ix^d) = dabs(wlp(ix^d,
mom(idim)) &
1828 - csoundl(ix^d)*dmean(ix^d))
1829 if(tmp2(ix^d) > wrp(ix^d,
e_) .and. wrp(ix^d,
e_) > zero)
then
1830 tmp3(ix^d) = csoundr(ix^d)**2*wrp(ix^d,
rho_)/wrp(ix^d,
e_)
1831 dmean(ix^d) = dsqrt(1.0d0 + (tmp3(ix^d)+1.0d0) &
1832 /(2.0d0*tmp3(ix^d)) &
1833 *(tmp2(ix^d)/wrp(ix^d,
e_) - 1.0d0))
1837 cmax(ix^d,1) = max(umean(ix^d), &
1838 wrp(ix^d,
mom(idim))+csoundr(ix^d)*dmean(ix^d))
1842 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1843 call dust_get_cmax(wmean, x, ixi^l, ixo^l, idim, cmax, cmin)
1847 end subroutine hd_get_cbounds
1859 integer,
intent(in) :: ixi^
l, ixo^
l
1860 double precision,
intent(in) :: w(ixi^s,nw)
1861 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1862 double precision,
intent(out) :: csound2(ixi^s)
1863 double precision :: pthermal(ixi^s)
1864 double precision :: inv_rho, nh_val, pres, g1
1871 tab_g1 =
eos%ionE .and.
eos%gamma1_method /=
'constant'
1872 {
do ix^db=ixomin^db,ixomax^db\}
1873 inv_rho = 1.0d0/w(ix^
d,
rho_)
1874 nh_val = w(ix^
d,
rho_)/
eos%nH2rhoFactor
1876 nh_val, dlog10(nh_val), inv_rho)
1879 csound2(ix^
d) = g1*pres*inv_rho
1882 call eos%get_thermal_pressure(w, x, ixi^l, ixo^l, pthermal)
1883 csound2(ixo^s) = eos%gamma * pthermal(ixo^s) / w(ixo^s,
rho_)
1885 call eos_timer_stop(timeeos_csound)
1895 integer,
intent(in) :: ixi^
l, ixo^
l
1896 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1897 double precision,
intent(out):: csound(ixi^s)
1899 double precision :: wprim(ixi^s, nw)
1901 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
1902 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
1913 integer,
intent(in) :: ixi^
l, ixo^
l
1914 double precision,
intent(in) :: w(ixi^s, nw), x(ixi^s,1:
ndim)
1915 double precision,
intent(out):: csound(ixi^s)
1918 double precision :: inv_rho
1919 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
1920 double precision :: prad_max(ixi^s)
1928 prad_tensor(ixo^s,idim,idim)=w(ixo^s,
r_e)/3.0d0
1932 {
do ix^db=ixomin^db,ixomax^db \}
1933 inv_rho=1.d0/w(ix^
d,
rho_)
1934 prad_max(ix^
d) = (4.0d0/3.0d0)*maxval(prad_tensor(ix^
d,:,:))
1935 csound(ix^
d)=(eos%gamma*w(ix^
d,
p_)+prad_max(ix^
d))*inv_rho
1938 if(minval(csound(ixo^s))<smalldouble)
then
1939 print *,
'issue with squared speed and rad pressure'
1940 print *,minval(csound(ixo^s))
1941 print *,minval(prad_max(ixo^s))
1942 call mpistop(
"negative squared speed in get_csrad2 for dt")
1953 integer,
intent(in) :: ixi^
l, ixo^
l
1954 double precision,
intent(in) :: w(ixi^s, 1:nw)
1955 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1956 double precision,
intent(out):: prad(ixi^s, 1:
ndim, 1:
ndim)
1966 integer,
intent(in) :: ixi^
l, ixo^
l
1967 double precision,
intent(in) :: w(ixi^s, 1:nw)
1968 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1969 double precision,
intent(out):: pth_plus_prad(ixi^s)
1971 double precision :: wprim(ixi^s, 1:nw)
1972 double precision :: prad_tensor(ixi^s, 1:
ndim, 1:
ndim)
1973 double precision :: prad_max(ixi^s)
1976 wprim(ixi^s,1:nw)=w(ixi^s,1:nw)
1977 call eos%to_primitive(ixi^
l,ixo^
l,wprim,x)
1979 {
do ix^
d = ixomin^
d,ixomax^
d\}
1980 prad_max(ix^
d) = maxval(prad_tensor(ix^
d,:,:))
1982 pth_plus_prad(ixo^s) = wprim(ixo^s,
p_) + prad_max(ixo^s)
1990 integer,
intent(in) :: ixi^
l, ixo^
l
1991 double precision,
intent(in) :: w(ixi^s, 1:nw)
1992 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1993 double precision,
intent(out):: trad(ixi^s)
2002 integer,
intent(in) :: ixi^
l, ixo^
l
2003 double precision,
intent(in) :: w(ixi^s, 1:nw)
2004 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2005 double precision,
intent(out):: res(ixi^s)
2007 double precision :: r(ixi^s)
2009 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
2010 call eos%get_thermal_pressure(w, x, ixi^
l, ixo^
l, res)
2011 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
2015 subroutine hd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
2017 integer,
intent(in) :: ixi^
l, ixo^
l
2018 double precision,
intent(in) :: w(ixi^s, 1:nw)
2019 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2020 double precision,
intent(out):: res(ixi^s)
2022 double precision :: r(ixi^s)
2024 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
2025 res(ixo^s) = (eos%gamma - 1.0d0) * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
2026 end subroutine hd_get_temperature_from_eint
2029 subroutine hd_get_flux(wC, w, x, ixI^L, ixO^L, idim, f)
2033 integer,
intent(in) :: ixi^
l, ixo^
l, idim
2035 double precision,
intent(in) :: wc(ixi^s, 1:nw)
2037 double precision,
intent(in) :: w(ixi^s, 1:nw)
2038 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2039 double precision,
intent(out) :: f(ixi^s, nwflux)
2041 double precision :: pth(ixi^s)
2045 {
do ix^db=ixomin^db,ixomax^db\}
2061 {
do ix^db=ixomin^db,ixomax^db\}
2066 call eos%get_thermal_pressure(wc, x, ixi^l, ixo^l, pth)
2067 {
do ix^db=ixomin^db,ixomax^db\}
2070 ^
c&f(ix^d,
m^
c_)=w(ix^d,
mom(idim))*wc(ix^d,
m^
c_)\
2071 f(ix^d,
mom(idim))=f(ix^d,
mom(idim))+pth(ix^d)
2076 {
do ix^db=ixomin^db,ixomax^db\}
2078 f(ix^d,
r_e)=w(ix^d,
mom(idim))*wc(ix^d,
r_e)
2087 f(ixo^s,
fip_) = w(ixo^s,
mom(idim)) * wc(ixo^s,
fip_)
2092 call dust_get_flux_prim(w, x, ixi^l, ixo^l, idim, f)
2095 end subroutine hd_get_flux
2102 subroutine hd_add_source_geom(qdt, dtfactor, ixI^L, ixO^L, wCT, wprim, w, x)
2108 integer,
intent(in) :: ixi^
l, ixo^
l
2109 double precision,
intent(in) :: qdt, dtfactor, x(ixi^s, 1:
ndim)
2110 double precision,
intent(inout) :: wct(ixi^s, 1:nw), wprim(ixi^s,1:nw),w(ixi^s, 1:nw)
2111 double precision :: pth(ixi^s),
source(ixi^s), minrho
2112 integer :: iw,idir, h1x^
l{^nooned, h2x^
l}
2113 integer :: mr_,mphi_
2114 integer :: irho, ifluid, n_fluids
2115 double precision :: exp_factor(ixi^s), del_exp_factor(ixi^s), exp_factor_primitive(ixi^s)
2137 source(ixo^s) =
source(ixo^s)*del_exp_factor(ixo^s)/exp_factor(ixo^s)
2141 do ifluid = 0, n_fluids-1
2143 if (ifluid == 0)
then
2167 where (wct(ixo^s, irho) > minrho)
2168 source(ixo^s) =
source(ixo^s) + wct(ixo^s,mphi_)*wprim(ixo^s,mphi_)
2169 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt*
source(ixo^s)/x(ixo^s,
r_)
2172 where (wct(ixo^s, irho) > minrho)
2173 source(ixo^s) = -wct(ixo^s, mphi_) * wprim(ixo^s, mr_)
2174 w(ixo^s, mphi_) = w(ixo^s, mphi_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
2178 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s,
r_)
2183 call mpistop(
"Dust geom source terms not implemented yet with spherical geometries")
2187 h1x^
l=ixo^
l-
kr(1,^
d); {^nooned h2x^
l=ixo^
l-
kr(2,^
d);}
2189 pth(ixo^s)=wprim(ixo^s,
p_)
2198 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
2199 *(
block%surfaceC(ixo^s, 1) -
block%surfaceC(h1x^s, 1)) &
2200 /
block%dvolume(ixo^s)
2204 w(ixo^s, mr_) = w(ixo^s, mr_) + qdt *
source(ixo^s) / x(ixo^s, 1)
2208 source(ixo^s) = pth(ixo^s) * x(ixo^s, 1) &
2209 * (
block%surfaceC(ixo^s, 2) -
block%surfaceC(h2x^s, 2)) &
2210 /
block%dvolume(ixo^s)
2212 source(ixo^s) =
source(ixo^s) + (wprim(ixo^s,
mom(3))**2 * wprim(ixo^s,
rho_)) / tan(x(ixo^s, 2))
2214 source(ixo^s) =
source(ixo^s) - (wprim(ixo^s,
mom(2)) * wprim(ixo^s, mr_)) * wprim(ixo^s,
rho_)
2215 w(ixo^s,
mom(2)) = w(ixo^s,
mom(2)) + qdt *
source(ixo^s) / x(ixo^s, 1)
2219 source(ixo^s) = -(wprim(ixo^s,
mom(3)) * wprim(ixo^s, mr_)) * wprim(ixo^s,
rho_)&
2220 - (wprim(ixo^s,
mom(2)) * wprim(ixo^s,
mom(3))) * wprim(ixo^s,
rho_) / tan(x(ixo^s, 2))
2221 w(ixo^s,
mom(3)) = w(ixo^s,
mom(3)) + qdt *
source(ixo^s) / x(ixo^s, 1)
2228 call mpistop(
"Rotating frame not implemented yet with dust")
2234 end subroutine hd_add_source_geom
2237 subroutine hd_add_source(qdt,dtfactor, ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2246 integer,
intent(in) :: ixi^
l, ixo^
l
2247 double precision,
intent(in) :: qdt, dtfactor
2248 double precision,
intent(in) :: wct(ixi^s, 1:nw),wctprim(ixi^s,1:nw), x(ixi^s, 1:
ndim)
2249 double precision,
intent(inout) :: w(ixi^s, 1:nw)
2250 logical,
intent(in) :: qsourcesplit
2251 logical,
intent(inout) :: active
2253 double precision :: gravity_field(ixi^s, 1:
ndim)
2254 integer :: idust, idim, ix^
d
2270 qsourcesplit,active,
rc_fl)
2295 + qdt * gravity_field(ixo^s, idim) * wct(ixo^s,
dust_rho(idust))
2307 call hd_add_radiation_source(qdt,ixi^
l,ixo^
l,wct,wctprim,w,x,qsourcesplit,active)
2310 if(eos%eos_type ==
'PI')
then
2311 if(.not.qsourcesplit)
then
2313 call eos%update_eos(ixi^
l,ixo^
l,w,x)
2320 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
2323 end subroutine hd_add_source
2345 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
2348 integer,
intent(in) :: ixi^
l,ixo^
l
2349 double precision,
intent(in) :: qdt
2350 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
2351 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
2352 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
2354 double precision :: te(ixi^s), rfactor(ixi^s)
2355 double precision :: qf_half(ixglo1:ixghi1)
2356 double precision :: qf_full(ixglo1:ixghi1)
2357 double precision :: t_l, t_r, t_cool_l, t_cool_r, t_kap_l, t_kap_r
2358 double precision :: kappa_l, kappa_r, kappa_f
2359 double precision :: sigma_t7_f, dt_face, dx_f
2360 double precision :: rho_f, p_l, p_r, p_f, cs_f, q_sat, q_sp, q_sp_star
2361 double precision :: f_sat, eint_loc_l, eint_loc_r, eint_loc_f
2362 double precision :: qn_face, tau_f, ratio, decay, ave_factor
2363 double precision :: q_face_max
2364 double precision,
parameter :: ratio_cap = 50.0d0
2365 integer :: ix1, nface_lo, nface_hi
2369 te(ixi^s) = wct(ixi^s,
te_)
2371 call eos%get_Rfactor(wctprim, x, ixi^
l, ixi^
l, rfactor)
2372 te(ixi^s) = wctprim(ixi^s,
p_) / (rfactor(ixi^s) * wctprim(ixi^s,
rho_))
2376 nface_lo = ixomin1 - 1
2381 do ix1 = nface_lo, nface_hi
2392 t_kap_l = max(t_l, t_cool_l)
2393 t_kap_r = max(t_r, t_cool_r)
2399 if (kappa_l + kappa_r > smalldouble)
then
2400 kappa_f = 2.0d0 * kappa_l * kappa_r / (kappa_l + kappa_r)
2405 dx_f = 0.5d0 * (
block%ds(ix1, 1) +
block%ds(ix1 + 1, 1))
2407 q_sp = -kappa_f * dt_face / dx_f
2410 rho_f = 0.5d0 * (wctprim(ix1,
rho_) + wctprim(ix1 + 1,
rho_))
2411 p_l = wctprim(ix1,
p_)
2412 p_r = wctprim(ix1 + 1,
p_)
2413 p_f = 0.5d0 * (p_l + p_r)
2414 cs_f = dsqrt(max(smalldouble, eos%gamma * p_f / max(rho_f, smalldouble)))
2418 q_sat = 1.5d0 * rho_f * (p_f / max(rho_f, smalldouble))**1.5d0
2419 if (q_sat > smalldouble)
then
2420 f_sat = 1.0d0 / (1.0d0 + dabs(q_sp) / q_sat)
2424 q_sp_star = f_sat * q_sp
2430 eint_loc_l = wct(ix1,
e_) &
2431 - 0.5d0 * wct(ix1, m1_)**2 / max(wct(ix1,
rho_), smalldouble)
2432 eint_loc_r = wct(ix1 + 1,
e_) &
2433 - 0.5d0 * wct(ix1 + 1, m1_)**2 / max(wct(ix1 + 1,
rho_), smalldouble)
2434 eint_loc_l = max(eint_loc_l, smalldouble)
2435 eint_loc_r = max(eint_loc_r, smalldouble)
2436 eint_loc_f = 0.5d0 * (eint_loc_l + eint_loc_r)
2441 sigma_t7_f = kappa_f * 0.5d0 * (t_l + t_r)
2442 tau_f = max(4.0d0 *
dt, &
2446 ratio = min(qdt / tau_f, ratio_cap)
2447 decay = dexp(-ratio)
2448 if (ratio > 1.0
d-6)
then
2449 ave_factor = (1.0d0 - decay) / ratio
2451 ave_factor = 1.0d0 - 0.5d0 * ratio + ratio * ratio / 6.0d0
2454 qn_face = 0.5d0 * (wct(ix1,
q_) + wct(ix1 + 1,
q_))
2456 qf_full(ix1) = q_sp_star + (qn_face - q_sp_star) * decay
2457 qf_half(ix1) = q_sp_star + (qn_face - q_sp_star) * ave_factor
2461 block%ds(ix1, 1) / max(qdt, smalldouble)
2462 qf_half(ix1) = sign(min(dabs(qf_half(ix1)), q_face_max), qf_half(ix1))
2466 do ix1 = ixomin1, ixomax1
2467 w(ix1,
e_) = w(ix1,
e_) &
2468 - qdt * (qf_half(ix1) - qf_half(ix1 - 1)) /
block%ds(ix1, 1)
2469 w(ix1,
q_) = 0.5d0 * (qf_full(ix1 - 1) + qf_full(ix1))
2473 end subroutine add_hypertc_source
2475 subroutine hd_add_radiation_source(qdt,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
2481 integer,
intent(in) :: ixi^
l, ixo^
l
2482 double precision,
intent(in) :: qdt, x(ixi^s,1:
ndim)
2483 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw)
2484 double precision,
intent(inout) :: w(ixi^s,1:nw)
2485 logical,
intent(in) :: qsourcesplit
2486 logical,
intent(inout) :: active
2492 end subroutine hd_add_radiation_source
2494 subroutine hd_get_dt(wprim, ixI^L, ixO^L, dtnew, dx^D, x)
2502 integer,
intent(in) :: ixi^
l, ixo^
l
2503 double precision,
intent(in) ::
dx^
d, x(ixi^s, 1:^nd)
2504 double precision,
intent(in) :: wprim(ixi^s, 1:nw)
2505 double precision,
intent(inout) :: dtnew
2529 end subroutine hd_get_dt
2534 subroutine hd_fld_implicit_update(dtfactor,qdt,qtC,psa,psb)
2539 double precision,
intent(in) :: qdt
2540 double precision,
intent(in) :: qtc
2541 double precision,
intent(in) :: dtfactor
2544 end subroutine hd_fld_implicit_update
2546 subroutine hd_fld_evaluate_implicit(qtC,psa)
2550 double precision,
intent(in) :: qtc
2553 end subroutine hd_fld_evaluate_implicit
2557 integer,
intent(in) :: ixi^
l, ixo^
l
2558 double precision,
intent(in) :: w(ixi^s, nw)
2559 double precision :: ke(ixo^s)
2560 double precision,
intent(in),
optional :: inv_rho(ixo^s)
2562 if (
present(inv_rho))
then
2563 ke = 0.5d0 * sum(w(ixo^s,
mom(:))**2, dim=
ndim+1) * inv_rho
2565 ke = 0.5d0 * sum(w(ixo^s,
mom(:))**2, dim=
ndim+1) / w(ixo^s,
rho_)
2569 function hd_inv_rho(w, ixI^L, ixO^L)
result(inv_rho)
2571 integer,
intent(in) :: ixi^
l, ixo^
l
2572 double precision,
intent(in) :: w(ixi^s, nw)
2573 double precision :: inv_rho(ixo^s)
2576 inv_rho = 1.0d0 / w(ixo^s,
rho_)
2577 end function hd_inv_rho
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)
2603 where(flag(ixo^s,
rho_)) w(ixo^s,
mom(idir)) = 0.0d0
2625 where(flag(ixo^s,
e_))
2651 call eos%get_thermal_pressure(w, x, ixi^
l, ixo^
l, w(ixo^s,
p_))
2654 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/w(ixo^s,
rho_)
2656 call eos%p_to_e(ixi^
l, ixo^
l, w, x)
2658 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))*w(ixo^s,
rho_)
2677 if(.not.primitive)
then
2681 call eos%get_thermal_pressure(w, x, ixi^
l, ixo^
l, w(ixo^s,
p_))
2686 w(ixo^s,
mom(idir)) = w(ixo^s,
mom(idir))/w(ixo^s,
rho_)
2693 if (
hd_fip)
call hd_bound_fip(primitive, ixi^
l, ixo^
l, w)
2716 subroutine hd_wb_prolong(ixI^L, ixO^L, w, x)
2720 integer,
intent(in) :: ixi^
l, ixo^
l
2721 double precision,
intent(inout) :: w(ixi^s, 1:nw)
2722 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2724 double precision :: gravity_field(ixi^s, 1:
ndim)
2725 double precision :: wb_t(ixi^s), p_eq(ixi^s)
2726 double precision :: dx_idims
2727 double precision :: alpha(ixi^s), beta(ixi^s)
2729 integer :: ix1, ix_mid
2733 wb_t(ixo^s) = w(ixo^s,
p_) / w(ixo^s,
rho_)
2742 alpha(ixomin1:ixomax1) = 0.5d0 * dx_idims &
2743 * gravity_field(ixomin1:ixomax1, 1) / wb_t(ixomin1:ixomax1)
2746 ix_mid = (ixomin1 + ixomax1) / 2
2747 p_eq(ix_mid) = w(ix_mid,
p_)
2750 beta(ix_mid:ixomax1-1) = (1.0d0 + alpha(ix_mid:ixomax1-1)) &
2751 / (1.0d0 - alpha(ix_mid+1:ixomax1))
2752 do ix1 = ix_mid + 1, ixomax1
2753 p_eq(ix1) = p_eq(ix1 - 1) * beta(ix1 - 1)
2757 beta(ixomin1:ix_mid-1) = (1.0d0 - alpha(ixomin1+1:ix_mid)) &
2758 / (1.0d0 + alpha(ixomin1:ix_mid-1))
2759 do ix1 = ix_mid - 1, ixomin1, -1
2760 p_eq(ix1) = p_eq(ix1 + 1) * beta(ix1)
2764 w(ixomin1:ixomax1,
p_) = p_eq(ixomin1:ixomax1)
2765 w(ixomin1:ixomax1,
rho_) = p_eq(ixomin1:ixomax1) / wb_t(ixomin1:ixomax1)
2768 end subroutine hd_wb_prolong
2780 subroutine hd_wb_transform(ixI^L, ixO^L, idims, w, x, wb_phi, &
2785 integer,
intent(in) :: ixi^
l, ixo^
l, idims
2786 double precision,
intent(inout) :: w(ixi^s, 1:nw)
2787 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
2788 double precision,
intent(out) :: wb_phi(ixi^s)
2789 double precision,
intent(out) :: wb_phi_face(ixi^s)
2790 double precision,
intent(out) :: wb_t(ixi^s)
2792 double precision :: gravity_field(ixi^s, 1:
ndim)
2793 double precision :: dx_idims
2794 double precision :: alpha(ixi^s), beta(ixi^s)
2800 wb_t(ixi^s) = w(ixi^s,
p_) / w(ixi^s,
rho_)
2814 alpha(iximin1:iximax1) = 0.5d0 * dx_idims &
2815 * gravity_field(iximin1:iximax1, idims) / wb_t(iximin1:iximax1)
2818 beta(iximin1:iximax1-1) = (1.0d0 + alpha(iximin1:iximax1-1)) &
2819 / (1.0d0 - alpha(iximin1+1:iximax1))
2822 wb_phi(iximin1) = w(iximin1,
p_)
2823 do ix1 = iximin1 + 1, iximax1
2824 wb_phi(ix1) = wb_phi(ix1 - 1) * beta(ix1 - 1)
2829 wb_phi_face(ixi^s) = wb_phi(ixi^s) * (1.0d0 + 0.5d0 * dx_idims * &
2830 gravity_field(ixi^s, idims) / wb_t(ixi^s))
2833 w(ixi^s,
rho_) = wb_t(ixi^s)
2834 w(ixi^s,
p_) = w(ixi^s,
p_) / wb_phi(ixi^s)
2836 end subroutine hd_wb_transform
2858 subroutine hd_wb_inverse(ixI^L, ixL^L, ixR^L, idims, wLp, wRp, w, &
2859 wb_phi, wb_phi_face, wb_T)
2862 integer,
intent(in) :: ixi^
l, ixl^
l, ixr^
l, idims
2863 double precision,
intent(inout) :: wlp(ixi^s, 1:nw), wrp(ixi^s, 1:nw)
2864 double precision,
intent(inout) :: w(ixi^s, 1:nw)
2865 double precision,
intent(in) :: wb_phi(ixi^s), wb_phi_face(ixi^s)
2866 double precision,
intent(in) :: wb_t(ixi^s)
2868 double precision :: t_shared(ixi^s)
2869 double precision :: t_face_l(ixi^s), t_face_r(ixi^s)
2870 double precision :: sigma(ixi^s), t_for_rhol(ixi^s), t_for_rhor(ixi^s)
2874 t_shared(iximin1:iximax1-1) = 0.5d0 * (wb_t(iximin1:iximax1-1) &
2875 + wb_t(iximin1+1:iximax1))
2876 t_shared(iximax1) = wb_t(iximax1)
2881 t_face_l(ixl^s) = wlp(ixl^s,
rho_)
2882 t_face_r(ixr^s) = wrp(ixr^s,
rho_)
2886 sigma(ixl^s) = dabs(t_face_l(ixl^s) - t_face_r(ixr^s)) &
2887 / (0.5d0 * (t_face_l(ixl^s) + t_face_r(ixr^s)) + smalldouble)
2888 sigma(ixl^s) = min(sigma(ixl^s), 1.0d0)
2891 t_for_rhol(ixl^s) = (1.d0 - sigma(ixl^s)) * t_shared(ixl^s) &
2892 + sigma(ixl^s) * t_face_l(ixl^s)
2893 t_for_rhor(ixr^s) = (1.d0 - sigma(ixl^s)) * t_shared(ixr^s) &
2894 + sigma(ixl^s) * t_face_r(ixr^s)
2897 wlp(ixl^s,
p_) = wlp(ixl^s,
p_) * wb_phi_face(ixl^s)
2898 wrp(ixr^s,
p_) = wrp(ixr^s,
p_) * wb_phi_face(ixr^s)
2901 wlp(ixl^s,
rho_) = wlp(ixl^s,
p_) / t_for_rhol(ixl^s)
2902 wrp(ixr^s,
rho_) = wrp(ixr^s,
p_) / t_for_rhor(ixr^s)
2905 w(ixi^s,
p_) = w(ixi^s,
p_) * wb_phi(ixi^s)
2906 w(ixi^s,
rho_) = w(ixi^s,
p_) / wb_t(ixi^s)
2908 end subroutine hd_wb_inverse
Calculate w(iw)=w(iw)+qdt*SOURCE[wCT,qtC,x] within ixO for all indices iw=iwmin......
Module with basic data types used in amrvac.
integer, parameter std_len
Default length for strings.
Module to include CAK radiation line force in (magneto)hydrodynamic models Computes both the force fr...
subroutine, public cak_add_source(qdt, ixil, ixol, wct, w, x, energy, qsourcesplit, active)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine, public cak_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Check time step for total radiation contribution.
subroutine, public cak_init(phys_gamma)
Initialize the module.
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter bigdouble
A very large real number.
Module for including dust species, which interact with the gas through a drag force.
subroutine, public dust_add_source(qdt, ixil, ixol, wct, w, x, qsourcesplit, active)
w[iw]= w[iw]+qdt*S[wCT, x] where S is the source based on wCT within ixO
subroutine, public dust_evaluate_implicit(qtc, psa)
inplace update of psa==>F_im(psa)
integer, dimension(:, :), allocatable, public, protected dust_mom
Indices of the dust momentum densities.
integer, public, protected dust_n_species
The number of dust species.
subroutine, public dust_get_flux_prim(w, x, ixil, ixol, idim, f)
integer, dimension(:), allocatable, public, protected dust_rho
Indices of the dust densities.
subroutine, public dust_get_cmax(w, x, ixil, ixol, idim, cmax, cmin)
subroutine, public dust_check_w(ixil, ixol, w, x, flag)
subroutine, public dust_check_params()
subroutine, public dust_get_cmax_prim(w, x, ixil, ixol, idim, cmax, cmin)
subroutine, public dust_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
Get dt related to dust and gas stopping time (Laibe 2011).
subroutine, public dust_init(g_rho, g_mom, g_energy)
subroutine, public dust_implicit_update(dtfactor, qdt, qtc, psb, psa)
Implicit solve of psb=psa+dtfactor*dt*F_im(psb).
EoS state container – the single thermodynamic authority for AMRVAC.
type(eos_container), allocatable, public eos
The single EoS state object, allocated in eos_init and shared (read-mostly) across all EoS sub-module...
integer, parameter, public eos_type_lte
LTE (Saha-table) EoS kernels and finalise for the eos% family.
double precision function, public lte_gamma1_from_p(pres, rho_val)
Gamma_1 of one cell from (p, rho): the ideal value where fully ionised, else the pressure- indexed ta...
double precision function, public lte_p_from_eint(eint_val, nh_val, log_nh_val, inv_rho)
LTE pressure from internal energy in one cell: ideal without ionE, else the table floor,...
PI (partial-ionisation) ionisation-degree backend for the eos% family.
Equation of state for AMRVAC, handled through a single eos_container object.
Module for escape probability radiative cooling modification.
subroutine, public escape_prob_init(iw_colmass, escape_sym, escape_height)
Register escape probability parameters. Called during hd_phys_init (before mesh parameters are availa...
Module for flux conservation near refinement boundaries.
Module for flux limited diffusion (FLD)-approximation in Radiation-(Magneto)hydrodynamics simulations...
double precision, public fld_bisect_tol
Tolerance for bisection method for Energy sourceterms This is a percentage of the minimum of gas- and...
subroutine, public fld_radforce_get_dt(w, ixil, ixol, dtnew, dxd, x, fl)
get dt limit for radiation force and FLD explicit source additions NOTE: w is primitive on entry
double precision, public fld_diff_tol
Tolerance for radiative Energy diffusion.
character(len=40) fld_fluxlimiter
flux limiter choice
character(len=40) fld_opal_table
double precision, public fld_cnorm
double precision, public fld_kappa0
Opacity value when using constant opacity.
subroutine, public add_fld_rad_force(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO This subroutine handles th...
character(len=40) fld_opacity_law
switches for opacity
character(len=40) fld_interaction_method
Which method to find the root for the energy interaction polynomial.
subroutine, public fld_get_radpress(w, x, ixil, ixol, rad_pressure, fl)
Returns Radiation Pressure as tensor NOTE: w is primitive on entry.
logical fld_radforce_split
source split for energy interact and radforce:
logical fld_bound_diff
switches for using changed cmax-cmin bounds
subroutine, public fld_implicit_update(dtfactor, qdt, qtc, psa, psb, fl)
Calling all subroutines to perform the multigrid method Communicates rad_e and diff_coeff to multigri...
subroutine, public fld_evaluate_implicit(qtc, psa, fl)
inplace update of psa==>F_im(psa)
subroutine, public fld_init(gas_eos_type, gas_ion_energy, gas_pi_table)
Initialising FLD-module Read opacities Initialise Multigrid and adimensionalise kappa.
integer nth_for_diff_mg
diffusion coefficient stencil control
Module with geometry-related routines (e.g., divergence, curl).
integer, parameter spherical
integer, parameter cylindrical
integer, parameter cartesian_expansion
subroutine gradient(q, ixil, ixol, idir, gradq, nth_in)
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
logical h_correction
If true, do H-correction to fix the carbuncle problem at grid-aligned shocks.
double precision const_kappae
double precision arad_norm
Normalised radiation constant.
double precision small_pressure
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
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 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 phys_escape_prob
Use escape probability for radiative cooling modification.
double precision const_rad_a
Physical factors useful for radiation fld.
double precision cmax_global
global fastest wave speed needed in fd scheme and glm method
logical use_particles
Use particles module or not.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer mype
The rank of the current MPI task.
double precision dt
global time step
integer ndir
Number of spatial dimensions (components) for vector variables.
double precision courantpar
The Courant (CFL) number used for the simulation.
double precision, dimension(:), allocatable, parameter d
logical slab
Cartesian geometry or not.
double precision const_sigmasb
integer nwauxio
Number of auxiliary variables that are only included in output.
double precision unit_velocity
Physical scaling factor for velocity.
double precision small_r_e
double precision c_norm
Normalised speed of light.
double precision unit_temperature
Physical scaling factor for temperature.
double precision unit_radflux
Physical scaling factor for radiation flux.
double precision, dimension(10) phys_trac_zone_splits
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.
double precision, dimension(:), allocatable w_refine_weight
Weights of variables used to calculate error for mesh refinement.
logical phys_trac
Use TRAC for MHD or 1D HD.
logical need_global_cmax
need global maximal wave speed
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
logical use_multigrid
Use multigrid (only available in 2D and 3D).
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, parameter unitconvert
double precision unit_erad
Physical scaling factor for radiation energy density.
Module for including gravity in (magneto)hydrodynamics simulations.
logical grav_split
source split or not
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
Hydrodynamics physics module.
integer, public, protected m
subroutine, public hd_check_params
logical, public, protected hd_energy
Whether an energy equation is used.
logical, public, protected hd_dust
Whether dust is added.
subroutine, public hd_get_pthermal_plus_pradiation(w, x, ixil, ixol, pth_plus_prad)
calculates the sum of the gas pressure and max Prad tensor element NOTE: only for diagnostic purposes...
subroutine, public hd_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).
logical, public, protected hd_radiative_cooling
Whether radiative cooling is added.
double precision, public, protected rr
subroutine, public hd_get_temperature_from_etot(w, x, ixil, ixol, res)
Calculate temperature=p/rho when in e_ the total energy is stored.
logical, public, protected hd_fld_pradtensor
integer, public, protected hd_trac_type
logical, public, protected hd_particles
Whether particles module is added.
logical, public, protected hd_fip
Whether FIP passive scalar is enabled.
double precision, public hypertc_kappa
Thermal-conductivity prefactor in hyperbolic TC, set in hd_physical_units. Spitzer form: κ(T) = hyper...
logical, public, protected hd_radiation_fld
Whether radiation-gas interaction is handled using flux limited diffusion.
double precision, public, protected hd_htc_beta
Face-recipe heat-wave speed scaling: c_HTC,f = hd_htc_beta * c_max,f. Higher value -> closer to diffu...
double precision, public, protected hd_trac_delta
Johnston 2021 resolution parameter delta (default 0.5).
type(tc_fluid), allocatable, public tc_fl
subroutine, public hd_check_w(primitive, ixil, ixol, w, flag)
Returns logical argument flag where values are ok.
logical, public, protected hd_viscosity
Whether viscosity is added.
integer, public, protected r_e
Index of the radiation energy (when fld active).
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
subroutine, public hd_get_csound2(w, x, ixil, ixol, csound2)
Calculate the square of the thermal sound speed csound2 within ixO^L. For conserved w: extracts pther...
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+).
double precision, public, protected hd_htc_gradt_floor
Gradient deadband: zero out the Spitzer face flux when abs(T_R - T_L) / max(T_L, T_R) < hd_htc_gradT_...
integer, public, protected te_
Indices of temperature.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
subroutine, public hd_get_pradiation_from_prim(w, x, ixil, ixol, prad)
Calculate radiation pressure within ixO^L NOTE: w is primitive on entry here! NOTE: used in FLD modul...
double precision, public, protected hd_trac_tfix
fixed cutoff temperature in K for hd_trac_type=0 (Lionello et al. 2009, Mikic et al....
double precision, public, protected hd_htc_hyp_diff
Hyperdiffusion coefficient applied to the cell-refreshed q at the end of each face-recipe substep....
logical, public, protected hd_hyperbolic_thermal_conduction
Whether hyperbolic thermal conduction (Cattaneo relaxation) is used. 1D only : the q-variable is trea...
double precision, public, protected h_ion_fr
Helium abundance over Hydrogen He_abundance is set in &eos_list and accessed via eosHe_abundance Ioni...
double precision function, dimension(ixo^s), public hd_kin_en(w, ixil, ixol, inv_rho)
logical, public, protected hd_cak_force
Whether CAK radiation line force is activated.
subroutine, public hd_phys_init()
Initialize the module.
integer, dimension(:), allocatable, public, protected tracer
Indices of the tracers.
subroutine, public hd_get_csrad2(w, x, ixil, ixol, csound)
Calculate modified squared sound speed for FLD NOTE: only for diagnostic purposes,...
logical, public, protected hd_thermal_conduction
Whether thermal conduction is added.
integer, public, protected q_
Index of the hyperbolic-TC heat-flux variable (-1 if not present).
double precision, public hd_htc_validity_max_runtime
Running max of l_r,f / dx_f across all face-recipe calls since simulation start. Inspect post-hoc via...
double precision, public hd_adiab
gamma is set in &eos_list and accessed via eosgamma
subroutine, public hd_get_trad(w, x, ixil, ixol, trad)
Calculates radiation temperature.
subroutine, public hd_get_csrad2_prim(w, x, ixil, ixol, csound)
Calculate modified squared sound speed for FLD NOTE: w is primitive on entry here!...
integer, public, protected rho_
Whether plasma is partially ionized.
subroutine, public hd_handle_small_values(primitive, w, x, ixil, ixol, subname)
double precision, public, protected hd_htc_sat_alpha
Cowie-McKee saturation coefficient: q_sat = hd_htc_sat_alpha * rho * c_s^3. Standard convention is al...
double precision, public, protected hd_htc_pos_eta
Per-face energy-positivity safety fraction: |q_f^{n+1/2} dt A_f| <= hd_htc_pos_eta * min(e_int_L V_L,...
logical, public, protected hd_radiative_transfer
Whether the short-characteristics radiative transfer is used, with its settings in &rt_list.
double precision, public, protected he_ion_fr
Ionization fraction of He He_ion_fr = (He2+ + He+)/(He2+ + He+ + He).
logical, public, protected hd_gravity
Whether gravity is added.
type(fld_fluid), allocatable, public fld_fl
Radiation fluid object (gas-EoS callbacks for FLD), wired in hd_link_eos.
double precision, public, protected hd_htc_kappa_override
Optional parfile override for hypertc_kappa (e.g. to match a constant-κ parabolic TC run for benchmar...
integer, public, protected hd_trac_nzones
integer, public, protected c_
type(rc_fluid), allocatable, public rc_fl
logical, public, protected hd_dust_implicit
Whether dust is added using and implicit update in IMEX.
logical, public, protected hd_trac
Whether TRAC method is used.
integer, public, protected fip_
Index of the FIP passive scalar rho*fip in conserved form, fip in primitive form.
double precision, public, protected hd_htc_validity_warn
Validity-monitor threshold for l_r,f / Delta_x_f. Warn if any face exceeds this in a given block (pri...
integer, public, protected hd_n_tracer
Number of tracer species.
type(te_fluid), allocatable, public te_fl_hd
double precision, dimension(10), public, protected hd_trac_zone_splits
logical, public, protected hd_rotating_frame
Whether rotating frame is activated.
logical, public, protected hd_htc_sat
Whether saturation is considered for hyperbolic TC.
logical, public, protected hd_well_balanced
Whether well-balanced reconstruction is used (Kaeppeli & Mishra style).
integer, public, protected iw_colmass
Index into wextra for escape probability column mass.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
integer, public, protected ne_
Index of the electron number density for LTE module.
subroutine, public hd_e_to_ei(ixil, ixol, w, x)
Transform total energy to internal energy.
Module containing all the particle routines.
subroutine particles_init()
Initialize particle data and parameters.
This module defines the procedures of a physics module. It contains function pointers for the various...
module radiative cooling – add optically thin radiative cooling
subroutine radiative_cooling_init_params(phys_gamma, he_abund)
Radiative cooling initialization.
subroutine findl(tpoint, lpoint, fl)
subroutine radiative_cooling_init(fl, read_params)
subroutine radiative_cooling_add_source(qdt, ixil, ixol, wct, wctprim, w, x, qsourcesplit, active, fl)
subroutine calc_l_extended(tpoint, lpoint, fl)
Module for including rotating frame in (magneto)hydrodynamics simulations The rotation vector is assu...
subroutine rotating_frame_add_source(qdt, dtfactor, ixil, ixol, wct, w, x)
w[iw]=w[iw]+qdt*S[wCT,qtC,x] where S is the source based on wCT within ixO
subroutine rotating_frame_init()
Initialize the module.
Public face of the short-characteristics (SC) radiative transfer and its coupling to the (M)HD.
subroutine, public rt_sc_add_source(qdt, ixil, ixol, wct, w, x, thin_share, e_internal)
Unsplit heating source of one block and stage, e += qdt Q, with Q read from i_qrad,...
subroutine, public rt_sc_activate()
Switch the RT on. The physics module calls this from its initialisation when hd_radiative_transfer or...
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.
Generic supertimestepping method which can be used for multiple source terms in the governing equatio...
subroutine, public add_sts_method(sts_getdt, sts_set_sources, startvar, nflux, startwbc, nwbc, evolve_b)
subroutine which added programatically a term to be calculated using STS Params: sts_getdt function c...
subroutine, public set_conversion_methods_to_head(sts_before_first_cycle, sts_after_last_cycle)
Set the hooks called before the first cycle and after the last cycle in the STS update This method sh...
subroutine, public set_error_handling_to_head(sts_error_handling)
Set the hook of error handling in the STS update. This method is called before updating the BC....
subroutine, public sts_init()
Initialize sts module.
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
subroutine, public tc_get_hd_params(fl, read_hd_params)
Init TC coefficients: HD case.
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 get_euv_image(qunit, fl)
subroutine get_sxr_image(qunit, fl)
subroutine get_euv_spectrum(qunit, fl)
subroutine get_whitelight_image(qunit, fl)
subroutine eos_timer_start()
Open an EoS timing window; inside an OpenMP parallel region the EoS is not timed.
subroutine eos_timer_stop(acc)
Close an EoS timing window, adding its time to acc when it is the outermost.
double precision timeeos_csound
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(sub_get_heating), pointer usr_get_heating
procedure(set_surface), pointer usr_set_surface
procedure(phys_gravity), pointer usr_gravity
procedure(hd_pthermal), pointer usr_set_pthermal
procedure(set_wlr), pointer usr_set_wlr
integer nw
Total number of variables.
integer number_species
number of species: each species has different characterictic speeds and should be used accordingly in...
The module add viscous source terms and check time step.
subroutine, public viscosity_get_dt(wprim, ixil, ixol, dtnew, dxd, x)
procedure(sub_add_source), pointer, public viscosity_add_source
subroutine, public viscosity_init(phys_wider_stencil)
Initialize the module.
Radiation fluid object: gas-EoS callbacks the FLD module needs, wired by the physics module at link t...