49 call mpistop(
"FFHD: ffhd_energy=.false. requires eos_type='FI'")
54 if (
eos%eos_type ==
'FI' .or.
eos%eos_type ==
'PI')
then
57 else if (
eos%eos_type ==
'LTE')
then
58 eos%to_conserved => ffhd_to_conserved_lte
59 eos%to_primitive => ffhd_to_primitive_lte
61 call mpistop(
"Unknown FFHD EOS type: " // trim(
eos%eos_type))
71 eos%p_to_e => ffhd_p_to_e
77 if (
eos%eos_type ==
'LTE')
then
80 eos%get_thermal_pressure => ffhd_get_pthermal_lte
100 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
101 eos%get_csound2 => ffhd_get_csound2_lte
112 if (
eos%eos_type ==
'PI')
then
124 eos%get_Rfactor => rfactor_from_constant_ionization
135 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
137 call mpistop(
'FFHD PI energy EoS requires ffhd_energy=.true.')
138 eos%to_conserved => ffhd_to_conserved_pi
139 eos%to_primitive => ffhd_to_primitive_pi
144 eos%p_to_e => ffhd_p_to_e_pi
147 eos%get_thermal_pressure => ffhd_get_pthermal_pi
157 subroutine ffhd_bind_eos_to_source()
164 if (
allocated(
tc_fl))
then
168 if (
allocated(
rc_fl))
then
170 rc_fl%get_pthermal =>
eos%get_thermal_pressure
171 rc_fl%get_var_Rfactor =>
eos%get_Rfactor
176 rc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
177 rc_fl%nH2rhoFactor =
eos%nH2rhoFactor
183 rc_fl%log_T_floor = eos_get_log_t_floor()
185 if (
eos%ionE .and.
eos%eos_type ==
'LTE')
then
193 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
195 if (
allocated(
rc_fl))
then
212 end subroutine ffhd_bind_eos_to_source
221 subroutine ffhd_to_conserved_lte(ixI^L, ixO^L, w, x)
223 integer,
intent(in) :: ixi^
l, ixo^
l
224 double precision,
intent(inout) :: w(ixi^s, nw)
225 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
227 call ffhd_p_to_e(ixi^
l, ixo^
l, w, x)
228 w(ixo^s,
mom(1)) = w(ixo^s,
rho_)*w(ixo^s,
mom(1))
229 end subroutine ffhd_to_conserved_lte
233 subroutine ffhd_p_to_e(ixI^L, ixO^L, w, x)
235 integer,
intent(in) :: ixi^
l, ixo^
l
236 double precision,
intent(inout) :: w(ixi^s, nw)
237 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
240 double precision :: nh(ixi^s), log_nh(ixi^s)
244 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
245 log_nh(ixo^s) = 0.0d0
246 if (
eos%ionE) log_nh(ixo^s) = dlog10(nh(ixo^s))
248 {
do ix^db=ixomin^db,ixomax^db\}
252 end subroutine ffhd_p_to_e
257 subroutine ffhd_to_primitive_lte(ixI^L, ixO^L, w, x)
259 integer,
intent(in) :: ixi^
l, ixo^
l
260 double precision,
intent(inout) :: w(ixi^s, nw)
261 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
263 double precision :: inv_rho
264 double precision :: nh(ixi^s), log_nh(ixi^s)
265 double precision :: eint_val
269 call ffhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
270 'ffhd_to_primitive_LTE')
273 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
274 if (eos%ionE) log_nh(ixo^s) = dlog10(nh(ixo^s))
276 {
do ix^db=ixomin^db,ixomax^db\}
277 inv_rho = 1.d0/w(ix^
d,rho_)
278 w(ix^
d,mom(1)) = w(ix^
d,mom(1))*inv_rho
279 if (ffhd_energy)
then
280 eint_val = w(ix^
d,e_) - half*w(ix^
d,rho_)*w(ix^
d,mom(1))**2
281 w(ix^
d,p_) = lte_p_from_eint(eint_val, nh(ix^
d), log_nh(ix^
d), inv_rho)
284 end subroutine ffhd_to_primitive_lte
289 subroutine ffhd_get_pthermal_lte(w, x, ixI^L, ixO^L, pth)
292 integer,
intent(in) :: ixi^
l, ixo^
l
293 double precision,
intent(in) :: w(ixi^s, 1:nw)
294 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
295 double precision,
intent(out):: pth(ixi^s)
297 double precision :: nh(ixi^s)
299 if (ffhd_energy)
then
300 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
301 pth(ixo^s) = nh(ixo^s) * (1.0d0 + eos%He_abundance &
302 + (w(ixo^s,iw_ne) / nh(ixo^s))) * w(ixo^s,iw_te)
304 pth(ixo^s) = ffhd_adiab * w(ixo^s, rho_)**eos%gamma
308 {
do ix^db= ixo^lim^db\}
311 else if (check_small_values)
then
312 {
do ix^db= ixo^lim^db\}
313 if(pth(ix^d)<small_pressure)
then
314 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
315 " encountered when call ffhd_get_pthermal_LTE"
316 write(*,*)
"Iteration: ", it,
" Time: ", global_time
317 write(*,*)
"Location: ", x(ix^d,:)
318 write(*,*)
"Cell number: ", ix^d
320 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
322 if(trace_small_values)
write(*,*) dsqrt(pth(ix^d)-bigdouble)
323 write(*,*)
"Saving status at the previous time step"
328 end subroutine ffhd_get_pthermal_lte
331 subroutine ffhd_get_csound2_lte(w, x, ixI^L, ixO^L, cs2)
333 integer,
intent(in) :: ixi^
l, ixo^
l
334 double precision,
intent(in) :: w(ixi^s, nw)
335 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
336 double precision,
intent(out) :: cs2(ixi^s)
339 call ffhd_get_gamma1_lte(w, x, ixi^
l, ixo^
l, cs2)
340 {
do ix^db=ixomin^db,ixomax^db\}
341 cs2(ix^
d) = cs2(ix^
d) * w(ix^
d, p_) / w(ix^
d, rho_)
343 end subroutine ffhd_get_csound2_lte
346 subroutine ffhd_get_gamma1_lte(w, x, ixI^L, ixO^L, gamma1)
348 integer,
intent(in) :: ixi^
l, ixo^
l
349 double precision,
intent(in) :: w(ixi^s, nw)
350 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
351 double precision,
intent(out) :: gamma1(ixi^s)
354 if (eos%gamma1_method ==
'constant')
then
355 gamma1(ixo^s) = eos%gamma
359 {
do ix^db=ixomin^db,ixomax^db\}
360 gamma1(ix^
d) = lte_gamma1_from_p(w(ix^
d,p_), w(ix^
d,rho_))
362 end subroutine ffhd_get_gamma1_lte
367 subroutine ffhd_to_prolong_lte(ixI^L, ixO^L, w, x)
368 integer,
intent(in) :: ixi^l, ixo^l
369 double precision,
intent(inout) :: w(ixi^s, nw)
370 double precision,
intent(in) :: x(ixi^s, 1:ndim)
372 double precision :: inv_rho, eint_val, nh_val, log_nh, t_loc, y_loc
375 {
do ix^db=ixomin^db,ixomax^db\}
376 inv_rho = 1.d0 / w(ix^d, rho_)
377 nh_val = w(ix^d, rho_) / eos%nH2rhoFactor
378 log_nh = dlog10(nh_val)
380 w(ix^d,mom(1)) = w(ix^d,mom(1))*inv_rho
382 eint_val = w(ix^d, e_) - half*w(ix^d, rho_)*w(ix^d,mom(1))**2
383 eint_val = max(eint_val, nh_val*eos%eint_nH_min, smalldouble)
385 if (eint_val * inv_rho > eos%eint_rho_FI_threshold)
then
386 w(ix^d, e_) = eos%gamma_minus_1 &
387 * (eint_val - eos%eion_per_nH * nh_val) &
388 / (nh_val * eos%n_per_nH_FI)
389 else if (eos%method_id == eos_analytic)
then
390 call saha_t_from_nh_eint(nh_val, eint_val / nh_val, t_loc, y_loc)
393 w(ix^d, e_) = t_from_nh_eint(log_nh, &
394 dlog10(eint_val) - log_nh)
397 end subroutine ffhd_to_prolong_lte
401 subroutine ffhd_from_prolong_lte(ixI^L, ixO^L, w, x)
402 integer,
intent(in) :: ixi^l, ixo^l
403 double precision,
intent(inout) :: w(ixi^s, nw)
404 double precision,
intent(in) :: x(ixi^s, 1:ndim)
406 double precision :: t_val, eint_val, t_fi, nh_val, log_nh, log_t_min
409 t_fi = (eos%eint_rho_FI_threshold &
410 * eos%nH2rhoFactor - eos%eion_per_nH) &
411 * eos%gamma_minus_1 / eos%n_per_nH_FI
413 if (eos%method_id == eos_entropy)
then
414 log_t_min = eos%eintT%var2_min
416 log_t_min = eos%eint_from_T%var2_min
419 {
do ix^db=ixomin^db,ixomax^db\}
421 nh_val = w(ix^d, rho_) / eos%nH2rhoFactor
422 log_nh = dlog10(nh_val)
424 if (t_val > t_fi)
then
426 * (eos%n_per_nH_FI * t_val * eos%inv_gamma_minus_1 &
428 else if (eos%method_id == eos_analytic)
then
429 eint_val = saha_eint_from_nh_t(nh_val, t_val) * nh_val
431 eint_val = eint_nh_from_t(log_nh, &
432 dlog10(max(t_val, 10.0d0**log_t_min))) * nh_val
435 w(ix^d, e_) = eint_val + half*w(ix^d, rho_)*w(ix^d,mom(1))**2
436 w(ix^d,mom(1)) = w(ix^d,rho_)*w(ix^d,mom(1))
438 end subroutine ffhd_from_prolong_lte
449 subroutine ffhd_p_to_e_pi(ixI^L, ixO^L, w, x)
451 integer,
intent(in) :: ixi^
l, ixo^
l
452 double precision,
intent(inout) :: w(ixi^s, nw)
453 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
454 double precision :: eint
457 {
do ix^db=ixomin^db,ixomax^db\}
458 if (ffhd_energy)
then
459 call eint_from_rho_p_pi(w(ix^
d,rho_), w(ix^
d,p_), eint)
460 w(ix^
d,e_) = eint + half*w(ix^
d,mom(1))**2*w(ix^
d,rho_)
463 end subroutine ffhd_p_to_e_pi
466 subroutine ffhd_to_conserved_pi(ixI^L, ixO^L, w, x)
468 integer,
intent(in) :: ixi^
l, ixo^
l
469 double precision,
intent(inout) :: w(ixi^s, nw)
470 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
472 call ffhd_p_to_e_pi(ixi^
l, ixo^
l, w, x)
473 w(ixo^s,mom(1)) = w(ixo^s,rho_)*w(ixo^s,mom(1))
474 end subroutine ffhd_to_conserved_pi
477 subroutine ffhd_to_primitive_pi(ixI^L, ixO^L, w, x)
479 integer,
intent(in) :: ixi^
l, ixo^
l
480 double precision,
intent(inout) :: w(ixi^s, nw)
481 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
482 double precision :: inv_rho, eint_val, t, rfac
486 call ffhd_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
487 'ffhd_to_primitive_PI')
490 {
do ix^db=ixomin^db,ixomax^db\}
491 inv_rho = 1.d0/w(ix^
d,rho_)
492 w(ix^
d,mom(1)) = w(ix^
d,mom(1))*inv_rho
493 if (ffhd_energy)
then
494 eint_val = w(ix^
d,e_) - half*w(ix^
d,rho_)*w(ix^
d,mom(1))**2
495 eint_val = max(eint_val, smalldouble)
496 call state_from_eint_pi(w(ix^
d,rho_), eint_val, &
500 end subroutine ffhd_to_primitive_pi
503 subroutine ffhd_get_pthermal_pi(w, x, ixI^L, ixO^L, pth)
505 integer,
intent(in) :: ixi^
l, ixo^
l
506 double precision,
intent(in) :: w(ixi^s, 1:nw), x(ixi^s, 1:
ndim)
507 double precision,
intent(out):: pth(ixi^s)
508 double precision :: ei(ixi^s), tpi, rpi
511 ei(ixo^s) = ffhd_get_ei(w, ixi^
l, ixo^
l)
512 {
do ix^db=ixomin^db,ixomax^db\}
513 call state_from_eint_pi(w(ix^
d,rho_), ei(ix^
d), tpi, pth(ix^
d), rpi)
515 end subroutine ffhd_get_pthermal_pi
520 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
522 integer,
intent(in) :: ixi^
l, ixo^
l
523 double precision,
intent(in) :: w(ixi^s,1:nw)
524 double precision,
intent(in) :: x(ixi^s,1:
ndim)
525 double precision,
intent(out):: rfactor(ixi^s)
529 end subroutine rfactor_from_constant_ionization
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
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 lte_eint_from_p(pres, nh_val, log_nh_val, rho_val)
LTE internal energy from pressure in one cell: FI bypass, else eint(nH, p).
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)
The EoS hooks of the conduction fluid fl.
FFHD <-> EoS seam: binds the eos% authority into force-free hydrodynamics.
subroutine, public ffhd_link_eos()
Link the appropriate EoS conversion/closure routines per eos_type. Called from ffhd_activate after ff...
Frozen-field hydrodynamics module.
integer, public, protected e_
Index of the energy density (-1 if not present).
subroutine, public ffhd_to_primitive_origin(ixil, ixol, w, x)
procedure(sub_get_pthermal), pointer, public ffhd_get_rfactor
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.
procedure(sub_get_pthermal), pointer, public ffhd_get_pthermal
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)
subroutine, public ffhd_get_csound2(w, x, ixil, ixol, csound2)
logical, public, protected ffhd_energy
Whether an energy equation is used.
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
subroutine, public ffhd_get_pthermal_origin(w, x, ixil, ixol, pth)
procedure(sub_convert), pointer, public ffhd_to_primitive
subroutine, public ffhd_get_temperature_from_te(w, x, ixil, ixol, res)
subroutine, public ffhd_to_conserved_origin(ixil, ixol, w, x)
subroutine, public ffhd_ei_to_e(ixil, ixol, w, x)
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
subroutine, public ffhd_e_to_ei(ixil, ixol, w, x)
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision small_pressure
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
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_e_to_ei), pointer phys_e_to_ei
procedure(sub_e_to_ei), pointer phys_ei_to_e
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