49 if (
eos%eos_type ==
'FI' .or.
eos%eos_type ==
'PI')
then
50 eos%to_conserved => hd_to_conserved_origin
51 eos%to_primitive => hd_to_primitive_origin
52 else if (
eos%eos_type ==
'LTE')
then
53 eos%to_conserved => hd_to_conserved_lte
54 eos%to_primitive => hd_to_primitive_lte
56 call mpistop(
'Error: Unknown HD EOS type: ' // trim(
eos%eos_type))
69 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
70 eos%get_csound2 => hd_get_csound2_lte
76 eos%get_csound2 => hd_get_csound2_fi
88 eos%get_Rfactor=>rfactor_from_constant_ionization
96 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
98 call mpistop(
'PI energy EoS requires hd_energy=.true.')
99 eos%to_conserved => hd_to_conserved_pi
100 eos%to_primitive => hd_to_primitive_pi
103 eos%p_to_e => p_to_e_pi
115 if (
allocated(
tc_fl))
then
116 tc_fl%get_temperature_from_conserved =>
eos%get_temperature_from_etot
119 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
122 tc_fl%get_temperature_from_eint =>
eos%get_temperature_from_eint
126 tc_fl%get_var_Rfactor =>
eos%get_Rfactor
127 tc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
128 tc_fl%nH2rhoFactor =
eos%nH2rhoFactor
129 tc_fl%log_T_floor = eos_get_log_t_floor()
133 if (
allocated(
rc_fl))
then
135 rc_fl%get_pthermal =>
eos%get_thermal_pressure
136 rc_fl%get_var_Rfactor =>
eos%get_Rfactor
141 rc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
142 rc_fl%nH2rhoFactor =
eos%nH2rhoFactor
154 if (
eos%ionE .and.
eos%eos_type ==
'LTE')
then
164 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
166 if (
allocated(
rc_fl))
then
174 if (
allocated(
fld_fl))
then
178 fld_fl%get_tgas =>
eos%get_temperature_from_pressure
181 end subroutine bind_eos_to_source
184 subroutine hd_to_conserved_origin(ixI^L, ixO^L, w, x)
187 integer,
intent(in) :: ixi^
l, ixo^
l
188 double precision,
intent(inout) :: w(ixi^s, nw)
189 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
195 {
do ix^db=ixomin^db,ixomax^db\}
198 w(ix^
d,
e_)=w(ix^
d,
p_)*
eos%inv_gamma_minus_1+&
206 call dust_to_conserved(ixi^l, ixo^l, w, x)
211 end subroutine hd_to_conserved_origin
214 subroutine hd_to_primitive_origin(ixI^L, ixO^L, w, x)
217 integer,
intent(in) :: ixi^
l, ixo^
l
218 double precision,
intent(inout) :: w(ixi^s, nw)
219 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
221 double precision :: inv_rho
230 {
do ix^db=ixomin^db,ixomax^db\}
231 inv_rho = 1.d0/w(ix^
d,
rho_)
237 w(ix^
d,
p_)=(
eos%gamma_minus_1)*(w(ix^
d,
e_)&
244 call dust_to_primitive(ixi^l, ixo^l, w, x)
249 end subroutine hd_to_primitive_origin
255 subroutine hd_to_conserved_lte(ixI^L, ixO^L, w, x)
258 integer,
intent(in) :: ixi^
l, ixo^
l
259 double precision,
intent(inout) :: w(ixi^s, nw)
260 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
264 call p_to_e(ixi^
l, ixo^
l, w, x)
275 end subroutine hd_to_conserved_lte
277 subroutine p_to_e(ixI^L, ixO^L, w, x)
289 integer,
intent(in) :: ixi^
l, ixo^
l
290 double precision,
intent(inout) :: w(ixi^s, nw)
291 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
294 double precision :: p_to_eint, p_over_rho
295 double precision :: nh(ixi^s), nh_in(ixi^s), p_in(ixi^s)
296 double precision :: log_eint_mid, eint_total
297 double precision :: t_solve, y_solve, eint_nh_solve
300 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
301 nh_in(ixo^s) = dlog10(nh(ixo^s))
302 if (
eos%p2eint_method /=
'bisect')
then
303 p_in(ixo^s) = dlog10(w(ixo^s,
p_)) - nh_in(ixo^s)
307 p_to_eint =
eos%inv_gamma_minus_1
308 {
do ix^db=ixomin^db,ixomax^db\}
311 p_over_rho = w(ix^
d,
p_) / w(ix^
d,
rho_)
312 if (p_over_rho >
eos%p_rho_FI_threshold)
then
314 p_to_eint =
eos%inv_gamma_minus_1 &
315 +
eos%eion_per_nH * nh(ix^
d) / w(ix^
d,
p_)
316 w(ix^
d,
e_) = w(ix^
d,
p_)*p_to_eint + &
318 else if (
eos%method ==
'analytic')
then
321 t_solve, y_solve, eint_nh_solve)
322 w(ix^
d,
e_) = eint_nh_solve * nh(ix^
d) + &
324 else if (
eos%p2eint_method ==
'bisect')
then
329 dlog10(w(ix^
d,
p_)), log_eint_mid)
330 eint_total = nh(ix^
d) * 10.0d0**log_eint_mid
331 eint_total = max(eint_total, &
332 nh(ix^
d) * 10.0d0**
eos%T%var2_min)
333 w(ix^
d,
e_) = eint_total + &
338 w(ix^
d,
e_) = w(ix^
d,
p_)*p_to_eint + &
342 w(ix^
d,
e_) = w(ix^
d,
p_)*p_to_eint + &
348 end subroutine p_to_e
358 subroutine hd_to_primitive_lte(ixI^L, ixO^L, w, x)
361 integer,
intent(in) :: ixi^
l, ixo^
l
362 double precision,
intent(inout) :: w(ixi^s, nw)
363 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
365 double precision :: inv_rho
366 double precision :: nh(ixi^s)
367 double precision :: log_nh(ixi^s)
368 double precision :: eint_val, eint_in, t_loc, y_loc
377 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
381 log_nh(ixo^s) = dlog10(nh(ixo^s))
384 {
do ix^db=ixomin^db,ixomax^db\}
385 inv_rho = 1.d0/w(ix^
d,
rho_)
394 eint_val = w(ix^
d,
e_) - half*w(ix^
d,
rho_)*(^
c&w(ix^
d,
m^
c_)**2+)
396 if (
eos%method /=
'analytic')
then
397 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**
eos%T%var2_min)
399 eint_val = max(eint_val, smalldouble)
400 if (eint_val * inv_rho >
eos%eint_rho_FI_threshold)
then
402 w(ix^
d,
p_) =
eos%gamma_minus_1 &
403 * (eint_val -
eos%eion_per_nH * nh(ix^
d))
406 eint_in = dlog10(eint_val) - log_nh(ix^
d)
407 w(ix^
d,
p_) = nh(ix^
d) &
411 w(ix^
d,
p_)=(
eos%gamma_minus_1)*(w(ix^
d,
e_)&
419 call dust_to_primitive(ixi^l, ixo^l, w, x)
424 end subroutine hd_to_primitive_lte
435 integer,
intent(in) :: ixi^
l, ixo^
l
436 double precision,
intent(in) :: w(ixi^s, 1:nw)
437 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
438 double precision,
intent(out):: pth(ixi^s)
440 double precision :: nh(ixi^s), ei(ixi^s), tpi, rpi
443 if (
eos%eos_type ==
'LTE')
then
445 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
446 pth(ixo^s) = nh(ixo^s) * (1.0d0 +
eos%He_abundance &
447 + (w(ixo^s,iw_ne) / nh(ixo^s))) * w(ixo^s,iw_te)
448 else if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
452 {
do ix^db=ixomin^db,ixomax^db\}
458 pth(ixo^s) =
eos%gamma_minus_1 * phys_get_ei(w, ixi^l, ixo^l)
461 if (.not.
associated(usr_set_pthermal))
then
464 call usr_set_pthermal(w,x,ixi^l,ixo^l,pth)
468 if (fix_small_values)
then
469 {
do ix^db= ixo^lim^db\}
470 if(pth(ix^d)<small_pressure)
then
471 pth(ix^d)=small_pressure
474 else if (check_small_values)
then
475 {
do ix^db= ixo^lim^db\}
476 if(pth(ix^d)<small_pressure)
then
477 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
478 " encountered when call hd_get_pthermal"
479 write(*,*)
"Iteration: ", it,
" Time: ", global_time
480 write(*,*)
"Location: ", x(ix^d,:)
481 write(*,*)
"Cell number: ", ix^d
483 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
485 if(trace_small_values)
write(*,*) dsqrt(pth(ix^d)-bigdouble)
486 write(*,*)
"Saving status at the previous time step"
496 subroutine hd_get_csound2_fi(w, x, ixI^L, ixO^L, cs2)
498 integer,
intent(in) :: ixi^
l, ixo^
l
499 double precision,
intent(in) :: w(ixi^s, nw)
500 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
501 double precision,
intent(out) :: cs2(ixi^s)
505 cs2(ixo^s) =
eos%gamma * w(ixo^s,
p_) / w(ixo^s,
rho_)
509 end subroutine hd_get_csound2_fi
513 subroutine hd_get_csound2_lte(w, x, ixI^L, ixO^L, cs2)
515 integer,
intent(in) :: ixi^
l, ixo^
l
516 double precision,
intent(in) :: w(ixi^s, nw)
517 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
518 double precision,
intent(out) :: cs2(ixi^s)
523 call hd_get_gamma1_lte(w, x, ixi^
l, ixo^
l, cs2)
524 {
do ix^db=ixomin^db,ixomax^db\}
525 cs2(ix^
d) = cs2(ix^
d) * w(ix^
d,
p_) / w(ix^
d,
rho_)
530 end subroutine hd_get_csound2_lte
539 subroutine p_to_e_pi(ixI^L, ixO^L, w, x)
541 integer,
intent(in) :: ixi^
l, ixo^
l
542 double precision,
intent(inout) :: w(ixi^s, nw)
543 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
544 double precision :: eint
547 {
do ix^db=ixomin^db,ixomax^db\}
553 end subroutine p_to_e_pi
556 subroutine hd_to_conserved_pi(ixI^L, ixO^L, w, x)
559 integer,
intent(in) :: ixi^
l, ixo^
l
560 double precision,
intent(inout) :: w(ixi^s, nw)
561 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
564 call p_to_e_pi(ixi^
l, ixo^
l, w, x)
569 end subroutine hd_to_conserved_pi
572 subroutine hd_to_primitive_pi(ixI^L, ixO^L, w, x)
575 integer,
intent(in) :: ixi^
l, ixo^
l
576 double precision,
intent(inout) :: w(ixi^s, nw)
577 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
578 double precision :: inv_rho, eint_val, t, rfac
585 'hd_to_primitive_PI')
588 {
do ix^db=ixomin^db,ixomax^db\}
589 inv_rho = 1.d0/w(ix^
d,
rho_)
593 eint_val = w(ix^
d,
e_) &
595 eint_val = max(eint_val, smalldouble)
601 if (
hd_dust)
call dust_to_primitive(ixi^l, ixo^l, w, x)
603 end subroutine hd_to_primitive_pi
629 subroutine hd_get_gamma1_lte(w, x, ixI^L, ixO^L, gamma1)
631 integer,
intent(in) :: ixi^
l, ixo^
l
632 double precision,
intent(in) :: w(ixi^s, nw)
633 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
634 double precision,
intent(out) :: gamma1(ixi^s)
636 double precision :: nh_val, p_over_rho
639 if (
eos%gamma1_method ==
'constant')
then
640 gamma1(ixo^s) =
eos%gamma
644 {
do ix^db=ixomin^db,ixomax^db\}
645 p_over_rho = w(ix^
d,
p_) / w(ix^
d,
rho_)
646 if (p_over_rho >
eos%p_rho_FI_threshold)
then
647 gamma1(ix^
d) =
eos%gamma
649 nh_val = w(ix^
d,
rho_) /
eos%nH2rhoFactor
650 if (
eos%method ==
'analytic')
then
651 if (iw_te > 0 .and. w(ix^
d,iw_te) > 0.0d0)
then
654 gamma1(ix^
d) =
eos%gamma
658 dlog10(w(ix^
d,
p_) / nh_val))
663 end subroutine hd_get_gamma1_lte
668 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
670 integer,
intent(in) :: ixi^
l, ixo^
l
671 double precision,
intent(in) :: w(ixi^s,1:nw)
672 double precision,
intent(in) :: x(ixi^s,1:
ndim)
673 double precision,
intent(out):: rfactor(ixi^s)
677 end subroutine rfactor_from_constant_ionization
682 subroutine hd_to_prolong_lte(ixI^L, ixO^L, w, x)
683 integer,
intent(in) :: ixi^l, ixo^l
684 double precision,
intent(inout) :: w(ixi^s, nw)
685 double precision,
intent(in) :: x(ixi^s, 1:ndim)
687 double precision :: inv_rho, eint_val, nh_val, log_nh, t_loc, y_loc
690 {
do ix^db=ixomin^db,ixomax^db\}
691 inv_rho = 1.d0 / w(ix^d,
rho_)
692 nh_val = w(ix^d,
rho_) /
eos%nH2rhoFactor
693 log_nh = dlog10(nh_val)
696 ^
c&w(ix^d,
m^
c_)=w(ix^d,
m^
c_)*inv_rho\
699 eint_val = w(ix^d,
e_) &
700 - half * w(ix^d,
rho_) * (^
c&w(ix^d,
m^
c_)**2+)
702 if (
eos%method /=
'analytic')
then
703 eint_val = max(eint_val, nh_val * 10.0d0**
eos%T%var2_min)
705 eint_val = max(eint_val, smalldouble)
708 if (eint_val * inv_rho >
eos%eint_rho_FI_threshold)
then
710 w(ix^d,
e_) =
eos%gamma_minus_1 &
711 * (eint_val -
eos%eion_per_nH * nh_val) &
712 / (nh_val *
eos%n_per_nH_FI)
713 else if (
eos%method ==
'analytic')
then
716 eint_val / nh_val, t_loc, y_loc)
721 dlog10(eint_val) - log_nh)
725 end subroutine hd_to_prolong_lte
729 subroutine hd_from_prolong_lte(ixI^L, ixO^L, w, x)
730 integer,
intent(in) :: ixi^l, ixo^l
731 double precision,
intent(inout) :: w(ixi^s, nw)
732 double precision,
intent(in) :: x(ixi^s, 1:ndim)
734 double precision :: t_val, eint_val, t_fi, nh_val, log_nh, log_t_min
737 t_fi = (eos%eint_rho_FI_threshold &
738 * eos%nH2rhoFactor - eos%eion_per_nH) &
739 * eos%gamma_minus_1 / eos%n_per_nH_FI
746 if (eos%method ==
'entropy')
then
747 log_t_min = eos%eintT%var2_min
749 log_t_min = eos%eint_from_T%var2_min
752 {
do ix^db=ixomin^db,ixomax^db\}
754 nh_val = w(ix^d, rho_) / eos%nH2rhoFactor
755 log_nh = dlog10(nh_val)
757 if (t_val > t_fi)
then
760 * (eos%n_per_nH_FI * t_val * eos%inv_gamma_minus_1 &
762 else if (eos%method ==
'analytic')
then
764 eint_val = saha_eint_from_nh_t(nh_val, t_val) * nh_val
767 eint_val = eint_nh_from_t(log_nh, &
768 dlog10(max(t_val, 10.0d0**log_t_min))) &
773 w(ix^d, e_) = eint_val &
774 + half * w(ix^d, rho_) * (^c&w(ix^d,m^c_)**2+)
776 ^c&w(ix^d,m^c_)=w(ix^d,rho_)*w(ix^d,m^c_)\
779 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.
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 H-only Saha EoS (eos_method == 'analytic').
double precision function, public saha_gamma1_from_nh_t(nh_code, t_code)
Look up Gamma1 from the analytical 2D table (nH, T axes in code units). For use when eosmethod == 'an...
subroutine, public saha_t_from_nh_eint(nh_code, eint_nh_code, t_out, y_out)
Temperature inversion: given (nH, eint/nH) in CODE UNITS, find T in CODE UNITS, by bisection (guarant...
subroutine, public saha_state_from_nh_p(nh_code, p_code, t_out, y_out, eint_nh_out)
Given (nH, p) in CODE UNITS, find T and y by solving p = nH*(1+y(T))*T_code. Uses bisection on T....
LTE (Saha-table) EoS kernels and finalise for the eos% family.
double precision function, public p_nh_from_eint(log_nh, log_eint_nh)
p/nH from (log10 nH, log10 eint/nH) in code units. Returns (1+He+y)*T directly – single lookup replac...
double precision function, public p2eint_from_nh_p(nh, ponh)
Pressure-to-eint ratio from (log10 nH, log10 p/nH) in code units. Dispatches: analytic -> Saha solve ...
double precision function, public eint_nh_from_t(log_nh, log_t)
Internal energy per nH from (log10 nH, log10 T) in code units. Uses the bisection-built inverse table...
subroutine, public eint_from_p_bisect(log_nh_val, log_p_val, log_eint_nh_out)
Given log10(nH) and log10(p), find log10(eint/nH) by table-guessed bisection on the forward pressure ...
double precision function, public y_from_nh_eint(nh, eint_nh)
Ionization fraction from (log10 nH, log10 eint/nH) in code units. Dispatches: analytic -> Saha quadra...
subroutine, public get_temperature_from_eint_fast_lte(w, x, ixil, ixol, res)
subroutine, public eos_get_eintt_grid(n_nh, lg_nh_min, lg_nh_max)
log_nH grid metadata of the (log_nH, log_T) inverse table (eint from T), choosing the container by me...
double precision function, public gamma1_from_nh_p(log_nh, log_p_nh)
Gamma_1 from pressure-indexed table: (log10 nH, log10 p/nH) -> Gamma_1. For 'entropy' the conversion ...
double precision function, public t_from_nh_eint(nh, eint_nh)
Temperature from (log10 nH, log10 eint/nH) in code units. Dispatches: analytic -> Saha bisection/Newt...
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.
subroutine, public eint_from_rho_p_pi(rho, p, eint)
Primitive pressure -> GAS internal energy (prim -> conserved direction): invert (rho,...
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.
subroutine, public state_from_eint_pi(rho, eint, t, p, rfactor, iz_h, iz_he)
Conserved gas internal energy -> temperature, thermal pressure, R. Inverse of p_eint_from_rho_T_PI....
Equation of state for AMRVAC, handled through a single eos_container object.
subroutine, public eos_finalise()
Phase 'commit' (after units are known): finalise the dispatch for the loaded physics – wire the metho...
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
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)
double precision, public, protected rr
type(tc_fluid), allocatable, public tc_fl
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
double precision, public hd_adiab
gamma is set in &eos_list and accessed via eosgamma
integer, public, protected rho_
Whether plasma is partially ionized.
subroutine, public hd_handle_small_values(primitive, w, x, ixil, ixol, subname)
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
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
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
double precision timeeos0
double precision timeeos_conv
double precision timeeos_csound
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor
procedure(hd_pthermal), pointer usr_set_pthermal