61 if (
eos%eos_type ==
'FI' .or.
eos%eos_type ==
'PI')
then
65 call mpistop(
'PI EoS not supported with equilibrium splitting')
67 eos%to_primitive => mhd_to_primitive_hde
68 eos%to_conserved => mhd_to_conserved_hde
71 eos%to_primitive => mhd_to_primitive_semirelati
72 eos%to_conserved => mhd_to_conserved_semirelati
74 eos%to_primitive => mhd_to_primitive_semirelati_noe
75 eos%to_conserved => mhd_to_conserved_semirelati_noe
79 eos%to_primitive => mhd_to_primitive_split_rho
80 eos%to_conserved => mhd_to_conserved_split_rho
82 eos%to_primitive => mhd_to_primitive_inte
83 eos%to_conserved => mhd_to_conserved_inte
85 eos%to_primitive => mhd_to_primitive_origin
86 eos%to_conserved => mhd_to_conserved_origin
88 eos%to_primitive => mhd_to_primitive_origin_noe
89 eos%to_conserved => mhd_to_conserved_origin_noe
92 else if (
eos%eos_type ==
'LTE')
then
95 call mpistop(
'LTE EoS not supported with mhd_hydrodynamic_e')
97 call mpistop(
'LTE EoS not supported with mhd_semirelativistic')
99 call mpistop(
'LTE EoS not supported with equilibrium splitting')
101 call mpistop(
'LTE EoS requires mhd_energy=.true.')
104 eos%to_primitive => mhd_to_primitive_inte_lte
105 eos%to_conserved => mhd_to_conserved_inte_lte
107 eos%to_primitive => mhd_to_primitive_origin_lte
108 eos%to_conserved => mhd_to_conserved_origin_lte
111 call mpistop(
'Error: Unknown MHD EOS type: ' // trim(
eos%eos_type))
120 eos%p_to_e => mhd_p_to_eint
122 eos%p_to_e => mhd_p_to_e
126 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
127 eos%get_csound2 => mhd_get_csound2_lte
130 eos%get_csound2 => mhd_get_csound2_fi
135 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
147 eos%get_Rfactor => rfactor_from_constant_ionization
170 if (
eos%eos_type ==
'LTE')
then
178 if(
eos%eos_type ==
'PI' .or.
eos%eos_type ==
'LTE')
then
209 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
211 call mpistop(
'PI energy EoS requires mhd_energy=.true.')
213 call mpistop(
'PI energy EoS not supported with mhd_hydrodynamic_e')
215 call mpistop(
'PI energy EoS not supported with mhd_semirelativistic')
217 call mpistop(
'PI energy EoS not supported with equilibrium splitting')
220 eos%to_conserved => mhd_to_conserved_inte_pi
221 eos%to_primitive => mhd_to_primitive_inte_pi
222 eos%p_to_e => mhd_p_to_eint_pi
226 eos%to_conserved => mhd_to_conserved_origin_pi
227 eos%to_primitive => mhd_to_primitive_origin_pi
228 eos%p_to_e => mhd_p_to_e_pi
254 subroutine bind_eos_to_source()
265 if (
eos%eos_type ==
'LTE')
then
268 eos%get_temperature_from_etot =>
eos%get_temperature_from_eint
271 eos%get_temperature_from_etot => mhd_get_temperature_from_etot_lte
277 eos%get_temperature_from_etot => mhd_get_temperature_from_eint_with_equi
278 eos%get_temperature_from_eint => mhd_get_temperature_from_eint_with_equi
280 eos%get_temperature_from_etot => mhd_get_temperature_from_eint
281 eos%get_temperature_from_eint => mhd_get_temperature_from_eint
286 eos%get_temperature_from_etot => mhd_get_temperature_from_etot_with_equi
287 eos%get_temperature_from_eint => mhd_get_temperature_from_eint_with_equi
289 eos%get_temperature_from_etot => mhd_get_temperature_from_etot
290 eos%get_temperature_from_eint => mhd_get_temperature_from_eint
295 if (
allocated(
tc_fl))
then
296 tc_fl%get_temperature_from_conserved =>
eos%get_temperature_from_etot
297 if (
eos%eos_type ==
'LTE' .and.
eos%ionE)
then
300 tc_fl%get_temperature_from_eint =>
eos%get_temperature_from_eint
304 tc_fl%get_var_Rfactor =>
eos%get_Rfactor
305 tc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
306 tc_fl%nH2rhoFactor =
eos%nH2rhoFactor
307 tc_fl%log_T_floor = eos_get_log_t_floor()
311 tc_fl%subtract_equi = .true.
312 tc_fl%get_temperature_equi => mhd_get_temperature_equi
313 tc_fl%get_rho_equi => mhd_get_rho_equi
315 tc_fl%subtract_equi = .false.
319 if (
allocated(
rc_fl))
then
321 rc_fl%get_pthermal =>
eos%get_thermal_pressure
322 rc_fl%get_var_Rfactor =>
eos%get_Rfactor
325 nullify(
rc_fl%get_rho2_factor)
329 rc_fl%inv_gamma_minus_1 =
eos%inv_gamma_minus_1
330 rc_fl%nH2rhoFactor =
eos%nH2rhoFactor
338 rc_fl%subtract_equi = .true.
339 rc_fl%get_rho_equi => mhd_get_rho_equi
340 rc_fl%get_pthermal_equi => mhd_get_pe_equi
341 rc_fl%get_ne_nH_equi => mhd_get_ne_nh_equi
342 rc_fl%get_temperature_equi => mhd_get_temperature_equi
344 rc_fl%subtract_equi = .false.
353 if (
eos%ionE .and.
eos%eos_type ==
'LTE')
then
364 if (
eos%eos_type ==
'PI' .and.
eos%ionE)
then
366 if (
allocated(
rc_fl))
then
381 if (
allocated(
fld_fl))
then
385 fld_fl%get_tgas =>
eos%get_temperature_from_pressure
389 end subroutine bind_eos_to_source
394 subroutine mhd_to_conserved_origin(ixI^L,ixO^L,w,x)
396 integer,
intent(in) :: ixi^
l, ixo^
l
397 double precision,
intent(inout) :: w(ixi^s, nw)
398 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
402 {
do ix^db=ixomin^db,ixomax^db\}
404 w(ix^
d,
e_)=w(ix^
d,
p_)*
eos%inv_gamma_minus_1&
406 +(^
c&w(ix^
d,
b^
c_)**2+))
413 end subroutine mhd_to_conserved_origin
416 subroutine mhd_to_conserved_origin_noe(ixI^L,ixO^L,w,x)
418 integer,
intent(in) :: ixi^
l, ixo^
l
419 double precision,
intent(inout) :: w(ixi^s, nw)
420 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
424 {
do ix^db=ixomin^db,ixomax^db\}
426 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
429 end subroutine mhd_to_conserved_origin_noe
432 subroutine mhd_to_conserved_hde(ixI^L,ixO^L,w,x)
434 integer,
intent(in) :: ixi^
l, ixo^
l
435 double precision,
intent(inout) :: w(ixi^s, nw)
436 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
440 {
do ix^db=ixomin^db,ixomax^db\}
442 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1&
443 +half*(^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)
445 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
448 end subroutine mhd_to_conserved_hde
451 subroutine mhd_to_conserved_inte(ixI^L,ixO^L,w,x)
453 integer,
intent(in) :: ixi^
l, ixo^
l
454 double precision,
intent(inout) :: w(ixi^s, nw)
455 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
459 {
do ix^db=ixomin^db,ixomax^db\}
461 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1
463 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
466 end subroutine mhd_to_conserved_inte
469 subroutine mhd_to_conserved_split_rho(ixI^L,ixO^L,w,x)
471 integer,
intent(in) :: ixi^
l, ixo^
l
472 double precision,
intent(inout) :: w(ixi^s, nw)
473 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
475 double precision :: rho
478 {
do ix^db=ixomin^db,ixomax^db\}
479 rho=w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,
b0i)
481 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1&
482 +half*((^c&w(ix^
d,m^c_)**2+)*rho&
483 +(^c&w(ix^
d,b^c_)**2+))
485 ^c&w(ix^
d,m^c_)=rho*w(ix^
d,m^c_)\
488 end subroutine mhd_to_conserved_split_rho
491 subroutine mhd_to_conserved_semirelati(ixI^L,ixO^L,w,x)
493 integer,
intent(in) :: ixi^
l, ixo^
l
494 double precision,
intent(inout) :: w(ixi^s, nw)
495 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
497 double precision :: e(ixo^s,1:
ndir), s(ixo^s,1:
ndir)
500 {
do ix^db=ixomin^db,ixomax^db\}
502 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
503 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
504 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
505 s(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
506 s(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
507 s(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
512 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
513 s(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
514 s(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
520 if(mhd_internal_e)
then
522 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1
526 w(ix^
d,e_)=w(ix^
d,p_)*eos%inv_gamma_minus_1&
527 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
528 +(^c&w(ix^
d,b^c_)**2+)&
529 +(^c&e(ix^
d,^c)**2+)*eos%inv_squared_c)
533 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)+s(ix^
d,^c)*eos%inv_squared_c\
537 end subroutine mhd_to_conserved_semirelati
539 subroutine mhd_to_conserved_semirelati_noe(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)
545 double precision :: e(ixo^s,1:
ndir), s(ixo^s,1:
ndir)
548 {
do ix^db=ixomin^db,ixomax^db\}
550 e(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
551 e(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
552 e(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
553 s(ix^
d,1)=e(ix^
d,2)*w(ix^
d,b3_)-e(ix^
d,3)*w(ix^
d,b2_)
554 s(ix^
d,2)=e(ix^
d,3)*w(ix^
d,b1_)-e(ix^
d,1)*w(ix^
d,b3_)
555 s(ix^
d,3)=e(ix^
d,1)*w(ix^
d,b2_)-e(ix^
d,2)*w(ix^
d,b1_)
560 e(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
561 s(ix^
d,1)=-e(ix^
d,2)*w(ix^
d,b2_)
562 s(ix^
d,2)=e(ix^
d,2)*w(ix^
d,b1_)
568 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)+s(ix^
d,^c)*eos%inv_squared_c\
572 end subroutine mhd_to_conserved_semirelati_noe
575 subroutine mhd_to_primitive_origin(ixI^L,ixO^L,w,x)
577 integer,
intent(in) :: ixi^
l, ixo^
l
578 double precision,
intent(inout) :: w(ixi^s, nw)
579 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
581 double precision :: inv_rho
585 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_origin')
588 {
do ix^db=ixomin^db,ixomax^db\}
589 inv_rho = 1.d0/w(ix^
d,rho_)
591 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
593 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)&
594 -half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+)&
595 +(^c&w(ix^
d,b^c_)**2+))&
596 -mhd_uawsom_wave_energy_cell(w(ix^
d,:)))
599 end subroutine mhd_to_primitive_origin
602 subroutine mhd_to_primitive_origin_noe(ixI^L,ixO^L,w,x)
604 integer,
intent(in) :: ixi^
l, ixo^
l
605 double precision,
intent(inout) :: w(ixi^s, nw)
606 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
608 double precision :: inv_rho
612 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_origin_noe')
615 {
do ix^db=ixomin^db,ixomax^db\}
616 inv_rho = 1.d0/w(ix^
d,rho_)
618 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
621 end subroutine mhd_to_primitive_origin_noe
624 subroutine mhd_to_primitive_hde(ixI^L,ixO^L,w,x)
626 integer,
intent(in) :: ixi^
l, ixo^
l
627 double precision,
intent(inout) :: w(ixi^s, nw)
628 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
630 double precision :: inv_rho
634 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_hde')
637 {
do ix^db=ixomin^db,ixomax^db\}
638 inv_rho = 1.d0/w(ix^
d,rho_)
640 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
642 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)-half*w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+))
645 end subroutine mhd_to_primitive_hde
648 subroutine mhd_to_primitive_inte(ixI^L,ixO^L,w,x)
650 integer,
intent(in) :: ixi^
l, ixo^
l
651 double precision,
intent(inout) :: w(ixi^s, nw)
652 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
654 double precision :: inv_rho
658 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_inte')
661 {
do ix^db=ixomin^db,ixomax^db\}
663 w(ix^
d,p_)=w(ix^
d,e_)*eos%gamma_minus_1
665 inv_rho = 1.d0/w(ix^
d,rho_)
666 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
669 end subroutine mhd_to_primitive_inte
672 subroutine mhd_to_primitive_split_rho(ixI^L,ixO^L,w,x)
674 integer,
intent(in) :: ixi^
l, ixo^
l
675 double precision,
intent(inout) :: w(ixi^s, nw)
676 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
678 double precision :: inv_rho
682 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_split_rho')
685 {
do ix^db=ixomin^db,ixomax^db\}
686 inv_rho=1.d0/(w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,
b0i))
688 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
690 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)&
691 -half*((w(ix^
d,rho_)+
block%equi_vars(ix^
d,equi_rho0_,
b0i))*&
692 (^c&w(ix^
d,m^c_)**2+)+(^c&w(ix^
d,b^c_)**2+)))
695 end subroutine mhd_to_primitive_split_rho
698 subroutine mhd_to_primitive_semirelati(ixI^L,ixO^L,w,x)
700 integer,
intent(in) :: ixi^
l, ixo^
l
701 double precision,
intent(inout) :: w(ixi^s, nw)
702 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
704 double precision :: b(ixo^s,1:
ndir), tmp, b2, gamma2, inv_rho
708 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_semirelati')
711 {
do ix^db=ixomin^db,ixomax^db\}
712 b2=(^c&w(ix^
d,b^c_)**2+)
713 if(b2>smalldouble)
then
718 ^c&b(ix^
d,^c)=w(ix^
d,b^c_)*tmp\
719 tmp=(^c&b(ix^
d,^c)*w(ix^
d,m^c_)+)
721 inv_rho=1.d0/w(ix^
d,rho_)
723 b2=b2*inv_rho*eos%inv_squared_c
725 gamma2=1.d0/(1.d0+b2)
727 ^c&w(ix^
d,m^c_)=gamma2*(w(ix^
d,m^c_)+b2*b(ix^
d,^c)*tmp)*inv_rho\
729 if(mhd_internal_e)
then
731 w(ix^
d,p_)=eos%gamma_minus_1*w(ix^
d,e_)
735 b(ix^
d,1)=w(ix^
d,b2_)*w(ix^
d,m3_)-w(ix^
d,b3_)*w(ix^
d,m2_)
736 b(ix^
d,2)=w(ix^
d,b3_)*w(ix^
d,m1_)-w(ix^
d,b1_)*w(ix^
d,m3_)
737 b(ix^
d,3)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
741 b(ix^
d,2)=w(ix^
d,b1_)*w(ix^
d,m2_)-w(ix^
d,b2_)*w(ix^
d,m1_)
747 w(ix^
d,p_)=eos%gamma_minus_1*(w(ix^
d,e_)&
748 -half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
749 +(^c&w(ix^
d,b^c_)**2+)&
750 +(^c&b(ix^
d,^c)**2+)*eos%inv_squared_c))
754 end subroutine mhd_to_primitive_semirelati
757 subroutine mhd_to_primitive_semirelati_noe(ixI^L,ixO^L,w,x)
759 integer,
intent(in) :: ixi^
l, ixo^
l
760 double precision,
intent(inout) :: w(ixi^s, nw)
761 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
763 double precision :: b(ixo^s,1:
ndir),tmp,b2,gamma2,inv_rho
764 integer :: ix^
d, idir
767 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l,
'mhd_to_primitive_semirelati_noe')
770 {
do ix^db=ixomin^db,ixomax^db\}
771 b2=(^c&w(ix^
d,b^c_)**2+)
772 if(b2>smalldouble)
then
777 ^c&b(ix^
d,^c)=w(ix^
d,b^c_)*tmp\
778 tmp=(^c&b(ix^
d,^c)*w(ix^
d,m^c_)+)
780 inv_rho=1.d0/w(ix^
d,rho_)
782 b2=b2*inv_rho*eos%inv_squared_c
784 gamma2=1.d0/(1.d0+b2)
786 ^c&w(ix^
d,m^c_)=gamma2*(w(ix^
d,m^c_)+b2*b(ix^
d,^c)*tmp)*inv_rho\
789 end subroutine mhd_to_primitive_semirelati_noe
795 subroutine mhd_to_conserved_origin_lte(ixI^L,ixO^L,w,x)
797 integer,
intent(in) :: ixi^
l, ixo^
l
798 double precision,
intent(inout) :: w(ixi^s, nw)
799 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
801 timeeos0 = mpi_wtime()
804 call mhd_p_to_e(ixi^
l, ixo^
l, w, x)
806 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
808 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
810 end subroutine mhd_to_conserved_origin_lte
814 subroutine mhd_to_conserved_inte_lte(ixI^L,ixO^L,w,x)
816 integer,
intent(in) :: ixi^
l, ixo^
l
817 double precision,
intent(inout) :: w(ixi^s, nw)
818 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
820 timeeos0 = mpi_wtime()
823 call mhd_p_to_eint(ixi^
l, ixo^
l, w, x)
825 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
827 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
829 end subroutine mhd_to_conserved_inte_lte
833 subroutine mhd_p_to_e(ixI^L,ixO^L,w,x)
835 integer,
intent(in) :: ixi^
l, ixo^
l
836 double precision,
intent(inout) :: w(ixi^s, nw)
837 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
840 double precision :: p_to_eint, p_over_rho
841 double precision :: nh(ixi^s), nh_in(ixi^s), p_in(ixi^s)
842 double precision :: t_solve, y_solve, eint_nh_solve
843 double precision :: log_eint_mid, eint_total
846 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
847 nh_in(ixo^s) = dlog10(nh(ixo^s))
848 if (eos%p2eint_method /=
'bisect')
then
849 p_in(ixo^s) = dlog10(w(ixo^s,p_)) - nh_in(ixo^s)
853 p_to_eint = eos%inv_gamma_minus_1
854 {
do ix^db=ixomin^db,ixomax^db\}
856 p_over_rho = w(ix^
d,p_) / w(ix^
d,rho_)
857 if (p_over_rho > eos%p_rho_FI_threshold)
then
858 p_to_eint = eos%inv_gamma_minus_1 &
859 + eos%eion_per_nH * nh(ix^
d) / w(ix^
d,p_)
860 w(ix^
d,e_)=w(ix^
d,p_)*p_to_eint&
861 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
862 +(^c&w(ix^
d,b^c_)**2+))
863 else if (eos%method ==
'analytic')
then
864 call saha_state_from_nh_p(nh(ix^
d), w(ix^
d,p_), &
865 t_solve, y_solve, eint_nh_solve)
866 w(ix^
d,e_) = eint_nh_solve * nh(ix^
d) &
867 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
868 +(^c&w(ix^
d,b^c_)**2+))
869 else if (eos%p2eint_method ==
'bisect')
then
870 call eint_from_p_bisect(nh_in(ix^
d), &
871 dlog10(w(ix^
d,p_)), log_eint_mid)
872 eint_total = nh(ix^
d) * 10.0d0**log_eint_mid
873 eint_total = max(eint_total, &
874 nh(ix^
d) * 10.0d0**eos%T%var2_min)
875 w(ix^
d,e_) = eint_total + &
876 half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
877 +(^c&w(ix^
d,b^c_)**2+))
879 p_to_eint = p2eint_from_nh_p(nh_in(ix^
d), p_in(ix^
d))
880 w(ix^
d,e_)=w(ix^
d,p_)*p_to_eint&
881 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
882 +(^c&w(ix^
d,b^c_)**2+))
885 w(ix^
d,e_)=w(ix^
d,p_)*p_to_eint&
886 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
887 +(^c&w(ix^
d,b^c_)**2+))
889 if(mhd_uawsom) w(ix^
d,e_)=w(ix^
d,e_)+&
890 w(ix^
d,waplus_)+w(ix^
d,waminus_)+w(ix^
d,wkplus_)+w(ix^
d,wkminus_)
893 end subroutine mhd_p_to_e
897 subroutine mhd_p_to_eint(ixI^L,ixO^L,w,x)
899 integer,
intent(in) :: ixi^
l, ixo^
l
900 double precision,
intent(inout) :: w(ixi^s, nw)
901 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
904 double precision :: p_to_eint, p_over_rho
905 double precision :: nh(ixi^s), nh_in(ixi^s), p_in(ixi^s)
906 double precision :: t_solve, y_solve, eint_nh_solve
907 double precision :: log_eint_mid, eint_total
910 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
911 nh_in(ixo^s) = dlog10(nh(ixo^s))
912 if (eos%p2eint_method /=
'bisect')
then
913 p_in(ixo^s) = dlog10(w(ixo^s,p_)) - nh_in(ixo^s)
917 p_to_eint = eos%inv_gamma_minus_1
918 {
do ix^db=ixomin^db,ixomax^db\}
920 p_over_rho = w(ix^
d,p_) / w(ix^
d,rho_)
921 if (p_over_rho > eos%p_rho_FI_threshold)
then
922 p_to_eint = eos%inv_gamma_minus_1 &
923 + eos%eion_per_nH * nh(ix^
d) / w(ix^
d,p_)
924 w(ix^
d,e_) = w(ix^
d,p_) * p_to_eint
925 else if (eos%method ==
'analytic')
then
926 call saha_state_from_nh_p(nh(ix^
d), w(ix^
d,p_), &
927 t_solve, y_solve, eint_nh_solve)
928 w(ix^
d,e_) = eint_nh_solve * nh(ix^
d)
929 else if (eos%p2eint_method ==
'bisect')
then
930 call eint_from_p_bisect(nh_in(ix^
d), &
931 dlog10(w(ix^
d,p_)), log_eint_mid)
932 eint_total = nh(ix^
d) * 10.0d0**log_eint_mid
933 eint_total = max(eint_total, &
934 nh(ix^
d) * 10.0d0**eos%T%var2_min)
935 w(ix^
d,e_) = eint_total
937 p_to_eint = p2eint_from_nh_p(nh_in(ix^
d), p_in(ix^
d))
938 w(ix^
d,e_) = w(ix^
d,p_) * p_to_eint
941 w(ix^
d,e_) = w(ix^
d,p_) * p_to_eint
945 end subroutine mhd_p_to_eint
949 subroutine mhd_to_primitive_origin_lte(ixI^L,ixO^L,w,x)
951 integer,
intent(in) :: ixi^
l, ixo^
l
952 double precision,
intent(inout) :: w(ixi^s, nw)
953 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
955 double precision :: inv_rho, eint_val, eint_in
956 double precision :: nh(ixi^s), log_nh(ixi^s)
959 timeeos0 = mpi_wtime()
962 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
963 'mhd_to_primitive_origin_LTE')
966 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
968 log_nh(ixo^s) = dlog10(nh(ixo^s))
971 {
do ix^db=ixomin^db,ixomax^db\}
972 inv_rho = 1.d0/w(ix^
d,rho_)
974 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
976 eint_val = w(ix^
d,e_) &
977 - half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
978 + (^c&w(ix^
d,b^c_)**2+))
980 if (eos%method /=
'analytic')
then
981 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**eos%T%var2_min)
983 eint_val = max(eint_val, smalldouble)
986 if (eint_val * inv_rho > eos%eint_rho_FI_threshold)
then
988 w(ix^
d,p_) = eos%gamma_minus_1 &
989 * (eint_val - eos%eion_per_nH * nh(ix^
d))
992 eint_in = dlog10(eint_val) - log_nh(ix^
d)
993 w(ix^
d,p_) = nh(ix^
d) * p_nh_from_eint(log_nh(ix^
d), eint_in)
997 w(ix^
d,p_) = eos%gamma_minus_1 * eint_val
1001 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
1003 end subroutine mhd_to_primitive_origin_lte
1007 subroutine mhd_to_primitive_inte_lte(ixI^L,ixO^L,w,x)
1009 integer,
intent(in) :: ixi^
l, ixo^
l
1010 double precision,
intent(inout) :: w(ixi^s, nw)
1011 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1013 double precision :: inv_rho, eint_val, eint_in, t_loc, y_loc
1014 double precision :: nh(ixi^s), log_nh(ixi^s)
1017 timeeos0 = mpi_wtime()
1020 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
1021 'mhd_to_primitive_inte_LTE')
1024 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1026 log_nh(ixo^s) = dlog10(nh(ixo^s))
1029 {
do ix^db=ixomin^db,ixomax^db\}
1031 eint_val = w(ix^
d,e_)
1032 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**eos%T%var2_min)
1035 if (eint_val / w(ix^
d,rho_) > eos%eint_rho_FI_threshold)
then
1036 w(ix^
d,p_) = eos%gamma_minus_1 &
1037 * (eint_val - eos%eion_per_nH * nh(ix^
d))
1039 eint_in = dlog10(eint_val) - log_nh(ix^
d)
1040 w(ix^
d,p_) = nh(ix^
d) * p_nh_from_eint(log_nh(ix^
d), eint_in)
1043 w(ix^
d,p_) = eos%gamma_minus_1 * eint_val
1047 inv_rho = 1.d0/w(ix^
d,rho_)
1048 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1051 timeeos_conv=timeeos_conv+(mpi_wtime()-timeeos0)
1053 end subroutine mhd_to_primitive_inte_lte
1060 subroutine mhd_to_prolong_lte(ixI^L,ixO^L,w,x)
1062 integer,
intent(in) :: ixi^
l, ixo^
l
1063 double precision,
intent(inout) :: w(ixi^s, nw)
1064 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1066 double precision :: inv_rho, eint_val, t_loc, y_loc
1067 double precision :: nh(ixi^s), log_nh(ixi^s)
1070 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1071 log_nh(ixo^s) = dlog10(nh(ixo^s))
1073 {
do ix^db=ixomin^db,ixomax^db\}
1074 inv_rho = 1.d0/w(ix^
d,rho_)
1076 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1077 if (mhd_internal_e)
then
1078 eint_val = w(ix^
d,e_)
1081 eint_val = w(ix^
d,e_) &
1082 - half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
1083 + (^c&w(ix^
d,b^c_)**2+))
1086 if (eos%method /=
'analytic')
then
1087 eint_val = max(eint_val, nh(ix^
d) * 10.0d0**eos%T%var2_min)
1089 eint_val = max(eint_val, smalldouble)
1091 if (eint_val * inv_rho > eos%eint_rho_FI_threshold)
then
1093 w(ix^
d,p_) = eos%gamma_minus_1 &
1094 * (eint_val - eos%eion_per_nH * nh(ix^
d)) &
1095 / (nh(ix^
d) * eos%n_per_nH_FI)
1096 else if (eos%method ==
'analytic')
then
1098 call saha_t_from_nh_eint(nh(ix^
d), &
1099 eint_val / nh(ix^
d), t_loc, y_loc)
1103 w(ix^
d,p_) = t_from_nh_eint( &
1105 dlog10(eint_val) - log_nh(ix^
d))
1109 end subroutine mhd_to_prolong_lte
1113 subroutine mhd_from_prolong_lte(ixI^L,ixO^L,w,x)
1115 integer,
intent(in) :: ixi^
l, ixo^
l
1116 double precision,
intent(inout) :: w(ixi^s, nw)
1117 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1119 double precision :: t_val, eint_val, t_fi, log_t_min
1120 double precision :: nh(ixi^s), log_nh(ixi^s)
1124 t_fi = (eos%eint_rho_FI_threshold &
1125 * eos%nH2rhoFactor - eos%eion_per_nH) &
1126 * eos%gamma_minus_1 / eos%n_per_nH_FI
1131 if (eos%method ==
'entropy')
then
1132 log_t_min = eos%eintT%var2_min
1134 log_t_min = eos%eint_from_T%var2_min
1137 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1138 log_nh(ixo^s) = dlog10(nh(ixo^s))
1140 {
do ix^db=ixomin^db,ixomax^db\}
1142 if (t_val > t_fi)
then
1144 eint_val = nh(ix^
d) &
1145 * (eos%n_per_nH_FI * t_val * eos%inv_gamma_minus_1 &
1147 else if (eos%method ==
'analytic')
then
1149 eint_val = saha_eint_from_nh_t(nh(ix^
d), t_val) * nh(ix^
d)
1152 eint_val = eint_nh_from_t( &
1154 dlog10(max(t_val, 10.0d0**log_t_min))) &
1157 if (mhd_internal_e)
then
1158 w(ix^
d,e_) = eint_val
1161 w(ix^
d,e_) = eint_val &
1162 + half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
1163 + (^c&w(ix^
d,b^c_)**2+))
1166 ^c&w(ix^
d,m^c_)=w(ix^
d,rho_)*w(ix^
d,m^c_)\
1169 end subroutine mhd_from_prolong_lte
1175 subroutine mhd_get_csound2_fi(w, x, ixI^L, ixO^L, cs2)
1177 integer,
intent(in) :: ixi^
l, ixo^
l
1178 double precision,
intent(in) :: w(ixi^s, nw)
1179 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1180 double precision,
intent(out) :: cs2(ixi^s)
1182 double precision :: rho(ixi^s), pth(ixi^s)
1184 timeeos0 = mpi_wtime()
1188 call eos%get_rho(w, x, ixi^
l, ixo^
l, rho)
1189 pth(ixo^s) = w(ixo^s, p_)
1190 if (iw_equi_p > 0) pth(ixo^s) = pth(ixo^s) &
1191 +
block%equi_vars(ixo^s, iw_equi_p,
b0i)
1192 cs2(ixo^s) = eos%gamma * pth(ixo^s) / rho(ixo^s)
1194 timeeos_csound = timeeos_csound + (mpi_wtime()-timeeos0)
1196 end subroutine mhd_get_csound2_fi
1200 subroutine mhd_get_csound2_lte(w, x, ixI^L, ixO^L, cs2)
1202 integer,
intent(in) :: ixi^
l, ixo^
l
1203 double precision,
intent(in) :: w(ixi^s, nw)
1204 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1205 double precision,
intent(out) :: cs2(ixi^s)
1207 double precision :: nh_val, log_nh, log_p_nh, g1, p_over_rho
1210 timeeos0 = mpi_wtime()
1212 if (eos%gamma1_method ==
'constant')
then
1213 cs2(ixo^s) = eos%gamma * w(ixo^s, p_) / w(ixo^s, rho_)
1215 {
do ix^db=ixomin^db,ixomax^db\}
1216 p_over_rho = w(ix^
d, p_) / w(ix^
d, rho_)
1217 if (p_over_rho > eos%p_rho_FI_threshold)
then
1218 cs2(ix^
d) = eos%gamma * p_over_rho
1220 nh_val = w(ix^
d, rho_) / eos%nH2rhoFactor
1221 if (eos%method ==
'analytic')
then
1222 if (iw_te > 0 .and. w(ix^
d,iw_te) > 0.0d0)
then
1223 g1 = saha_gamma1_from_nh_t(nh_val, w(ix^
d,iw_te))
1228 log_nh = dlog10(nh_val)
1229 log_p_nh = dlog10(w(ix^
d, p_) / nh_val)
1230 g1 = gamma1_from_nh_p(log_nh, log_p_nh)
1232 cs2(ix^
d) = g1 * p_over_rho
1237 timeeos_csound = timeeos_csound + (mpi_wtime()-timeeos0)
1239 end subroutine mhd_get_csound2_lte
1241 subroutine mhd_get_gamma1_lte(w, x, ixI^L, ixO^L, gamma1)
1243 integer,
intent(in) :: ixi^
l, ixo^
l
1244 double precision,
intent(in) :: w(ixi^s, nw)
1245 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1246 double precision,
intent(out) :: gamma1(ixi^s)
1248 double precision :: nh_val, p_over_rho
1251 if (eos%gamma1_method ==
'constant')
then
1252 gamma1(ixo^s) = eos%gamma
1256 {
do ix^db=ixomin^db,ixomax^db\}
1257 p_over_rho = w(ix^
d, p_) / w(ix^
d, rho_)
1258 if (p_over_rho > eos%p_rho_FI_threshold)
then
1259 gamma1(ix^
d) = eos%gamma
1261 nh_val = w(ix^
d, rho_) / eos%nH2rhoFactor
1262 if (eos%method ==
'analytic')
then
1263 if (iw_te > 0 .and. w(ix^
d,iw_te) > 0.0d0)
then
1264 gamma1(ix^
d) = saha_gamma1_from_nh_t(nh_val, w(ix^
d,iw_te))
1266 gamma1(ix^
d) = eos%gamma
1269 gamma1(ix^
d) = gamma1_from_nh_p(dlog10(nh_val), &
1270 dlog10(w(ix^
d, p_) / nh_val))
1275 end subroutine mhd_get_gamma1_lte
1282 subroutine rfactor_from_constant_ionization(w,x,ixI^L,ixO^L,Rfactor)
1284 integer,
intent(in) :: ixi^
l, ixo^
l
1285 double precision,
intent(in) :: w(ixi^s,1:nw)
1286 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1287 double precision,
intent(out):: rfactor(ixi^s)
1291 end subroutine rfactor_from_constant_ionization
1298 subroutine mhd_get_pthermal_noe(w,x,ixI^L,ixO^L,pth)
1301 integer,
intent(in) :: ixi^
l, ixo^
l
1302 double precision,
intent(in) :: w(ixi^s,nw)
1303 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1304 double precision,
intent(out):: pth(ixi^s)
1306 if(has_equi_rho_and_p)
then
1307 pth(ixo^s)=mhd_adiab*(w(ixo^s,rho_)+
block%equi_vars(ixo^s,equi_rho0_,0))**eos%gamma
1309 pth(ixo^s)=mhd_adiab*w(ixo^s,rho_)**eos%gamma
1312 end subroutine mhd_get_pthermal_noe
1315 subroutine mhd_get_pthermal_inte(w,x,ixI^L,ixO^L,pth)
1319 integer,
intent(in) :: ixi^
l, ixo^
l
1320 double precision,
intent(in) :: w(ixi^s,nw)
1321 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1322 double precision,
intent(out):: pth(ixi^s)
1326 {
do ix^db= ixomin^db,ixomax^db\}
1327 if(has_equi_rho_and_p)
then
1328 pth(ix^
d)=eos%gamma_minus_1*w(ix^
d,e_)+
block%equi_vars(ix^
d,equi_pe0_,0)
1330 pth(ix^
d)=eos%gamma_minus_1*w(ix^
d,e_)
1335 if(check_small_values.and..not.fix_small_values)
then
1336 {
do ix^db= ixomin^db,ixomax^db\}
1337 if(pth(ix^d)<small_pressure)
then
1338 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1339 " encountered when call mhd_get_pthermal_inte"
1340 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1341 write(*,*)
"Location: ", x(ix^d,:)
1342 write(*,*)
"Cell number: ", ix^d
1344 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1346 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1347 write(*,*)
"Saving status at the previous time step"
1353 end subroutine mhd_get_pthermal_inte
1356 subroutine mhd_get_pthermal_origin(w,x,ixI^L,ixO^L,pth)
1360 integer,
intent(in) :: ixi^
l, ixo^
l
1361 double precision,
intent(in) :: w(ixi^s,nw)
1362 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1363 double precision,
intent(out):: pth(ixi^s)
1367 {
do ix^db=ixomin^db,ixomax^db\}
1368 if(has_equi_rho_and_p)
then
1369 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))&
1370 +(^c&w(ix^
d,b^c_)**2+)))+
block%equi_vars(ix^
d,equi_pe0_,0)
1372 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)-half*((^c&w(ix^
d,m^c_)**2+)/w(ix^
d,rho_)&
1373 +(^c&w(ix^
d,b^c_)**2+))-mhd_uawsom_wave_energy_cell(w(ix^
d,:)))
1378 if(check_small_values.and..not.fix_small_values)
then
1379 {
do ix^db=ixomin^db,ixomax^db\}
1380 if(pth(ix^d)<small_pressure)
then
1381 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1382 " encountered when call mhd_get_pthermal"
1383 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1384 write(*,*)
"Location: ", x(ix^d,:)
1385 write(*,*)
"Cell number: ", ix^d
1387 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1389 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1390 write(*,*)
"Saving status at the previous time step"
1396 end subroutine mhd_get_pthermal_origin
1399 subroutine mhd_get_pthermal_lte(w,x,ixI^L,ixO^L,pth)
1403 integer,
intent(in) :: ixi^
l, ixo^
l
1404 double precision,
intent(in) :: w(ixi^s,nw)
1405 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1406 double precision,
intent(out):: pth(ixi^s)
1407 double precision :: nh(ixi^s)
1412 call eos%get_nH(w, x, ixi^
l, ixo^
l, nh)
1413 pth(ixo^s) = nh(ixo^s) * (1.0d0 + eos%He_abundance &
1414 + (w(ixo^s,ne_) / nh(ixo^s))) * w(ixo^s,te_)
1417 {
do ix^db=ixomin^db,ixomax^db\}
1420 else if(check_small_values)
then
1421 {
do ix^db=ixomin^db,ixomax^db\}
1422 if(pth(ix^d)<small_pressure)
then
1423 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1424 " encountered when call mhd_get_pthermal_LTE"
1425 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1426 write(*,*)
"Location: ", x(ix^d,:)
1427 write(*,*)
"Cell number: ", ix^d
1429 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1431 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1432 write(*,*)
"Saving status at the previous time step"
1438 end subroutine mhd_get_pthermal_lte
1441 subroutine mhd_get_pthermal_semirelati(w,x,ixI^L,ixO^L,pth)
1445 integer,
intent(in) :: ixi^
l, ixo^
l
1446 double precision,
intent(in) :: w(ixi^s,nw)
1447 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1448 double precision,
intent(out):: pth(ixi^s)
1450 double precision :: b(ixo^s,1:
ndir), v(ixo^s,1:
ndir), tmp, b2, gamma2, inv_rho
1453 {
do ix^db=ixomin^db,ixomax^db\}
1454 b2=(^c&w(ix^
d,b^c_)**2+)
1455 if(b2>smalldouble)
then
1460 ^c&b(ix^
d,^c)=w(ix^
d,b^c_)*tmp\
1461 tmp=(^c&b(ix^
d,^c)*w(ix^
d,m^c_)+)
1463 inv_rho=1.d0/w(ix^
d,rho_)
1465 b2=b2*inv_rho*eos%inv_squared_c
1467 gamma2=1.d0/(1.d0+b2)
1469 ^c&v(ix^
d,^c)=gamma2*(w(ix^
d,m^c_)+b2*b(ix^
d,^c)*tmp)*inv_rho\
1473 b(ix^
d,1)=w(ix^
d,b2_)*v(ix^
d,3)-w(ix^
d,b3_)*v(ix^
d,2)
1474 b(ix^
d,2)=w(ix^
d,b3_)*v(ix^
d,1)-w(ix^
d,b1_)*v(ix^
d,3)
1475 b(ix^
d,3)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
1479 b(ix^
d,2)=w(ix^
d,b1_)*v(ix^
d,2)-w(ix^
d,b2_)*v(ix^
d,1)
1485 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)&
1486 -half*((^c&v(ix^
d,^c)**2+)*w(ix^
d,rho_)&
1487 +(^c&w(ix^
d,b^c_)**2+)&
1488 +(^c&b(ix^
d,^c)**2+)*eos%inv_squared_c))
1492 if(check_small_values.and..not.fix_small_values)
then
1493 {
do ix^db=ixomin^db,ixomax^db\}
1494 if(pth(ix^d)<small_pressure)
then
1495 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1496 " encountered when call mhd_get_pthermal_semirelati"
1497 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1498 write(*,*)
"Location: ", x(ix^d,:)
1499 write(*,*)
"Cell number: ", ix^d
1501 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1503 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1504 write(*,*)
"Saving status at the previous time step"
1510 end subroutine mhd_get_pthermal_semirelati
1513 subroutine mhd_get_pthermal_hde(w,x,ixI^L,ixO^L,pth)
1517 integer,
intent(in) :: ixi^
l, ixo^
l
1518 double precision,
intent(in) :: w(ixi^s,nw)
1519 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1520 double precision,
intent(out):: pth(ixi^s)
1524 {
do ix^db= ixomin^db,ixomax^db\}
1525 pth(ix^
d)=eos%gamma_minus_1*(w(ix^
d,e_)-half*((^c&w(ix^
d,m^c_)**2+)/w(ix^
d,rho_)))
1528 if(check_small_values.and..not.fix_small_values)
then
1529 {
do ix^db= ixomin^db,ixomax^db\}
1530 if(pth(ix^d)<small_pressure)
then
1531 write(*,*)
"Error: small value of gas pressure",pth(ix^d),&
1532 " encountered when call mhd_get_pthermal_hde"
1533 write(*,*)
"Iteration: ", it,
" Time: ", global_time
1534 write(*,*)
"Location: ", x(ix^d,:)
1535 write(*,*)
"Cell number: ", ix^d
1537 write(*,*) trim(cons_wnames(iw)),
": ",w(ix^d,iw)
1539 if(trace_small_values)
write(*,*) sqrt(pth(ix^d)-bigdouble)
1540 write(*,*)
"Saving status at the previous time step"
1546 end subroutine mhd_get_pthermal_hde
1551 subroutine mhd_get_temperature_from_te(w, x, ixI^L, ixO^L, res)
1553 integer,
intent(in) :: ixi^
l, ixo^
l
1554 double precision,
intent(in) :: w(ixi^s, 1:nw)
1555 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1556 double precision,
intent(out):: res(ixi^s)
1557 res(ixo^s) = w(ixo^s, te_)
1558 end subroutine mhd_get_temperature_from_te
1561 subroutine mhd_get_temperature_from_eint(w, x, ixI^L, ixO^L, res)
1563 integer,
intent(in) :: ixi^
l, ixo^
l
1564 double precision,
intent(in) :: w(ixi^s, 1:nw)
1565 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1566 double precision,
intent(out):: res(ixi^s)
1568 double precision :: r(ixi^s)
1570 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1571 res(ixo^s) = eos%gamma_minus_1 * w(ixo^s, e_)/(w(ixo^s,rho_)*r(ixo^s))
1572 end subroutine mhd_get_temperature_from_eint
1575 subroutine mhd_get_temperature_from_etot(w, x, ixI^L, ixO^L, res)
1577 integer,
intent(in) :: ixi^
l, ixo^
l
1578 double precision,
intent(in) :: w(ixi^s, 1:nw)
1579 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1580 double precision,
intent(out):: res(ixi^s)
1582 double precision :: r(ixi^s)
1584 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1586 res(ixo^s)=res(ixo^s)/(r(ixo^s)*w(ixo^s,rho_))
1588 end subroutine mhd_get_temperature_from_etot
1590 subroutine mhd_get_temperature_from_etot_with_equi(w, x, ixI^L, ixO^L, res)
1592 integer,
intent(in) :: ixi^
l, ixo^
l
1593 double precision,
intent(in) :: w(ixi^s, 1:nw)
1594 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1595 double precision,
intent(out):: res(ixi^s)
1597 double precision :: r(ixi^s)
1599 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1601 res(ixo^s)=res(ixo^s)/(r(ixo^s)*(w(ixo^s,rho_)+
block%equi_vars(ixo^s,equi_rho0_,
b0i)))
1603 end subroutine mhd_get_temperature_from_etot_with_equi
1605 subroutine mhd_get_temperature_from_eint_with_equi(w, x, ixI^L, ixO^L, res)
1607 integer,
intent(in) :: ixi^
l, ixo^
l
1608 double precision,
intent(in) :: w(ixi^s, 1:nw)
1609 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1610 double precision,
intent(out):: res(ixi^s)
1612 double precision :: r(ixi^s)
1614 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1615 res(ixo^s) = (eos%gamma_minus_1 * w(ixo^s, e_) +
block%equi_vars(ixo^s,equi_pe0_,
b0i)) /&
1616 ((w(ixo^s,rho_) +
block%equi_vars(ixo^s,equi_rho0_,
b0i))*r(ixo^s))
1618 end subroutine mhd_get_temperature_from_eint_with_equi
1626 subroutine mhd_get_temperature_from_etot_lte(w, x, ixI^L, ixO^L, res)
1628 integer,
intent(in) :: ixi^
l, ixo^
l
1629 double precision,
intent(in) :: w(ixi^s, 1:nw)
1630 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1631 double precision,
intent(out):: res(ixi^s)
1633 double precision :: wlocal(ixi^s, 1:nw)
1635 wlocal(ixi^s, 1:nw) = w(ixi^s, 1:nw)
1637 call phys_e_to_ei(ixi^
l, ixo^
l, wlocal, x)
1639 call eos%get_temperature_from_eint(wlocal, x, ixi^
l, ixo^
l, res)
1641 end subroutine mhd_get_temperature_from_etot_lte
1643 subroutine mhd_get_temperature_equi(w,x, ixI^L, ixO^L, res)
1645 integer,
intent(in) :: ixi^
l, ixo^
l
1646 double precision,
intent(in) :: w(ixi^s, 1:nw)
1647 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1648 double precision,
intent(out):: res(ixi^s)
1650 double precision :: r(ixi^s)
1652 call eos%get_Rfactor(w,x,ixi^
l,ixo^
l,r)
1653 res(ixo^s)=
block%equi_vars(ixo^s,equi_pe0_,
b0i)/(
block%equi_vars(ixo^s,equi_rho0_,
b0i)*r(ixo^s))
1655 end subroutine mhd_get_temperature_equi
1659 subroutine mhd_get_rho_equi(w, x, ixI^L, ixO^L, res)
1661 integer,
intent(in) :: ixi^
l, ixo^
l
1662 double precision,
intent(in) :: w(ixi^s, 1:nw)
1663 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1664 double precision,
intent(out):: res(ixi^s)
1665 res(ixo^s) =
block%equi_vars(ixo^s,equi_rho0_,
b0i)
1666 end subroutine mhd_get_rho_equi
1668 subroutine mhd_get_pe_equi(w,x, ixI^L, ixO^L, res)
1670 integer,
intent(in) :: ixi^
l, ixo^
l
1671 double precision,
intent(in) :: w(ixi^s, 1:nw)
1672 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1673 double precision,
intent(out):: res(ixi^s)
1674 res(ixo^s) =
block%equi_vars(ixo^s,equi_pe0_,
b0i)
1675 end subroutine mhd_get_pe_equi
1680 subroutine mhd_get_ne_nh_equi(ixI^L, ixO^L, w, x, ne, nH)
1682 integer,
intent(in) :: ixi^
l, ixo^
l
1683 double precision,
intent(in) :: w(ixi^s, nw)
1684 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1685 double precision,
intent(out):: ne(ixi^s), nh(ixi^s)
1686 nh(ixo^s) =
block%equi_vars(ixo^s,equi_rho0_,
b0i) / eos%nH2rhoFactor
1687 ne(ixo^s) = nh(ixo^s) * eos%neOnH_FI
1688 end subroutine mhd_get_ne_nh_equi
1693 function mhd_get_ei_origin(w, ixI^L, ixO^L)
result(ei)
1695 integer,
intent(in) :: ixi^
l, ixo^
l
1696 double precision,
intent(in) :: w(ixi^s, nw)
1697 double precision :: ei(ixo^s)
1700 ei(ixo^s) = w(ixo^s,e_) - half*((^c&w(ixo^s,m^c_)**2+)/w(ixo^s,rho_) &
1701 + (^c&w(ixo^s,b^c_)**2+))
1702 end function mhd_get_ei_origin
1705 function mhd_get_ei_inte(w, ixI^L, ixO^L)
result(ei)
1707 integer,
intent(in) :: ixi^
l, ixo^
l
1708 double precision,
intent(in) :: w(ixi^s, nw)
1709 double precision :: ei(ixo^s)
1712 ei(ixo^s) = w(ixo^s,e_)
1713 end function mhd_get_ei_inte
1728 subroutine mhd_p_to_e_pi(ixI^L,ixO^L,w,x)
1730 integer,
intent(in) :: ixi^
l, ixo^
l
1731 double precision,
intent(inout) :: w(ixi^s, nw)
1732 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1734 double precision :: eint
1737 {
do ix^db=ixomin^db,ixomax^db\}
1738 call eint_from_rho_p_pi(w(ix^
d,rho_), w(ix^
d,p_), eint)
1740 +half*((^c&w(ix^
d,m^c_)**2+)*w(ix^
d,rho_)&
1741 +(^c&w(ix^
d,b^c_)**2+))
1744 end subroutine mhd_p_to_e_pi
1747 subroutine mhd_p_to_eint_pi(ixI^L,ixO^L,w,x)
1749 integer,
intent(in) :: ixi^
l, ixo^
l
1750 double precision,
intent(inout) :: w(ixi^s, nw)
1751 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1753 double precision :: eint
1756 {
do ix^db=ixomin^db,ixomax^db\}
1757 call eint_from_rho_p_pi(w(ix^
d,rho_), w(ix^
d,p_), eint)
1761 end subroutine mhd_p_to_eint_pi
1764 subroutine mhd_to_conserved_origin_pi(ixI^L,ixO^L,w,x)
1766 integer,
intent(in) :: ixi^
l, ixo^
l
1767 double precision,
intent(inout) :: w(ixi^s, nw)
1768 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1770 call mhd_p_to_e_pi(ixi^
l, ixo^
l, w, x)
1771 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
1773 end subroutine mhd_to_conserved_origin_pi
1776 subroutine mhd_to_conserved_inte_pi(ixI^L,ixO^L,w,x)
1778 integer,
intent(in) :: ixi^
l, ixo^
l
1779 double precision,
intent(inout) :: w(ixi^s, nw)
1780 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1782 call mhd_p_to_eint_pi(ixi^
l, ixo^
l, w, x)
1783 ^c&w(ixo^s,m^c_)=w(ixo^s,rho_)*w(ixo^s,m^c_)\
1785 end subroutine mhd_to_conserved_inte_pi
1788 subroutine mhd_to_primitive_origin_pi(ixI^L,ixO^L,w,x)
1790 integer,
intent(in) :: ixi^
l, ixo^
l
1791 double precision,
intent(inout) :: w(ixi^s, nw)
1792 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1794 double precision :: inv_rho, eint_val, t, rfac
1798 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
1799 'mhd_to_primitive_origin_PI')
1802 {
do ix^db=ixomin^db,ixomax^db\}
1803 inv_rho = 1.d0/w(ix^
d,rho_)
1805 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1807 eint_val = w(ix^
d,e_) &
1808 - half*(w(ix^
d,rho_)*(^c&w(ix^
d,m^c_)**2+) &
1809 + (^c&w(ix^
d,b^c_)**2+))
1810 eint_val = max(eint_val, smalldouble)
1811 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, w(ix^
d,p_), rfac)
1814 end subroutine mhd_to_primitive_origin_pi
1817 subroutine mhd_to_primitive_inte_pi(ixI^L,ixO^L,w,x)
1819 integer,
intent(in) :: ixi^
l, ixo^
l
1820 double precision,
intent(inout) :: w(ixi^s, nw)
1821 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
1823 double precision :: inv_rho, eint_val, t, rfac
1827 call phys_handle_small_values(.false., w, x, ixi^
l, ixo^
l, &
1828 'mhd_to_primitive_inte_PI')
1831 {
do ix^db=ixomin^db,ixomax^db\}
1832 eint_val = max(w(ix^
d,e_), smalldouble)
1833 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, w(ix^
d,p_), rfac)
1835 inv_rho = 1.d0/w(ix^
d,rho_)
1836 ^c&w(ix^
d,m^c_)=w(ix^
d,m^c_)*inv_rho\
1839 end subroutine mhd_to_primitive_inte_pi
1842 subroutine mhd_get_pthermal_origin_pi(w,x,ixI^L,ixO^L,pth)
1844 integer,
intent(in) :: ixi^
l, ixo^
l
1845 double precision,
intent(in) :: w(ixi^s,nw)
1846 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1847 double precision,
intent(out):: pth(ixi^s)
1849 double precision :: eint_val, t, rfac
1852 {
do ix^db=ixomin^db,ixomax^db\}
1853 eint_val = w(ix^
d,e_) &
1854 - half*((^c&w(ix^
d,m^c_)**2+)/w(ix^
d,rho_) &
1855 + (^c&w(ix^
d,b^c_)**2+))
1856 eint_val = max(eint_val, smalldouble)
1857 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, pth(ix^
d), rfac)
1861 end subroutine mhd_get_pthermal_origin_pi
1864 subroutine mhd_get_pthermal_inte_pi(w,x,ixI^L,ixO^L,pth)
1866 integer,
intent(in) :: ixi^
l, ixo^
l
1867 double precision,
intent(in) :: w(ixi^s,nw)
1868 double precision,
intent(in) :: x(ixi^s,1:
ndim)
1869 double precision,
intent(out):: pth(ixi^s)
1871 double precision :: eint_val, t, rfac
1874 {
do ix^db=ixomin^db,ixomax^db\}
1875 eint_val = max(w(ix^
d,e_), smalldouble)
1876 call state_from_eint_pi(w(ix^
d,rho_), eint_val, t, pth(ix^
d), rfac)
1880 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.
integer, public, protected wkminus_
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
integer, public, protected waminus_
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 waplus_
Conserved wave-energy indices. The plus variables propagate against B.
subroutine, public mhd_uawsom_rho2_factor(ixil, ixol, w, x, factor)
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 wkplus_
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, protected mhd_uawsom
Enable the Uniturbulence and Alfven Wave Solar Model extension.
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
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