con2primHydro_eos Subroutine

public pure subroutine con2primHydro_eos(lfac, xi, d, sqrs, tau)

SRHD iteration solves for p via NR, and then gives xi as output

Arguments

Type IntentOptional Attributes Name
double precision, intent(out) :: lfac
double precision, intent(out) :: xi
double precision, intent(in) :: d
double precision, intent(in) :: sqrs
double precision, intent(in) :: tau

Called by

proc~~con2primhydro_eos~~CalledByGraph proc~con2primhydro_eos con2primHydro_eos proc~con2prim_eos con2prim_eos proc~con2prim_eos->proc~con2primhydro_eos proc~to_primitive to_primitive proc~to_primitive->proc~con2prim_eos proc~to_primitive~10 to_primitive proc~to_primitive~10->proc~con2prim_eos proc~to_primitive~4 to_primitive proc~to_primitive~4->proc~con2prim_eos proc~to_primitive~9 to_primitive proc~to_primitive~9->proc~con2prim_eos proc~add_split_source~4 add_split_source proc~add_split_source~4->proc~to_primitive~10 proc~finite_volume_local_muscl_hll finite_volume_local_muscl_hll proc~finite_volume_local_muscl_hll->proc~to_primitive~9 proc~finite_volume_local_muscl_hllc finite_volume_local_muscl_hllc proc~finite_volume_local_muscl_hllc->proc~to_primitive~9 proc~finite_volume_local_muscl_llf finite_volume_local_muscl_llf proc~finite_volume_local_muscl_llf->proc~to_primitive~9 proc~phys_to_primitive phys_to_primitive proc~phys_to_primitive->proc~to_primitive~4 proc~setdt setdt proc~setdt->proc~to_primitive proc~finite_volume_local finite_volume_local proc~finite_volume_local->proc~finite_volume_local_muscl_hll proc~finite_volume_local->proc~finite_volume_local_muscl_hllc proc~finite_volume_local->proc~finite_volume_local_muscl_llf

Source Code

  pure subroutine con2primHydro_eos(lfac,xi,d,sqrs,tau)
    
    double precision, intent(out) :: xi,lfac
    double precision, intent(in)  :: d,sqrs,tau

    ! .. local ..
    integer          :: ni,niiter,nit,n2it,ni3
    double precision :: pcurrent,pnew
    double precision :: er,er1,ff,df,dp,v2
    double precision :: pmin,lfac2inv,pLabs,pRabs,pprev
    double precision :: dv2d2p
    double precision :: xicurrent,h,dhdp
    double precision :: oldff1,oldff2,Nff
    double precision :: pleft,pright
    double precision :: rho,E_th,E
    double precision :: dE_thdp,dEdp
    !---------------------------------------------------------------------

    ! left and right brackets for p-range
    pmin=dsqrt(sqrs)/(one-dmaxvel)-tau-d
    pLabs=max(srhd_small_pressure,pmin)
    pRabs=1.0d99
    ! start value from input
    pcurrent=pLabs

    er1=one
    pprev=pcurrent

    ! Fudge Parameters
    oldff1=1.0d7  ! High number
    oldff2=1.0d9  ! High number bigger then oldff1
    n2it = 0
    nit  = 0

    LoopNR:  do ni=1,maxitnr
       nit = nit + 1
       !=== Relax NR iteration accuracy=======!
       if(nit>maxitnr/4)then
          ! mix pressure value for convergence
          pcurrent=half*(pcurrent+pprev)
          ! relax accuracy requirement
          er1=10.0d0*er1
          nit = nit - maxitnr/10
       endif
       !=======================================!

       niiter=ni
       xicurrent=tau+d+pcurrent

       v2=sqrs/xicurrent**2
       lfac2inv=one - v2
          lfac=one/dsqrt(lfac2inv)

       dv2d2p=sqrs/(xicurrent**3)
       !== calculation done using the EOS ==!
       rho=d*dsqrt(lfac2inv)
       E_th = pcurrent/(phys_gamma-1.0d0)
       E = (E_th + dsqrt(E_th**2+rho**2))
       !== Enthalpy ==!
       h = half*((phys_gamma+one)*E-(phys_gamma-1.0d0)*rho*(rho/E))
       !=== Derivative of thermal energy ===!
       dE_thdp = one/(phys_gamma-1.0d0)
       !=== Derivative of internal energy ===!
       dEdp = dE_thdp * (one+E_th/dsqrt(E_th**2+rho**2))&
              +  d**2*dv2d2p/dsqrt(E_th**2+rho**2)
       !====== Derivative of Enthalpy ======!
       dhdp = half*((phys_gamma+one)*dEdp + &
              (phys_gamma-1.0d0)*(rho*(rho/E))*(-2.0d0*dv2d2p/lfac2inv+dEdp/E))
       !=======================================!
       ff=-xicurrent*lfac2inv + h
       df=- two*sqrs/xicurrent**2  + dhdp - lfac2inv

       if (ff*df==zero) then
          if (ff==zero) then
             exit ! zero found
          endif
       else
          pnew=pcurrent-ff/df
          if (ff*df>zero) then
             ! pressure iterate has decreased
             ! restrict to left
             pnew=max(pnew,pLabs)
          else  ! ff*df<0
             ! pressure iterate has increased
             ! restrict to right
             pnew=min(pnew,pRabs)
          endif
       endif

       !===============================================!
       dp=pcurrent-pnew
       er=two*dabs(dp)/(pnew+pcurrent)
       if(((er<tolernr*er1).or.(dabs(dp)<absaccnr))) exit LoopNR
       !===============================================!

       ! For very small values of pressure, NR algorithm is not efficient to
       ! find root, use Euler algorithm to find precise value of pressure
       if((dabs(oldff2-ff) < 1.0d-8 .or. niiter >= maxitnr-maxitnr/20).and.&
            ff * oldff1 < zero    .and.  dabs(ff)>absaccnr)then

          n2it=n2it+1
          if(n2it<=3) pcurrent=half*(pnew+pcurrent)
          if(n2it>3)then
             pright =pcurrent
             pleft=pprev
             pcurrent=half*(pleft+pright)
             Dicho:  do ni3=1,maxitnr
                !===================!
                xicurrent=tau+d+pcurrent
                v2=sqrs/xicurrent**2
                lfac2inv=one - v2

                   lfac=one/dsqrt(lfac2inv)

                !== calculation done using the EOS ==!
                rho=d*dsqrt(lfac2inv)
                E_th = pnew/(phys_gamma-1.0d0)
                E = (E_th + dsqrt(E_th**2+rho**2))
                !== Enthalpy ==!
                h = half*((phys_gamma+one)*E-(phys_gamma-1.0d0)*rho*(rho/E))
                Nff=-xicurrent*lfac2inv + h
                !=======================================!
                !==== Iterate ====!
                if(ff * Nff < zero)then
                   pleft=pcurrent
                else
                   pright=pcurrent
                endif

                pcurrent=half*(pleft+pright)
                !==================!

                !=== The iteration converged ===!
                if(2.0d0*dabs(pleft-pright)/(pleft+pright)< absaccnr &
                     .or. dabs(ff)<absaccnr)then
                   pnew=pcurrent
                   exit LoopNR
                endif
                !==============================!

                !==============================!

                !=== conserve the last value of Nff ===!
                ff=Nff
                !======================================!
             enddo    Dicho
          endif

       else
          !====== There is no problems, continue the NR iteration ======!
          pprev=pcurrent
          pcurrent=pnew
          !=============================================================!
       endif


       !=== keep the values of the 2 last ff ===!
       oldff2=oldff1
       oldff1=ff
       !========================================!
    enddo LoopNR

    !------------------------------!
    xi=tau+d+pcurrent
    v2=sqrs/xicurrent**2
    lfac2inv=one - v2
       lfac=one/dsqrt(lfac2inv)
  end subroutine con2primHydro_eos