MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_ffhd_eos.t
Go to the documentation of this file.
1!=============================================================================
2!> FFHD <-> EoS seam: binds the eos% authority into force-free hydrodynamics.
3!>
4!> Mirrors mod_hd_eos.t, adapted to FFHD's structure: a single field-aligned
5!> momentum component mom(1) and NO magnetic energy (force-free, frozen B0), so
6!> every kinetic-energy term is half*rho*mom(1)**2. The B0 projection lives in
7!> the flux/cmax/velocity layer (mod_ffhd_phys.t) and is orthogonal to the EoS
8!> seam, so the thermodynamic conversions are HD-like with one momentum
9!> component.
10!>
11!> ffhd_link_eos -- wires eos%/phys_ pointers per eos_type (FI now;
12!> LTE/PI guarded until milestones 2/3).
13!> ffhd_bind_eos_to_source -- wires the thermal-conduction (tc_fl), radiative-
14!> cooling (rc_fl) and thermal-emission (te_fl_ffhd)
15!> fluid-port callbacks from eos%. This is what the
16!> pre-eos% hand-wiring was missing (rc_fl%get_Te /
17!> get_ne_nH), which caused the cooling SIGSEGV.
18!=============================================================================
21 use mod_physics
22 use mod_eos
23 !> Mode-specific kernels come from their sub-modules (the facade no longer
24 !> re-exports them); each mpistops if called under the wrong eos_type/method.
25 use mod_eos_lte
27 use mod_eos_pi
31
32 use mod_comm_lib, only: mpistop
33
34 implicit none
35 private
36
37 public :: ffhd_link_eos
38
39contains
40
41 !> Link the appropriate EoS conversion/closure routines per eos_type.
42 !> Called from ffhd_activate after ffhd_phys_init (mirrors hd_activate).
43 subroutine ffhd_link_eos()
45
46 ! Isothermal FFHD (no energy equation) has no thermodynamic state for
47 ! the EoS to close -- only FI is meaningful there.
48 if (.not. ffhd_energy .and. eos%eos_type /= 'FI') &
49 call mpistop("FFHD: ffhd_energy=.false. requires eos_type='FI'")
50
51 ! FI / PI base conversions = ffhd's origin routines (single-component
52 ! KE). PI energy mode overrides them below (milestone 3). LTE routes
53 ! primitive<->conserved through ffhd_p_to_e / table inversion.
54 if (eos%eos_type == 'FI' .or. eos%eos_type == 'PI') then
55 eos%to_conserved => ffhd_to_conserved_origin
56 eos%to_primitive => ffhd_to_primitive_origin
57 else if (eos%eos_type == 'LTE') then
58 eos%to_conserved => ffhd_to_conserved_lte
59 eos%to_primitive => ffhd_to_primitive_lte
60 else
61 call mpistop("Unknown FFHD EOS type: " // trim(eos%eos_type))
62 end if
63
64 phys_to_primitive => eos%to_primitive
65 phys_to_conserved => eos%to_conserved
66 ffhd_to_primitive => eos%to_primitive
67 ffhd_to_conserved => eos%to_conserved
68 phys_get_rho => eos%get_rho
69
70 ! suitable for both FI (origin inlines it) and LTE (conversions call it)
71 eos%p_to_e => ffhd_p_to_e
72
73 ! pthermal: the isothermal (no-energy) pointer is wired in phys_init and
74 ! left untouched; for the energy equation route through eos%. LTE reads
75 ! the stored Te_/Ne_ aux state; FI/PI use (gamma-1)*(e-KE).
76 if (ffhd_energy) then
77 if (eos%eos_type == 'LTE') then
78 phys_get_pthermal => ffhd_get_pthermal_lte
79 ffhd_get_pthermal => ffhd_get_pthermal_lte
80 eos%get_thermal_pressure => ffhd_get_pthermal_lte
81 else
84 eos%get_thermal_pressure => ffhd_get_pthermal_origin
85 end if
86 end if
87
88 phys_bind_eos_to_source => ffhd_bind_eos_to_source
89
90 ! Energy<->internal heads: ffhd previously handed these only to the TC
91 ! STS via set_conversion_methods_to_head; the LTE fast-T kernel and
92 ! phys_update_temperature also need the module-level phys_ pointers.
95 phys_get_ei => ffhd_get_ei ! LTE+ionE cooling recovers eint via this
96
97 ! sound speed / gamma1. LTE+ionE: Gamma_1(nH,p) from the EoS tables and
98 ! EoS-aware AMR prolongation (interpolate in (rho,v,T) to avoid Jensen's
99 ! inequality across the ionisation plateau). Otherwise FI: cs2=gamma*p/rho.
100 if (eos%eos_type == 'LTE' .and. eos%ionE) then
101 eos%get_csound2 => ffhd_get_csound2_lte
102 phys_get_gamma1 => ffhd_get_gamma1_lte
103 phys_to_prolong => ffhd_to_prolong_lte
104 phys_from_prolong => ffhd_from_prolong_lte
105 else
106 eos%get_csound2 => ffhd_get_csound2
107 phys_get_gamma1 => get_gamma1_fi
108 end if
109
110 ! ffhd_get_temperature (phys pointer) by eos_type: PI reads the cached
111 ! Te_, the others recompute from etot.
112 if (eos%eos_type == 'PI') then
114 else
116 end if
117 ! Rfactor: only the FI case is physics-dependent (usr_Rfactor). LTE and PI
118 ! bind pure eos% routines in eos_finalise_{LTE,PI} (run after this, before
119 ! ffhd_bind_eos_to_source -> targets stay private). usr_Rfactor thus applies
120 ! to FI only, consistent with mhd/hd.
121 if (associated(usr_rfactor)) then
122 eos%get_Rfactor => usr_rfactor
123 else
124 eos%get_Rfactor => rfactor_from_constant_ionization
125 end if
126 ! ffhd_get_Rfactor (runtime alias) captured in ffhd_bind_eos_to_source,
127 ! AFTER eos_finalise has set eos%get_Rfactor for LTE/PI.
128
129 !> PI energy-mode overrides (eos_type='PI', ionE=.true.). Energy mode
130 !> differs from no-energy PI only in the eint<->p relation (eint carries
131 !> the ionisation energy), so override exactly the routines touching it,
132 !> all via the portable mod_eos_pi backend. get_Rfactor stays the
133 !> Te_-addressed routine above (Te_ refreshed each step by
134 !> ffhd_update_temperature_PI).
135 if (eos%eos_type == 'PI' .and. eos%ionE) then
136 if (.not. ffhd_energy) &
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
140 phys_to_primitive => eos%to_primitive
141 phys_to_conserved => eos%to_conserved
142 ffhd_to_primitive => eos%to_primitive
143 ffhd_to_conserved => eos%to_conserved
144 eos%p_to_e => ffhd_p_to_e_pi
145 phys_get_pthermal => ffhd_get_pthermal_pi
146 ffhd_get_pthermal => ffhd_get_pthermal_pi
147 eos%get_thermal_pressure => ffhd_get_pthermal_pi
148 !> eos%get_csound2 => get_csound2_PI set in eos_finalise_PI (private target)
150 end if
151
152 end subroutine ffhd_link_eos
153
154 !> Wire the source-term fluid ports from eos%. Called from eos_finalise via
155 !> phys_bind_eos_to_source, AFTER eos_finalise has set eos%get_Te,
156 !> get_ne_nH, eion_per_nH, n_per_nH_FI/neOnH_FI, get_temperature_from_*.
157 subroutine ffhd_bind_eos_to_source()
158
159 !> Runtime R-factor alias: eos%get_Rfactor is fully set by now
160 !> (eos_finalise ran before phys_bind_eos_to_source), incl. the LTE/PI
161 !> bindings done in eos_finalise_{LTE,PI}.
162 ffhd_get_rfactor => eos%get_Rfactor
163
164 if (allocated(tc_fl)) then
165 call eos_bind_tc(tc_fl)
166 end if
167
168 if (allocated(rc_fl)) then
169 rc_fl%get_rho => eos%get_rho
170 rc_fl%get_pthermal => eos%get_thermal_pressure
171 rc_fl%get_var_Rfactor => eos%get_Rfactor
172 rc_fl%get_Te => eos%get_Te
173 rc_fl%get_ne_nH => eos%get_ne_nH
174 rc_fl%ionE = eos%ionE
175 rc_fl%method_analytic = (eos%method_id == eos_analytic)
176 rc_fl%inv_gamma_minus_1 = eos%inv_gamma_minus_1
177 rc_fl%nH2rhoFactor = eos%nH2rhoFactor
178 rc_fl%eion_per_nH = eos%eion_per_nH
179 rc_fl%eint_from_T => eint_nh_from_t
180 rc_fl%p2eint => p2eint_from_nh_p
181 rc_fl%T_from_eint => t_from_nh_eint
182 rc_fl%y_from_eint => y_from_nh_eint
183 rc_fl%log_T_floor = eos_get_log_t_floor()
185 if (eos%ionE .and. eos%eos_type == 'LTE') then
186 call eos_get_eintt_grid(rc_fl%Y_mod_n_nH, &
187 rc_fl%Y_mod_lg_nH_min, rc_fl%Y_mod_lg_nH_max)
189 end if
190 end if
191
192 !> PI energy-mode: repoint eint<->p kernels at the portable backend.
193 if (eos%eos_type == 'PI' .and. eos%ionE) then
194 if (allocated(tc_fl)) tc_fl%eint_from_T => eint_from_t_pi
195 if (allocated(rc_fl)) then
196 rc_fl%eint_from_T => eint_from_t_pi
197 rc_fl%p2eint => p2eint_pi
198 rc_fl%T_from_eint => t_from_eint_pi
199 rc_fl%y_from_eint => y_from_eint_pi
200 end if
201 end if
202
203 {^ifthreed
204 if (allocated(te_fl_ffhd)) then
205 te_fl_ffhd%get_rho => eos%get_rho
206 te_fl_ffhd%get_pthermal => eos%get_thermal_pressure
207 te_fl_ffhd%get_var_Rfactor => eos%get_Rfactor
208 te_fl_ffhd%get_ne_nH => eos%get_ne_nH
209 end if
210 }
211
212 end subroutine ffhd_bind_eos_to_source
213
214 !=========================================================================
215 !> LTE (Saha table) thermodynamics for FFHD. Mirrors mod_hd_eos.t adapted
216 !> to FFHD's single field-aligned momentum mom(1) and total-energy-only
217 !> ("origin") formulation; no dust, no magnetic energy.
218 !=========================================================================
219
220 !> LTE primitive -> conserved. On entry rho/v/p; on exit rho/mom/E.
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)
226
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
230
231 !> Convert pressure to total energy: E = eint(rho, p) + KE.
232 !> On entry rho/v/p; on exit w(e_) = total energy (rho, mom unchanged).
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)
238
239 integer :: ix^d
240 double precision :: nh(ixi^s), log_nh(ixi^s)
241
242 if (.not. ffhd_energy) return
243
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))
247
248 {do ix^db=ixomin^db,ixomax^db\}
249 w(ix^d,e_) = lte_eint_from_p(w(ix^d,p_), nh(ix^d), log_nh(ix^d), w(ix^d,rho_)) &
250 + half*w(ix^d,mom(1))**2*w(ix^d,rho_)
251 {end do\}
252 end subroutine ffhd_p_to_e
253
254 !> LTE conserved -> primitive. On entry rho/mom/E; on exit rho/v/p.
255 !> Pressure is energy-consistent from actual eint (stored Ne_/Te_ may be
256 !> stale after AMR prolong/coarsen on the nonlinear EoS).
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)
262
263 double precision :: inv_rho
264 double precision :: nh(ixi^s), log_nh(ixi^s)
265 double precision :: eint_val
266 integer :: ix^d
267
268 if (fix_small_values) then
269 call ffhd_handle_small_values(.false., w, x, ixi^l, ixo^l, &
270 'ffhd_to_primitive_LTE')
271 end if
272
273 call eos%get_nH(w, x, ixi^l, ixo^l, nh)
274 if (eos%ionE) log_nh(ixo^s) = dlog10(nh(ixo^s))
275
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)
282 end if
283 {end do\}
284 end subroutine ffhd_to_primitive_lte
285
286 !> LTE thermal pressure from the stored aux state: p = nH(1+He+ne/nH)*Te.
287 !> Mirrors the LTE branch of hd_get_pthermal (small-value guards from
288 !> ffhd_get_pthermal_origin).
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)
296 integer :: iw, ix^d
297 double precision :: nh(ixi^s)
298
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)
303 else
304 pth(ixo^s) = ffhd_adiab * w(ixo^s, rho_)**eos%gamma
305 end if
306
307 if (fix_small_values) then
308 {do ix^db= ixo^lim^db\}
309 if(pth(ix^d)<small_pressure) pth(ix^d)=small_pressure
310 {end do^D&\}
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
319 do iw=1,nw
320 write(*,*) trim(cons_wnames(iw)),": ",w(ix^d,iw)
321 end do
322 if(trace_small_values) write(*,*) dsqrt(pth(ix^d)-bigdouble)
323 write(*,*) "Saving status at the previous time step"
324 crash=.true.
325 end if
326 {end do^D&\}
327 end if
328 end subroutine ffhd_get_pthermal_lte
329
330 !> cs2 = Gamma_1(LTE) * p/rho.
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)
337 integer :: ix^d
338
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_)
342 {end do\}
343 end subroutine ffhd_get_csound2_lte
344
345 !> Effective Gamma_1 for LTE+IonE (dispatch on gamma1_method / eos%method).
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)
352 integer :: ix^d
353
354 if (eos%gamma1_method == 'constant') then
355 gamma1(ixo^s) = eos%gamma
356 return
357 end if
358
359 {do ix^db=ixomin^db,ixomax^db\}
360 gamma1(ix^d) = lte_gamma1_from_p(w(ix^d,p_), w(ix^d,rho_))
361 {end do\}
362 end subroutine ffhd_get_gamma1_lte
363
364 !> Conserved (rho, rho*v, E) -> prolong form (rho, v, T); T in the e_ slot.
365 !> Interpolating in (rho, v, T) avoids Jensen's inequality across the
366 !> ionisation plateau. Mirrors hd_to_prolong_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)
371
372 double precision :: inv_rho, eint_val, nh_val, log_nh, t_loc, y_loc
373 integer :: ix^d
374
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)
379
380 w(ix^d,mom(1)) = w(ix^d,mom(1))*inv_rho
381
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)
384
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)
391 w(ix^d, e_) = t_loc
392 else
393 w(ix^d, e_) = t_from_nh_eint(log_nh, &
394 dlog10(eint_val) - log_nh)
395 end if
396 {end do\}
397 end subroutine ffhd_to_prolong_lte
398
399 !> Prolong form (rho, v, T) -> conserved (rho, rho*v, E); T read from e_.
400 !> Mirrors hd_from_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)
405
406 double precision :: t_val, eint_val, t_fi, nh_val, log_nh, log_t_min
407 integer :: ix^d
408
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
412
413 if (eos%method_id == eos_entropy) then
414 log_t_min = eos%eintT%var2_min
415 else
416 log_t_min = eos%eint_from_T%var2_min
417 end if
418
419 {do ix^db=ixomin^db,ixomax^db\}
420 t_val = w(ix^d, e_)
421 nh_val = w(ix^d, rho_) / eos%nH2rhoFactor
422 log_nh = dlog10(nh_val)
423
424 if (t_val > t_fi) then
425 eint_val = nh_val &
426 * (eos%n_per_nH_FI * t_val * eos%inv_gamma_minus_1 &
427 + eos%eion_per_nH)
428 else if (eos%method_id == eos_analytic) then
429 eint_val = saha_eint_from_nh_t(nh_val, t_val) * nh_val
430 else
431 eint_val = eint_nh_from_t(log_nh, &
432 dlog10(max(t_val, 10.0d0**log_t_min))) * nh_val
433 end if
434
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))
437 {end do\}
438 end subroutine ffhd_from_prolong_lte
439
440 !=========================================================================
441 !> PI energy-mode (eos_type='PI', ionE=.true.) thermodynamics for FFHD.
442 !> eint carries the ionisation-energy term, so p=(gamma-1)*eint no longer
443 !> holds; the eint<->p relation is delegated to the portable scalar backend
444 !> (mod_eos_pi). Single momentum, total-energy only. Mirrors the
445 !> hd PI-energy family.
446 !=========================================================================
447
448 !> Primitive pressure -> total energy via backend (mom(1) is velocity here).
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
455 integer :: ix^d
456
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_)
461 end if
462 {end do\}
463 end subroutine ffhd_p_to_e_pi
464
465 !> Primitive -> conserved (PI energy).
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)
471
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
475
476 !> Conserved -> primitive (PI energy): KE removed -> eint, backend -> p.
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
483 integer :: ix^d
484
485 if (fix_small_values) then
486 call ffhd_handle_small_values(.false., w, x, ixi^l, ixo^l, &
487 'ffhd_to_primitive_PI')
488 end if
489
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, &
497 t, w(ix^d,p_), rfac)
498 end if
499 {end do\}
500 end subroutine ffhd_to_primitive_pi
501
502 !> PI-energy thermal pressure: eint (= e-KE) -> p via the backend.
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
509 integer :: ix^d
510
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)
514 {end do\}
515 end subroutine ffhd_get_pthermal_pi
516
517 !> Rfactor = p/(rho*T) for constant ionisation degree (FI/PI no-energy).
518 !> Stays in the seam: RR is the physics module's gas-constant factor, not
519 !> visible to mod_eos. Rfactor_from_LTE lives in mod_eos (no RR).
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)
526
527 rfactor(ixo^s)=rr
528
529 end subroutine rfactor_from_constant_ionization
530
531 !> Adiabatic sound speed^2 from primitive (rho, p) via the backend.
532
533 !> Effective Gamma_1 = cs2 * rho / p (PI energy).
534
535 !> PI-energy Te_ refresh: eint (= e-KE) -> T via the backend.
536
537 !> Prominence (T,p table) R-factor from (rho, pth) -- no-energy only, so
538 !> pth=(gamma-1)*eint and R is independent of it. Mirrors hd_Rfactor_prominence.
539
540 !> Prominence (T,p) Te_ update from (rho, pth).
541
542end module mod_ffhd_eos
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.
Definition mod_eos_lte.t:12
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.
Definition mod_eos_pi.t:27
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).
Definition mod_eos_pi.t:322
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).
Definition mod_eos_pi.t:315
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...
Definition mod_eos_pi.t:340
subroutine, public get_gamma1_pi(w, x, ixil, ixol, gamma1)
Effective Gamma1 = cs2 * rho / p for the same primitive state.
Definition mod_eos_pi.t:143
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.
Definition mod_eos_pi.t:331
Equation of state for AMRVAC, handled through a single eos_container object.
Definition mod_eos.t:30
subroutine, public eos_bind_tc(fl)
The EoS hooks of the conduction fluid fl.
Definition mod_eos.t:434
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...
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...
Definition mod_physics.t:4
procedure(sub_check_params), pointer phys_bind_eos_to_source
Definition mod_physics.t:55
procedure(sub_convert), pointer phys_to_primitive
Definition mod_physics.t:54
procedure(sub_e_to_ei), pointer phys_e_to_ei
Definition mod_physics.t:68
procedure(sub_e_to_ei), pointer phys_ei_to_e
Definition mod_physics.t:69
procedure(sub_get_pthermal), pointer phys_get_gamma1
Definition mod_physics.t:80
procedure(sub_get_pthermal), pointer phys_get_pthermal
Definition mod_physics.t:79
procedure(sub_get_ei), pointer phys_get_ei
Definition mod_physics.t:70
procedure(sub_convert), pointer phys_to_prolong
Definition mod_physics.t:57
procedure(sub_convert), pointer phys_to_conserved
Definition mod_physics.t:53
procedure(sub_convert), pointer phys_from_prolong
Definition mod_physics.t:58
procedure(sub_get_rho), pointer phys_get_rho
Definition mod_physics.t:72
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