48 if (
eos%eos_type ==
'FI' .or.
eos%eos_type ==
'PI')
then
49 eos%to_conserved => hd_to_conserved_origin
50 eos%to_primitive => hd_to_primitive_origin
51 else if (
eos%eos_type ==
'LTE')
then
52 eos%to_conserved => hd_to_conserved_lte
53 eos%to_primitive => hd_to_primitive_lte
55 call mpistop(
'Error: Unknown HD EOS type: ' // trim(
eos%eos_type))
68 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
69 eos%get_csound2 => hd_get_csound2_lte
75 eos%get_csound2 => hd_get_csound2_fi
87 eos%get_Rfactor=>rfactor_from_constant_ionization
95 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
97 call mpistop(
'PI energy EoS requires hd_energy=.true.')
98 eos%to_conserved => hd_to_conserved_pi
99 eos%to_primitive => hd_to_primitive_pi
102 eos%p_to_e => p_to_e_pi
114 subroutine bind_eos_to_source()
115 if (
allocated(
tc_fl))
then
116 call eos_bind_tc(
tc_fl, .not.
associated(
eos%get_Rfactor, rfactor_from_constant_ionization))
119 if (
allocated(
rc_fl))
then
121 rc_fl%get_pthermal =>
eos%get_thermal_pressure
122 rc_fl%get_var_Rfactor =>
eos%get_Rfactor
127 rc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
128 rc_fl%nH2rhoFactor =
eos%nH2rhoFactor
134 rc_fl%log_T_floor = eos_get_log_t_floor()
142 if (
eos%ionE .and.
eos%eos_type ==
'LTE')
then
152 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
154 if (
allocated(
rc_fl))
then
167 if (
allocated(
fld_fl))
then
171 fld_fl%get_tgas =>
eos%get_temperature_from_pressure
174 end subroutine bind_eos_to_source
177 subroutine hd_to_conserved_origin(ixI^L, ixO^L, w, x)
180 integer,
intent(in) :: ixi^
l, ixo^
l
181 double precision,
intent(inout) :: w(ixi^s, nw)
182 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
186 {
do ix^db=ixomin^db,ixomax^db\}
189 w(ix^
d,
e_)=w(ix^
d,
p_)*
eos%inv_gamma_minus_1+&
197 call dust_to_conserved(ixi^l, ixo^l, w, x)
200 end subroutine hd_to_conserved_origin
203 subroutine hd_to_primitive_origin(ixI^L, ixO^L, w, x)
206 integer,
intent(in) :: ixi^
l, ixo^
l
207 double precision,
intent(inout) :: w(ixi^s, nw)
208 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
210 double precision :: inv_rho
214 call hd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'hd_to_primitive')
217 {
do ix^db=ixomin^db,ixomax^db\}
218 inv_rho = 1.d0/w(ix^
d,rho_)
220 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
224 w(ix^
d,p_)=(eos%gamma_minus_1)*(w(ix^
d,e_)&
225 -half*w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+))
231 call dust_to_primitive(ixi^l, ixo^l, w, x)
234 end subroutine hd_to_primitive_origin
240 subroutine hd_to_conserved_lte(ixI^L, ixO^L, w, x)
243 integer,
intent(in) :: ixi^
l, ixo^
l
244 double precision,
intent(inout) :: w(ixi^s, nw)
245 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
247 call p_to_e(ixi^
l, ixo^
l, w, x)
250 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
256 end subroutine hd_to_conserved_lte
258 subroutine p_to_e(ixI^L, ixO^L, w, x)
262 integer,
intent(in) :: ixi^
l, ixo^
l
263 double precision,
intent(inout) :: w(ixi^s, nw)
264 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
267 double precision :: nh(ixi^s), log_nh(ixi^s)
269 if (.not. hd_energy)
return
271 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
272 log_nh(ixo^s) = dlog10(nh(ixo^s))
274 {
do ix^db=ixomin^db,ixomax^db\}
276 w(ix^
d,e_) = lte_eint_from_p(w(ix^
d,p_), nh(ix^
d), log_nh(ix^
d), w(ix^
d,rho_)) + &
277 half*(^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)
279 w(ix^
d,e_) = w(ix^
d,p_)*eos%inv_gamma_minus_1 + &
280 half*(^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)
284 end subroutine p_to_e
294 subroutine hd_to_primitive_lte(ixI^L, ixO^L, w, x)
297 integer,
intent(in) :: ixi^
l, ixo^
l
298 double precision,
intent(inout) :: w(ixi^s, nw)
299 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
301 double precision :: inv_rho
302 double precision :: nh(ixi^s)
303 double precision :: log_nh(ixi^s)
304 double precision :: eint_val
308 call hd_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'hd_to_primitive_LTE')
311 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
315 log_nh(ixo^s) = dlog10(nh(ixo^s))
318 {
do ix^db=ixomin^db,ixomax^db\}
319 inv_rho = 1.d0/w(ix^
d,rho_)
321 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
326 eint_val = w(ix^
d,e_) - half*w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+)
327 w(ix^
d,p_) = lte_p_from_eint(eint_val, nh(ix^
d), log_nh(ix^
d), inv_rho)
333 call dust_to_primitive(ixi^l, ixo^l, w, x)
336 end subroutine hd_to_primitive_lte
347 integer,
intent(in) :: ixi^
l, ixo^
l
348 double precision,
intent(in) :: w(ixi^s, 1:nw)
349 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
350 double precision,
intent(out):: pth(ixi^s)
352 double precision :: nh(ixi^s), ei(ixi^s), tpi, rpi
355 if (eos%eos_type ==
'LTE')
then
357 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
358 pth(ixo^s) = nh(ixo^s) * (1.0d0 + eos%He_abundance &
359 + (w(ixo^s,iw_ne) / nh(ixo^s))) * w(ixo^s,iw_te)
360 else if (eos%eos_type ==
'PI' .and. eos%ionE)
then
364 {
do ix^db=ixomin^db,ixomax^db\}
365 call state_from_eint_pi(w(ix^
d,rho_), ei(ix^
d), &
370 pth(ixo^s) = eos%gamma_minus_1 * phys_get_ei(w, ixi^l, ixo^l)
373 if (.not.
associated(usr_set_pthermal))
then
374 pth(ixo^s) = hd_adiab * w(ixo^s, rho_)**eos%gamma
376 call usr_set_pthermal(w,x,ixi^l,ixo^l,pth)
380 if (fix_small_values)
then
381 {
do ix^db= ixo^lim^db\}
382 if(pth(ix^d)<small_pressure)
then
383 pth(ix^d)=small_pressure
386 else if (check_small_values)
then
387 {
do ix^db= ixo^lim^db\}
388 if(pth(ix^d)<small_pressure)
then
389 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
390 " encountered when call hd_get_pthermal"
391 write(*,*)
"Iteration: ", it,
" Time: ", global_time
392 write(*,*)
"Location: ", x(ix^d,:)
393 write(*,*)
"Cell number: ", ix^d
395 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
397 if(trace_small_values)
write(*,*) dsqrt(pth(ix^d)-bigdouble)
398 write(*,*)
"Saving status at the previous time step"
408 subroutine hd_get_csound2_fi(w, x, ixI^L, ixO^L, cs2)
410 integer,
intent(in) :: ixi^
l, ixo^
l
411 double precision,
intent(in) :: w(ixi^s, nw)
412 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
413 double precision,
intent(out) :: cs2(ixi^s)
415 cs2(ixo^s) = eos%gamma * w(ixo^s, p_) / w(ixo^s, rho_)
417 end subroutine hd_get_csound2_fi
421 subroutine hd_get_csound2_lte(w, x, ixI^L, ixO^L, cs2)
423 integer,
intent(in) :: ixi^
l, ixo^
l
424 double precision,
intent(in) :: w(ixi^s, nw)
425 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
426 double precision,
intent(out) :: cs2(ixi^s)
429 call hd_get_gamma1_lte(w, x, ixi^
l, ixo^
l, cs2)
430 {
do ix^db=ixomin^db,ixomax^db\}
431 cs2(ix^
d) = cs2(ix^
d) * w(ix^
d, p_) / w(ix^
d, rho_)
434 end subroutine hd_get_csound2_lte
443 subroutine p_to_e_pi(ixI^L, ixO^L, w, x)
445 integer,
intent(in) :: ixi^
l, ixo^
l
446 double precision,
intent(inout) :: w(ixi^s, nw)
447 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
448 double precision :: eint
451 {
do ix^db=ixomin^db,ixomax^db\}
453 call eint_from_rho_p_pi(w(ix^
d,rho_), w(ix^
d,p_), eint)
454 w(ix^
d,e_) = eint + half*(^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)
457 end subroutine p_to_e_pi
460 subroutine hd_to_conserved_pi(ixI^L, ixO^L, w, x)
463 integer,
intent(in) :: ixi^
l, ixo^
l
464 double precision,
intent(inout) :: w(ixi^s, nw)
465 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
467 call p_to_e_pi(ixi^
l, ixo^
l, w, x)
469 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
471 end subroutine hd_to_conserved_pi
474 subroutine hd_to_primitive_pi(ixI^L, ixO^L, w, x)
477 integer,
intent(in) :: ixi^
l, ixo^
l
478 double precision,
intent(inout) :: w(ixi^s, nw)
479 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
480 double precision :: inv_rho, eint_val, t, rfac
484 call hd_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
485 'hd_to_primitive_PI')
488 {
do ix^db=ixomin^db,ixomax^db\}
489 inv_rho = 1.d0/w(ix^
d,rho_)
491 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
493 eint_val = w(ix^
d,e_) &
494 - half*w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+)
495 eint_val = max(eint_val, smalldouble)
496 call state_from_eint_pi(w(ix^
d,rho_), eint_val, &
501 if (hd_dust)
call dust_to_primitive(ixi^l, ixo^l, w, x)
502 end subroutine hd_to_primitive_pi
528 subroutine hd_get_gamma1_lte(w, x, ixI^L, ixO^L, gamma1)
530 integer,
intent(in) :: ixi^
l, ixo^
l
531 double precision,
intent(in) :: w(ixi^s, nw)
532 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
533 double precision,
intent(out) :: gamma1(ixi^s)
537 if (eos%gamma1_method ==
'constant')
then
538 gamma1(ixo^s) = eos%gamma
542 {
do ix^db=ixomin^db,ixomax^db\}
543 gamma1(ix^
d) = lte_gamma1_from_p(w(ix^
d,p_), w(ix^
d,rho_))
546 end subroutine hd_get_gamma1_lte
551 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
553 integer,
intent(in) :: ixi^
l, ixo^
l
554 double precision,
intent(in) :: w(ixi^s,1:nw)
555 double precision,
intent(in) :: x(ixi^s,1:
ndim)
556 double precision,
intent(out):: rfactor(ixi^s)
560 end subroutine rfactor_from_constant_ionization
565 subroutine hd_to_prolong_lte(ixI^L, ixO^L, w, x)
566 integer,
intent(in) :: ixi^l, ixo^l
567 double precision,
intent(inout) :: w(ixi^s, nw)
568 double precision,
intent(in) :: x(ixi^s, 1:ndim)
570 double precision :: inv_rho, eint_val, nh_val, log_nh, t_loc, y_loc
573 {
do ix^db=ixomin^db,ixomax^db\}
574 inv_rho = 1.d0 / w(ix^d, rho_)
575 nh_val = w(ix^d, rho_) / eos%nH2rhoFactor
576 log_nh = dlog10(nh_val)
579 ^c&w(ix^d,m^c_)=w(ix^d,m^c_)*inv_rho\
582 eint_val = w(ix^d, e_) &
583 - half * w(ix^d, rho_) * (^c&w(ix^d,m^c_)**2+)
584 eint_val = max(eint_val, nh_val*eos%eint_nH_min, smalldouble)
587 if (eint_val * inv_rho > eos%eint_rho_FI_threshold)
then
589 w(ix^d, e_) = eos%gamma_minus_1 &
590 * (eint_val - eos%eion_per_nH * nh_val) &
591 / (nh_val * eos%n_per_nH_FI)
592 else if (eos%method_id == eos_analytic)
then
594 call saha_t_from_nh_eint(nh_val, &
595 eint_val / nh_val, t_loc, y_loc)
599 w(ix^d, e_) = t_from_nh_eint(log_nh, &
600 dlog10(eint_val) - log_nh)
604 end subroutine hd_to_prolong_lte
608 subroutine hd_from_prolong_lte(ixI^L, ixO^L, w, x)
609 integer,
intent(in) :: ixi^l, ixo^l
610 double precision,
intent(inout) :: w(ixi^s, nw)
611 double precision,
intent(in) :: x(ixi^s, 1:ndim)
613 double precision :: t_val, eint_val, t_fi, nh_val, log_nh, t_min
616 t_fi = (eos%eint_rho_FI_threshold &
617 * eos%nH2rhoFactor - eos%eion_per_nH) &
618 * eos%gamma_minus_1 / eos%n_per_nH_FI
620 t_min = 10.0d0**eos_get_log_t_floor()
622 {
do ix^db=ixomin^db,ixomax^db\}
624 nh_val = w(ix^d, rho_) / eos%nH2rhoFactor
625 log_nh = dlog10(nh_val)
627 if (t_val > t_fi)
then
630 * (eos%n_per_nH_FI * t_val * eos%inv_gamma_minus_1 &
632 else if (eos%method_id == eos_analytic)
then
634 eint_val = saha_eint_from_nh_t(nh_val, t_val) * nh_val
637 eint_val = eint_nh_from_t(log_nh, &
638 dlog10(max(t_val, t_min))) &
643 w(ix^d, e_) = eint_val &
644 + half * w(ix^d, rho_) * (^c&w(ix^d,m^c_)**2+)
646 ^c&w(ix^d,m^c_)=w(ix^d,rho_)*w(ix^d,m^c_)\
649 end subroutine hd_from_prolong_lte
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for including dust species, which interact with the gas through a drag force.
subroutine, public dust_to_primitive(ixil, ixol, w, x)
subroutine, public dust_to_conserved(ixil, ixol, w, x)
EoS state container – the single thermodynamic authority for AMRVAC.
integer, parameter, public eos_analytic
type(eos_container), allocatable, public eos
The single EoS state object, allocated in eos_init and shared (read-mostly) across all EoS sub-module...
Analytic hydrogen Saha EoS with neutral helium (eos_method == 'analytic').
LTE (Saha-table) EoS kernels and finalise for the eos% family.
double precision function, public p2eint_from_nh_p(nh, ponh)
Ratio eint/p from (log10 nH, log10 p/nH).
double precision function, public eint_nh_from_t(log_nh, log_t)
eint/nH from (log10 nH, log10 T), from the inverse table when one is built and the Saha solve otherwi...
double precision function, public y_from_nh_eint(nh, eint_nh)
Scalar EoS kernels: one cell on (log10 nH, log10 eint/nH) or (log10 nH, log10 p/nH),...
subroutine, public eos_get_eintt_grid(n_nh, lg_nh_min, lg_nh_max)
####################################################################### Table-metadata helpers: expos...
double precision function, public t_from_nh_eint(nh, eint_nh)
Temperature from (log10 nH, log10 eint/nH).
PI (partial-ionisation, eos_type='PI') arm of the eos% family.
double precision function, dimension(log_nh, log_p_nh), public p2eint_pi(log_nh, log_p_nh)
eint/p factor from pressure per H: maps p -> eint = p * (this).
double precision function, dimension(log_nh, log_t), public eint_from_t_pi(log_nh, log_t)
Internal energy per H from temperature: eint/nH(T).
double precision function, dimension(log_nh, log_eint_nh), public y_from_eint_pi(log_nh, log_eint_nh)
Electron-to-hydrogen ratio ne/nH from internal energy per H. ne/nH = iz_H + A_He*iz_He*(1+iz_He) (mat...
subroutine, public get_gamma1_pi(w, x, ixil, ixol, gamma1)
Effective Gamma1 = cs2 * rho / p for the same primitive state.
double precision function, dimension(log_nh, log_eint_nh), public t_from_eint_pi(log_nh, log_eint_nh)
Temperature from internal energy per H.
Equation of state for AMRVAC, handled through a single eos_container object.
subroutine, public eos_bind_tc(fl, sat_r_variable)
The EoS hooks of the conduction fluid fl. sat_R_variable is false when R is the constant 1,...
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision, dimension(:), allocatable, parameter d
double precision unit_temperature
Physical scaling factor for temperature.
logical fix_small_values
fix small values with average or replace methods
HD <-> EoS seam: binds the eos% authority into hydrodynamics.
subroutine, public hd_get_pthermal(w, x, ixil, ixol, pth)
Calculate thermal pressure within ixO^L. For energy runs delegates to eosget_thermal_pressure; for no...
procedure(sub_convert), pointer, public hd_to_conserved
subroutine, public hd_link_eos()
Link the appropriate EOS conversion routines based on the selected EoS type.
procedure(sub_convert), pointer, public hd_to_primitive
Hydrodynamics physics module.
integer, public, protected m
logical, public, protected hd_energy
Whether an energy equation is used.
logical, public, protected hd_dust
Whether dust is added.
integer, public, protected e_
Index of the energy density (-1 if not present).
type(tc_fluid), allocatable, public tc_fl
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
integer, public, protected rho_
Whether plasma is partially ionized.
type(fld_fluid), allocatable, public fld_fl
Radiation fluid object (gas-EoS callbacks for FLD), wired in hd_link_eos.
integer, public, protected c_
type(rc_fluid), allocatable, public rc_fl
type(te_fluid), allocatable, public te_fl_hd
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_check_params), pointer phys_bind_eos_to_source
procedure(sub_convert), pointer phys_to_primitive
procedure(sub_get_pthermal), pointer phys_get_gamma1
procedure(sub_get_pthermal), pointer phys_get_pthermal
procedure(sub_get_ei), pointer phys_get_ei
procedure(sub_convert), pointer phys_to_prolong
procedure(sub_convert), pointer phys_to_conserved
procedure(sub_convert), pointer phys_from_prolong
procedure(sub_get_rho), pointer phys_get_rho
module radiative cooling – add optically thin radiative cooling
double precision, parameter rc_t_ymod_max_k
Temperature in K above which c_V is constant, the upper end of the Y_mod path.
subroutine build_y_mod_table(fl)
===================================================================
Module for handling problematic values in simulations, such as negative pressures.
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(hd_pthermal), pointer usr_set_pthermal