61 if (
eos%eos_type ==
'FI' .or.
eos%eos_type ==
'PI')
then
63 eos%to_primitive => mhd_to_primitive_hde
64 eos%to_conserved => mhd_to_conserved_hde
67 eos%to_primitive => mhd_to_primitive_semirelati
68 eos%to_conserved => mhd_to_conserved_semirelati
70 eos%to_primitive => mhd_to_primitive_semirelati_noe
71 eos%to_conserved => mhd_to_conserved_semirelati_noe
75 eos%to_primitive => mhd_to_primitive_split_rho
76 eos%to_conserved => mhd_to_conserved_split_rho
78 eos%to_primitive => mhd_to_primitive_inte
79 eos%to_conserved => mhd_to_conserved_inte
81 eos%to_primitive => mhd_to_primitive_origin
82 eos%to_conserved => mhd_to_conserved_origin
84 eos%to_primitive => mhd_to_primitive_origin_noe
85 eos%to_conserved => mhd_to_conserved_origin_noe
88 else if (
eos%eos_type ==
'LTE')
then
91 call mpistop(
'LTE EoS not supported with mhd_hydrodynamic_e')
93 call mpistop(
'LTE EoS not supported with mhd_semirelativistic')
95 call mpistop(
'LTE EoS not supported with equilibrium splitting')
97 call mpistop(
'LTE EoS requires mhd_energy=.true.')
100 eos%to_primitive => mhd_to_primitive_inte_lte
101 eos%to_conserved => mhd_to_conserved_inte_lte
103 eos%to_primitive => mhd_to_primitive_origin_lte
104 eos%to_conserved => mhd_to_conserved_origin_lte
107 call mpistop(
'Error: Unknown MHD EOS type: ' // trim(
eos%eos_type))
117 eos%p_to_e => mhd_p_to_eint
119 eos%p_to_e => mhd_p_to_e
123 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
124 eos%get_csound2 => mhd_get_csound2_lte
127 eos%get_csound2 => mhd_get_csound2_fi
132 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
144 eos%get_Rfactor => rfactor_from_constant_ionization
167 if (
eos%eos_type ==
'LTE')
then
175 if(
eos%eos_type ==
'PI' .or.
eos%eos_type ==
'LTE')
then
206 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
208 call mpistop(
'PI energy EoS requires mhd_energy=.true.')
210 call mpistop(
'PI energy EoS not supported with mhd_hydrodynamic_e')
212 call mpistop(
'PI energy EoS not supported with mhd_semirelativistic')
214 call mpistop(
'PI energy EoS not supported with equilibrium splitting')
217 eos%to_conserved => mhd_to_conserved_inte_pi
218 eos%to_primitive => mhd_to_primitive_inte_pi
219 eos%p_to_e => mhd_p_to_eint_pi
223 eos%to_conserved => mhd_to_conserved_origin_pi
224 eos%to_primitive => mhd_to_primitive_origin_pi
225 eos%p_to_e => mhd_p_to_e_pi
251 subroutine bind_eos_to_source()
262 if (
eos%eos_type ==
'LTE')
then
265 eos%get_temperature_from_etot =>
eos%get_temperature_from_eint
268 eos%get_temperature_from_etot => mhd_get_temperature_from_etot_lte
274 eos%get_temperature_from_etot => mhd_get_temperature_from_eint_with_equi
275 eos%get_temperature_from_eint => mhd_get_temperature_from_eint_with_equi
277 eos%get_temperature_from_etot => mhd_get_temperature_from_eint
278 eos%get_temperature_from_eint => mhd_get_temperature_from_eint
283 eos%get_temperature_from_etot => mhd_get_temperature_from_etot_with_equi
284 eos%get_temperature_from_eint => mhd_get_temperature_from_eint_with_equi
286 eos%get_temperature_from_etot => mhd_get_temperature_from_etot
287 eos%get_temperature_from_eint => mhd_get_temperature_from_eint
292 if (
allocated(
tc_fl))
then
293 tc_fl%get_temperature_from_conserved =>
eos%get_temperature_from_etot
294 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
297 tc_fl%get_temperature_from_eint =>
eos%get_temperature_from_eint
301 tc_fl%get_var_Rfactor =>
eos%get_Rfactor
302 tc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
303 tc_fl%nH2rhoFactor =
eos%nH2rhoFactor
304 tc_fl%log_T_floor = eos_get_log_t_floor()
308 tc_fl%subtract_equi = .true.
309 tc_fl%get_temperature_equi => mhd_get_temperature_equi
310 tc_fl%get_rho_equi => mhd_get_rho_equi
312 tc_fl%subtract_equi = .false.
316 if (
allocated(
rc_fl))
then
318 rc_fl%get_pthermal =>
eos%get_thermal_pressure
319 rc_fl%get_var_Rfactor =>
eos%get_Rfactor
324 rc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
325 rc_fl%nH2rhoFactor =
eos%nH2rhoFactor
333 rc_fl%subtract_equi = .true.
334 rc_fl%get_rho_equi => mhd_get_rho_equi
335 rc_fl%get_pthermal_equi => mhd_get_pe_equi
337 rc_fl%subtract_equi = .false.
346 if (
eos%ionE .and.
eos%eos_type ==
'LTE')
then
357 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
359 if (
allocated(
rc_fl))
then
374 if (
allocated(
fld_fl))
then
378 fld_fl%get_tgas =>
eos%get_temperature_from_pressure
382 end subroutine bind_eos_to_source
387 subroutine mhd_to_conserved_origin(ixI^L,ixO^L,w,x)
389 integer,
intent(in) :: ixi^
l, ixo^
l
390 double precision,
intent(inout) :: w(ixi^s, nw)
391 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
395 {
do ix^db=ixomin^db,ixomax^db\}
397 w(ix^
d,
e_)=w(ix^
d,
p_)*
eos%inv_gamma_minus_1&
399 +(^
c&w(ix^
d,
b^
c_)**2+))
404 end subroutine mhd_to_conserved_origin
407 subroutine mhd_to_conserved_origin_noe(ixI^L,ixO^L,w,x)
409 integer,
intent(in) :: ixi^
l, ixo^
l
410 double precision,
intent(inout) :: w(ixi^s, nw)
411 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
415 {
do ix^db=ixomin^db,ixomax^db\}
417 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
420 end subroutine mhd_to_conserved_origin_noe
423 subroutine mhd_to_conserved_hde(ixI^L,ixO^L,w,x)
425 integer,
intent(in) :: ixi^
l, ixo^
l
426 double precision,
intent(inout) :: w(ixi^s, nw)
427 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
431 {
do ix^db=ixomin^db,ixomax^db\}
433 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1&
434 +half*(^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)
436 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
439 end subroutine mhd_to_conserved_hde
442 subroutine mhd_to_conserved_inte(ixI^L,ixO^L,w,x)
444 integer,
intent(in) :: ixi^
l, ixo^
l
445 double precision,
intent(inout) :: w(ixi^s, nw)
446 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
450 {
do ix^db=ixomin^db,ixomax^db\}
452 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1
454 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
457 end subroutine mhd_to_conserved_inte
460 subroutine mhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
462 integer,
intent(in) :: ixi^
l, ixo^
l
463 double precision,
intent(inout) :: w(ixi^s, nw)
464 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
466 double precision :: rho
469 {
do ix^db=ixomin^db,ixomax^db\}
470 rho=w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,
b0i)
472 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1&
473 +half*((^c&w(ix^
d,m^c_)**2+)*rho&
474 +(^c&w(ix^
d,b^c_)**2+))
476 ^c&w(ix^
d,m^c_)=rho*w(ix^
d,m^c_)\
479 end subroutine mhd_to_conserved_split_rho
482 subroutine mhd_to_conserved_semirelati(ixI^L,ixO^L,w,x)
484 integer,
intent(in) :: ixi^
l, ixo^
l
485 double precision,
intent(inout) :: w(ixi^s, nw)
486 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
488 double precision :: e(ixo^s,1:
ndir), s(ixo^s,1:
ndir)
491 {
do ix^db=ixomin^db,ixomax^db\}
493 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
494 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
495 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
496 s(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
497 s(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
498 s(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
503 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
504 s(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
505 s(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
511 if(mhd_internal_e)
then
513 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1
517 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1&
518 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
519 +(^c&w(ix^
d,b^c_)**2+)&
520 +(^c&e(ix^
d,^c)**2+)*eos%inv_squared_c)
524 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)+s(ix^
d,^c)*eos%inv_squared_c\
528 end subroutine mhd_to_conserved_semirelati
530 subroutine mhd_to_conserved_semirelati_noe(ixI^L,ixO^L,w,x)
532 integer,
intent(in) :: ixi^
l, ixo^
l
533 double precision,
intent(inout) :: w(ixi^s, nw)
534 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
536 double precision :: e(ixo^s,1:
ndir), s(ixo^s,1:
ndir)
539 {
do ix^db=ixomin^db,ixomax^db\}
541 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
542 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
543 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
544 s(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
545 s(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
546 s(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
551 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
552 s(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
553 s(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
559 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)+s(ix^
d,^c)*eos%inv_squared_c\
563 end subroutine mhd_to_conserved_semirelati_noe
566 subroutine mhd_to_primitive_origin(ixI^L,ixO^L,w,x)
568 integer,
intent(in) :: ixi^
l, ixo^
l
569 double precision,
intent(inout) :: w(ixi^s, nw)
570 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
572 double precision :: inv_rho
576 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_origin')
579 {
do ix^db=ixomin^db,ixomax^db\}
580 inv_rho = 1.d0/w(ix^
d,rho_)
582 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
584 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)&
585 -half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+)&
586 +(^c&w(ix^
d,b^c_)**2+)))
589 end subroutine mhd_to_primitive_origin
592 subroutine mhd_to_primitive_origin_noe(ixI^L,ixO^L,w,x)
594 integer,
intent(in) :: ixi^
l, ixo^
l
595 double precision,
intent(inout) :: w(ixi^s, nw)
596 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
598 double precision :: inv_rho
602 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_origin_noe')
605 {
do ix^db=ixomin^db,ixomax^db\}
606 inv_rho = 1.d0/w(ix^
d,rho_)
608 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
611 end subroutine mhd_to_primitive_origin_noe
614 subroutine mhd_to_primitive_hde(ixI^L,ixO^L,w,x)
616 integer,
intent(in) :: ixi^
l, ixo^
l
617 double precision,
intent(inout) :: w(ixi^s, nw)
618 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
620 double precision :: inv_rho
624 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_hde')
627 {
do ix^db=ixomin^db,ixomax^db\}
628 inv_rho = 1.d0/w(ix^
d,rho_)
630 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
632 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)-half*w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+))
635 end subroutine mhd_to_primitive_hde
638 subroutine mhd_to_primitive_inte(ixI^L,ixO^L,w,x)
640 integer,
intent(in) :: ixi^
l, ixo^
l
641 double precision,
intent(inout) :: w(ixi^s, nw)
642 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
644 double precision :: inv_rho
648 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_inte')
651 {
do ix^db=ixomin^db,ixomax^db\}
653 w(ix^
d,p_)=w(ix^
d,e_)*eos%gamma_minus_1
655 inv_rho = 1.d0/w(ix^
d,rho_)
656 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
659 end subroutine mhd_to_primitive_inte
662 subroutine mhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
664 integer,
intent(in) :: ixi^
l, ixo^
l
665 double precision,
intent(inout) :: w(ixi^s, nw)
666 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
668 double precision :: inv_rho
672 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_split_rho')
675 {
do ix^db=ixomin^db,ixomax^db\}
676 inv_rho=1.d0/(w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,
b0i))
678 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
680 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)&
681 -half*((w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,
b0i))*&
682 (^c&w(ix^
d,m^c_)**2+)+(^c&w(ix^
d,b^c_)**2+)))
685 end subroutine mhd_to_primitive_split_rho
688 subroutine mhd_to_primitive_semirelati(ixI^L,ixO^L,w,x)
690 integer,
intent(in) :: ixi^
l, ixo^
l
691 double precision,
intent(inout) :: w(ixi^s, nw)
692 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
694 double precision :: b(ixo^s,1:
ndir), tmp, b2, gamma2, inv_rho
698 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_semirelati')
701 {
do ix^db=ixomin^db,ixomax^db\}
702 b2=(^c&w(ix^
d,b^c_)**2+)
703 if(b2>smalldouble)
then
708 ^c&b(ix^
d,^c)=w(ix^
d,b^c_)*tmp\
709 tmp=(^c&b(ix^
d,^c)*w(ix^
d,m^c_)+)
711 inv_rho=1.d0/w(ix^
d,rho_)
713 b2=b2*inv_rho*eos%inv_squared_c
715 gamma2=1.d0/(1.d0+b2)
717 ^c&w(ix^
d,m^c_)=gamma2*(w(ix^
d,m^c_)+b2*b(ix^
d,^c)*tmp)*inv_rho\
719 if(mhd_internal_e)
then
721 w(ix^
d,p_)=eos%gamma_minus_1*w(ix^
d,e_)
725 b(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
726 b(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
727 b(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
731 b(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
737 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)&
738 -half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
739 +(^c&w(ix^
d,b^c_)**2+)&
740 +(^c&b(ix^
d,^c)**2+)*eos%inv_squared_c))
744 end subroutine mhd_to_primitive_semirelati
747 subroutine mhd_to_primitive_semirelati_noe(ixI^L,ixO^L,w,x)
749 integer,
intent(in) :: ixi^
l, ixo^
l
750 double precision,
intent(inout) :: w(ixi^s, nw)
751 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
753 double precision :: b(ixo^s,1:
ndir),tmp,b2,gamma2,inv_rho
754 integer :: ix^
d, idir
757 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_semirelati_noe')
760 {
do ix^db=ixomin^db,ixomax^db\}
761 b2=(^c&w(ix^
d,b^c_)**2+)
762 if(b2>smalldouble)
then
767 ^c&b(ix^
d,^c)=w(ix^
d,b^c_)*tmp\
768 tmp=(^c&b(ix^
d,^c)*w(ix^
d,m^c_)+)
770 inv_rho=1.d0/w(ix^
d,rho_)
772 b2=b2*inv_rho*eos%inv_squared_c
774 gamma2=1.d0/(1.d0+b2)
776 ^c&w(ix^
d,m^c_)=gamma2*(w(ix^
d,m^c_)+b2*b(ix^
d,^c)*tmp)*inv_rho\
779 end subroutine mhd_to_primitive_semirelati_noe
785 subroutine mhd_to_conserved_origin_lte(ixI^L,ixO^L,w,x)
787 integer,
intent(in) :: ixi^
l, ixo^
l
788 double precision,
intent(inout) :: w(ixi^s, nw)
789 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
791 timeeos0 = mpi_wtime()
794 call mhd_p_to_e(ixi^
l, ixo^
l, w, x)
796 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
798 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
800 end subroutine mhd_to_conserved_origin_lte
804 subroutine mhd_to_conserved_inte_lte(ixI^L,ixO^L,w,x)
806 integer,
intent(in) :: ixi^
l, ixo^
l
807 double precision,
intent(inout) :: w(ixi^s, nw)
808 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
810 timeeos0 = mpi_wtime()
813 call mhd_p_to_eint(ixi^
l, ixo^
l, w, x)
815 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
817 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
819 end subroutine mhd_to_conserved_inte_lte
823 subroutine mhd_p_to_e(ixI^L,ixO^L,w,x)
825 integer,
intent(in) :: ixi^
l, ixo^
l
826 double precision,
intent(inout) :: w(ixi^s, nw)
827 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
830 double precision :: p_to_eint, p_over_rho
831 double precision :: nh(ixi^s), nh_in(ixi^s), p_in(ixi^s)
832 double precision :: t_solve, y_solve, eint_nh_solve
833 double precision :: log_eint_mid, eint_total
836 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
837 nh_in(ixo^s) = dlog10(nh(ixo^s))
838 if (eos%p2eint_method /=
'bisect')
then
839 p_in(ixo^s) = dlog10(w(ixo^s,p_)) - nh_in(ixo^s)
843 p_to_eint = eos%inv_gamma_minus_1
844 {
do ix^db=ixomin^db,ixomax^db\}
846 p_over_rho = w(ix^
d,p_) / w(ix^
d,rho_)
847 if (p_over_rho > eos%p_rho_FI_threshold)
then
848 p_to_eint = eos%inv_gamma_minus_1 &
849 + eos%eion_per_nH * nh(ix^
d) / w(ix^
d,p_)
850 w(ix^
d,e_)=w(ix^
d,p_)*p_to_eint&
851 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
852 +(^c&w(ix^
d,b^c_)**2+))
853 else if (eos%method ==
'analytic')
then
854 call saha_state_from_nh_p(nh(ix^
d), w(ix^
d,p_), &
855 t_solve, y_solve, eint_nh_solve)
856 w(ix^
d,e_) = eint_nh_solve * nh(ix^
d) &
857 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
858 +(^c&w(ix^
d,b^c_)**2+))
859 else if (eos%p2eint_method ==
'bisect')
then
860 call eint_from_p_bisect(nh_in(ix^
d), &
861 dlog10(w(ix^
d,p_)), log_eint_mid)
862 eint_total = nh(ix^
d) * 10.0d0**log_eint_mid
863 eint_total = max(eint_total, &
864 nh(ix^
d) * 10.0d0**eos%T%var2_min)
865 w(ix^
d,e_) = eint_total + &
866 half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
867 +(^c&w(ix^
d,b^c_)**2+))
869 p_to_eint = p2eint_from_nh_p(nh_in(ix^
d), p_in(ix^
d))
870 w(ix^
d,e_)=w(ix^
d,p_)*p_to_eint&
871 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
872 +(^c&w(ix^
d,b^c_)**2+))
875 w(ix^
d,e_)=w(ix^
d,p_)*p_to_eint&
876 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
877 +(^c&w(ix^
d,b^c_)**2+))
881 end subroutine mhd_p_to_e
885 subroutine mhd_p_to_eint(ixI^L,ixO^L,w,x)
887 integer,
intent(in) :: ixi^
l, ixo^
l
888 double precision,
intent(inout) :: w(ixi^s, nw)
889 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
892 double precision :: p_to_eint, p_over_rho
893 double precision :: nh(ixi^s), nh_in(ixi^s), p_in(ixi^s)
894 double precision :: t_solve, y_solve, eint_nh_solve
895 double precision :: log_eint_mid, eint_total
898 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
899 nh_in(ixo^s) = dlog10(nh(ixo^s))
900 if (eos%p2eint_method /=
'bisect')
then
901 p_in(ixo^s) = dlog10(w(ixo^s,p_)) - nh_in(ixo^s)
905 p_to_eint = eos%inv_gamma_minus_1
906 {
do ix^db=ixomin^db,ixomax^db\}
908 p_over_rho = w(ix^
d,p_) / w(ix^
d,rho_)
909 if (p_over_rho > eos%p_rho_FI_threshold)
then
910 p_to_eint = eos%inv_gamma_minus_1 &
911 + eos%eion_per_nH * nh(ix^
d) / w(ix^
d,p_)
912 w(ix^
d,e_) = w(ix^
d,p_) * p_to_eint
913 else if (eos%method ==
'analytic')
then
914 call saha_state_from_nh_p(nh(ix^
d), w(ix^
d,p_), &
915 t_solve, y_solve, eint_nh_solve)
916 w(ix^
d,e_) = eint_nh_solve * nh(ix^
d)
917 else if (eos%p2eint_method ==
'bisect')
then
918 call eint_from_p_bisect(nh_in(ix^
d), &
919 dlog10(w(ix^
d,p_)), log_eint_mid)
920 eint_total = nh(ix^
d) * 10.0d0**log_eint_mid
921 eint_total = max(eint_total, &
922 nh(ix^
d) * 10.0d0**eos%T%var2_min)
923 w(ix^
d,e_) = eint_total
925 p_to_eint = p2eint_from_nh_p(nh_in(ix^
d), p_in(ix^
d))
926 w(ix^
d,e_) = w(ix^
d,p_) * p_to_eint
929 w(ix^
d,e_) = w(ix^
d,p_) * p_to_eint
933 end subroutine mhd_p_to_eint
937 subroutine mhd_to_primitive_origin_lte(ixI^L,ixO^L,w,x)
939 integer,
intent(in) :: ixi^
l, ixo^
l
940 double precision,
intent(inout) :: w(ixi^s, nw)
941 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
943 double precision :: inv_rho, eint_val, eint_in
944 double precision :: nh(ixi^s), log_nh(ixi^s)
947 timeeos0 = mpi_wtime()
950 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
951 'mhd_to_primitive_origin_LTE')
954 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
956 log_nh(ixo^s) = dlog10(nh(ixo^s))
959 {
do ix^db=ixomin^db,ixomax^db\}
960 inv_rho = 1.d0/w(ix^
d,rho_)
962 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
964 eint_val = w(ix^
d,e_) &
965 - half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
966 + (^c&w(ix^
d,b^c_)**2+))
968 if (eos%method /=
'analytic')
then
969 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**eos%T%var2_min)
971 eint_val = max(eint_val, smalldouble)
974 if (eint_val * inv_rho > eos%eint_rho_FI_threshold)
then
976 w(ix^
d,p_) = eos%gamma_minus_1 &
977 * (eint_val - eos%eion_per_nH * nh(ix^
d))
980 eint_in = dlog10(eint_val) - log_nh(ix^
d)
981 w(ix^
d,p_) = nh(ix^
d) * p_nh_from_eint(log_nh(ix^
d), eint_in)
985 w(ix^
d,p_) = eos%gamma_minus_1 * eint_val
989 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
991 end subroutine mhd_to_primitive_origin_lte
995 subroutine mhd_to_primitive_inte_lte(ixI^L,ixO^L,w,x)
997 integer,
intent(in) :: ixi^
l, ixo^
l
998 double precision,
intent(inout) :: w(ixi^s, nw)
999 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1001 double precision :: inv_rho, eint_val, eint_in, t_loc, y_loc
1002 double precision :: nh(ixi^s), log_nh(ixi^s)
1005 timeeos0 = mpi_wtime()
1008 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
1009 'mhd_to_primitive_inte_LTE')
1012 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1014 log_nh(ixo^s) = dlog10(nh(ixo^s))
1017 {
do ix^db=ixomin^db,ixomax^db\}
1019 eint_val = w(ix^
d,e_)
1020 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**eos%T%var2_min)
1023 if (eint_val / w(ix^
d,rho_) > eos%eint_rho_FI_threshold)
then
1024 w(ix^
d,p_) = eos%gamma_minus_1 &
1025 * (eint_val - eos%eion_per_nH * nh(ix^
d))
1027 eint_in = dlog10(eint_val) - log_nh(ix^
d)
1028 w(ix^
d,p_) = nh(ix^
d) * p_nh_from_eint(log_nh(ix^
d), eint_in)
1031 w(ix^
d,p_) = eos%gamma_minus_1 * eint_val
1035 inv_rho = 1.d0/w(ix^
d,rho_)
1036 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1039 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
1041 end subroutine mhd_to_primitive_inte_lte
1048 subroutine mhd_to_prolong_lte(ixI^L,ixO^L,w,x)
1050 integer,
intent(in) :: ixi^
l, ixo^
l
1051 double precision,
intent(inout) :: w(ixi^s, nw)
1052 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1054 double precision :: inv_rho, eint_val, t_loc, y_loc
1055 double precision :: nh(ixi^s), log_nh(ixi^s)
1058 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1059 log_nh(ixo^s) = dlog10(nh(ixo^s))
1061 {
do ix^db=ixomin^db,ixomax^db\}
1062 inv_rho = 1.d0/w(ix^
d,rho_)
1064 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1065 if (mhd_internal_e)
then
1066 eint_val = w(ix^
d,e_)
1069 eint_val = w(ix^
d,e_) &
1070 - half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
1071 + (^c&w(ix^
d,b^c_)**2+))
1074 if (eos%method /=
'analytic')
then
1075 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**eos%T%var2_min)
1077 eint_val = max(eint_val, smalldouble)
1079 if (eint_val * inv_rho > eos%eint_rho_FI_threshold)
then
1081 w(ix^
d,p_) = eos%gamma_minus_1 &
1082 * (eint_val - eos%eion_per_nH * nh(ix^
d)) &
1083 / (nh(ix^
d) * eos%n_per_nH_FI)
1084 else if (eos%method ==
'analytic')
then
1086 call saha_t_from_nh_eint(nh(ix^
d), &
1087 eint_val / nh(ix^
d), t_loc, y_loc)
1091 w(ix^
d,p_) = t_from_nh_eint( &
1093 dlog10(eint_val) - log_nh(ix^
d))
1097 end subroutine mhd_to_prolong_lte
1101 subroutine mhd_from_prolong_lte(ixI^L,ixO^L,w,x)
1103 integer,
intent(in) :: ixi^
l, ixo^
l
1104 double precision,
intent(inout) :: w(ixi^s, nw)
1105 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1107 double precision :: t_val, eint_val, t_fi, log_t_min
1108 double precision :: nh(ixi^s), log_nh(ixi^s)
1112 t_fi = (eos%eint_rho_FI_threshold &
1113 * eos%nH2rhoFactor - eos%eion_per_nH) &
1114 * eos%gamma_minus_1 / eos%n_per_nH_FI
1119 if (eos%method ==
'entropy')
then
1120 log_t_min = eos%eintT%var2_min
1122 log_t_min = eos%eint_from_T%var2_min
1125 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1126 log_nh(ixo^s) = dlog10(nh(ixo^s))
1128 {
do ix^db=ixomin^db,ixomax^db\}
1130 if (t_val > t_fi)
then
1132 eint_val = nh(ix^
d) &
1133 * (eos%n_per_nH_FI * t_val * eos%inv_gamma_minus_1 &
1135 else if (eos%method ==
'analytic')
then
1137 eint_val = saha_eint_from_nh_t(nh(ix^
d), t_val) * nh(ix^
d)
1140 eint_val = eint_nh_from_t( &
1142 dlog10(max(t_val, 10.0d0**log_t_min))) &
1145 if (mhd_internal_e)
then
1146 w(ix^
d,e_) = eint_val
1149 w(ix^
d,e_) = eint_val &
1150 + half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
1151 + (^c&w(ix^
d,b^c_)**2+))
1154 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
1157 end subroutine mhd_from_prolong_lte
1163 subroutine mhd_get_csound2_fi(w, x, ixI^L, ixO^L, cs2)
1165 integer,
intent(in) :: ixi^
l, ixo^
l
1166 double precision,
intent(in) :: w(ixi^s, nw)
1167 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1168 double precision,
intent(out) :: cs2(ixi^s)
1170 timeeos0 = mpi_wtime()
1172 cs2(ixo^s) = eos%gamma * w(ixo^s, p_) / w(ixo^s, rho_)
1174 timeeos_csound = timeeos_csound + (mpi_wtime()-timeeos0)
1176 end subroutine mhd_get_csound2_fi
1180 subroutine mhd_get_csound2_lte(w, x, ixI^L, ixO^L, cs2)
1182 integer,
intent(in) :: ixi^
l, ixo^
l
1183 double precision,
intent(in) :: w(ixi^s, nw)
1184 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1185 double precision,
intent(out) :: cs2(ixi^s)
1187 double precision :: nh_val, log_nh, log_p_nh, g1, p_over_rho
1190 timeeos0 = mpi_wtime()
1192 if (eos%gamma1_method ==
'constant')
then
1193 cs2(ixo^s) = eos%gamma * w(ixo^s, p_) / w(ixo^s, rho_)
1195 {
do ix^db=ixomin^db,ixomax^db\}
1196 p_over_rho = w(ix^
d, p_) / w(ix^
d, rho_)
1197 if (p_over_rho > eos%p_rho_FI_threshold)
then
1198 cs2(ix^
d) = eos%gamma * p_over_rho
1200 nh_val = w(ix^
d, rho_) / eos%nH2rhoFactor
1201 if (eos%method ==
'analytic')
then
1202 if (iw_te > 0 .and. w(ix^
d,iw_te) > 0.0d0)
then
1203 g1 = saha_gamma1_from_nh_t(nh_val, w(ix^
d,iw_te))
1208 log_nh = dlog10(nh_val)
1209 log_p_nh = dlog10(w(ix^
d, p_) / nh_val)
1210 g1 = gamma1_from_nh_p(log_nh, log_p_nh)
1212 cs2(ix^
d) = g1 * p_over_rho
1217 timeeos_csound = timeeos_csound + (mpi_wtime()-timeeos0)
1219 end subroutine mhd_get_csound2_lte
1221 subroutine mhd_get_gamma1_lte(w, x, ixI^L, ixO^L, gamma1)
1223 integer,
intent(in) :: ixi^
l, ixo^
l
1224 double precision,
intent(in) :: w(ixi^s, nw)
1225 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1226 double precision,
intent(out) :: gamma1(ixi^s)
1228 double precision :: nh_val, p_over_rho
1231 if (eos%gamma1_method ==
'constant')
then
1232 gamma1(ixo^s) = eos%gamma
1236 {
do ix^db=ixomin^db,ixomax^db\}
1237 p_over_rho = w(ix^
d, p_) / w(ix^
d, rho_)
1238 if (p_over_rho > eos%p_rho_FI_threshold)
then
1239 gamma1(ix^
d) = eos%gamma
1241 nh_val = w(ix^
d, rho_) / eos%nH2rhoFactor
1242 if (eos%method ==
'analytic')
then
1243 if (iw_te > 0 .and. w(ix^
d,iw_te) > 0.0d0)
then
1244 gamma1(ix^
d) = saha_gamma1_from_nh_t(nh_val, w(ix^
d,iw_te))
1246 gamma1(ix^
d) = eos%gamma
1249 gamma1(ix^
d) = gamma1_from_nh_p(dlog10(nh_val), &
1250 dlog10(w(ix^
d, p_) / nh_val))
1255 end subroutine mhd_get_gamma1_lte
1262 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
1264 integer,
intent(in) :: ixi^
l, ixo^
l
1265 double precision,
intent(in) :: w(ixi^s,1:nw)
1266 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1267 double precision,
intent(out):: rfactor(ixi^s)
1271 end subroutine rfactor_from_constant_ionization
1278 subroutine mhd_get_pthermal_noe(w,x,ixI^L,ixO^L,pth)
1281 integer,
intent(in) :: ixi^
l, ixo^
l
1282 double precision,
intent(in) :: w(ixi^s,nw)
1283 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1284 double precision,
intent(out):: pth(ixi^s)
1286 if(has_equi_rho_and_p)
then
1287 pth(ixo^s)=mhd_adiab*(w(ixo^s,rho_)+
block%equi_vars(ixo^s,equi_rho0_,0))**eos%gamma
1289 pth(ixo^s)=mhd_adiab*w(ixo^s,rho_)**eos%gamma
1292 end subroutine mhd_get_pthermal_noe
1295 subroutine mhd_get_pthermal_inte(w,x,ixI^L,ixO^L,pth)
1299 integer,
intent(in) :: ixi^
l, ixo^
l
1300 double precision,
intent(in) :: w(ixi^s,nw)
1301 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1302 double precision,
intent(out):: pth(ixi^s)
1306 {
do ix^db= ixomin^db,ixomax^db\}
1307 if(has_equi_rho_and_p)
then
1308 pth(ix^
d)=eos%gamma_minus_1*w(ix^
d,e_)+
block%equi_vars(ix^
d,equi_pe0_,0)
1310 pth(ix^
d)=eos%gamma_minus_1*w(ix^
d,e_)
1315 if(check_small_values.and..not.fix_small_values)
then
1316 {
do ix^db= ixomin^db,ixomax^db\}
1317 if(pth(ix^d)<small_pressure)
then
1318 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1319 " encountered when call mhd_get_pthermal_inte"
1320 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1321 write(*,*)
"Location: ", x(ix^d,:)
1322 write(*,*)
"Cell number: ", ix^d
1324 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1326 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1327 write(*,*)
"Saving status at the previous time step"
1333 end subroutine mhd_get_pthermal_inte
1336 subroutine mhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
1340 integer,
intent(in) :: ixi^
l, ixo^
l
1341 double precision,
intent(in) :: w(ixi^s,nw)
1342 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1343 double precision,
intent(out):: pth(ixi^s)
1347 {
do ix^db=ixomin^db,ixomax^db\}
1348 if(has_equi_rho_and_p)
then
1349 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)-half*((^c&w(ix^
d,m^c_)**2+)/(w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,0))&
1350 +(^c&w(ix^
d,b^c_)**2+)))+
block%equi_vars(ix^
d,equi_pe0_,0)
1352 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)-half*((^c&w(ix^
d,m^c_)**2+)/w(ix^
d,rho_)&
1353 +(^c&w(ix^
d,b^c_)**2+)))
1358 if(check_small_values.and..not.fix_small_values)
then
1359 {
do ix^db=ixomin^db,ixomax^db\}
1360 if(pth(ix^d)<small_pressure)
then
1361 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1362 " encountered when call mhd_get_pthermal"
1363 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1364 write(*,*)
"Location: ", x(ix^d,:)
1365 write(*,*)
"Cell number: ", ix^d
1367 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1369 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1370 write(*,*)
"Saving status at the previous time step"
1376 end subroutine mhd_get_pthermal_origin
1379 subroutine mhd_get_pthermal_lte(w,x,ixI^L,ixO^L,pth)
1383 integer,
intent(in) :: ixi^
l, ixo^
l
1384 double precision,
intent(in) :: w(ixi^s,nw)
1385 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1386 double precision,
intent(out):: pth(ixi^s)
1387 double precision :: nh(ixi^s)
1392 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1393 pth(ixo^s) = nh(ixo^s) * (1.0d0 + eos%He_abundance &
1394 + (w(ixo^s,ne_) / nh(ixo^s))) * w(ixo^s,te_)
1397 {
do ix^db=ixomin^db,ixomax^db\}
1400 else if(check_small_values)
then
1401 {
do ix^db=ixomin^db,ixomax^db\}
1402 if(pth(ix^d)<small_pressure)
then
1403 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1404 " encountered when call mhd_get_pthermal_LTE"
1405 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1406 write(*,*)
"Location: ", x(ix^d,:)
1407 write(*,*)
"Cell number: ", ix^d
1409 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1411 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1412 write(*,*)
"Saving status at the previous time step"
1418 end subroutine mhd_get_pthermal_lte
1421 subroutine mhd_get_pthermal_semirelati(w,x,ixI^L,ixO^L,pth)
1425 integer,
intent(in) :: ixi^
l, ixo^
l
1426 double precision,
intent(in) :: w(ixi^s,nw)
1427 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1428 double precision,
intent(out):: pth(ixi^s)
1430 double precision :: b(ixo^s,1:
ndir), v(ixo^s,1:
ndir), tmp, b2, gamma2, inv_rho
1433 {
do ix^db=ixomin^db,ixomax^db\}
1434 b2=(^c&w(ix^
d,b^c_)**2+)
1435 if(b2>smalldouble)
then
1440 ^c&b(ix^
d,^c)=w(ix^
d,b^c_)*tmp\
1441 tmp=(^c&b(ix^
d,^c)*w(ix^
d,m^c_)+)
1443 inv_rho=1.d0/w(ix^
d,rho_)
1445 b2=b2*inv_rho*eos%inv_squared_c
1447 gamma2=1.d0/(1.d0+b2)
1449 ^c&v(ix^
d,^c)=gamma2*(w(ix^
d,m^c_)+b2*b(ix^
d,^c)*tmp)*inv_rho\
1453 b(ix^
d,1)=w(ix^
d,b2_)*v(ix^
d,3)-w(ix^
d,b3_)*v(ix^
d,2)
1454 b(ix^
d,2)=w(ix^
d,b3_)*v(ix^
d,1)-w(ix^
d,b1_)*v(ix^
d,3)
1455 b(ix^
d,3)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
1459 b(ix^
d,2)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
1465 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)&
1466 -half*((^c&v(ix^
d,^c)**2+)*w(ix^
d,rho_)&
1467 +(^c&w(ix^
d,b^c_)**2+)&
1468 +(^c&b(ix^
d,^c)**2+)*eos%inv_squared_c))
1472 if(check_small_values.and..not.fix_small_values)
then
1473 {
do ix^db=ixomin^db,ixomax^db\}
1474 if(pth(ix^d)<small_pressure)
then
1475 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1476 " encountered when call mhd_get_pthermal_semirelati"
1477 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1478 write(*,*)
"Location: ", x(ix^d,:)
1479 write(*,*)
"Cell number: ", ix^d
1481 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1483 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1484 write(*,*)
"Saving status at the previous time step"
1490 end subroutine mhd_get_pthermal_semirelati
1493 subroutine mhd_get_pthermal_hde(w,x,ixI^L,ixO^L,pth)
1497 integer,
intent(in) :: ixi^
l, ixo^
l
1498 double precision,
intent(in) :: w(ixi^s,nw)
1499 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1500 double precision,
intent(out):: pth(ixi^s)
1504 {
do ix^db= ixomin^db,ixomax^db\}
1505 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)-half*((^c&w(ix^
d,m^c_)**2+)/w(ix^
d,rho_)))
1508 if(check_small_values.and..not.fix_small_values)
then
1509 {
do ix^db= ixomin^db,ixomax^db\}
1510 if(pth(ix^d)<small_pressure)
then
1511 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1512 " encountered when call mhd_get_pthermal_hde"
1513 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1514 write(*,*)
"Location: ", x(ix^d,:)
1515 write(*,*)
"Cell number: ", ix^d
1517 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1519 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1520 write(*,*)
"Saving status at the previous time step"
1526 end subroutine mhd_get_pthermal_hde
1531 subroutine mhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
1533 integer,
intent(in) :: ixi^
l, ixo^
l
1534 double precision,
intent(in) :: w(ixi^s, 1:nw)
1535 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1536 double precision,
intent(out):: res(ixi^s)
1537 res(ixo^s) = w(ixo^s, te_)
1538 end subroutine mhd_get_temperature_from_te
1541 subroutine mhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
1543 integer,
intent(in) :: ixi^
l, ixo^
l
1544 double precision,
intent(in) :: w(ixi^s, 1:nw)
1545 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1546 double precision,
intent(out):: res(ixi^s)
1548 double precision :: r(ixi^s)
1550 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1551 res(ixo^s) = eos%gamma_minus_1 * w(ixo^s, e_)/(w(ixo^s,rho_)*r(ixo^s))
1552 end subroutine mhd_get_temperature_from_eint
1555 subroutine mhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
1557 integer,
intent(in) :: ixi^
l, ixo^
l
1558 double precision,
intent(in) :: w(ixi^s, 1:nw)
1559 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1560 double precision,
intent(out):: res(ixi^s)
1562 double precision :: r(ixi^s)
1564 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1566 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,rho_))
1568 end subroutine mhd_get_temperature_from_etot
1570 subroutine mhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
1572 integer,
intent(in) :: ixi^
l, ixo^
l
1573 double precision,
intent(in) :: w(ixi^s, 1:nw)
1574 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1575 double precision,
intent(out):: res(ixi^s)
1577 double precision :: r(ixi^s)
1579 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1581 res(ixo^s)=res(ixo^s)/(r(ixo^s)*(w(ixo^s,rho_)+
block%equi_vars(ixo^s,equi_rho0_,
b0i)))
1583 end subroutine mhd_get_temperature_from_etot_with_equi
1585 subroutine mhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
1587 integer,
intent(in) :: ixi^
l, ixo^
l
1588 double precision,
intent(in) :: w(ixi^s, 1:nw)
1589 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1590 double precision,
intent(out):: res(ixi^s)
1592 double precision :: r(ixi^s)
1594 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1595 res(ixo^s) = (eos%gamma_minus_1 * w(ixo^s, e_) +
block%equi_vars(ixo^s,equi_pe0_,
b0i)) /&
1596 ((w(ixo^s,rho_) +
block%equi_vars(ixo^s,equi_rho0_,
b0i))*r(ixo^s))
1598 end subroutine mhd_get_temperature_from_eint_with_equi
1606 subroutine mhd_get_temperature_from_etot_lte(w, x, ixI^L, ixO^L, res)
1608 integer,
intent(in) :: ixi^
l, ixo^
l
1609 double precision,
intent(in) :: w(ixi^s, 1:nw)
1610 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1611 double precision,
intent(out):: res(ixi^s)
1613 double precision :: wlocal(ixi^s, 1:nw)
1615 wlocal(ixi^s, 1:nw) = w(ixi^s, 1:nw)
1617 call phys_e_to_ei(ixi^
l, ixo^
l, wlocal, x)
1619 call eos%get_temperature_from_eint(wlocal, x, ixi^
l, ixo^
l, res)
1621 end subroutine mhd_get_temperature_from_etot_lte
1623 subroutine mhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
1625 integer,
intent(in) :: ixi^
l, ixo^
l
1626 double precision,
intent(in) :: w(ixi^s, 1:nw)
1627 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1628 double precision,
intent(out):: res(ixi^s)
1630 double precision :: r(ixi^s)
1632 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1633 res(ixo^s)=
block%equi_vars(ixo^s,equi_pe0_,
b0i)/(
block%equi_vars(ixo^s,equi_rho0_,
b0i)*r(ixo^s))
1635 end subroutine mhd_get_temperature_equi
1639 subroutine mhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
1641 integer,
intent(in) :: ixi^
l, ixo^
l
1642 double precision,
intent(in) :: w(ixi^s, 1:nw)
1643 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1644 double precision,
intent(out):: res(ixi^s)
1645 res(ixo^s) =
block%equi_vars(ixo^s,equi_rho0_,
b0i)
1646 end subroutine mhd_get_rho_equi
1648 subroutine mhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
1650 integer,
intent(in) :: ixi^
l, ixo^
l
1651 double precision,
intent(in) :: w(ixi^s, 1:nw)
1652 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1653 double precision,
intent(out):: res(ixi^s)
1654 res(ixo^s) =
block%equi_vars(ixo^s,equi_pe0_,
b0i)
1655 end subroutine mhd_get_pe_equi
1660 function mhd_get_ei_origin(w, ixI^L, ixO^L)
result(ei)
1662 integer,
intent(in) :: ixi^
l, ixo^
l
1663 double precision,
intent(in) :: w(ixi^s, nw)
1664 double precision :: ei(ixo^s)
1667 ei(ixo^s) = w(ixo^s,e_) - half*((^c&w(ixo^s,m^c_)**2+)/w(ixo^s,rho_) &
1668 + (^c&w(ixo^s,b^c_)**2+))
1669 end function mhd_get_ei_origin
1672 function mhd_get_ei_inte(w, ixI^L, ixO^L)
result(ei)
1674 integer,
intent(in) :: ixi^
l, ixo^
l
1675 double precision,
intent(in) :: w(ixi^s, nw)
1676 double precision :: ei(ixo^s)
1679 ei(ixo^s) = w(ixo^s,e_)
1680 end function mhd_get_ei_inte
1695 subroutine mhd_p_to_e_pi(ixI^L,ixO^L,w,x)
1697 integer,
intent(in) :: ixi^
l, ixo^
l
1698 double precision,
intent(inout) :: w(ixi^s, nw)
1699 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1701 double precision :: eint
1704 {
do ix^db=ixomin^db,ixomax^db\}
1705 call eint_from_rho_p_pi(w(ix^
d,rho_), w(ix^
d,p_), eint)
1707 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
1708 +(^c&w(ix^
d,b^c_)**2+))
1711 end subroutine mhd_p_to_e_pi
1714 subroutine mhd_p_to_eint_pi(ixI^L,ixO^L,w,x)
1716 integer,
intent(in) :: ixi^
l, ixo^
l
1717 double precision,
intent(inout) :: w(ixi^s, nw)
1718 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1720 double precision :: eint
1723 {
do ix^db=ixomin^db,ixomax^db\}
1724 call eint_from_rho_p_pi(w(ix^
d,rho_), w(ix^
d,p_), eint)
1728 end subroutine mhd_p_to_eint_pi
1731 subroutine mhd_to_conserved_origin_pi(ixI^L,ixO^L,w,x)
1733 integer,
intent(in) :: ixi^
l, ixo^
l
1734 double precision,
intent(inout) :: w(ixi^s, nw)
1735 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1737 call mhd_p_to_e_pi(ixi^
l, ixo^
l, w, x)
1738 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
1740 end subroutine mhd_to_conserved_origin_pi
1743 subroutine mhd_to_conserved_inte_pi(ixI^L,ixO^L,w,x)
1745 integer,
intent(in) :: ixi^
l, ixo^
l
1746 double precision,
intent(inout) :: w(ixi^s, nw)
1747 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1749 call mhd_p_to_eint_pi(ixi^
l, ixo^
l, w, x)
1750 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
1752 end subroutine mhd_to_conserved_inte_pi
1755 subroutine mhd_to_primitive_origin_pi(ixI^L,ixO^L,w,x)
1757 integer,
intent(in) :: ixi^
l, ixo^
l
1758 double precision,
intent(inout) :: w(ixi^s, nw)
1759 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1761 double precision :: inv_rho, eint_val, t, rfac
1765 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
1766 'mhd_to_primitive_origin_PI')
1769 {
do ix^db=ixomin^db,ixomax^db\}
1770 inv_rho = 1.d0/w(ix^
d,rho_)
1772 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1774 eint_val = w(ix^
d,e_) &
1775 - half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
1776 + (^c&w(ix^
d,b^c_)**2+))
1777 eint_val = max(eint_val, smalldouble)
1778 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, w(ix^
d,p_), rfac)
1781 end subroutine mhd_to_primitive_origin_pi
1784 subroutine mhd_to_primitive_inte_pi(ixI^L,ixO^L,w,x)
1786 integer,
intent(in) :: ixi^
l, ixo^
l
1787 double precision,
intent(inout) :: w(ixi^s, nw)
1788 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1790 double precision :: inv_rho, eint_val, t, rfac
1794 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
1795 'mhd_to_primitive_inte_PI')
1798 {
do ix^db=ixomin^db,ixomax^db\}
1799 eint_val = max(w(ix^
d,e_), smalldouble)
1800 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, w(ix^
d,p_), rfac)
1802 inv_rho = 1.d0/w(ix^
d,rho_)
1803 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1806 end subroutine mhd_to_primitive_inte_pi
1809 subroutine mhd_get_pthermal_origin_pi(w,x,ixI^L,ixO^L,pth)
1811 integer,
intent(in) :: ixi^
l, ixo^
l
1812 double precision,
intent(in) :: w(ixi^s,nw)
1813 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1814 double precision,
intent(out):: pth(ixi^s)
1816 double precision :: eint_val, t, rfac
1819 {
do ix^db=ixomin^db,ixomax^db\}
1820 eint_val = w(ix^
d,e_) &
1821 - half*((^c&w(ix^
d,m^c_)**2+)/w(ix^
d,rho_) &
1822 + (^c&w(ix^
d,b^c_)**2+))
1823 eint_val = max(eint_val, smalldouble)
1824 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, pth(ix^
d), rfac)
1828 end subroutine mhd_get_pthermal_origin_pi
1831 subroutine mhd_get_pthermal_inte_pi(w,x,ixI^L,ixO^L,pth)
1833 integer,
intent(in) :: ixi^
l, ixo^
l
1834 double precision,
intent(in) :: w(ixi^s,nw)
1835 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1836 double precision,
intent(out):: pth(ixi^s)
1838 double precision :: eint_val, t, rfac
1841 {
do ix^db=ixomin^db,ixomax^db\}
1842 eint_val = max(w(ix^
d,e_), smalldouble)
1843 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, pth(ix^
d), rfac)
1847 end subroutine mhd_get_pthermal_inte_pi
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
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').
LTE (Saha-table) EoS kernels and finalise for the eos% family.
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...
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 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.
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.
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
integer, parameter ndim
Number of spatial dimensions for grid variables.
integer b0i
background magnetic field location indicator
integer ndir
Number of spatial dimensions (components) for vector variables.
double precision, dimension(:), allocatable, parameter d
logical fix_small_values
fix small values with average or replace methods
MHD <-> EoS seam: binds the eos% authority into magnetohydrodynamics.
subroutine, public mhd_link_eos()
Link the appropriate EOS conversion routines based on the selected EoS type.
procedure(sub_get_pthermal), pointer, public mhd_get_temperature
Temperature pointer: set by mhd_link_eos based on EoS type and energy formulation.
procedure(sub_get_pthermal), pointer, public mhd_get_pthermal
Thermal pressure pointer: set by mhd_link_eos based on energy formulation. Internal to mod_mhd_eos — ...
procedure(sub_convert), pointer, public mhd_to_conserved
use habitual name of converting to conserved
procedure(sub_convert), pointer, public mhd_to_primitive
use habitual name of converting to primitive
Magneto-hydrodynamics module.
integer, public, protected c_
logical, public, protected mhd_internal_e
Whether internal energy is solved instead of total energy.
type(tc_fluid), allocatable, public tc_fl
type of fluid for thermal conduction
logical, public, protected mhd_semirelativistic
Whether semirelativistic MHD equations (Gombosi 2002 JCP) are solved.
integer, public, protected m
type(te_fluid), allocatable, public te_fl_mhd
type of fluid for thermal emission synthesis
logical, public has_equi_rho_and_p
whether split off equilibrium density and pressure
logical, public, protected mhd_energy
Whether an energy equation is used.
type(fld_fluid), allocatable, public fld_fl
Radiation fluid object (gas-EoS callbacks for FLD), wired in mhd_link_eos.
integer, public, protected p_
Index of the gas pressure (-1 if not present) should equal e_.
integer, public, protected c
Indices of the momentum density for the form of better vectorization.
integer, public, protected b
logical, public, protected mhd_hydrodynamic_e
Whether hydrodynamic energy is solved instead of total energy.
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 e_
Index of the energy density (-1 if not present)
logical, public mhd_equi_thermal
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
Module with all the methods that users can customize in AMRVAC.
procedure(rfactor), pointer usr_rfactor