56 integer,
public,
protected ::
rho_
59 integer,
allocatable,
public,
protected ::
mom(:)
62 integer,
public,
protected ::
e_
65 integer,
public,
protected ::
p_
68 integer,
public,
protected ::
te_
69 integer,
public,
protected ::
ne_
74 integer,
public,
protected ::
q_
87 double precision,
public,
protected ::
h_ion_fr=1d0
90 double precision,
public,
protected ::
he_ion_fr=1d0
97 double precision,
public,
protected ::
rr=1d0
104 function fun_kin_en(w, ixI^L, ixO^L, inv_rho)
result(ke)
106 integer,
intent(in) :: ixi^
l, ixo^
l
107 double precision,
intent(in) :: w(ixi^s, nw)
108 double precision :: ke(ixo^s)
109 double precision,
intent(in),
optional :: inv_rho(ixo^s)
110 end function fun_kin_en
148 subroutine ffhd_read_params(files)
150 character(len=*),
intent(in) :: files(:)
159 do n = 1,
size(files)
160 open(
unitpar, file=trim(files(n)), status=
"old")
161 read(
unitpar, ffhd_list,
end=111)
164 end subroutine ffhd_read_params
167 subroutine ffhd_write_info(fh)
169 integer,
intent(in) :: fh
170 integer,
parameter :: n_par = 1
171 double precision :: values(n_par)
172 character(len=name_len) :: names(n_par)
173 integer,
dimension(MPI_STATUS_SIZE) :: st
176 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
179 values(1) = eos%gamma
180 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
181 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
182 end subroutine ffhd_write_info
200 if(
mype==0)
write(*,*)
'WARNING: set ffhd_thermal_conduction=F when ffhd_energy=F'
204 if(
mype==0)
write(*,*)
'WARNING: set ffhd_hyperbolic_tc=F when ffhd_energy=F'
208 if(
mype==0)
write(*,*)
'WARNING: set ffhd_radiative_cooling=F when ffhd_energy=F'
212 if(
mype==0)
write(*,*)
'WARNING: set ffhd_trac=F when ffhd_energy=F'
216 if (eos%eos_type /=
'FI') &
217 call mpistop(
"eos_type "//trim(eos%eos_type)//
" requires ffhd_energy=T")
222 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
225 physics_type =
"ffhd"
227 phys_internal_e=.false.
232 phys_gamma = eos%gamma
239 if(
mype==0)
write(*,*)
'WARNING: reset ffhd_trac_type=1 for 1D simulation'
244 if(
mype==0)
write(*,*)
'WARNING: set ffhd_trac_mask==bigdouble for global TRAC method'
248 allocate(start_indices(number_species),stop_indices(number_species))
254 mom(:) = var_set_momentum(1)
258 e_ = var_set_energy()
266 q_ = var_set_fluxvar(
'q',
'q', need_bc=.false.)
276 if (eos%eos_type ==
'LTE')
then
279 else if (eos%eos_type ==
'PI')
then
297 if (iw_ne > 0) nwgc = max(nwgc, iw_ne)
298 if (iw_te > 0) nwgc = max(nwgc, iw_te)
301 stop_indices(1)=nwflux
319 if(.not.
allocated(flux_type))
then
320 allocate(flux_type(
ndir, nwflux))
321 flux_type = flux_default
322 else if(any(shape(flux_type) /= [
ndir, nwflux]))
then
323 call mpistop(
"phys_check error: flux_type has wrong shape")
326 phys_get_dt => ffhd_get_dt
327 phys_get_cmax => ffhd_get_cmax_origin
328 phys_get_tcutoff => ffhd_get_tcutoff
329 phys_get_cbounds => ffhd_get_cbounds
334 phys_get_flux => ffhd_get_flux
335 phys_get_v => ffhd_get_v_origin
339 phys_add_source_geom => ffhd_add_source_geom
340 phys_add_source => ffhd_add_source
341 phys_check_params => ffhd_check_params
342 phys_write_info => ffhd_write_info
343 phys_handle_small_values => ffhd_handle_small_values_origin
345 phys_check_w => ffhd_check_w_origin
348 phys_get_pthermal => ffhd_get_pthermal_iso
358 call ffhd_physical_units()
370 call mpistop(
"thermal conduction needs ffhd_energy=T")
373 call mpistop(
"hyperbolic thermal conduction needs ffhd_energy=T")
376 call mpistop(
"radiative cooling needs ffhd_energy=T")
386 call add_sts_method(ffhd_get_tc_dt_ffhd,ffhd_sts_set_source_tc_ffhd,
e_,1,
e_,1,.false.)
401 rc_fl%subtract_equi = .false.
408 phys_te_images => ffhd_te_images
424 subroutine ffhd_te_images
429 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
431 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
433 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
435 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
438 call mpistop(
"Error in synthesize emission: Unknown convert_type")
440 end subroutine ffhd_te_images
443 subroutine ffhd_sts_set_source_tc_ffhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
447 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
448 double precision,
intent(in) :: x(ixi^s,1:
ndim)
449 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
450 double precision,
intent(in) :: my_dt
451 logical,
intent(in) :: fix_conserve_at_step
453 end subroutine ffhd_sts_set_source_tc_ffhd
455 function ffhd_get_tc_dt_ffhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
462 integer,
intent(in) :: ixi^
l, ixo^
l
463 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
464 double precision,
intent(in) :: w(ixi^s,1:nw)
465 double precision :: dtnew
468 end function ffhd_get_tc_dt_ffhd
470 subroutine ffhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
473 integer,
intent(in) :: ixi^
l,ixo^
l
474 double precision,
intent(inout) :: w(ixi^s,1:nw)
475 double precision,
intent(in) :: x(ixi^s,1:
ndim)
476 integer,
intent(in) :: step
477 character(len=140) :: error_msg
479 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
480 call ffhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
481 end subroutine ffhd_tc_handle_small_e
483 subroutine tc_params_read_ffhd(fl)
485 type(tc_fluid),
intent(inout) :: fl
488 logical :: tc_saturate=.false.
489 double precision :: tc_k_para=0d0
490 character(len=std_len) :: tc_slope_limiter=
"MC"
492 namelist /tc_list/ tc_saturate, tc_slope_limiter, tc_k_para
496 read(
unitpar, tc_list,
end=111)
500 fl%tc_saturate = tc_saturate
501 fl%tc_k_para = tc_k_para
502 select case(tc_slope_limiter)
504 fl%tc_slope_limiter = 0
507 fl%tc_slope_limiter = 1
510 fl%tc_slope_limiter = 2
513 fl%tc_slope_limiter = 3
516 fl%tc_slope_limiter = 4
518 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod")
520 end subroutine tc_params_read_ffhd
522 subroutine rc_params_read(fl)
525 type(rc_fluid),
intent(inout) :: fl
527 integer :: ncool = 4000
530 character(len=std_len) :: coolcurve=
'JCcorona'
533 logical :: tfix=.false.
539 logical :: rc_split=.false.
540 logical :: rad_damp=.false.
541 double precision :: rad_damp_height=0.5d0
542 double precision :: rad_damp_scale=0.15d0
544 namelist /rc_list/ coolcurve, ncool, tlow, tfix, rc_split, rad_damp, rad_damp_height, rad_damp_scale
548 read(
unitpar, rc_list,
end=111)
553 fl%coolcurve=coolcurve
558 fl%rad_damp_height=rad_damp_height
559 fl%rad_damp_scale=rad_damp_scale
560 end subroutine rc_params_read
562 subroutine ffhd_check_params
570 if (eos%gamma <= 0.0d0)
call mpistop (
"Error: eos%gamma <= 0")
571 if (
ffhd_adiab < 0.0d0)
call mpistop (
"Error: ffhd_adiab < 0")
574 if (eos%gamma <= 0.0d0 .or. eos%gamma == 1.0d0) &
575 call mpistop (
"Error: eos%gamma <= 0 or eos%gamma == 1")
580 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
585 write(*,*)
'====FFHD run with settings===================='
586 write(*,*)
'Using mod_ffhd_phys with settings:'
588 write(*,*)
'Dimensionality :',
ndim
589 write(*,*)
'vector components:',
ndir
591 write(*,*)
'number of variables nw=',nw
592 write(*,*)
' start index iwstart=',iwstart
593 write(*,*)
'number of vector variables=',nvector
594 write(*,*)
'number of stagger variables nws=',nws
595 write(*,*)
'number of variables with BCs=',nwgc
596 write(*,*)
'number of vars with fluxes=',nwflux
597 write(*,*)
'number of vars with flux + BC=',nwfluxbc
598 write(*,*)
'number of auxiliary variables=',nwaux
599 write(*,*)
'number of extra vars without flux=',nwextra
600 write(*,*)
'number of extra vars for wextra=',nw_extra
601 write(*,*)
'number of auxiliary I/O variables=',
nwauxio
608 write(*,*)
'number due to phys_wider_stencil=',phys_wider_stencil
609 write(*,*)
'==========================================='
611 end subroutine ffhd_check_params
613 subroutine ffhd_physical_units()
615 double precision :: mp,kb
616 double precision :: a,b
629 if (eos%eos_type ==
'LTE')
then
633 eos%nH2rhoFactor = 1d0+4d0*eos%He_abundance
634 rr=(2d0+3d0*eos%He_abundance)/(1d0+4d0*eos%He_abundance)
639 a=1d0+4d0*eos%He_abundance
640 if(eos%eos_type==
'PI')
then
643 b=2d0+3d0*eos%He_abundance
712 end subroutine ffhd_physical_units
714 subroutine ffhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
716 logical,
intent(in) :: primitive
717 integer,
intent(in) :: ixi^
l, ixo^
l
718 double precision,
intent(in) :: w(ixi^s,nw)
719 double precision :: tmp(ixi^s)
720 logical,
intent(inout) :: flag(ixi^s,1:nw)
730 where(tmp(ixo^s) <
small_e) flag(ixo^s,
e_) = .true.
733 end subroutine ffhd_check_w_origin
737 integer,
intent(in) :: ixi^
l, ixo^
l
738 double precision,
intent(inout) :: w(ixi^s, nw)
739 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
742 w(ixo^s,
e_)=w(ixo^s,
p_)*eos%inv_gamma_minus_1+half*w(ixo^s,
mom(1))**2*w(ixo^s,
rho_)
749 integer,
intent(in) :: ixi^
l, ixo^
l
750 double precision,
intent(inout) :: w(ixi^s, nw)
751 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
757 w(ixo^s,
mom(1)) = w(ixo^s,
mom(1))/w(ixo^s,
rho_)
759 w(ixo^s,
p_)=eos%gamma_minus_1*(w(ixo^s,
e_)-half*w(ixo^s,
rho_)*w(ixo^s,
mom(1))**2)
765 integer,
intent(in) :: ixi^
l, ixo^
l
766 double precision,
intent(inout) :: w(ixi^s, nw)
767 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
774 integer,
intent(in) :: ixi^
l, ixo^
l
775 double precision,
intent(inout) :: w(ixi^s, nw)
776 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
784 call ffhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,
'ffhd_e_to_ei')
793 integer,
intent(in) :: ixi^
l, ixo^
l
794 double precision,
intent(in) :: w(ixi^s, nw)
795 double precision :: ei(ixo^s)
800 subroutine ffhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
803 logical,
intent(in) :: primitive
804 integer,
intent(in) :: ixi^
l,ixo^
l
805 double precision,
intent(inout) :: w(ixi^s,1:nw)
806 double precision,
intent(in) :: x(ixi^s,1:
ndim)
807 character(len=*),
intent(in) :: subname
809 logical :: flag(ixi^s,1:nw)
810 double precision :: tmp2(ixi^s)
812 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
819 where(flag(ixo^s,
rho_)) w(ixo^s,
mom(1)) = 0.0d0
825 where(flag(ixo^s,
e_))
842 if(.not.primitive)
then
851 end subroutine ffhd_handle_small_values_origin
853 subroutine ffhd_get_v_origin(w,x,ixI^L,ixO^L,v)
855 integer,
intent(in) :: ixi^
l, ixo^
l
856 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
857 double precision,
intent(out) :: v(ixi^s,
ndir)
858 double precision :: rho(ixi^s)
862 rho(ixo^s)=1.d0/rho(ixo^s)
864 v(ixo^s,
ndir) = w(ixo^s,
mom(1))*
block%B0(ixo^s,idir,0)*rho(ixo^s)
866 end subroutine ffhd_get_v_origin
870 integer,
intent(in) :: ixi^
l, ixo^
l, idim
871 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
872 double precision,
intent(out) :: v(ixi^s)
873 double precision :: rho(ixi^s)
876 v(ixo^s) = (w(ixo^s,
mom(1))*
block%B0(ixo^s,idim,0)) / rho(ixo^s)
879 subroutine ffhd_get_cmax_origin(wprim,x,ixI^L,ixO^L,idim,cmax)
881 integer,
intent(in) :: ixi^
l, ixo^
l, idim
883 double precision,
intent(in) :: wprim(ixi^s, nw), x(ixi^s,1:
ndim)
884 double precision,
intent(inout) :: cmax(ixi^s)
889 call eos%get_csound2(wprim,x,ixi^
l,ixo^
l,cmax)
890 cmax(ixo^s)=dsqrt(cmax(ixo^s))
892 cmax(ixo^s)=dsqrt(eos%gamma*wprim(ixo^s,
p_)/wprim(ixo^s,
rho_))
895 cmax(ixo^s)=dsqrt(eos%gamma*
ffhd_adiab*wprim(ixo^s,
rho_)**eos%gamma_minus_1)
897 cmax(ixo^s)=dabs(wprim(ixo^s,
mom(1))*
block%B0(ixo^s,idim,0))+cmax(ixo^s)
899 end subroutine ffhd_get_cmax_origin
901 subroutine ffhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
904 integer,
intent(in) :: ixi^
l,ixo^
l
905 double precision,
intent(in) :: x(ixi^s,1:
ndim)
906 double precision,
intent(inout) :: w(ixi^s,1:nw)
907 double precision,
intent(out) :: tco_local,tmax_local
908 double precision,
parameter :: trac_delta=0.25d0
909 double precision :: te(ixi^s),lts(ixi^s)
910 double precision,
dimension(ixI^S,1:ndim) :: gradt
911 double precision :: bdir(
ndim)
912 double precision :: ltrc,ltrp,altr
913 integer :: idims,ix^
d,jxo^
l,hxo^
l,ixa^
d,ixb^
d
914 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
915 logical :: lrlt(ixi^s)
919 tmax_local=maxval(te(ixo^s))
929 lts(ixo^s)=0.5d0*dabs(te(jxo^s)-te(hxo^s))/te(ixo^s)
931 where(lts(ixo^s) > trac_delta)
934 if(any(lrlt(ixo^s)))
then
935 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
946 lts(ixp^s)=0.5d0*dabs(te(jxp^s)-te(hxp^s))/te(ixp^s)
947 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
948 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
949 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
951 call mpistop(
"ffhd_trac_type not allowed for 1D simulation")
966 call gradient(te,ixi^
l,ixo^
l,idims,gradt(ixi^s,idims))
972 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
975 if(sum(bdir(:)**2) .gt. zero)
then
976 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
978 block%special_values(3:ndim+2)=bdir(1:ndim)
980 {
do ix^db=ixomin^db,ixomax^db\}
983 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2))*&
984 abs(^d&gradt({ix^d},^d)*block%B0({ix^d},^d,0)+)/te(ix^d)
988 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2),block%ds(ix^d,3))*&
989 abs(^d&gradt({ix^d},^d)*block%B0({ix^d},^d,0)+)/te(ix^d)
991 if(lts(ix^d)>trac_delta)
then
992 block%special_values(1)=max(block%special_values(1),te(ix^d))
995 block%special_values(2)=tmax_local
1013 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
1014 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
1015 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
1017 {
do ix^db=ixpmin^db,ixpmax^db\}
1019 lts(ix^d)=abs(^d&gradt({ix^d},^d)*block%B0({ix^d},^d,0)+)/te(ix^d)
1021 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
1022 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
1027 {
do ix^db=ixpmin^db,ixpmax^db\}
1029 altr=0.25d0*((lts(ix1-1,ix2)+two*lts(ix^d)+lts(ix1+1,ix2))*block%B0(ix^d,1,0)**2+&
1030 (lts(ix1,ix2-1)+two*lts(ix^d)+lts(ix1,ix2+1))*block%B0(ix^d,2,0)**2)
1031 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
1034 altr=0.25d0*((lts(ix1-1,ix2,ix3)+two*lts(ix^d)+lts(ix1+1,ix2,ix3))*block%B0(ix^d,1,0)**2+&
1035 (lts(ix1,ix2-1,ix3)+two*lts(ix^d)+lts(ix1,ix2+1,ix3))*block%B0(ix^d,2,0)**2+&
1036 (lts(ix1,ix2,ix3-1)+two*lts(ix^d)+lts(ix1,ix2,ix3+1))*block%B0(ix^d,3,0)**2)
1037 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
1043 call mpistop(
"unknown ffhd_trac_type")
1046 end subroutine ffhd_get_tcutoff
1048 subroutine ffhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1050 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1051 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1052 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1053 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1054 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1055 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1056 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1057 double precision :: wmean(ixi^s,nw), wmeanp(ixi^s,nw)
1058 double precision,
dimension(ixI^S) :: umean, dmean, csoundl, csoundr, tmp1,tmp2,tmp3
1064 tmp1(ixo^s)=dsqrt(wlp(ixo^s,
rho_))
1065 tmp2(ixo^s)=dsqrt(wrp(ixo^s,
rho_))
1066 tmp3(ixo^s)=1.d0/(tmp1(ixo^s)+tmp2(ixo^s))
1067 umean(ixo^s)=(wlp(ixo^s,
mom(1))*tmp1(ixo^s)&
1068 +wrp(ixo^s,
mom(1))*tmp2(ixo^s))*tmp3(ixo^s)
1069 umean(ixo^s)=umean(ixo^s)*
block%B0(ixo^s,idim,idim)
1070 call ffhd_csound2_cbounds(wlc,wlp,x,ixi^
l,ixo^
l,csoundl)
1071 call ffhd_csound2_cbounds(wrc,wrp,x,ixi^
l,ixo^
l,csoundr)
1072 dmean(ixo^s)=(tmp1(ixo^s)*csoundl(ixo^s)+tmp2(ixo^s)*csoundr(ixo^s)) * &
1073 tmp3(ixo^s) + 0.5d0*tmp1(ixo^s)*tmp2(ixo^s)*tmp3(ixo^s)**2 * &
1074 ((wrp(ixo^s,
mom(1))-wlp(ixo^s,
mom(1)))*
block%B0(ixo^s,idim,idim))**2
1075 dmean(ixo^s)=dsqrt(dmean(ixo^s))
1076 if(
present(cmin))
then
1077 cmin(ixo^s,1)=umean(ixo^s)-dmean(ixo^s)
1078 cmax(ixo^s,1)=umean(ixo^s)+dmean(ixo^s)
1080 cmax(ixo^s,1)=dabs(umean(ixo^s))+dmean(ixo^s)
1083 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1084 tmp1(ixo^s)=wmean(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim)/wmean(ixo^s,
rho_)
1086 wmeanp(ixo^s,1:nwflux)=0.5d0*(wlp(ixo^s,1:nwflux)+wrp(ixo^s,1:nwflux))
1087 call eos%get_csound2(wmeanp,x,ixi^
l,ixo^
l,csoundr)
1091 csoundr(ixo^s) = dsqrt(csoundr(ixo^s))
1092 if(
present(cmin))
then
1093 cmax(ixo^s,1)=max(tmp1(ixo^s)+csoundr(ixo^s),zero)
1094 cmin(ixo^s,1)=min(tmp1(ixo^s)-csoundr(ixo^s),zero)
1096 cmax(ixo^s,1)=dabs(tmp1(ixo^s))+csoundr(ixo^s)
1100 call ffhd_csound2_cbounds(wlc,wlp,x,ixi^
l,ixo^
l,csoundl)
1101 call ffhd_csound2_cbounds(wrc,wrp,x,ixi^
l,ixo^
l,csoundr)
1102 csoundl(ixo^s)=max(dsqrt(csoundl(ixo^s)),dsqrt(csoundr(ixo^s)))
1103 if(
present(cmin))
then
1104 cmin(ixo^s,1)=min(wlp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim),&
1105 wrp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim))-csoundl(ixo^s)
1106 cmax(ixo^s,1)=max(wlp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim),&
1107 wrp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim))+csoundl(ixo^s)
1109 cmax(ixo^s,1)=max(wlp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim),&
1110 wrp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim))+csoundl(ixo^s)
1113 end subroutine ffhd_get_cbounds
1119 subroutine ffhd_csound2_cbounds(wC,wp,x,ixI^L,ixO^L,cs2)
1121 integer,
intent(in) :: ixi^
l, ixo^
l
1122 double precision,
intent(in) :: wc(ixi^s,nw), wp(ixi^s,nw), x(ixi^s,1:
ndim)
1123 double precision,
intent(out):: cs2(ixi^s)
1126 call eos%get_csound2(wp,x,ixi^
l,ixo^
l,cs2)
1130 end subroutine ffhd_csound2_cbounds
1132 subroutine ffhd_get_pthermal_iso(w,x,ixI^L,ixO^L,pth)
1135 integer,
intent(in) :: ixi^
l, ixo^
l
1136 double precision,
intent(in) :: w(ixi^s,nw)
1137 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1138 double precision,
intent(out):: pth(ixi^s)
1142 end subroutine ffhd_get_pthermal_iso
1147 integer,
intent(in) :: ixi^
l, ixo^
l
1148 double precision,
intent(in) :: w(ixi^s,nw)
1149 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1150 double precision,
intent(out):: pth(ixi^s)
1155 {
do ix^db= ixo^lim^db\}
1160 elseif(check_small_values)
then
1161 {
do ix^db= ixo^lim^db\}
1162 if(pth(ix^d)<small_pressure)
then
1163 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1164 " encountered when call ffhd_get_pthermal"
1165 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1166 write(*,*)
"Location: ", x(ix^d,:)
1167 write(*,*)
"Cell number: ", ix^d
1169 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1172 if(trace_small_values)
write(*,*) dsqrt(pth(ix^d)-bigdouble)
1173 write(*,*)
"Saving status at the previous time step"
1182 integer,
intent(in) :: ixi^
l, ixo^
l
1183 double precision,
intent(in) :: w(ixi^s, 1:nw)
1184 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1185 double precision,
intent(out):: res(ixi^s)
1187 res(ixo^s) = w(ixo^s,
te_)
1192 integer,
intent(in) :: ixi^
l, ixo^
l
1193 double precision,
intent(in) :: w(ixi^s, 1:nw)
1194 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1195 double precision,
intent(out):: res(ixi^s)
1196 double precision :: r(ixi^s)
1199 res(ixo^s) = eos%gamma_minus_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
1204 integer,
intent(in) :: ixi^
l, ixo^
l
1205 double precision,
intent(in) :: w(ixi^s, 1:nw)
1206 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1207 double precision,
intent(out):: res(ixi^s)
1209 double precision :: r(ixi^s)
1213 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
1218 integer,
intent(in) :: ixi^
l, ixo^
l
1219 double precision,
intent(in) :: w(ixi^s,nw)
1220 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1221 double precision,
intent(out) :: csound2(ixi^s)
1222 double precision :: rho(ixi^s)
1227 csound2(ixo^s)=eos%gamma*csound2(ixo^s)/rho(ixo^s)
1229 csound2(ixo^s)=eos%gamma*
ffhd_adiab*rho(ixo^s)**eos%gamma_minus_1
1233 subroutine ffhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
1236 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1238 double precision,
intent(in) :: wc(ixi^s,nw)
1240 double precision,
intent(in) :: w(ixi^s,nw)
1241 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1242 double precision,
intent(out) :: f(ixi^s,nwflux)
1243 double precision :: ptotal(ixo^s)
1248 ptotal(ixo^s)=w(ixo^s,
p_)
1254 f(ixo^s,
mom(1))=(wc(ixo^s,
mom(1))*w(ixo^s,
mom(1))+ptotal(ixo^s))*
block%B0(ixo^s,idim,idim)
1258 f(ixo^s,
e_)=w(ixo^s,
mom(1))*(wc(ixo^s,
e_)+ptotal(ixo^s))*
block%B0(ixo^s,idim,idim)
1260 f(ixo^s,
e_)=f(ixo^s,
e_)+w(ixo^s,
q_)*
block%B0(ixo^s,idim,idim)
1264 end subroutine ffhd_get_flux
1266 subroutine ffhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
1270 integer,
intent(in) :: ixi^
l, ixo^
l
1271 double precision,
intent(in) :: qdt,dtfactor
1272 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
1273 double precision,
intent(inout) :: w(ixi^s,1:nw)
1274 logical,
intent(in) :: qsourcesplit
1275 logical,
intent(inout) :: active
1277 if (.not. qsourcesplit)
then
1279 call add_punitb(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
1281 call add_hyperbolic_tc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
1287 w,x,qsourcesplit,active,
rc_fl)
1296 if(eos%eos_type ==
'PI')
then
1297 if(.not.qsourcesplit)
then
1299 call eos%update_eos(ixi^
l,ixo^
l,w,x)
1302 end subroutine ffhd_add_source
1304 subroutine add_punitb(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
1307 integer,
intent(in) :: ixi^
l,ixo^
l
1308 double precision,
intent(in) :: qdt
1309 double precision,
intent(in) :: wct(ixi^s,1:nw),x(ixi^s,1:
ndim)
1310 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
1311 double precision,
intent(inout) :: w(ixi^s,1:nw)
1313 integer :: idims,hxo^
l
1314 double precision :: divb(ixi^s)
1315 double precision :: rhovpar(ixi^s),gradrhov(ixi^s)
1320 hxo^
l=ixo^
l-
kr(idims,^
d);
1321 divb(ixo^s)=divb(ixo^s)+(
block%B0(ixo^s,idims,idims)-
block%B0(hxo^s,idims,idims))/
dxlevel(idims)
1326 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+qdt*wctprim(ixo^s,
p_)*divb(ixo^s)
1327 end subroutine add_punitb
1331 integer,
intent(in) :: ixi^
l, ixo^
l
1332 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
1333 double precision,
intent(out) :: rho(ixi^s)
1335 rho(ixo^s) = w(ixo^s,
rho_)
1338 subroutine ffhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
1341 integer,
intent(in) :: ixi^
l,ixo^
l, ie
1342 double precision,
intent(inout) :: w(ixi^s,1:nw)
1343 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1344 character(len=*),
intent(in) :: subname
1346 logical :: flag(ixi^s,1:nw)
1347 double precision :: rho(ixi^s)
1350 where(w(ixo^s,ie)<
small_e) flag(ixo^s,ie)=.true.
1351 if(any(flag(ixo^s,ie)))
then
1354 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e
1358 w(ixo^s,
e_)=w(ixo^s,
e_)*eos%gamma_minus_1
1360 w(ixo^s,
mom(1)) = w(ixo^s,
mom(1))/rho(ixo^s)
1364 end subroutine ffhd_handle_small_ei
1367 subroutine ffhd_get_dt(wprim,ixI^L,ixO^L,dtnew,dx^D,x)
1371 integer,
intent(in) :: ixi^
l, ixo^
l
1372 double precision,
intent(inout) :: dtnew
1373 double precision,
intent(in) ::
dx^
d
1374 double precision,
intent(in) :: wprim(ixi^s,1:nw)
1375 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1382 end subroutine ffhd_get_dt
1384 subroutine ffhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
1386 integer,
intent(in) :: ixi^
l, ixo^
l
1387 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
1388 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
1391 end subroutine ffhd_add_source_geom
1393 function ffhd_kin_en_origin(w, ixI^L, ixO^L, inv_rho)
result(ke)
1395 integer,
intent(in) :: ixi^
l, ixo^
l
1396 double precision,
intent(in) :: w(ixi^s, nw)
1397 double precision :: ke(ixo^s)
1398 double precision,
intent(in),
optional :: inv_rho(ixo^s)
1400 if(
present(inv_rho))
then
1401 ke(ixo^s)=0.5d0*w(ixo^s,
mom(1))**2*inv_rho(ixo^s)
1403 ke(ixo^s)=0.5d0*w(ixo^s,
mom(1))**2/w(ixo^s,
rho_)
1405 end function ffhd_kin_en_origin
1410 integer,
intent(in) :: ixi^
l, ixo^
l
1411 double precision,
intent(in) :: w(ixi^s,1:nw)
1412 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1413 double precision,
intent(out):: rfactor(ixi^s)
1418 subroutine add_hyperbolic_tc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
1421 integer,
intent(in) :: ixi^
l,ixo^
l
1422 double precision,
intent(in) :: qdt
1423 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
1424 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
1425 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
1427 double precision,
dimension(ixI^S) :: te, r
1428 double precision :: sigma_t5,sigma_t7,sigmat5_bgradt,f_sat,tau
1436 te(ixi^s)=wctprim(ixi^s,
p_)/(r(ixi^s)*wct(ixi^s,
rho_))
1440 do ix2=ixomin2,ixomax2
1441 do ix1=ixomin1,ixomax1
1448 sigma_t7=sigma_t5*te(ix^
d)
1452 sigma_t7=sigma_t5*te(ix^
d)
1454 sigmat5_bgradt=sigma_t5*(&
1455 block%B0(ix^
d,1,0)*((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)&
1456 +
block%B0(ix^
d,2,0)*((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))
1459 f_sat=one/(one+dabs(sigmat5_bgradt)/(1.5d0*wct(ix^
d,
rho_)*(wctprim(ix^
d,
p_)/wct(ix^
d,
rho_))**1.5d0))
1461 w(ix^
d,
q_)=w(ix^
d,
q_)-qdt*(f_sat*sigmat5_bgradt+wct(ix^
d,
q_))/tau
1463 w(ix^
d,
q_)=w(ix^
d,
q_)-qdt*(sigmat5_bgradt+wct(ix^
d,
q_))/&
1470 do ix3=ixomin3,ixomax3
1471 do ix2=ixomin2,ixomax2
1472 do ix1=ixomin1,ixomax1
1479 sigma_t7=sigma_t5*te(ix^
d)
1483 sigma_t7=sigma_t5*te(ix^
d)
1485 sigmat5_bgradt=sigma_t5*(&
1486 block%B0(ix^
d,1,0)*((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)&
1487 +
block%B0(ix^
d,2,0)*((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)&
1488 +
block%B0(ix^
d,3,0)*((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))
1491 f_sat=one/(one+dabs(sigmat5_bgradt)/(1.5d0*wct(ix^
d,
rho_)*(wctprim(ix^
d,
p_)/wct(ix^
d,
rho_))**1.5d0))
1493 w(ix^
d,
q_)=w(ix^
d,
q_)-qdt*(f_sat*sigmat5_bgradt+wct(ix^
d,
q_))/tau
1495 w(ix^
d,
q_)=w(ix^
d,
q_)-qdt*(sigmat5_bgradt+wct(ix^
d,
q_))/&
1502 end subroutine add_hyperbolic_tc_source
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
double precision, parameter bigdouble
A very large real number.
subroutine add_convert_method(phys_convert_vars, nwc, dataset_names, file_suffix)
PI (partial-ionisation) ionisation-degree backend for the eos% family.
Equation of state for AMRVAC, handled through a single eos_container object.
Frozen-field hydrodynamics module.
integer, public, protected te_
Indices of temperature and electron number density (LTE stored aux state)
integer, public, protected ffhd_trac_type
Which TRAC method is used.
integer, public, protected e_
Index of the energy density (-1 if not present)
subroutine, public ffhd_to_primitive_origin(ixil, ixol, w, x)
double precision, public hyperbolic_tc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
procedure(sub_get_pthermal), pointer, public ffhd_get_rfactor
double precision, public ffhd_adiab
The adiabatic index (now owned by eos%; use eosgamma)
procedure(sub_get_pthermal), pointer, public ffhd_get_temperature
type(rc_fluid), allocatable, public rc_fl
type of fluid for radiative cooling
integer, public, protected rho_
Whether plasma is partially ionized.
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
procedure(sub_get_pthermal), pointer, public ffhd_get_pthermal
subroutine, public ffhd_get_rho(w, x, ixil, ixol, rho)
integer, public, protected ne_
procedure(sub_convert), pointer, public ffhd_to_conserved
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
subroutine, public ffhd_get_temperature_from_etot(w, x, ixil, ixol, res)
logical, public, protected ffhd_hyperbolic_tc_use_perp
Whether the perpendicular hyperbolic-TC channel is enabled.
double precision, public, protected h_ion_fr
Helium abundance over Hydrogen (now owned by eos%; use eosHe_abundance) Ionization fraction of H H_io...
procedure(fun_kin_en), pointer, public ffhd_kin_en
subroutine, public ffhd_phys_init()
procedure(sub_get_v), pointer, public ffhd_get_v
subroutine, public ffhd_get_csound2(w, x, ixil, ixol, csound2)
logical, public, protected ffhd_energy
Whether an energy equation is used.
double precision, public, protected rr
type(tc_fluid), allocatable, public tc_fl
type of fluid for thermal conduction
double precision function, dimension(ixo^s), public ffhd_get_ei(w, ixil, ixol)
Internal energy eint = E_total - E_kinetic (single field-aligned momentum). Wired to phys_get_ei; the...
type(te_fluid), allocatable, public te_fl_ffhd
type of fluid for thermal emission synthesis
logical, public, protected ffhd_hyperbolic_tc
Whether hyperbolic type thermal conduction is used.
logical, public, protected ffhd_radiative_cooling
Whether radiative cooling is added.
subroutine, public ffhd_get_v_idim(w, x, ixil, ixol, idim, v)
subroutine, public ffhd_get_pthermal_origin(w, x, ixil, ixol, pth)
integer, public, protected q_
procedure(sub_convert), pointer, public ffhd_to_primitive
logical, public, protected ffhd_hyperbolic_tc_sat
Whether saturation is considered for hyperbolic TC.
subroutine, public ffhd_get_temperature_from_te(w, x, ixil, ixol, res)
integer, public, protected tweight_
double precision, public, protected he_ion_fr2
Ratio of number He2+ / number He+ + He2+ He_ion_fr2 = He2+/(He2+ + He+)
logical, public, protected ffhd_trac
Whether TRAC method is used.
subroutine, public ffhd_to_conserved_origin(ixil, ixol, w, x)
logical, public, protected ffhd_thermal_conduction
Whether thermal conduction is used.
subroutine, public ffhd_ei_to_e(ixil, ixol, w, x)
logical, public, protected ffhd_gravity
Whether gravity is added.
subroutine, public rfactor_from_constant_ionization(w, x, ixil, ixol, rfactor)
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
double precision, public, protected ffhd_trac_mask
Height of the mask used in the TRAC method.
double precision, public, protected he_ion_fr
Ionization fraction of He He_ion_fr = (He2+ + He+)/(He2+ + He+ + He)
subroutine, public ffhd_get_temperature_from_eint(w, x, ixil, ixol, res)
integer, public, protected ffhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
procedure(sub_small_values), pointer, public ffhd_handle_small_values
subroutine, public ffhd_e_to_ei(ixil, ixol, w, x)
Module for flux conservation near refinement boundaries.
Module with geometry-related routines (e.g., divergence, curl)
subroutine divvector(qvec, ixil, ixol, divq, nth_in)
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.
double precision small_pressure
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
integer, parameter unitpar
file handle for IO
double precision unit_mass
Physical scaling factor for mass.
integer, dimension(3, 3) kr
Kronecker delta tensor.
double precision phys_trac_mask
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.
double precision cmax_global
global fastest wave speed needed in fd scheme and glm method
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.
integer nwauxio
Number of auxiliary variables that are only included in output.
double precision unit_velocity
Physical scaling factor for velocity.
logical b0field
split magnetic field as background B0 field
double precision unit_temperature
Physical scaling factor for temperature.
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.
logical phys_trac
Use TRAC for MHD or 1D HD.
logical need_global_cmax
need global maximal wave speed
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 slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
double precision small_density
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
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
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 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_...
subroutine, public tc_get_hd_params(fl, read_hd_params)
Init TC coefficients: HD case.
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...
subroutine tc_init_params(phys_gamma)
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 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(set_equi_vars), pointer usr_set_equi_vars