54 integer,
public,
protected ::
rho_
57 integer,
allocatable,
public,
protected ::
mom(:)
60 integer,
public,
protected ::
e_
63 integer,
public,
protected ::
p_
66 integer,
public,
protected ::
te_
71 integer,
public,
protected ::
q_
86 double precision,
public,
protected ::
h_ion_fr=1d0
89 double precision,
public,
protected ::
he_ion_fr=1d0
96 double precision,
public,
protected ::
rr=1d0
103 double precision :: gamma_1, inv_gamma_1
108 function fun_kin_en(w, ixI^L, ixO^L, inv_rho)
result(ke)
110 integer,
intent(in) :: ixi^
l, ixo^
l
111 double precision,
intent(in) :: w(ixi^s, nw)
112 double precision :: ke(ixo^s)
113 double precision,
intent(in),
optional :: inv_rho(ixo^s)
114 end function fun_kin_en
142 subroutine ffhd_read_params(files)
144 character(len=*),
intent(in) :: files(:)
152 do n = 1,
size(files)
153 open(
unitpar, file=trim(files(n)), status=
"old")
154 read(
unitpar, ffhd_list,
end=111)
157 end subroutine ffhd_read_params
160 subroutine ffhd_write_info(fh)
162 integer,
intent(in) :: fh
163 integer,
parameter :: n_par = 1
164 double precision :: values(n_par)
165 character(len=name_len) :: names(n_par)
166 integer,
dimension(MPI_STATUS_SIZE) :: st
169 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
173 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
174 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
175 end subroutine ffhd_write_info
193 if(
mype==0)
write(*,*)
'WARNING: set ffhd_thermal_conduction=F when ffhd_energy=F'
197 if(
mype==0)
write(*,*)
'WARNING: set ffhd_hyperbolic_thermal_conduction=F when ffhd_energy=F'
201 if(
mype==0)
write(*,*)
'WARNING: set ffhd_radiative_cooling=F when ffhd_energy=F'
205 if(
mype==0)
write(*,*)
'WARNING: set ffhd_trac=F when ffhd_energy=F'
209 if(
mype==0)
write(*,*)
'WARNING: set ffhd_partial_ionization=F when ffhd_energy=F'
215 if(
mype==0)
write(*,*)
'WARNING: set ffhd_partial_ionization=F when eq_state_units=F'
221 if(
mype==0)
write(*,*)
'WARNING: turn off parabolic TC when using hyperbolic TC'
224 physics_type =
"ffhd"
226 phys_internal_e=.false.
238 if(
mype==0)
write(*,*)
'WARNING: reset ffhd_trac_type=1 for 1D simulation'
243 if(
mype==0)
write(*,*)
'WARNING: set ffhd_trac_mask==bigdouble for global TRAC method'
247 allocate(start_indices(number_species),stop_indices(number_species))
253 mom(:) = var_set_momentum(1)
257 e_ = var_set_energy()
275 stop_indices(1)=nwflux
279 te_ = var_set_auxvar(
'Te',
'Te')
300 if(.not.
allocated(flux_type))
then
301 allocate(flux_type(
ndir, nwflux))
302 flux_type = flux_default
303 else if(any(shape(flux_type) /= [
ndir, nwflux]))
then
304 call mpistop(
"phys_check error: flux_type has wrong shape")
307 phys_get_dt => ffhd_get_dt
308 phys_get_cmax => ffhd_get_cmax_origin
309 phys_get_tcutoff => ffhd_get_tcutoff
310 phys_get_cbounds => ffhd_get_cbounds
311 phys_to_primitive => ffhd_to_primitive_origin
313 phys_to_conserved => ffhd_to_conserved_origin
315 phys_get_flux => ffhd_get_flux
316 phys_get_v => ffhd_get_v_origin
320 phys_add_source_geom => ffhd_add_source_geom
321 phys_add_source => ffhd_add_source
322 phys_check_params => ffhd_check_params
323 phys_write_info => ffhd_write_info
324 phys_handle_small_values => ffhd_handle_small_values_origin
325 ffhd_handle_small_values => ffhd_handle_small_values_origin
326 phys_check_w => ffhd_check_w_origin
329 phys_get_pthermal => ffhd_get_pthermal_iso
332 phys_get_pthermal => ffhd_get_pthermal_origin
338 ffhd_get_rfactor=>rfactor_from_temperature_ionization
339 phys_update_temperature => ffhd_update_temperature
343 ffhd_get_rfactor=>rfactor_from_constant_ionization
353 call ffhd_physical_units()
365 call mpistop(
"thermal conduction needs ffhd_energy=T")
368 call mpistop(
"hyperbolic thermal conduction needs ffhd_energy=T")
371 call mpistop(
"radiative cooling needs ffhd_energy=T")
381 call add_sts_method(ffhd_get_tc_dt_ffhd,ffhd_sts_set_source_tc_ffhd,
e_,1,
e_,1,.false.)
382 tc_fl%get_temperature_from_conserved => ffhd_get_temperature_from_etot
383 tc_fl%get_temperature_from_eint => ffhd_get_temperature_from_eint
398 rc_fl%get_var_Rfactor => ffhd_get_rfactor
401 rc_fl%has_equi = .false.
402 rc_fl%subtract_equi = .false.
409 te_fl_ffhd%get_var_Rfactor => ffhd_get_rfactor
410 phys_te_images => ffhd_te_images
423 subroutine ffhd_te_images
428 case(
'EIvtiCCmpi',
'EIvtuCCmpi')
430 case(
'ESvtiCCmpi',
'ESvtuCCmpi')
432 case(
'SIvtiCCmpi',
'SIvtuCCmpi')
434 case(
'WIvtiCCmpi',
'WIvtuCCmpi')
437 call mpistop(
"Error in synthesize emission: Unknown convert_type")
439 end subroutine ffhd_te_images
442 subroutine ffhd_sts_set_source_tc_ffhd(ixI^L,ixO^L,w,x,wres,fix_conserve_at_step,my_dt,igrid,nflux)
446 integer,
intent(in) :: ixi^
l, ixo^
l, igrid, nflux
447 double precision,
intent(in) :: x(ixi^s,1:
ndim)
448 double precision,
intent(inout) :: wres(ixi^s,1:nw), w(ixi^s,1:nw)
449 double precision,
intent(in) :: my_dt
450 logical,
intent(in) :: fix_conserve_at_step
452 end subroutine ffhd_sts_set_source_tc_ffhd
454 function ffhd_get_tc_dt_ffhd(w,ixI^L,ixO^L,dx^D,x)
result(dtnew)
461 integer,
intent(in) :: ixi^
l, ixo^
l
462 double precision,
intent(in) ::
dx^
d, x(ixi^s,1:
ndim)
463 double precision,
intent(in) :: w(ixi^s,1:nw)
464 double precision :: dtnew
467 end function ffhd_get_tc_dt_ffhd
469 subroutine ffhd_tc_handle_small_e(w, x, ixI^L, ixO^L, step)
472 integer,
intent(in) :: ixi^
l,ixo^
l
473 double precision,
intent(inout) :: w(ixi^s,1:nw)
474 double precision,
intent(in) :: x(ixi^s,1:
ndim)
475 integer,
intent(in) :: step
476 character(len=140) :: error_msg
478 write(error_msg,
"(a,i3)")
"Thermal conduction step ", step
479 call ffhd_handle_small_ei(w,x,ixi^
l,ixo^
l,
e_,error_msg)
480 end subroutine ffhd_tc_handle_small_e
482 subroutine tc_params_read_ffhd(fl)
484 type(tc_fluid),
intent(inout) :: fl
487 logical :: tc_saturate=.false.
488 double precision :: tc_k_para=0d0
489 character(len=std_len) :: tc_slope_limiter=
"MC"
491 namelist /tc_list/ tc_saturate, tc_slope_limiter, tc_k_para
495 read(
unitpar, tc_list,
end=111)
499 fl%tc_saturate = tc_saturate
500 fl%tc_k_para = tc_k_para
501 select case(tc_slope_limiter)
503 fl%tc_slope_limiter = 0
506 fl%tc_slope_limiter = 1
509 fl%tc_slope_limiter = 2
512 fl%tc_slope_limiter = 3
515 fl%tc_slope_limiter = 4
517 call mpistop(
"Unknown tc_slope_limiter, choose MC, minmod")
519 end subroutine tc_params_read_ffhd
521 subroutine rc_params_read(fl)
524 type(rc_fluid),
intent(inout) :: fl
526 integer :: ncool = 4000
529 character(len=std_len) :: coolcurve=
'JCcorona'
532 logical :: tfix=.false.
538 logical :: rc_split=.false.
539 logical :: rad_cut=.false.
540 double precision :: rad_cut_hgt=0.5d0
541 double precision :: rad_cut_dey=0.15d0
543 namelist /rc_list/ coolcurve, ncool, tlow, tfix, rc_split, rad_cut, rad_cut_hgt, rad_cut_dey
547 read(
unitpar, rc_list,
end=111)
552 fl%coolcurve=coolcurve
557 fl%rad_cut_hgt=rad_cut_hgt
558 fl%rad_cut_dey=rad_cut_dey
559 end subroutine rc_params_read
561 subroutine ffhd_check_params
570 if (
ffhd_gamma <= 0.0d0)
call mpistop (
"Error: ffhd_gamma <= 0")
571 if (
ffhd_adiab < 0.0d0)
call mpistop (
"Error: ffhd_adiab < 0")
575 call mpistop (
"Error: ffhd_gamma <= 0 or ffhd_gamma == 1")
576 inv_gamma_1=1.d0/gamma_1
581 call mpistop(
"usr_set_equi_vars has to be implemented in the user file")
586 write(*,*)
'====FFHD run with settings===================='
587 write(*,*)
'Using mod_ffhd_phys with settings:'
589 write(*,*)
'Dimensionality :',
ndim
590 write(*,*)
'vector components:',
ndir
592 write(*,*)
'number of variables nw=',nw
593 write(*,*)
' start index iwstart=',iwstart
594 write(*,*)
'number of vector variables=',nvector
595 write(*,*)
'number of stagger variables nws=',nws
596 write(*,*)
'number of variables with BCs=',nwgc
597 write(*,*)
'number of vars with fluxes=',nwflux
598 write(*,*)
'number of vars with flux + BC=',nwfluxbc
599 write(*,*)
'number of auxiliary variables=',nwaux
600 write(*,*)
'number of extra vars without flux=',nwextra
601 write(*,*)
'number of extra vars for wextra=',nw_extra
602 write(*,*)
'number of auxiliary I/O variables=',
nwauxio
609 write(*,*)
'number due to phys_wider_stencil=',phys_wider_stencil
610 write(*,*)
'==========================================='
612 end subroutine ffhd_check_params
614 subroutine ffhd_physical_units()
616 double precision :: mp,kb
617 double precision :: a,b
704 end subroutine ffhd_physical_units
706 subroutine ffhd_check_w_origin(primitive,ixI^L,ixO^L,w,flag)
708 logical,
intent(in) :: primitive
709 integer,
intent(in) :: ixi^
l, ixo^
l
710 double precision,
intent(in) :: w(ixi^s,nw)
711 double precision :: tmp(ixi^s)
712 logical,
intent(inout) :: flag(ixi^s,1:nw)
722 where(tmp(ixo^s) <
small_e) flag(ixo^s,
e_) = .true.
725 end subroutine ffhd_check_w_origin
727 subroutine ffhd_to_conserved_origin(ixI^L,ixO^L,w,x)
729 integer,
intent(in) :: ixi^
l, ixo^
l
730 double precision,
intent(inout) :: w(ixi^s, nw)
731 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
734 w(ixo^s,
e_)=w(ixo^s,
p_)*inv_gamma_1+half*w(ixo^s,
mom(1))**2*w(ixo^s,
rho_)
737 end subroutine ffhd_to_conserved_origin
739 subroutine ffhd_to_primitive_origin(ixI^L,ixO^L,w,x)
741 integer,
intent(in) :: ixi^
l, ixo^
l
742 double precision,
intent(inout) :: w(ixi^s, nw)
743 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
746 call ffhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'ffhd_to_primitive_origin')
749 w(ixo^s,
mom(1)) = w(ixo^s,
mom(1))/w(ixo^s,
rho_)
751 w(ixo^s,
p_)=gamma_1*(w(ixo^s,
e_)-half*w(ixo^s,
rho_)*w(ixo^s,
mom(1))**2)
753 end subroutine ffhd_to_primitive_origin
757 integer,
intent(in) :: ixi^
l, ixo^
l
758 double precision,
intent(inout) :: w(ixi^s, nw)
759 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
766 integer,
intent(in) :: ixi^
l, ixo^
l
767 double precision,
intent(inout) :: w(ixi^s, nw)
768 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
772 call ffhd_handle_small_ei(w,x,ixi^
l,ixi^
l,
e_,
'ffhd_e_to_ei')
776 subroutine ffhd_handle_small_values_origin(primitive, w, x, ixI^L, ixO^L, subname)
779 logical,
intent(in) :: primitive
780 integer,
intent(in) :: ixi^
l,ixo^
l
781 double precision,
intent(inout) :: w(ixi^s,1:nw)
782 double precision,
intent(in) :: x(ixi^s,1:
ndim)
783 character(len=*),
intent(in) :: subname
785 logical :: flag(ixi^s,1:nw)
786 double precision :: tmp2(ixi^s)
788 call phys_check_w(primitive, ixi^
l, ixi^
l, w, flag)
795 where(flag(ixo^s,
rho_)) w(ixo^s,
mom(1)) = 0.0d0
801 where(flag(ixo^s,
e_))
818 if(.not.primitive)
then
827 end subroutine ffhd_handle_small_values_origin
829 subroutine ffhd_get_v_origin(w,x,ixI^L,ixO^L,v)
831 integer,
intent(in) :: ixi^
l, ixo^
l
832 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
833 double precision,
intent(out) :: v(ixi^s,
ndir)
834 double precision :: rho(ixi^s)
838 rho(ixo^s)=1.d0/rho(ixo^s)
840 v(ixo^s,
ndir) = w(ixo^s,
mom(1))*
block%B0(ixo^s,idir,0)*rho(ixo^s)
842 end subroutine ffhd_get_v_origin
846 integer,
intent(in) :: ixi^
l, ixo^
l, idim
847 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
848 double precision,
intent(out) :: v(ixi^s)
849 double precision :: rho(ixi^s)
852 v(ixo^s) = (w(ixo^s,
mom(1))*
block%B0(ixo^s,idim,0)) / rho(ixo^s)
855 subroutine ffhd_get_cmax_origin(wprim,x,ixI^L,ixO^L,idim,cmax)
857 integer,
intent(in) :: ixi^
l, ixo^
l, idim
859 double precision,
intent(in) :: wprim(ixi^s, nw), x(ixi^s,1:
ndim)
860 double precision,
intent(inout) :: cmax(ixi^s)
867 cmax(ixo^s)=dabs(wprim(ixo^s,
mom(1))*
block%B0(ixo^s,idim,0))+cmax(ixo^s)
869 end subroutine ffhd_get_cmax_origin
871 subroutine ffhd_get_tcutoff(ixI^L,ixO^L,w,x,Tco_local,Tmax_local)
874 integer,
intent(in) :: ixi^
l,ixo^
l
875 double precision,
intent(in) :: x(ixi^s,1:
ndim)
876 double precision,
intent(inout) :: w(ixi^s,1:nw)
877 double precision,
intent(out) :: tco_local,tmax_local
878 double precision,
parameter :: trac_delta=0.25d0
879 double precision :: te(ixi^s),lts(ixi^s)
880 double precision,
dimension(ixI^S,1:ndim) :: gradt
881 double precision :: bdir(
ndim)
882 double precision :: ltrc,ltrp,altr
883 integer :: idims,ix^
d,jxo^
l,hxo^
l,ixa^
d,ixb^
d
884 integer :: jxp^
l,hxp^
l,ixp^
l,ixq^
l
885 logical :: lrlt(ixi^s)
889 tmax_local=maxval(te(ixo^s))
899 lts(ixo^s)=0.5d0*dabs(te(jxo^s)-te(hxo^s))/te(ixo^s)
901 where(lts(ixo^s) > trac_delta)
904 if(any(lrlt(ixo^s)))
then
905 tco_local=maxval(te(ixo^s), mask=lrlt(ixo^s))
916 lts(ixp^s)=0.5d0*dabs(te(jxp^s)-te(hxp^s))/te(ixp^s)
917 lts(ixp^s)=max(one, (exp(lts(ixp^s))/ltrc)**ltrp)
918 lts(ixo^s)=0.25d0*(lts(jxo^s)+two*lts(ixo^s)+lts(hxo^s))
919 block%wextra(ixo^s,
tcoff_)=te(ixo^s)*lts(ixo^s)**0.4d0
921 call mpistop(
"ffhd_trac_type not allowed for 1D simulation")
936 call gradient(te,ixi^
l,ixo^
l,idims,gradt(ixi^s,idims))
942 ixb^
d=(ixomin^
d+ixomax^
d-1)/2+ixa^
d;
945 if(sum(bdir(:)**2) .gt. zero)
then
946 bdir(1:ndim)=bdir(1:ndim)/dsqrt(sum(bdir(:)**2))
948 block%special_values(3:ndim+2)=bdir(1:ndim)
950 {
do ix^db=ixomin^db,ixomax^db\}
953 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2))*&
954 abs(^d&gradt({ix^d},^d)*block%B0({ix^d},^d,0)+)/te(ix^d)
958 lts(ix^d)=min(block%ds(ix^d,1),block%ds(ix^d,2),block%ds(ix^d,3))*&
959 abs(^d&gradt({ix^d},^d)*block%B0({ix^d},^d,0)+)/te(ix^d)
961 if(lts(ix^d)>trac_delta)
then
962 block%special_values(1)=max(block%special_values(1),te(ix^d))
965 block%special_values(2)=tmax_local
983 call gradient(te,ixi^l,ixq^l,idims,gradt(ixi^s,idims))
984 call gradientf(te,x,ixi^l,hxp^l,idims,gradt(ixi^s,idims),nghostcells,.true.)
985 call gradientf(te,x,ixi^l,jxp^l,idims,gradt(ixi^s,idims),nghostcells,.false.)
987 {
do ix^db=ixpmin^db,ixpmax^db\}
989 lts(ix^d)=abs(^d&gradt({ix^d},^d)*block%B0({ix^d},^d,0)+)/te(ix^d)
991 lts(ix^d)=min(^d&block%ds({ix^d},^d))*lts(ix^d)
992 lts(ix^d)=max(one,(exp(lts(ix^d))/ltrc)**ltrp)
997 {
do ix^db=ixpmin^db,ixpmax^db\}
999 altr=0.25d0*((lts(ix1-1,ix2)+two*lts(ix^d)+lts(ix1+1,ix2))*block%B0(ix^d,1,0)**2+&
1000 (lts(ix1,ix2-1)+two*lts(ix^d)+lts(ix1,ix2+1))*block%B0(ix^d,2,0)**2)
1001 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
1004 altr=0.25d0*((lts(ix1-1,ix2,ix3)+two*lts(ix^d)+lts(ix1+1,ix2,ix3))*block%B0(ix^d,1,0)**2+&
1005 (lts(ix1,ix2-1,ix3)+two*lts(ix^d)+lts(ix1,ix2+1,ix3))*block%B0(ix^d,2,0)**2+&
1006 (lts(ix1,ix2,ix3-1)+two*lts(ix^d)+lts(ix1,ix2,ix3+1))*block%B0(ix^d,3,0)**2)
1007 block%wextra(ix^d,
tcoff_)=te(ix^d)*altr**0.4d0
1013 call mpistop(
"unknown ffhd_trac_type")
1016 end subroutine ffhd_get_tcutoff
1018 subroutine ffhd_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
1020 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1021 double precision,
intent(in) :: wlc(ixi^s, nw), wrc(ixi^s, nw)
1022 double precision,
intent(in) :: wlp(ixi^s, nw), wrp(ixi^s, nw)
1023 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1024 double precision,
intent(inout) :: cmax(ixi^s,1:number_species)
1025 double precision,
intent(inout),
optional :: cmin(ixi^s,1:number_species)
1026 double precision,
intent(in) :: hspeed(ixi^s,1:number_species)
1027 double precision :: wmean(ixi^s,nw)
1028 double precision,
dimension(ixI^S) :: umean, dmean, csoundl, csoundr, tmp1,tmp2,tmp3
1034 tmp1(ixo^s)=dsqrt(wlp(ixo^s,
rho_))
1035 tmp2(ixo^s)=dsqrt(wrp(ixo^s,
rho_))
1036 tmp3(ixo^s)=1.d0/(tmp1(ixo^s)+tmp2(ixo^s))
1037 umean(ixo^s)=(wlp(ixo^s,
mom(1))*tmp1(ixo^s)&
1038 +wrp(ixo^s,
mom(1))*tmp2(ixo^s))*tmp3(ixo^s)
1039 umean(ixo^s)=umean(ixo^s)*
block%B0(ixo^s,idim,idim)
1042 dmean(ixo^s)=(tmp1(ixo^s)*csoundl(ixo^s)+tmp2(ixo^s)*csoundr(ixo^s)) * &
1043 tmp3(ixo^s) + 0.5d0*tmp1(ixo^s)*tmp2(ixo^s)*tmp3(ixo^s)**2 * &
1044 ((wrp(ixo^s,
mom(1))-wlp(ixo^s,
mom(1)))*
block%B0(ixo^s,idim,idim))**2
1045 dmean(ixo^s)=dsqrt(dmean(ixo^s))
1046 if(
present(cmin))
then
1047 cmin(ixo^s,1)=umean(ixo^s)-dmean(ixo^s)
1048 cmax(ixo^s,1)=umean(ixo^s)+dmean(ixo^s)
1050 cmax(ixo^s,1)=dabs(umean(ixo^s))+dmean(ixo^s)
1053 wmean(ixo^s,1:nwflux)=0.5d0*(wlc(ixo^s,1:nwflux)+wrc(ixo^s,1:nwflux))
1054 tmp1(ixo^s)=wmean(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim)/wmean(ixo^s,
rho_)
1056 csoundr(ixo^s) = dsqrt(csoundr(ixo^s))
1057 if(
present(cmin))
then
1058 cmax(ixo^s,1)=max(tmp1(ixo^s)+csoundr(ixo^s),zero)
1059 cmin(ixo^s,1)=min(tmp1(ixo^s)-csoundr(ixo^s),zero)
1061 cmax(ixo^s,1)=dabs(tmp1(ixo^s))+csoundr(ixo^s)
1067 csoundl(ixo^s)=max(dsqrt(csoundl(ixo^s)),dsqrt(csoundr(ixo^s)))
1068 if(
present(cmin))
then
1069 cmin(ixo^s,1)=min(wlp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim),&
1070 wrp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim))-csoundl(ixo^s)
1071 cmax(ixo^s,1)=max(wlp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim),&
1072 wrp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim))+csoundl(ixo^s)
1074 cmax(ixo^s,1)=max(wlp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim),&
1075 wrp(ixo^s,
mom(1))*
block%B0(ixo^s,idim,idim))+csoundl(ixo^s)
1078 end subroutine ffhd_get_cbounds
1080 subroutine ffhd_get_pthermal_iso(w,x,ixI^L,ixO^L,pth)
1083 integer,
intent(in) :: ixi^
l, ixo^
l
1084 double precision,
intent(in) :: w(ixi^s,nw)
1085 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1086 double precision,
intent(out):: pth(ixi^s)
1090 end subroutine ffhd_get_pthermal_iso
1092 subroutine ffhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
1095 integer,
intent(in) :: ixi^
l, ixo^
l
1096 double precision,
intent(in) :: w(ixi^s,nw)
1097 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1098 double precision,
intent(out):: pth(ixi^s)
1103 {
do ix^db= ixo^lim^db\}
1108 elseif(check_small_values)
then
1109 {
do ix^db= ixo^lim^db\}
1110 if(pth(ix^d)<small_pressure)
then
1111 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1112 " encountered when call ffhd_get_pthermal"
1113 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1114 write(*,*)
"Location: ", x(ix^d,:)
1115 write(*,*)
"Cell number: ", ix^d
1117 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1120 if(trace_small_values)
write(*,*) dsqrt(pth(ix^d)-bigdouble)
1121 write(*,*)
"Saving status at the previous time step"
1126 end subroutine ffhd_get_pthermal_origin
1128 subroutine ffhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
1130 integer,
intent(in) :: ixi^
l, ixo^
l
1131 double precision,
intent(in) :: w(ixi^s, 1:nw)
1132 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1133 double precision,
intent(out):: res(ixi^s)
1135 res(ixo^s) = w(ixo^s,
te_)
1136 end subroutine ffhd_get_temperature_from_te
1138 subroutine ffhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
1140 integer,
intent(in) :: ixi^
l, ixo^
l
1141 double precision,
intent(in) :: w(ixi^s, 1:nw)
1142 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1143 double precision,
intent(out):: res(ixi^s)
1144 double precision :: r(ixi^s)
1146 call ffhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
1147 res(ixo^s) = gamma_1 * w(ixo^s,
e_)/(w(ixo^s,
rho_)*r(ixo^s))
1148 end subroutine ffhd_get_temperature_from_eint
1150 subroutine ffhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
1152 integer,
intent(in) :: ixi^
l, ixo^
l
1153 double precision,
intent(in) :: w(ixi^s, 1:nw)
1154 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1155 double precision,
intent(out):: res(ixi^s)
1157 double precision :: r(ixi^s)
1159 call ffhd_get_rfactor(w,x,ixi^
l,ixo^
l,r)
1161 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,
rho_))
1162 end subroutine ffhd_get_temperature_from_etot
1166 integer,
intent(in) :: ixi^
l, ixo^
l
1167 double precision,
intent(in) :: w(ixi^s,nw)
1168 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1169 double precision,
intent(out) :: csound2(ixi^s)
1170 double precision :: rho(ixi^s)
1175 csound2(ixo^s)=
ffhd_gamma*csound2(ixo^s)/rho(ixo^s)
1181 subroutine ffhd_get_flux(wC,w,x,ixI^L,ixO^L,idim,f)
1184 integer,
intent(in) :: ixi^
l, ixo^
l, idim
1186 double precision,
intent(in) :: wc(ixi^s,nw)
1188 double precision,
intent(in) :: w(ixi^s,nw)
1189 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1190 double precision,
intent(out) :: f(ixi^s,nwflux)
1191 double precision :: ptotal(ixo^s)
1196 ptotal(ixo^s)=w(ixo^s,
p_)
1202 f(ixo^s,
mom(1))=(wc(ixo^s,
mom(1))*w(ixo^s,
mom(1))+ptotal(ixo^s))*
block%B0(ixo^s,idim,idim)
1206 f(ixo^s,
e_)=w(ixo^s,
mom(1))*(wc(ixo^s,
e_)+ptotal(ixo^s))*
block%B0(ixo^s,idim,idim)
1208 f(ixo^s,
e_)=f(ixo^s,
e_)+w(ixo^s,
q_)*
block%B0(ixo^s,idim,idim)
1212 end subroutine ffhd_get_flux
1214 subroutine ffhd_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
1218 integer,
intent(in) :: ixi^
l, ixo^
l
1219 double precision,
intent(in) :: qdt,dtfactor
1220 double precision,
intent(in) :: wct(ixi^s,1:nw),wctprim(ixi^s,1:nw), x(ixi^s,1:
ndim)
1221 double precision,
intent(inout) :: w(ixi^s,1:nw)
1222 logical,
intent(in) :: qsourcesplit
1223 logical,
intent(inout) :: active
1225 if (.not. qsourcesplit)
then
1227 call add_punitb(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
1229 call add_hypertc_source(qdt,ixi^
l,ixo^
l,wct,w,x,wctprim)
1235 w,x,qsourcesplit,active,
rc_fl)
1245 if(.not.qsourcesplit)
then
1247 call ffhd_update_temperature(ixi^
l,ixo^
l,wct,w,x)
1250 end subroutine ffhd_add_source
1252 subroutine add_punitb(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
1255 integer,
intent(in) :: ixi^
l,ixo^
l
1256 double precision,
intent(in) :: qdt
1257 double precision,
intent(in) :: wct(ixi^s,1:nw),x(ixi^s,1:
ndim)
1258 double precision,
intent(in) :: wctprim(ixi^s,1:nw)
1259 double precision,
intent(inout) :: w(ixi^s,1:nw)
1261 integer :: idims,hxo^
l
1262 double precision :: divb(ixi^s)
1263 double precision :: rhovpar(ixi^s),gradrhov(ixi^s)
1268 hxo^
l=ixo^
l-
kr(idims,^
d);
1269 divb(ixo^s)=divb(ixo^s)+(
block%B0(ixo^s,idims,idims)-
block%B0(hxo^s,idims,idims))/
dxlevel(idims)
1274 w(ixo^s,
mom(1))=w(ixo^s,
mom(1))+qdt*wctprim(ixo^s,
p_)*divb(ixo^s)
1275 end subroutine add_punitb
1279 integer,
intent(in) :: ixi^
l, ixo^
l
1280 double precision,
intent(in) :: w(ixi^s,1:nw),x(ixi^s,1:
ndim)
1281 double precision,
intent(out) :: rho(ixi^s)
1283 rho(ixo^s) = w(ixo^s,
rho_)
1286 subroutine ffhd_handle_small_ei(w, x, ixI^L, ixO^L, ie, subname)
1289 integer,
intent(in) :: ixi^
l,ixo^
l, ie
1290 double precision,
intent(inout) :: w(ixi^s,1:nw)
1291 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1292 character(len=*),
intent(in) :: subname
1294 logical :: flag(ixi^s,1:nw)
1295 double precision :: rho(ixi^s)
1298 where(w(ixo^s,ie)<
small_e) flag(ixo^s,ie)=.true.
1299 if(any(flag(ixo^s,ie)))
then
1302 where(flag(ixo^s,ie)) w(ixo^s,ie)=
small_e
1306 w(ixo^s,
e_)=w(ixo^s,
e_)*gamma_1
1308 w(ixo^s,
mom(1)) = w(ixo^s,
mom(1))/rho(ixo^s)
1312 end subroutine ffhd_handle_small_ei
1314 subroutine ffhd_update_temperature(ixI^L,ixO^L,wCT,w,x)
1317 integer,
intent(in) :: ixi^
l, ixo^
l
1318 double precision,
intent(in) :: wct(ixi^s,1:nw), x(ixi^s,1:
ndim)
1319 double precision,
intent(inout) :: w(ixi^s,1:nw)
1320 double precision :: iz_h(ixo^s),iz_he(ixo^s), pth(ixi^s)
1326 end subroutine ffhd_update_temperature
1328 subroutine ffhd_get_dt(wprim,ixI^L,ixO^L,dtnew,dx^D,x)
1332 integer,
intent(in) :: ixi^
l, ixo^
l
1333 double precision,
intent(inout) :: dtnew
1334 double precision,
intent(in) ::
dx^
d
1335 double precision,
intent(in) :: wprim(ixi^s,1:nw)
1336 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1343 end subroutine ffhd_get_dt
1345 subroutine ffhd_add_source_geom(qdt,dtfactor,ixI^L,ixO^L,wCT,wprim,w,x)
1347 integer,
intent(in) :: ixi^
l, ixo^
l
1348 double precision,
intent(in) :: qdt, dtfactor,x(ixi^s,1:
ndim)
1349 double precision,
intent(inout) :: wct(ixi^s,1:nw), wprim(ixi^s,1:nw),w(ixi^s,1:nw)
1352 end subroutine ffhd_add_source_geom
1354 function ffhd_kin_en_origin(w, ixI^L, ixO^L, inv_rho)
result(ke)
1356 integer,
intent(in) :: ixi^
l, ixo^
l
1357 double precision,
intent(in) :: w(ixi^s, nw)
1358 double precision :: ke(ixo^s)
1359 double precision,
intent(in),
optional :: inv_rho(ixo^s)
1361 if(
present(inv_rho))
then
1362 ke(ixo^s)=0.5d0*w(ixo^s,
mom(1))**2*inv_rho(ixo^s)
1364 ke(ixo^s)=0.5d0*w(ixo^s,
mom(1))**2/w(ixo^s,
rho_)
1366 end function ffhd_kin_en_origin
1368 subroutine rfactor_from_temperature_ionization(w,x,ixI^L,ixO^L,Rfactor)
1371 integer,
intent(in) :: ixi^
l, ixo^
l
1372 double precision,
intent(in) :: w(ixi^s,1:nw)
1373 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1374 double precision,
intent(out):: rfactor(ixi^s)
1375 double precision :: iz_h(ixo^s),iz_he(ixo^s)
1378 rfactor(ixo^s)=(1.d0+iz_h(ixo^s)+0.1d0*(1.d0+iz_he(ixo^s)*(1.d0+iz_he(ixo^s))))/(2.d0+3.d0*
he_abundance)
1379 end subroutine rfactor_from_temperature_ionization
1381 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
1383 integer,
intent(in) :: ixi^
l, ixo^
l
1384 double precision,
intent(in) :: w(ixi^s,1:nw)
1385 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1386 double precision,
intent(out):: rfactor(ixi^s)
1389 end subroutine rfactor_from_constant_ionization
1391 subroutine add_hypertc_source(qdt,ixI^L,ixO^L,wCT,w,x,wCTprim)
1394 integer,
intent(in) :: ixi^
l,ixo^
l
1395 double precision,
intent(in) :: qdt
1396 double precision,
dimension(ixI^S,1:ndim),
intent(in) :: x
1397 double precision,
dimension(ixI^S,1:nw),
intent(in) :: wct,wctprim
1398 double precision,
dimension(ixI^S,1:nw),
intent(inout) :: w
1400 double precision,
dimension(ixI^S) :: te
1401 double precision :: sigma_t5,sigma_t7,sigmat5_bgradt,f_sat,tau
1404 te(ixi^s)=wctprim(ixi^s,
p_)/wct(ixi^s,
rho_)
1408 do ix2=ixomin2,ixomax2
1409 do ix1=ixomin1,ixomax1
1416 sigma_t7=sigma_t5*te(ix^
d)
1420 sigma_t7=sigma_t5*te(ix^
d)
1422 sigmat5_bgradt=sigma_t5*(&
1423 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)&
1424 +
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))
1427 f_sat=one/(one+dabs(sigmat5_bgradt)/(1.5d0*wct(ix^
d,
rho_)*(wctprim(ix^
d,
p_)/wct(ix^
d,
rho_))**1.5d0))
1429 w(ix^
d,
q_)=w(ix^
d,
q_)-qdt*(f_sat*sigmat5_bgradt+wct(ix^
d,
q_))/tau
1431 w(ix^
d,
q_)=w(ix^
d,
q_)-qdt*(sigmat5_bgradt+wct(ix^
d,
q_))/&
1438 do ix3=ixomin3,ixomax3
1439 do ix2=ixomin2,ixomax2
1440 do ix1=ixomin1,ixomax1
1447 sigma_t7=sigma_t5*te(ix^
d)
1451 sigma_t7=sigma_t5*te(ix^
d)
1453 sigmat5_bgradt=sigma_t5*(&
1454 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)&
1455 +
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)&
1456 +
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))
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 end subroutine add_hypertc_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)
Frozen-field hydrodynamics module.
integer, public, protected te_
Indices of temperature.
integer, public, protected ffhd_trac_type
Which TRAC method is used.
double precision, public hypertc_kappa
The thermal conductivity kappa in hyperbolic thermal conduction.
integer, public, protected e_
Index of the energy density (-1 if not present)
double precision, public ffhd_gamma
The adiabatic index.
logical, public, protected eq_state_units
double precision, public ffhd_adiab
The adiabatic constant.
procedure(sub_get_pthermal), pointer, public ffhd_get_temperature
logical, public, protected ffhd_hyperbolic_thermal_conduction
Whether hyperbolic type thermal conduction is used.
type(rc_fluid), allocatable, public rc_fl
type of fluid for radiative cooling
integer, public, protected rho_
Index of the density (in the w array)
integer, public, protected tcoff_
Index of the cutoff temperature for the TRAC method.
procedure(sub_get_pthermal), pointer, public ffhd_get_pthermal
logical, public, protected ffhd_htc_sat
Wheterh saturation is considered for hyperbolic TC.
subroutine, public ffhd_get_rho(w, x, ixil, ixol, rho)
logical, public, protected ffhd_partial_ionization
Whether plasma is partially ionized.
procedure(sub_convert), pointer, public ffhd_to_conserved
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
double precision, public, protected h_ion_fr
Ionization fraction of H H_ion_fr = H+/(H+ + H)
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
type(te_fluid), allocatable, public te_fl_ffhd
type of fluid for thermal emission synthesis
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
logical, public, protected ffhd_radiative_cooling
Whether radiative cooling is added.
subroutine, public ffhd_get_v_idim(w, x, ixil, ixol, idim, v)
integer, public, protected q_
procedure(sub_convert), pointer, public ffhd_to_primitive
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.
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.
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)
integer, public, protected ffhd_trac_finegrid
Distance between two adjacent traced magnetic field lines (in finest cell size)
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, dimension(:), allocatable, parameter d
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.
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
module ionization degree - get ionization degree for given temperature
subroutine ionization_degree_from_temperature(ixil, ixol, te, iz_h, iz_he)
subroutine ionization_degree_init()
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