LCOV - code coverage report
Current view: top level - star/private - rsp_build.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 575 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 17 0

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2018-2019  Radek Smolec & The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              :       module rsp_build
      21              :       use star_def, only: star_info
      22              :       use utils_lib, only: is_bad
      23              :       use const_def, only: dp, crad
      24              :       use eos_lib, only: Radiation_Pressure
      25              :       use rsp_def
      26              :       use rsp_eval_eos_and_kap, only: X, Y, Z
      27              :       use rsp_lina, only: mesa_eos_kap, do_LINA
      28              :       use rsp_relax_env, only: EOP, RELAX_ENV
      29              : 
      30              :       implicit none
      31              : 
      32              :       private
      33              :       public :: do_rsp_build
      34              : 
      35              :       real(dp) :: PREC,FSUB,TIN,CFIDDLE,ALF, &
      36              :          HHFAC,DdmFAC,EFL02,EMR,ELR, &
      37              :          E_0,E_1,T_0,T_1,V_0,V_1,P_0,P_1,QQ_0,QQ_1, &
      38              :          CP_0,CP_1,OP_0,OP_1,R_1,M_0,dm_bar_0
      39              :       real(dp), dimension(15) :: PERS,ETO
      40              :       real(dp), pointer, dimension(:) :: &
      41              :          M, DM, DM_BAR, R, Vol, T, w, Et, E, P, Lr, Lc, Hp_face, Y_face, K, CPS, QQS
      42              :       logical, parameter :: RSP_eddi = .true.  ! use Eddington approx at surface
      43              : 
      44              :       contains
      45              : 
      46            0 :       subroutine do_rsp_build(s,ierr)
      47              :       !use rsp_create_env, only: do_rsp_create_env
      48              :       type (star_info), pointer :: s
      49              :       integer, intent(out) :: ierr
      50              :       integer :: NZT    ! warst. z joniz./il. warstw
      51            0 :       real(dp) :: TH0                ! temp. warstwy jonizacji
      52            0 :       real(dp) :: Mass,L
      53            0 :       real(dp) :: H,dmN
      54              :       integer :: NMODES            ! ilosc modow rozwazanych (N=NMODES)
      55              :       integer :: NDIM1,NDIM2       ! maks. ilosc modow/warstw
      56              :       real(dp) :: VEL0(15)
      57              :       integer :: I,J,kk,NSEQ
      58            0 :       real(dp) ::  GEFF,MBOL
      59              :       character (len=250) :: FILENAME
      60              : 
      61              :       integer :: IO,II
      62            0 :       real(dp) :: SS, AA, BB
      63            0 :       real(dp), allocatable :: TA(:), VEL(:,:), TEMP(:)
      64            0 :       real(dp) :: TAUTEFF, TAUATTEFF
      65              :       logical :: RELAX
      66            0 :       real(dp) :: amix1, amix2
      67              : 
      68            0 :       ierr = 0
      69              : 
      70            0 :       if (.not. associated(M)) then
      71              :          allocate( &
      72              :             M(NZN+1), DM(NZN+1), DM_BAR(NZN+1), T(NZN+1), E(NZN+1), w(NZN+1), &
      73              :             Et(NZN+1), P(NZN+1), R(NZN+1), Vol(NZN+1), &
      74              :             Lr(NZN+1), Lc(NZN+1), Hp_face(NZN+1), Y_face(NZN+1), K(NZN+1), &
      75            0 :             CPS(NZN+1), QQS(NZN+1))
      76              :       end if
      77              : 
      78            0 :       allocate(TA(NZN+1),VEL(NZN+1,15),TEMP(NZN))
      79              : 
      80            0 :       TH0 = s% RSP_T_anchor
      81            0 :       TIN = s% RSP_T_inner
      82            0 :       NZT = s% RSP_nz_outer
      83            0 :       FSUB = s% RSP_dq_1_factor
      84            0 :       ddmfac = 1d0  ! s% RSP_ddmfac
      85            0 :       hhfac = 1.02d0  ! s% RSP_hhfac
      86            0 :       nmodes = s% RSP_nmodes
      87            0 :       RELAX = s% RSP_relax_initial_model
      88            0 :       EFL02 = EFL0*EFL0
      89              : 
      90              : !     START MAIN CYCLE
      91              : 
      92              : !     INITIALIZE ARRAYS
      93            0 :       NDIM1=15  !max. number of modes
      94            0 :       NDIM2=NZN+1
      95            0 :       do J=1,NDIM1
      96            0 :          do I=1,NDIM2
      97            0 :             VEL(I,J)=0.d0
      98              :          end do
      99              :       end do
     100            0 :       do I=1,NDIM1
     101            0 :          PERS(I)= 0.d0
     102              :          VEL0(I)= 0.d0
     103            0 :          ETO(I) = 0.d0
     104              :          !SGR(I) = 0.d0
     105              :       end do
     106            0 :       do I=1,NDIM2
     107            0 :          R(I) = 0.d0
     108            0 :          P(I) = 0.d0
     109            0 :          Vol(I) = 0.d0
     110            0 :          E(I) = 0.d0
     111            0 :          T(I) = 0.d0
     112            0 :          K(I)= 0.d0
     113            0 :          M(I)= 0.d0
     114            0 :          dm(I)= 0.d0
     115            0 :          dm_bar(I)= 0.d0
     116            0 :          w(I)=0.d0
     117            0 :          Hp_face(I)    = 0.d0
     118            0 :          Y_face(I)   = 0.d0
     119            0 :          CPS(I)    = 0.d0
     120            0 :          QQS(I)    = 0.d0
     121            0 :          Lc(I) = 0.d0
     122            0 :          Lr(I) = 0.d0
     123            0 :          w(I) = 0.d0
     124              :       end do
     125              : 
     126              : !     SET STANDARD PARAMETERS
     127              : !     NSEQ = SEQUENCE NUMBER (DUMMY)
     128            0 :       NSEQ    = 1
     129              : 
     130            0 :       CFIDDLE = 0.02d0  !0.02
     131            0 :       ALF     = 1.0d-6
     132              : !     PRECISIONS
     133            0 :       PREC    = 1d-10
     134              : 
     135            0 :       EMR = s% RSP_mass
     136            0 :       ELR = s% RSP_L
     137            0 :       TE = s% RSP_Teff
     138            0 :       Mass=EMR*SUNM
     139            0 :       L=ELR*SUNL
     140              : 
     141            0 :       if (s% RSP_trace_RSP_build_model) then
     142            0 :          write(*,*) '*** build initial model ***'
     143            0 :          write(*,'(a9,f15.5)') 'M/Msun', EMR
     144            0 :          write(*,'(a9,f15.5)') 'L/Lsun', ELR
     145            0 :          write(*,'(a9,f15.5)') '  Teff', TE
     146              :       end if
     147              : 
     148            0 :       call STAH(s,Mass,L,TE,H,dmN,TH0,NZT,NZN,ierr)
     149            0 :       if (ierr /= 0) return
     150              : 
     151              : !     INITIAL GUESS FOR w=E_T (NOW DEFINED AT THE ZONE)
     152            0 :       TEMP(1)=0.d0
     153            0 :       do I=2,NZN
     154              :          !TEMP(I)=0.5d0*(w(I)**2+w(I-1)**2)
     155              :          !TEMP(I)=sqrt(w(I)**2*w(I-1)**2)
     156              :          TEMP(I)=(w(I)**2*dm(I)+w(I-1)**2*dm(I-1))/ &
     157            0 :                  (dm(I)+dm(I-1))
     158              :       end do
     159            0 :       do I=1,NZN
     160            0 :          w(I)=TEMP(I)
     161              : !        LINE BELOW MUST BE PRESENT IF MAIN VARIABLE IS E_T
     162              : !        (DERIVATIVES ~1/sqrt(E_T) AND WITH w=0, LAPACK
     163              : !         PROBLEM ARISES; NO SUCH PROBLEM WHEN E_T^2 IS USED
     164              : !         AND LINE BELOW IS NOT NECESSARY THEN)
     165            0 :          if(w(I)<=EFL02) w(I)=EFL02
     166              :          !write(*,*) NZN-I+1, sqrt(w(i))
     167              :       end do
     168              : 
     169              :       ! NOTE: w(I) now holds Et = w**2
     170              :       ! watch out
     171              : 
     172            0 :       if(RELAX) then
     173              :          call RELAX_ENV(s, L, TH0, TE, NZT, NZN, &
     174            0 :             M, DM, DM_BAR, R, Vol, T, w, ierr)
     175            0 :          if (ierr /= 0) return
     176              :       end if
     177              : 
     178              :       ! optical depth.  just for output.
     179            0 :       TA(NZN) = s% tau_factor*s% tau_base
     180            0 :       SS=TA(NZN)
     181            0 :       do I=NZN,2,-1
     182            0 :          SS=SS+K(I)*(R(I)-R(I-1))/Vol(I)
     183            0 :          TA(I-1)=SS
     184              :       end do
     185            0 :       II=0; IO=0
     186            0 :       do I=NZN,1,-1
     187            0 :          if(TA(I)>2.d0/3.d0)then
     188            0 :             II=I
     189            0 :             IO=I+1
     190            0 :             GOTO 77
     191              :          end if
     192              :       end do
     193              :  77   continue
     194            0 :       if (IO == 0) then
     195            0 :          write(*,*) 'failed to find photosphere'
     196            0 :          ierr = -1
     197            0 :          return
     198              :       end if
     199            0 :       AA=(T(IO)-T(II))/(TA(IO)-TA(II))
     200            0 :       BB=T(IO)-AA*TA(IO)
     201            0 :       TAUTEFF=AA*2.d0/3.d0+BB
     202              : 
     203            0 :       do I=NZN,1,-1
     204              :          if(T(I)>TE)then
     205              :             II=I
     206              :             IO=I+1
     207              :             GOTO 78
     208              :          end if
     209              :       end do
     210              :  78   continue
     211            0 :       AA=(T(IO)-T(II))/(TA(IO)-TA(II))
     212            0 :       BB=T(IO)-AA*TA(IO)
     213            0 :       TAUATTEFF=(TE-BB)/AA
     214              : 
     215            0 :       call cleanup_for_LINA(s, M, DM, DM_BAR, R, Vol, T, w, P, ierr)
     216              : 
     217              :  1    format(1X,1P,5D26.16)
     218              : 
     219            0 :       GEFF=G*Mass/R(NZN)**2
     220            0 :       MBOL=-2.5d0*dlog10(ELR)+4.79d0
     221              : 
     222            0 :       if(NMODES==0) GOTO 11  ! jesli masz liczyc tylko static envelope
     223              : 
     224            0 :       if (.not. (s% use_RSP_new_start_scheme .or. s% use_other_RSP_linear_analysis)) then
     225            0 :          if (s% RSP_trace_RSP_build_model) write(*,*) '*** linear analysis ***'
     226            0 :          do I=1,NZN  ! LINA changes Et, so make a work copy for it
     227            0 :             Et(I) = w(I)
     228              :          end do
     229              :          call do_LINA(s, L, NZN, NMODES, VEL, PERS, ETO, &
     230            0 :             M, DM, DM_BAR, R, Vol, T, Et, Lr, ierr)
     231            0 :          if (ierr /= 0) then
     232              :             return
     233              :          end if
     234            0 :          FILENAME=trim(s% log_directory) // '/' // 'LINA_period_growth.data'
     235            0 :          open(15,file=trim(FILENAME),status='unknown')
     236            0 :          write(*,'(a)') '            P(days)         growth'
     237            0 :          do I=1,NMODES
     238            0 :             s% rsp_LINA_periods(i) = PERS(I)
     239            0 :             s% rsp_LINA_growth_rates(i) = ETO(I)
     240            0 :             write(*,'(I3,2X,99e16.5)') I-1, &
     241            0 :                PERS(I)/86400.d0,ETO(I)
     242            0 :             write(15,'(I3,2X,99e16.5)') I-1, &
     243            0 :                PERS(I)/86400.d0,ETO(I)
     244              :          end do
     245            0 :          close(15)
     246            0 :          s% RSP_have_set_velocities = .true.
     247              :       else
     248            0 :          PERS(1:NMODES) = 0d0
     249            0 :          VEL0(1:NMODES) = 0d0
     250            0 :          do I=1,NZN
     251            0 :             do j=1,nmodes
     252            0 :                VEL(I,J) = 0d0
     253              :             end do
     254              :          end do
     255              :       end if
     256              : 
     257              :  11   continue
     258              : 
     259              : 5568  format(1X,1P,5E15.6)
     260              : 
     261              :  444  format(F6.3,tr2,f8.2,tr2,f7.2,tr2,d9.3)
     262            0 :       if (s% RSP_trace_RSP_build_model) then
     263            0 :          write(*,*) '*** done creating initial model ***'
     264            0 :          write(*,'(A)')
     265              :       end if
     266              :       ! recall that w is actually Et = w**2 at this point
     267            0 :       call set_build_vars(s,M,DM,DM_BAR,R,Vol,T,w,Lr,Lc)
     268              : 
     269            0 :       IWORK=0
     270            0 :       TEFF = TE
     271            0 :       RSTA = R(NZN)
     272            0 :       do I=1,NZN
     273            0 :          kk = NZN+1-i
     274            0 :          s% L(kk)=L
     275            0 :          s% L_start(kk)=0.0d0  !SMOLEC!
     276            0 :          s% v(kk)=0d0
     277              :       end do
     278            0 :       s% L_center=L
     279            0 :       if(ALFA==0.d0) EFL0=0.d0
     280            0 :       s% rsp_period=s% RSP_default_PERIODLIN
     281            0 :       if (is_bad(s% rsp_period)) then
     282            0 :          write(*,1) 'rsp_period', s% rsp_period
     283            0 :          call mesa_error(__FILE__,__LINE__,'rsp_build read_model')
     284              :       end if
     285            0 :       amix1 = s% RSP_fraction_1st_overtone
     286            0 :       amix2 = s% RSP_fraction_2nd_overtone
     287            0 :       if((AMIX1+AMIX2)>1.d0) write(*,*) 'AMIX DO NOT ADD UP RIGHT'
     288            0 :       if (.not. s% use_RSP_new_start_scheme) then
     289            0 :          PERIODLIN=PERS(s% RSP_mode_for_setting_PERIODLIN+1)
     290            0 :          s% rsp_period=PERIODLIN
     291            0 :          s% v_center = 0d0
     292            0 :          do I=1,NZN
     293              :             s% v(NZN+1-i)=1.0d5*s% RSP_kick_vsurf_km_per_sec* &
     294            0 :               ((1.0d0-AMIX1-AMIX2)*VEL(I,1)+AMIX1*VEL(I,2)+AMIX2*VEL(I,3))
     295              :          end do
     296              :       end if
     297              : 
     298            0 :       end subroutine do_rsp_build
     299              : 
     300              : 
     301            0 :       subroutine STAH(s,MX,L,TE,H0,dmN0,TH0,NZT,NZN,ierr)
     302              :    !     INTEGRATE STATIC ENVELOPE
     303              :    !     CONVECTIVE FLUX INCLUDED (WUCHTERL & FEUCHTINGER 1998)
     304              :    !     TURBULENT PRESSERE AND OVERSHOOTING NEGLECTED
     305              :    !     (ALPHA_P = ALPHA_T = 0)
     306              :    !     DIFFUSION APPROXIMATION FOR RADIATIVE TRANSFER
     307              :    !     HYDROGEN ZONE DEPTH (NZT, IN ZONES), AND TEMPERATURE(TH0) FIXED
     308              :    !     ARGUMENTS.. M(GM), L(CGS), TE,TH0(DEG K)
     309              : 
     310              :          type (star_info), pointer :: s
     311              :          real(dp), intent(in) :: MX,L,TE,TH0
     312              :          real(dp), intent(out) :: H0,dmN0
     313              :          integer, intent(in) :: NZT
     314              :          integer, intent(inout) :: NZN
     315              :          integer, intent(out) :: ierr
     316              : 
     317            0 :          real(dp) :: dmN,dm_0,H,Psurf,DDT
     318            0 :          real(dp) :: GPF
     319            0 :          real(dp) :: F2,F1,D,HH,TT,dmL
     320            0 :          real(dp) :: T4_1,RM,T4_0,WE,dmNL
     321            0 :          real(dp) :: FACQ,HH1,HH2
     322              :          integer :: N,N1,I,ITIN,dmN_cnt,NCHANG,IG,H_cnt
     323            0 :          real(dp) :: HP_0,HP_1,IGR_0,IGR_1,w_0
     324            0 :          real(dp) :: Lr_0,Lc_0,SVEL_0,HSTART,tau_sum,TH0_tol,TIN_tol, &
     325            0 :             dmN_too_large, dmN_too_small, H_too_large, H_too_small
     326              :          logical :: adjusting_dmN, in_photosphere, in_outer_env, &
     327              :             have_dmN_too_large, have_dmN_too_small, &
     328              :             have_H_too_large, have_H_too_small, have_T
     329              : 
     330              :          include 'formats'
     331              :          ierr = 0
     332            0 :          IG  = 0
     333            0 :          HH1 = 1.005d0  !1.005
     334            0 :          HH2 = 1.005d0  !1.005
     335            0 :          NCHANG = 0
     336            0 :          HSTART = 1.01d0  ! s% RSP_hstart
     337            0 :          FACQ = 1.005d0  ! 1.005
     338            0 :          ITIN = 1
     339            0 :          tau_sum = 0
     340            0 :          adjusting_dmN = .true.
     341            0 :          in_photosphere = .true.
     342            0 :          in_outer_env = .true.
     343            0 :          have_dmN_too_large = .false.
     344            0 :          have_dmN_too_small = .false.
     345            0 :          have_H_too_large = .false.
     346            0 :          have_H_too_small = .false.
     347              : 
     348            0 :          TH0_tol = s% RSP_T_anchor_tolerance
     349            0 :          TIN_tol = s% RSP_T_inner_tolerance
     350              : 
     351            0 :          call ZNVAR(s,H,dmN,L,TE,MX,ierr)
     352            0 :          if (ierr /= 0) return
     353            0 :          dmN_cnt = 1
     354            0 :          H_cnt = 1
     355              : 
     356            0 :          start_from_top_loop: do
     357            0 :             if (s% RSP_trace_RSP_build_model) write(*,*) 'call setup_outer_zone'
     358            0 :             call setup_outer_zone(ierr)
     359            0 :             if (ierr /= 0) return
     360            0 :             if (s% RSP_trace_RSP_build_model) write(*,*) 'call store_N'
     361            0 :             call store_N
     362            0 :             zone_loop: do
     363            0 :                R_1=pow(R_1**3-3.d0*V_0*dm_0/P4,1.d0/3.d0)
     364            0 :                N=N-1
     365            0 :                if (s% RSP_trace_RSP_build_model) write(*,*) 'zone_loop', N, T_0, TIN
     366            0 :                if (N==0 .or. T_0 >= TIN) then
     367            0 :                   if (s% RSP_trace_RSP_build_model) write(*,*) 'call next_H'
     368            0 :                   call next_H  ! sets HH
     369            0 :                   if (N==0 .and. abs(T(1)-TIN)<TIN*TIN_tol) then
     370            0 :                      s% M_center = M_0 - dm_0
     371            0 :                      s% star_mass = s% RSP_mass
     372            0 :                      s% mstar = s% star_mass*SUNM
     373            0 :                      s% xmstar = s% mstar - s% M_center
     374            0 :                      s% M_center = s% mstar - s% xmstar  ! this is how it is set when read file
     375            0 :                      s% L_center = s% RSP_L*SUNL
     376            0 :                      s% R_center = pow(r(1)**3 - Vol(1)*dm(1)/P43, 1d0/3d0)
     377            0 :                      s% v_center = 0
     378            0 :                      if (s% RSP_trace_RSP_build_model) &
     379            0 :                         write(*,*) '   inner dm growth scale', HH
     380              :                      exit start_from_top_loop  ! done
     381              :                   end if
     382            0 :                   if (H_cnt >= s% RSP_max_inner_scale_tries) then
     383            0 :                      write(*,*) 'failed to find inner dm scaling to satisfy tolerance for T_inner'
     384            0 :                      write(*,*) 'you might try increasing RSP_T_inner_tolerance'
     385            0 :                      ierr = -1
     386            0 :                      return
     387              :                      !call mesa_error(__FILE__,__LINE__)
     388              :                   end if
     389            0 :                   if (s% RSP_trace_RSP_build_model) write(*,*) 'call prepare_for_new_H'
     390            0 :                   call prepare_for_new_H
     391            0 :                   cycle zone_loop
     392              :                end if
     393            0 :                if (s% RSP_trace_RSP_build_model) write(*,*) 'call setup_next_zone'
     394            0 :                call setup_next_zone
     395              :                ! pick T to make Lr + Lc = L
     396            0 :                if (s% RSP_trace_RSP_build_model) write(*,*) 'call get_T'
     397            0 :                have_T = get_T(ierr)
     398            0 :                if (ierr /= 0) return
     399            0 :                if (.not. have_T) then
     400            0 :                   call failed
     401            0 :                   DDT = dmN/1.d3
     402            0 :                   dmN = dmN-DDT
     403            0 :                   cycle start_from_top_loop
     404              :                end if
     405            0 :                if (s% RSP_trace_RSP_build_model) write(*,*) 'call get_V'
     406            0 :                call get_V(ierr)
     407            0 :                if (ierr /= 0) return
     408              :                if((NZN-N+1==NZT .or. T_0 >= TH0) &
     409            0 :                      .and. adjusting_dmN) then
     410            0 :                   if (s% RSP_trace_RSP_build_model) &
     411            0 :                      write(*,*) 'call next_dmN', dmN_cnt, NZN-N+1, T_0, TH0, abs(T_0-TH0), TH0_tol*TH0
     412            0 :                   if (dmN_cnt >= s% RSP_max_outer_dm_tries) then
     413            0 :                      write(*,*) 'failed to find outer dm to satisfy tolerance for T_anchor'
     414            0 :                      write(*,*) 'you might try increasing RSP_T_anchor_tolerance'
     415            0 :                      ierr = -1
     416            0 :                      return
     417              :                      !call mesa_error(__FILE__,__LINE__)
     418              :                   end if
     419            0 :                   call next_dmN
     420            0 :                   if(NZN-N+1==NZT.and.abs(T_0-TH0)<TH0_tol*TH0) then
     421            0 :                      adjusting_dmN = .false.
     422            0 :                      if (s% RSP_trace_RSP_build_model) &
     423            0 :                         write(*,*) '           outer dm/Msun', dmN/SUNM
     424              :                   end if
     425              :                   ! one last repeat with final dmN
     426              :                   !if (s% RSP_trace_RSP_build_model) write(*,*) 'cycle start_from_top_loop', dmN_cnt, dmN/SUNM
     427              :                   cycle start_from_top_loop
     428              :                end if
     429            0 :                if (s% RSP_trace_RSP_build_model) write(*,*) 'call store_N'
     430            0 :                call store_N
     431              :             end do zone_loop
     432              :          end do start_from_top_loop
     433              : 
     434            0 :          s% R_center=R_1; H0=H; dmN0=dmN
     435            0 :          if(N/=0) call change_NZN
     436              : 
     437              :       contains
     438              : 
     439              :       subroutine report_location_of_photosphere
     440              :          real(dp) :: tau, dtau
     441              :          integer :: i
     442              :          include 'formats'
     443              :          tau = 0d0  ! surface currently at tau=0
     444              :          do i=NZN,1,-1
     445              :             dtau = dm(i)*K(i)/(4d0*pi*r(i)**2)
     446              :             tau = tau + dtau
     447              :             if (tau >= 2d0/3d0) then
     448              :                write(*,2) 'cells from surface tau=0 to tau=2/3', &
     449              :                   NZN+1-i, tau-dtau, 2d0/3d0, tau, T(i), TE
     450              :                return
     451              :             end if
     452              :          end do
     453              :       end subroutine report_location_of_photosphere
     454              : 
     455            0 :       subroutine setup_outer_zone(ierr)
     456              :          use rsp_eval_eos_and_kap, only: get_surf_P_T_kap
     457              :          integer, intent(out) :: ierr
     458            0 :          real(dp) :: tau_surf, kap_guess, T_surf, kap_surf, Teff_atm
     459              :          include 'formats'
     460            0 :          dm_0=dmN*FSUB
     461            0 :          M_0=MX
     462            0 :          dm_bar_0=(dm_0/2.d0)
     463              :          if(.not.RSP_eddi) then  !     EXACT GREY RELATION
     464              :             WE=TE**4
     465              :             T4_0=WE*sqrt(3.d0)/4.d0               !0.4330127018d0
     466              :             T_0= pow(sqrt(3.d0)/4.d0,0.25d0)*TE  !0.811194802d0*TE
     467              :          else  !     EDDINGTON APPROXIMATION
     468            0 :             WE=TE**4
     469            0 :             T4_0=WE*0.5d0  ! T4_0=WE*1.0d0/2.d0
     470            0 :             T_0=pow(0.5d0, 0.25d0)*TE  ! T_0= pow(1.0d0/2.d0,0.25d0)*TE
     471              :          end if
     472            0 :          RM=sqrt(L/(P4*SIG*WE))
     473            0 :          R_1=RM
     474            0 :          if (s% RSP_use_atm_grey_with_kap_for_Psurf) then
     475            0 :             tau_surf = s% RSP_tau_surf_for_atm_grey_with_kap
     476            0 :             kap_guess = 1d-2
     477              :             call get_surf_P_T_kap(s, &
     478              :                MX, RM, L, tau_surf, kap_guess, &
     479            0 :                T_surf, Psurf, kap_surf, Teff_atm, ierr)
     480              :             !write(*,*) 'Psurf from atm, Prad_surf', Psurf, crad*T_0*T_0*T_0*T_0/3d0
     481            0 :             if (ierr /= 0) then
     482            0 :                write(*,*) 'failed in get_surf_P_T_kap'
     483            0 :                return
     484              :             end if
     485            0 :          else if (s% RSP_use_Prad_for_Psurf) then
     486            0 :             Psurf = crad*T_0*T_0*T_0*T_0/3d0
     487              :          else
     488            0 :             Psurf = 0d0
     489              :          end if
     490            0 :          Psurf_from_atm = Psurf
     491            0 :          P_0=Psurf+G*M_0*dm_bar_0/(P4*R_1**4)
     492              :          call EOP(s,-1,T_0,P_0,V_0, &
     493            0 :                   E_0,CP_0,QQ_0,SVEL_0,OP_0,ierr)
     494            0 :          if (ierr /= 0) return
     495            0 :          w_0=0.d0
     496            0 :          Lc_0=0.d0
     497            0 :          Lr_0=L
     498            0 :          N=NZN
     499            0 :       end subroutine setup_outer_zone
     500              : 
     501            0 :       subroutine get_V(ierr)
     502              :          integer, intent(out) :: ierr
     503              :          ierr = 0
     504            0 :          T_0=sqrt(sqrt(T4_0))
     505              :          call EOP(s,N,T_0,P_0,V_0, &
     506            0 :                   E_0,CP_0,QQ_0,SVEL_0,OP_0,ierr)
     507            0 :          if (ierr /= 0) return
     508            0 :          if(N/=NZN)then
     509            0 :             call CFLUX(HP_0,IGR_0,Lc_0,w_0,GPF,N)
     510            0 :             if(Lc_0>=L) then
     511            0 :                write(*,*) 'trouble!',I
     512            0 :                stop
     513              :             end if
     514              :          end if
     515            0 :       end subroutine get_V
     516              : 
     517            0 :       subroutine next_dmN
     518              :          real(dp), parameter :: search_factor = 2d0
     519            0 :          dmN_cnt = dmN_cnt+1
     520            0 :          dmNL=dmN
     521            0 :          if (T_0 < TH0) then  ! dmN is too small
     522            0 :             dmN_too_small = dmN
     523            0 :             have_dmN_too_small = .true.
     524            0 :             if (.not. have_dmN_too_large) then
     525            0 :                dmN = dmN * search_factor
     526            0 :                DDT = dmN - dmNL
     527            0 :                return
     528              :             end if
     529              :          else  ! T_0 > TH0, dmN is too large
     530            0 :             dmN_too_large = dmN
     531            0 :             have_dmN_too_large = .true.
     532            0 :             if (.not. have_dmN_too_small) then
     533            0 :                dmN = dmN / search_factor
     534            0 :                DDT = dmN - dmNL
     535            0 :                return
     536              :             end if
     537              :          end if
     538              :          ! search using bounds
     539              :          ! just bisect since for dmN too large, stop short of target cell
     540            0 :          dmN = 0.5d0*(dmN_too_large + dmN_too_small)
     541            0 :          DDT = dmN - dmNL
     542              :       end subroutine next_dmN
     543              : 
     544            0 :       subroutine next_H  ! same scheme as next_dmN.  bound and bisect.
     545              :          real(dp), parameter :: search_factor = 1.05d0
     546              :          real(dp) :: HH_prev
     547            0 :          HH_prev = HH
     548            0 :          H_cnt = H_cnt+1
     549              :          !write(*,*) 'next_H have_H_too_large', have_H_too_large, H_too_large
     550              :          !write(*,*) 'next_H have_H_too_small', have_H_too_small, H_too_small
     551            0 :          if (T_0 < TIN) then  ! H is too small
     552            0 :             H_too_small = H
     553            0 :             have_H_too_small = .true.
     554            0 :             if (.not. have_H_too_large) then
     555            0 :                HH = H * search_factor
     556              :                !write(*,*) 'too small next_H HH, HH_prev', HH, HH_prev
     557            0 :                return
     558              :             end if
     559              :          else  ! T_0 > TIN, H is too large
     560            0 :             H_too_large = H
     561            0 :             have_H_too_large = .true.
     562            0 :             if (.not. have_H_too_small) then
     563            0 :                HH = H / search_factor
     564              :                !write(*,*) 'too large next_H HH, HH_prev', HH, HH_prev
     565            0 :                return
     566              :             end if
     567              :          end if
     568              :          ! search using bounds.  keep it simple.
     569              :          ! just bisect since for H too large, stop short of target cell
     570            0 :          HH = 0.5d0*(H_too_large + H_too_small)
     571              :          !write(*,*) 'next_H HH, HH_prev', HH, HH_prev
     572              :          !if (abs(HH - HH_prev) < 1d-6*HH) call mesa_error(__FILE__,__LINE__,'next_H')
     573              :       end subroutine next_H
     574              : 
     575            0 :       subroutine store_N
     576            0 :          real(dp) :: dtau
     577            0 :          R(N)  = R_1
     578            0 :          P(N)  = P_0
     579            0 :          Vol(N)  = V_0
     580            0 :          E(N)  = E_0
     581            0 :          T(N)  = T_0
     582            0 :          K(N) = OP_0
     583            0 :          M(N) = M_0
     584            0 :          dm(N) = dm_0
     585            0 :          dm_bar(N) = dm_bar_0
     586            0 :          Hp_face(N) = HP_0
     587            0 :          Y_face(N)= IGR_0
     588            0 :          CPS(N) = CP_0
     589            0 :          QQS(N) = QQ_0
     590            0 :          Lc(N) = Lc_0
     591            0 :          Lr(N) = Lr_0
     592            0 :          w(N) = w_0
     593            0 :          dtau = dm(N)*K(N)/(P4*R(N)**2)
     594            0 :          if (in_photosphere .and. T(N) >= TE) then
     595            0 :             if (s% RSP_testing) &
     596            0 :                write(*,*) 'nz phot, tau_sum, T', &
     597            0 :                   NZN-N, tau_sum, tau_sum+dtau, T(N+1), TE, T(N)
     598            0 :             in_photosphere = .false.
     599              :          end if
     600            0 :          tau_sum = tau_sum + dtau
     601            0 :       end subroutine store_N
     602              : 
     603            0 :       subroutine setup_next_zone
     604            0 :          P_1  = P_0
     605            0 :          V_1  = V_0
     606            0 :          OP_1 = OP_0
     607            0 :          T4_1  = T4_0
     608            0 :          M_0   = M_0-dm_0
     609            0 :          dmL = dm_0   !dmL IS dm IN A PREVIOUS ZONE
     610            0 :          HP_1  = HP_0
     611            0 :          IGR_1 = IGR_0
     612            0 :          CP_1  = CP_0
     613            0 :          QQ_1  = QQ_0
     614            0 :          T_1 = sqrt(sqrt(T4_1))
     615            0 :          E_1 = E_0
     616              :          !     RESET dm FOR THE INNER ZONES
     617            0 :          if(N==NZN-1) then
     618            0 :             dm_0=dmN
     619            0 :          else if (T_1 > TH0) then
     620            0 :             if (in_outer_env) then
     621            0 :                in_outer_env = .false.
     622            0 :                if (s% RSP_testing) write(*,*) 'nz outer', NZN-N, T_1, TH0
     623              :             end if
     624            0 :             dm_0=dm_0*H
     625              :          end if
     626            0 :          dm_bar_0=(dm_0+dmL)/2.d0
     627            0 :          P_0=P_1+G*M_0*dm_bar_0/(P4*R_1**4)
     628            0 :       end subroutine setup_next_zone
     629              : 
     630            0 :       real(dp) function eval_T_residual(ierr)
     631              :          integer, intent(out) :: ierr
     632              :          call EOP(s,0, &
     633            0 :             T_0,P_0,V_0,E_0,CP_0,QQ_0,SVEL_0,OP_0,ierr)
     634            0 :          if (ierr /= 0) return
     635            0 :          call CFLUX(HP_0,IGR_0,Lc_0,w_0,GPF,N)
     636            0 :          TT=4.d0*SIG*P4**2*R_1**4/(3.d0*dm_bar_0*L)
     637            0 :          T4_0 = T_0**4
     638              :          Lr_0=TT*(T4_0/OP_0-T4_1/OP_1)/ &
     639            0 :                (1.d0-dlog(OP_0/OP_1)/dlog(T4_0/T4_1))*L
     640            0 :          eval_T_residual = (Lr_0 + Lc_0)/L - 1d0
     641            0 :       end function eval_T_residual
     642              : 
     643            0 :       real(dp) function get_T_residual(lnT, dfdx, lrpar, rpar, lipar, ipar, ierr)
     644              :          ! returns with ierr = 0 if was able to evaluate f and df/dx at x
     645              :          ! if df/dx not available, it is okay to set it to 0
     646              :          use const_def, only: dp
     647              :          integer, intent(in) :: lrpar, lipar
     648              :          real(dp), intent(in) :: lnT
     649              :          real(dp), intent(out) :: dfdx
     650              :          integer, intent(inout), pointer :: ipar(:)  ! (lipar)
     651              :          real(dp), intent(inout), pointer :: rpar(:)  ! (lrpar)
     652              :          integer, intent(out) :: ierr
     653            0 :          ierr = 0
     654            0 :          dfdx = 0
     655            0 :          T_0 = exp(lnT)
     656            0 :          get_T_residual = eval_T_residual(ierr)
     657            0 :       end function get_T_residual
     658              : 
     659            0 :       logical function get_T_estimate()
     660              :          use num_lib, only: safe_root_with_brackets
     661            0 :          real(dp) :: Tmax, epsx, epsy, residual, lnT, &
     662            0 :             lnT_min, lnT_max, resid_T_min, resid_T_max, dfdx
     663              :          integer :: n, ierr
     664              :          integer, parameter :: lrpar=1, lipar=1, imax=50
     665            0 :          real(dp), pointer :: rpar(:)
     666            0 :          integer, pointer :: ipar(:)
     667              :          include 'formats'
     668            0 :          Tmax = 0.99d0*(3d0*P_0/crad)**0.25d0  ! Prad must be < P_0
     669            0 :          lnT_min = log(T_1)
     670            0 :          lnT_max = log(Tmax)
     671              :          resid_T_min = get_T_residual(lnT_min, &
     672            0 :             dfdx, lrpar, rpar, lipar, ipar, ierr)
     673              :          resid_T_max = get_T_residual(lnT_max, &
     674            0 :             dfdx, lrpar, rpar, lipar, ipar, ierr)
     675            0 :          epsx = 1d-5
     676            0 :          epsy = 1d-5
     677              :          ierr = 0
     678              :          lnT = safe_root_with_brackets( &
     679              :             get_T_residual, lnT_min, lnT_max, &
     680              :             resid_T_min, resid_T_max, &
     681              :             imax, epsx, epsy, &
     682            0 :             lrpar, rpar, lipar, ipar, ierr)
     683            0 :          if (ierr /= 0) then
     684            0 :             write(*,2) 'T_1', N, T_1
     685            0 :             write(*,2) 'Tmax', N, Tmax
     686            0 :             write(*,2) 'resid_T_min', N, resid_T_min
     687            0 :             write(*,2) 'resid_T_max', N, resid_T_max
     688            0 :             return
     689              :             call mesa_error(__FILE__,__LINE__,'get_T failed in root find')
     690              :          end if
     691            0 :          T_0 = exp(lnT)
     692              :          residual = get_T_residual(lnT, &
     693            0 :             dfdx, lrpar, rpar, lipar, ipar, ierr)
     694            0 :          get_T_estimate = .true.
     695            0 :       end function get_T_estimate
     696              : 
     697            0 :       logical function get_T(ierr)
     698              :          integer, intent(out) :: ierr
     699            0 :          real(dp) :: Prad
     700            0 :          ierr = 0
     701            0 :          if (get_T_estimate()) then
     702              :             ! use T_0 from get_T_estimate as initial guess
     703            0 :             T4_0 = T_0*T_0*T_0*T_0
     704              :          else
     705            0 :             T4_0=T4_1*1.2d0
     706            0 :             T_0=sqrt(sqrt(T4_0))
     707            0 :             if (s% RSP_testing) then
     708            0 :                do
     709            0 :                   Prad = Radiation_Pressure(T_0)
     710            0 :                   if (Prad < P_0) exit
     711            0 :                   write(*,*) '1 reduce T_0 in get_T', N
     712            0 :                   T_0 = 0.99d0*T_0
     713              :                end do
     714              :             end if
     715              :          end if
     716              : 
     717            0 :          Lc_loop1: do  ! reduce T if Lc >= L
     718              :             call EOP(s,N, &
     719            0 :                T_0,P_0,V_0,E_0,CP_0,QQ_0,SVEL_0,OP_0,ierr)
     720            0 :             if (ierr /= 0) return
     721            0 :             call CFLUX(HP_0,IGR_0,Lc_0,w_0,GPF,N)
     722            0 :             if(Lc_0<L) exit Lc_loop1
     723            0 :             T_0=T_0-10.d0*(Lc_0/L)
     724            0 :             if (T_0 <= 0) then
     725            0 :                ierr = -1
     726            0 :                return
     727              :                call mesa_error(__FILE__,__LINE__,'T_0 <= 0 in Lc_loop1')
     728              :             end if
     729            0 :             T4_0=T_0**4
     730              :          end do Lc_loop1
     731              : 
     732            0 :          TT=4.d0*SIG*P4**2*R_1**4/(3.d0*dm_bar_0*L)
     733              :          Lr_0=TT*(T4_0/OP_0-T4_1/OP_1)/ &
     734            0 :                (1.d0-dlog(OP_0/OP_1)/dlog(T4_0/T4_1))*L
     735            0 :          F1=(Lr_0+Lc_0)/L-1.d0
     736              : 
     737            0 :          D=T4_0/1.d3
     738            0 :          I=0
     739            0 :          T1_loop: do  ! adjust T to make Lr + Lc = L
     740            0 :             I=I+1
     741            0 :             if(I>10000) then
     742            0 :                get_T = .false.
     743            0 :                if (s% RSP_testing) then
     744            0 :                   write(*,*) 'failed get_T', N, T_0
     745            0 :                   call mesa_error(__FILE__,__LINE__,'get_T')
     746              :                end if
     747            0 :                return
     748              :             end if
     749            0 :             do while (abs(D/T4_0)>0.5d0)
     750            0 :                D=(T4_0/2.d0)*(D/abs(D))
     751              :             end do
     752            0 :             T4_0 = T4_0-D
     753            0 :             T_0=sqrt(sqrt(T4_0))
     754            0 :             Lc_loop: do  ! reduce T if Lc >= L
     755              :                call EOP(s,N, &
     756            0 :                    T_0,P_0,V_0,E_0,CP_0,QQ_0,SVEL_0,OP_0,ierr)
     757            0 :                if (ierr /= 0) return
     758            0 :                call CFLUX(HP_0,IGR_0,Lc_0,w_0,GPF,N)
     759            0 :                if (Lc_0<L) exit Lc_loop
     760            0 :                T_0=T_0-10.d0*(Lc_0/L)
     761            0 :                if (T_0 <= 0) then
     762            0 :                   ierr = -1
     763            0 :                   return
     764              :                   call mesa_error(__FILE__,__LINE__,'T_0 <= 0 in Lc_loop')
     765              :                end if
     766            0 :                T4_0=T_0**4
     767              :             end do Lc_loop
     768              :             Lr_0=TT*(T4_0/OP_0-T4_1/OP_1)/ &
     769            0 :                   (1.d0-dlog(OP_0/OP_1)/dlog(T4_0/T4_1))*L
     770            0 :             F2=(Lr_0+Lc_0)/L-1.d0
     771            0 :             if(ABS(F2)<PREC .or. F2==F1) exit T1_loop
     772            0 :             D=F2*(T4_0-T4_0)/(F2-F1)
     773            0 :             F1=F2
     774            0 :             T4_0=T4_0
     775              :          end do T1_loop
     776              : 
     777            0 :          get_T = .true.
     778            0 :          if (s% RSP_testing) write(*,*) 'done get_T', N, T_0
     779            0 :       end function get_T
     780              : 
     781            0 :       subroutine failed
     782            0 :          write(*,*) 'NO CONVERGENCE IN STA INNER LOOP',I
     783            0 :          if((.not.adjusting_dmN) .OR. dmN_cnt>1 .or. IG > 54) then
     784            0 :             write(*,*) 'zone ',N,'IGR= ',IGR_0
     785            0 :             stop
     786              :          end if
     787            0 :          dmN=dmN/4.d0
     788            0 :          write(*,*) 'PHOENIX CONDITION'
     789            0 :          IG=IG+1
     790            0 :       end subroutine failed
     791              : 
     792            0 :       subroutine prepare_for_new_H
     793            0 :          ITIN = ITIN+1
     794              :          ! STRATOWE WARTOSCI DLA ITERACJI PONIZEJ TH0
     795            0 :          N1 = NZN-NZT+1
     796            0 :          R_1 = R(N1)
     797            0 :          V_0  = Vol(N1)
     798            0 :          P_0  = P(N1)
     799            0 :          T_0  = T(N1)
     800            0 :          T4_0  = T_0**4
     801            0 :          M_0  = M(N1)
     802            0 :          dm_0 = dm(N1)
     803            0 :          OP_0 = K(N1)
     804            0 :          N  = N1
     805            0 :          H  = HH
     806            0 :          HP_0 = Hp_face(N1)
     807            0 :          IGR_0 = Y_face(N1)
     808            0 :          QQ_0 = QQS(N1)
     809            0 :          CP_0 = CPS(N1)
     810            0 :          Lc_0 = Lc(N1)
     811            0 :          E_0 = E(N1)
     812            0 :       end subroutine prepare_for_new_H
     813              : 
     814            0 :       subroutine change_NZN
     815            0 :          NZN=NZN-N
     816            0 :          do I=1,NZN
     817            0 :             R(I)=R(I+N)
     818            0 :             P(I)=P(I+N)
     819            0 :             Vol(I)=Vol(I+N)
     820            0 :             E(I)=E(I+N)
     821            0 :             T(I)=T(I+N)
     822            0 :             K(I)=K(I+N)
     823            0 :             M(I)=M(I+N)
     824            0 :             dm(I)=dm(I+N)
     825            0 :             dm_bar(I)=dm_bar(I+N)
     826            0 :             Hp_face(I) = Hp_face(I+N)
     827            0 :             Y_face(I) = Y_face(I+N)
     828            0 :             CPS(I) = CPS(I+N)
     829            0 :             QQS(I) = QQS(I+N)
     830            0 :             Lc(I) = Lc(I+N)
     831            0 :             Lr(I) = Lr(I+N)
     832            0 :             w(I) = w(I+N)
     833              :          end do
     834            0 :       end subroutine change_NZN
     835              : 
     836              :       end subroutine STAH
     837              : 
     838              : 
     839            0 :       subroutine ZNVAR(s,H,dmN,L,TE,M,ierr)
     840              :       type (star_info), pointer :: s
     841              :       integer, intent(out) :: ierr
     842            0 :       real(dp) :: H,dmN,L,TE,M,Psurf
     843            0 :       real(dp) :: T0,R,TAU0,P,V, &
     844            0 :          dtau, kap, alfa, G_M_dtau_div_R2, Prad, Pgas_0, &
     845            0 :          dP_dV, dkap_dV, xx, residual, d_residual_dlnV, &
     846            0 :          dkap_dlnV, dlnV, dP_dlnV, lnV
     847              :       integer :: I
     848            0 :       H=HHFAC
     849            0 :       ierr = 0
     850              :       if(.not.RSP_eddi) then  !     EXACT GREY RELATION
     851              :          T0= pow(sqrt(3.d0)/4.d0,0.25d0)*TE  !0.811194802d0*TE
     852              :       else  !     EDDINGTON APPROXIMATION
     853            0 :          T0= pow(0.5d0, 0.25d0)*TE  ! T0= pow(1.0d0/2.d0,0.25d0)*TE
     854              :       end if
     855              :       if (s% RSP_use_Prad_for_Psurf) then
     856              :          Psurf = crad*T0*T0*T0*T0/3d0
     857              :       else
     858            0 :          Psurf = 0d0
     859              :       end if
     860            0 :       R=sqrt(L/(4.d0*PI*SIG))/TE**2
     861            0 :       TAU0=0.003d0
     862              : 
     863              :       ! dtau is optical depth we want to middle of 1st cell; ~ 0.003
     864              :       ! dtau = dm*kap/(4*pi*R^2)
     865              :       ! mass of 1st cell will be 2*dm, so dm is mass above center of cell.
     866              :       ! R is derived from L and Teff.
     867              :       ! T0 is derived from Teff. it is temperature at center of 1st cell.
     868              :       ! Psurf is pressure just outside 1st cell; either 0 or, better, Prad(T0).
     869              :       ! need to find P, pressure at center of 1st cell
     870              :       ! P = Psurf + G*M*dm/(4*pi*R^4)
     871              :       ! substitute for dm to get
     872              :       ! P = Psurf + G*M*dtau/(R^2*kap)
     873              :       ! kap depends on P, so need to solve this implicit equation iteratively.
     874              :       ! once find P and kap, can evaluate dm = 4*pi*R^2*dtau/kap
     875              : 
     876              :       ! note that since T0 is fixed, we can only change P by changing Pgas.
     877              :       ! for most cases this is not a problem since Prad << Pgas.
     878              :       ! but for massive blue stars, we can have Prad >> Pgas.
     879              :       ! to handle both cases well, we need to iterate on Pgas instead of P
     880              :       ! that will let us make sure we don't create guesses that imply Pgas < 0.
     881              : 
     882            0 :       dtau = TAU0  ! s% RSP_outer_dtau_target
     883              :       ! make rough initial guess for opacity based on T0
     884            0 :       if (T0 < 4700d0) then
     885            0 :          kap = 1d-3
     886            0 :       else if (T0 > 5100d0) then
     887            0 :          kap = 1d-2*(1d0 + X)
     888              :       else
     889            0 :          alfa = (T0 - 4700)/(5100 - 4700)
     890            0 :          kap = alfa*1d-2*(1d0 + X) + (1d0-alfa)*1d-3
     891              :       end if
     892            0 :       G_M_dtau_div_R2 = G*M*dtau/R**2
     893            0 :       Prad = crad*T0*T0*T0*T0/3d0
     894            0 :       Pgas_0 = G_M_dtau_div_R2/kap
     895            0 :       P = Pgas_0 + Prad  ! initial guess for P
     896            0 :       call EOP(s,0,T0,P,V,xx,xx,xx,xx,xx,ierr)  ! initial V
     897            0 :       if (ierr /= 0) return
     898              :       !write(*,*) 'init T0,P,V', T0,P,V
     899            0 :       do I=1,25
     900              :          call mesa_eos_kap(s,-4, &
     901            0 :             T0,V,P,dP_dV,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,kap,dkap_dV,xx,ierr)
     902            0 :          if (ierr /= 0) return
     903            0 :          residual = P - (Prad + G_M_dtau_div_R2/kap)
     904            0 :          if (abs(residual) < 1d-6*P) exit  ! done
     905            0 :          dP_dlnV = dP_dV*V
     906            0 :          lnV = log(V)
     907            0 :          dkap_dlnV = dkap_dV*V
     908            0 :          d_residual_dlnV = dP_dlnV + G_M_dtau_div_R2*dkap_dlnV/kap**2
     909            0 :          dlnV = - residual/d_residual_dlnV
     910            0 :          V = exp(lnV + dlnV)
     911              :          !write(*,*) 'T0, new V, P, kap, residual, dP_dV', i, T0, V, P, kap, residual, dP_dV
     912              :       end do
     913              : 
     914              :       !write(*,*) 'V, P, kap, residual', i, V, P, kap, residual
     915              : 
     916            0 :       dmN = 4*pi*R**2*dtau/kap
     917            0 :       if (s% RSP_testing) write(*,*) 'initial dmN', dmN/SUNM
     918              :       !stop
     919              :       end subroutine ZNVAR
     920              : 
     921              : 
     922            0 :       subroutine CFLUX(HP_0,IGR_0,Lc_0,OMEGA_0,GPF,N)
     923              : 
     924            0 :       real(dp) :: POM,POM2,HP_0,IGR_0,OMEGA_0,PII,Lc_0
     925            0 :       real(dp) :: FF,GG,GPF,ENT
     926            0 :       real(dp) :: AA,BB,CC,DELTA
     927              :       integer :: N
     928              : !-
     929            0 :       if(ALFA==0.d0) then
     930            0 :          OMEGA_0=0.d0
     931            0 :          Lc_0=0.d0
     932            0 :          return
     933              :       end if
     934              : 
     935              : !     PRESSURE SCALE HEIGHT
     936            0 :       HP_0=R_1**2/(G*M_0)*(P_0*V_0+P_1*V_1)/2.d0
     937            0 :       POM=P4*R_1**2*HP_0/dm_bar_0/(V_0+V_1)*2.d0
     938              : 
     939              : !     SUPERADIABATIC GRADIENT, Y
     940              :       IGR_0=POM*((QQ_0/CP_0+QQ_1/CP_1)/2.d0*(P_1-P_0) &
     941            0 :             -(dlog(T_1)-dlog(T_0)))  !hyt!
     942              : 
     943            0 :       POM=sqrt(2.d0/3.d0)*0.5d0
     944            0 :       ENT=(E_0+P_0*V_0)/T_0+(E_1+P_1*V_1)/T_1
     945            0 :       FF=POM*ENT
     946            0 :       POM=ALFAS*ALFA
     947            0 :       POM2=0.5d0*(CP_0+CP_1)
     948            0 :       GG=POM*POM2*IGR_0
     949            0 :       GPF=GG/FF
     950              : 
     951              : 
     952              : !     BOTTOM BOUNDARY CONDITION FOR CONVECTION
     953            0 :       if(N<=IBOTOM)then
     954            0 :          Lc_0=0.d0
     955            0 :          OMEGA_0=0.d0
     956            0 :          return
     957              :       end if
     958            0 :       if(IGR_0>0.d0)then
     959              :          if(.true. .or. GAMMAR==0.d0)then   ! gammar breaks Cep 11.5M model  BP
     960              :            OMEGA_0=sqrt(ALFA/CEDE*FF*GPF* &
     961            0 :              (T_0*P_0*QQ_0/CP_0+T_1*P_1*QQ_1/CP_1)*0.5d0)
     962              :          else
     963              :             AA=CEDE/ALFA
     964              :             POM=(GAMMAR**2/ALFA**2)*4.d0*SIG
     965              :             BB=(POM/HP_0)* &
     966              :                (T_0**3*V_0**2/CP_0/OP_0 &
     967              :                  +T_1**3*V_1**2/CP_1/OP_1)*0.5d0
     968              :             CC=-(T_0*P_0*QQ_0/CP_0 &
     969              :                      +T_1*P_1*QQ_1/CP_1)*0.5d0*FF*GPF
     970              :             DELTA=BB**2-4.d0*AA*CC
     971              :             if(DELTA<=0.d0) then
     972              :                write(*,*) 'CFLUX: Error! : Y>0, but no solution found'
     973              :                stop
     974              :             end if
     975              :             OMEGA_0=(-BB+sqrt(DELTA))/(2.d0*AA)
     976              :          end if
     977            0 :          PII=FF*OMEGA_0*GPF
     978            0 :          Lc_0=P4*R_1**2*(T_0/V_0+T_1/V_1)*0.5d0*PII*(ALFAC/ALFAS)
     979              : !                                                 (REPLACES ALFAS BY ALFAC)
     980              :       else
     981            0 :          OMEGA_0=0.d0
     982            0 :          Lc_0=0.d0
     983              :       end if
     984              :       end subroutine CFLUX
     985              : 
     986              :       end module rsp_build
        

Generated by: LCOV version 2.0-1