LCOV - code coverage report
Current view: top level - kap/public - kap_lib.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 24.8 % 242 60
Test Date: 2025-05-08 18:23:42 Functions: 34.6 % 26 9

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  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              : 
      21              :       module kap_lib
      22              :       ! library for calculating opacities
      23              : 
      24              :       ! the data interface for the library is defined in kap_def
      25              : 
      26              :       use const_def, only: dp
      27              :       use math_lib
      28              : 
      29              :       implicit none
      30              : 
      31              :       integer , pointer, public, save :: izz(:),ite(:),jne(:)
      32              :       real(dp), pointer, public, save :: sig(:,:,:)
      33              :       real(dp), pointer, public, save :: epatom(:,:),amamu(:),eumesh(:,:,:)
      34              :       real(dp), pointer, public, save :: lkap_ross_pcg(:)
      35              :       integer, public, parameter :: ngp = 2
      36              :       real(dp), public, save :: lgamm_pcg(ngp,17,1648), lkap_face_pcg(ngp,1648), logT_pcg(ngp,1648), logRho_pcg(ngp,1648)
      37              :       integer, parameter :: nzm = 3000
      38              :       real(dp), public, save :: fk_old(nzm,17), fk_old_grad(nzm,17)
      39              :       real(dp), public, save ::logT_grid_old(nzm,4,4), logRho_grid_old(nzm,4,4), fk_pcg(17), fk_grad_pcg(ngp,17)
      40              :       real(dp), public, save :: lkap_grid_old(nzm,4,4), logT_cntr_old(nzm), logRho_cntr_old(nzm)
      41              :       logical :: initialize_fk_old = .true.
      42              :       contains  ! the procedure interface for the library
      43              :       ! client programs should only call these routines.
      44              : 
      45              : 
      46              :       ! call this routine to initialize the kap module.
      47              :       ! only needs to be done once at start of run.
      48              :       ! Reads data from the 'kap' directory in the data_dir.
      49              :       ! If use_cache is true and there is a 'kap/cache' directory, it will try that first.
      50              :       ! If it doesn't find what it needs in the cache,
      51              :       ! it reads the data and writes the cache for next time.
      52            5 :       subroutine kap_init(use_cache, kap_cache_dir, ierr)
      53              :          use kap_def, only : kap_def_init, kap_use_cache, kap_is_initialized
      54              :          logical, intent(in) :: use_cache
      55              :          character (len=*), intent(in) :: kap_cache_dir  ! blank means use default
      56              :          integer, intent(out) :: ierr  ! 0 means AOK.
      57            5 :          ierr = 0
      58            5 :          if (kap_is_initialized) return
      59            5 :          call kap_def_init(kap_cache_dir)
      60            5 :          kap_use_cache = use_cache
      61            5 :          kap_is_initialized = .true.
      62              :       end subroutine kap_init
      63              : 
      64              : 
      65            3 :       subroutine kap_shutdown
      66              :          use kap_def, only: do_Free_Kap_Tables, kap_is_initialized
      67            3 :          call do_Free_Kap_Tables()
      68            3 :          kap_is_initialized = .false.
      69            3 :       end subroutine kap_shutdown
      70              : 
      71              : 
      72              :       ! after kap_init has finished, you can allocate a "handle".
      73              : 
      74            2 :       integer function alloc_kap_handle(ierr) result(handle)
      75              :          integer, intent(out) :: ierr  ! 0 means AOK.
      76              :          character (len=0) :: inlist
      77            2 :          handle = alloc_kap_handle_using_inlist(inlist, ierr)
      78            2 :       end function alloc_kap_handle
      79              : 
      80            9 :       integer function alloc_kap_handle_using_inlist(inlist,ierr) result(handle)
      81              :          use kap_def, only:do_alloc_kap,kap_is_initialized
      82              :          use kap_ctrls_io, only:read_namelist
      83              :          character (len=*), intent(in) :: inlist  ! empty means just use defaults.
      84              :          integer, intent(out) :: ierr  ! 0 means AOK.
      85              :          ierr = 0
      86            9 :          if (.not. kap_is_initialized) then
      87            0 :             ierr=-1
      88            0 :             return
      89              :          end if
      90            9 :          handle = do_alloc_kap(ierr)
      91            9 :          if (ierr /= 0) return
      92            9 :          call read_namelist(handle, inlist, ierr)
      93            9 :          if (ierr /= 0) return
      94            9 :          call kap_setup_tables(handle, ierr)
      95            9 :          call kap_setup_hooks(handle, ierr)
      96           18 :       end function alloc_kap_handle_using_inlist
      97              : 
      98            1 :       subroutine free_kap_handle(handle)
      99              :          ! frees the handle and all associated data
     100            9 :          use kap_def,only: Kap_General_Info,do_free_kap
     101              :          integer, intent(in) :: handle
     102            1 :          call do_free_kap(handle)
     103            1 :       end subroutine free_kap_handle
     104              : 
     105              : 
     106       172482 :       subroutine kap_ptr(handle,rq,ierr)
     107              :          use kap_def,only:Kap_General_Info,get_kap_ptr,kap_is_initialized
     108              :          integer, intent(in) :: handle  ! from alloc_kap_handle
     109              :          type (Kap_General_Info), pointer :: rq
     110              :          integer, intent(out):: ierr
     111        86241 :          if (.not. kap_is_initialized) then
     112            0 :             ierr=-1
     113            0 :             return
     114              :          end if
     115        86241 :          call get_kap_ptr(handle,rq,ierr)
     116              :       end subroutine kap_ptr
     117              : 
     118              : 
     119           11 :       subroutine kap_setup_tables(handle, ierr)
     120              :          use kap_def, only : Kap_General_Info, get_kap_ptr
     121              :          use load_kap, only : Setup_Kap_Tables
     122              :          integer, intent(in) :: handle
     123              :          integer, intent(out):: ierr
     124              : 
     125              :          type (Kap_General_Info), pointer :: rq
     126              :          logical, parameter :: use_cache = .true.
     127              :          logical, parameter :: load_on_demand = .true.
     128              : 
     129              :          ierr = 0
     130           11 :          call get_kap_ptr(handle,rq,ierr)
     131           11 :          call Setup_Kap_Tables(rq, use_cache, load_on_demand, ierr)
     132              : 
     133           11 :       end subroutine kap_setup_tables
     134              : 
     135              : 
     136            9 :       subroutine kap_setup_hooks(handle, ierr)
     137           11 :          use kap_def, only : Kap_General_Info, get_kap_ptr
     138              :          use other_elect_cond_opacity
     139              :          use other_compton_opacity
     140              :          integer, intent(in) :: handle
     141              :          integer, intent(out):: ierr
     142              : 
     143              :          type (Kap_General_Info), pointer :: rq
     144              : 
     145              :          ierr = 0
     146            9 :          call get_kap_ptr(handle,rq,ierr)
     147              : 
     148            9 :          rq% other_elect_cond_opacity => null_other_elect_cond_opacity
     149            9 :          rq% other_compton_opacity => null_other_compton_opacity
     150              : 
     151            9 :       end subroutine kap_setup_hooks
     152              : 
     153              : 
     154              :       ! kap evaluation
     155              :       ! you can call these routines after you've setup the tables for the handle.
     156              :       ! NOTE: the structures referenced via the handle are read-only
     157              :       ! for the evaluation routines, so you can do multiple evaluations in parallel
     158              :       ! using the same handle.
     159              : 
     160              : 
     161        86216 :       subroutine kap_get( &
     162        86216 :          handle, species, chem_id, net_iso, xa, &
     163              :          logRho, logT, &
     164              :          lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT, &
     165              :          eta, d_eta_dlnRho, d_eta_dlnT , &
     166        86216 :          kap_fracs, kap, dlnkap_dlnRho, dlnkap_dlnT, dlnkap_dxa, ierr)
     167              :          use chem_def, only: chem_isos
     168              :          use chem_lib, only: basic_composition_info
     169              :          use kap_def, only : kap_is_initialized, Kap_General_Info, num_kap_fracs, i_frac_Type2
     170              :          use kap_eval, only : Get_kap_Results
     171              :          ! INPUT
     172              :          integer, intent(in) :: handle  ! from alloc_kap_handle; in star, pass s% kap_handle
     173              :          integer, intent(in) :: species
     174              :          integer, pointer :: chem_id(:)  ! maps species to chem id
     175              :          integer, pointer :: net_iso(:)  ! maps chem id to species number
     176              :          real(dp), intent(in) :: xa(:)  ! mass fractions
     177              :          real(dp), intent(in) :: logRho  ! density
     178              :          real(dp), intent(in) :: logT  ! temperature
     179              :          real(dp), intent(in) :: lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT
     180              :          ! free_e := total combined number per nucleon of free electrons and positrons
     181              :          real(dp), intent(in)  :: eta, d_eta_dlnRho, d_eta_dlnT
     182              :          ! eta := electron degeneracy parameter from eos
     183              : 
     184              :          ! OUTPUT
     185              :          real(dp), intent(out) :: kap_fracs(num_kap_fracs)
     186              :          real(dp), intent(out) :: kap  ! opacity
     187              :          real(dp), intent(out) :: dlnkap_dlnRho  ! partial derivative at constant T
     188              :          real(dp), intent(out) :: dlnkap_dlnT   ! partial derivative at constant Rho
     189              :          real(dp), intent(out) :: dlnkap_dxa(:)  ! partial derivative w.r.t. species
     190              :          integer, intent(out) :: ierr  ! 0 means AOK.
     191              : 
     192              :          type (Kap_General_Info), pointer :: rq
     193              : 
     194        86216 :          real(dp) :: X, Y, Z, abar, zbar, z2bar, z53bar, ye, mass_correction, sumx
     195        86216 :          real(dp) :: XC, XN, XO, XNe
     196              :          integer :: i, iz
     197              : 
     198              :          ierr = 0
     199        86216 :          if (.not. kap_is_initialized) then
     200            0 :             ierr=-1
     201            0 :             return
     202              :          end if
     203              : 
     204        86216 :          call kap_ptr(handle,rq,ierr)
     205        86216 :          if (ierr /= 0) return
     206              : 
     207              :          call basic_composition_info( &
     208              :             species, chem_id, xa, X, Y, Z, &
     209        86216 :             abar, zbar, z2bar, z53bar, ye, mass_correction, sumx)
     210              : 
     211        86216 :          xc = 0; xn = 0; xo = 0; xne = 0
     212       769728 :          do i=1, species
     213       683512 :             iz = chem_isos% Z(chem_id(i))
     214        86216 :             select case(iz)
     215              :             case (6)
     216        86216 :                xc = xc + xa(i)
     217              :             case (7)
     218        86216 :                xn = xn + xa(i)
     219              :             case (8)
     220        86216 :                xo = xo + xa(i)
     221              :             case (10)
     222       683512 :                xne = xne + xa(i)
     223              :             end select
     224              :          end do
     225              : 
     226              :          call Get_kap_Results( &
     227              :             rq, zbar, X, Z, XC, XN, XO, XNe, logRho, logT, &
     228              :             lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT, &
     229              :             eta, d_eta_dlnRho, d_eta_dlnT, &
     230        86216 :             kap_fracs, kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     231              : 
     232              :          ! composition derivatives not implemented
     233       769728 :          dlnkap_dxa = 0
     234              : 
     235        86216 :       end subroutine kap_get
     236              : 
     237              : 
     238            0 :       subroutine kap_get_elect_cond_opacity( &
     239              :             handle, zbar, logRho, logT, &
     240              :             kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     241        86216 :          use condint, only: do_electron_conduction
     242              :          use kap_def, only : kap_is_initialized, Kap_General_Info
     243              :          integer, intent(in) :: handle  ! from alloc_kap_handle; in star, pass s% kap_handle
     244              :          real(dp), intent(in) :: zbar  ! average ionic charge (for electron conduction)
     245              :          real(dp), intent(in) :: logRho  ! the density
     246              :          real(dp), intent(in) :: logT  ! the temperature
     247              :          real(dp), intent(out) :: kap  ! electron conduction opacity
     248              :          real(dp), intent(out) :: dlnkap_dlnRho  ! partial derivative at constant T
     249              :          real(dp), intent(out) :: dlnkap_dlnT   ! partial derivative at constant Rho
     250              :          integer, intent(out) :: ierr  ! 0 means AOK.
     251              : 
     252              :          type (Kap_General_Info), pointer :: rq
     253              : 
     254            0 :          if (.not. kap_is_initialized) then
     255            0 :             ierr=-1
     256            0 :             return
     257              :          end if
     258              :          ierr = 0
     259              : 
     260            0 :          call kap_ptr(handle,rq,ierr)
     261            0 :          if (ierr /= 0) return
     262              : 
     263              :          call do_electron_conduction( &
     264              :             rq, zbar, logRho, logT, &
     265            0 :             kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     266              : 
     267            0 :       end subroutine kap_get_elect_cond_opacity
     268              : 
     269              : 
     270            0 :       subroutine kap_get_compton_opacity( &
     271              :          handle, &
     272              :          Rho, T, lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT, &
     273              :          eta, d_eta_dlnRho, d_eta_dlnT, &
     274              :          kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     275            0 :          use kap_eval, only: Compton_Opacity
     276              :          use kap_def, only : kap_is_initialized, Kap_General_Info
     277              :          integer, intent(in) :: handle  ! kap handle; from star, pass s% kap_handle
     278              :          real(dp), intent(in) :: Rho, T
     279              :          real(dp), intent(in) :: lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT
     280              :             ! free_e := total combined number per nucleon of free electrons and positrons
     281              :          real(dp), intent(in)  :: eta, d_eta_dlnT, d_eta_dlnRho
     282              :             ! eta := electron degeneracy parameter from eos
     283              :          real(dp), intent(out) :: kap  ! electron conduction opacity
     284              :          real(dp), intent(out) :: dlnkap_dlnRho, dlnkap_dlnT
     285              :          integer, intent(out) :: ierr  ! 0 means AOK.
     286              : 
     287              :          type (Kap_General_Info), pointer :: rq
     288              : 
     289            0 :          if (.not. kap_is_initialized) then
     290            0 :             ierr=-1
     291            0 :             return
     292              :          end if
     293              :          ierr = 0
     294              : 
     295            0 :          call kap_ptr(handle,rq,ierr)
     296            0 :          if (ierr /= 0) return
     297              : 
     298              :          call Compton_Opacity(rq, &
     299              :             Rho, T, lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT, &
     300              :             eta, d_eta_dlnRho, d_eta_dlnT, &
     301            0 :             kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     302              : 
     303            0 :       end subroutine kap_get_compton_opacity
     304              : 
     305              : 
     306            0 :       subroutine kap_get_radiative_opacity( &
     307              :          handle, &
     308              :          X, Z, XC, XN, XO, XNe, logRho, logT, &
     309              :          frac_lowT, frac_highT, frac_Type2, kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     310              : 
     311            0 :          use kap_eval, only: Get_kap_Results_blend_T
     312              :          use kap_def, only : kap_is_initialized, Kap_General_Info
     313              : 
     314              :          ! INPUT
     315              :          integer, intent(in) :: handle  ! kap handle; from star, pass s% kap_handle
     316              :          real(dp), intent(in) :: X, Z, XC, XN, XO, XNe  ! composition
     317              :          real(dp), intent(in) :: logRho  ! density
     318              :          real(dp), intent(in) :: logT  ! temperature
     319              : 
     320              :          ! OUTPUT
     321              :          real(dp), intent(out) :: frac_lowT, frac_highT, frac_Type2
     322              :          real(dp), intent(out) :: kap  ! opacity
     323              :          real(dp), intent(out) :: dlnkap_dlnRho  ! partial derivative at constant T
     324              :          real(dp), intent(out) :: dlnkap_dlnT   ! partial derivative at constant Rho
     325              :          integer, intent(out) :: ierr  ! 0 means AOK.
     326              : 
     327              :          type (Kap_General_Info), pointer :: rq
     328              : 
     329            0 :          if (.not. kap_is_initialized) then
     330            0 :             ierr=-1
     331            0 :             return
     332              :          end if
     333              :          ierr = 0
     334              : 
     335            0 :          call kap_ptr(handle,rq,ierr)
     336            0 :          if (ierr /= 0) return
     337              : 
     338              :          call Get_kap_Results_blend_T( &
     339              :             rq, X, Z, XC, XN, XO, XNe, logRho, logT, &
     340            0 :             frac_lowT, frac_highT, frac_Type2, kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     341              : 
     342            0 :       end subroutine kap_get_radiative_opacity
     343              : 
     344              : 
     345            0 :       subroutine kap_get_op_mono( &
     346              :             handle, zbar, logRho, logT, &
     347              :             ! args for op_mono
     348              :             use_op_mono_alt_get_kap, &
     349            0 :             nel, izzp, fap, fac, screening, umesh, semesh, ff, rs, &
     350              :             ! output
     351              :             kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     352            0 :          use kap_def
     353              :          use kap_eval, only: combine_rad_with_conduction
     354              :          integer, intent(in) :: handle  ! from alloc_kap_handle; in star, pass s% kap_handle
     355              :          real(dp), intent(in) :: zbar  ! average ionic charge (for electron conduction)
     356              :          real(dp), intent(in) :: logRho  ! the density
     357              :          real(dp), intent(in) :: logT  ! the temperature
     358              :          ! args for op_mono_get_kap
     359              :          logical, intent(in) :: use_op_mono_alt_get_kap
     360              :          integer, intent(in) :: nel
     361              :          integer, intent(in) :: izzp(:)  ! (nel)
     362              :          real(dp), intent(in) :: fap(:)  ! (nel) number fractions of elements
     363              :          real(dp), intent(in) :: fac(:)  ! (nel) scale factors for element opacity
     364              :          logical, intent(in) :: screening
     365              :          ! work arrays
     366              :          real, pointer :: umesh(:), semesh(:), ff(:,:,:,:), rs(:,:,:)
     367              :             ! umesh(nptot)
     368              :             ! semesh(nptot)
     369              :             ! ff(nptot, ipe, 4, 4)
     370              :             ! rs(nptot, 4, 4)
     371              :          ! output
     372              :          real(dp), intent(out) :: kap  ! opacity
     373              :          real(dp), intent(out) :: dlnkap_dlnRho  ! partial derivative at constant T
     374              :          real(dp), intent(out) :: dlnkap_dlnT   ! partial derivative at constant Rho
     375              :          integer, intent(out) :: ierr  ! 0 means AOK.
     376              : 
     377            0 :          real(dp) :: g1, kap_rad, dlnkap_rad_dlnRho, dlnkap_rad_dlnT
     378            0 :          real(dp) :: Rho, T
     379              :          type (Kap_General_Info), pointer :: rq
     380              : 
     381              :          ierr = 0
     382            0 :          if (.not. kap_is_initialized) then
     383            0 :             ierr=-1
     384            0 :             return
     385              :          end if
     386            0 :          call kap_ptr(handle,rq,ierr)
     387            0 :          if (ierr /= 0) return
     388              : 
     389            0 :          Rho = exp10(logRho)
     390            0 :          T = exp10(logT)
     391              : 
     392            0 :          if (use_op_mono_alt_get_kap) then
     393              :             call op_mono_alt_get_kap( &
     394              :                nel, izzp, fap, fac, logT, logRho, screening, &
     395              :                g1, dlnkap_rad_dlnT, dlnkap_rad_dlnRho, &
     396            0 :                umesh, semesh, ff, rs, ierr)
     397              :          else
     398              :             call op_mono_get_kap( &
     399              :                nel, izzp, fap, fac, logT, logRho, screening, &
     400              :                g1, dlnkap_rad_dlnT, dlnkap_rad_dlnRho, &
     401            0 :                umesh, semesh, ff, rs, ierr)
     402              :          end if
     403            0 :          if (ierr /= 0) return
     404              : 
     405            0 :          kap_rad = exp10(g1)
     406              : 
     407              :          call combine_rad_with_conduction( &
     408              :             rq, logRho, logT, zbar, &
     409              :             kap_rad, dlnkap_rad_dlnRho, dlnkap_rad_dlnT, &
     410            0 :             kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     411              : 
     412            0 :       end subroutine kap_get_op_mono
     413              : 
     414              : 
     415              : 
     416              :       ! interface to OP routines as modified by Haili Hu for radiative levitation in diffusion
     417              : 
     418              :       ! ref: Hu et al MNRAS 418 (2011)
     419              : 
     420            0 :       subroutine load_op_mono_data(op_mono_data_path, op_mono_data_cache_filename, ierr)
     421            0 :          use kap_def
     422              :          use op_load, only: op_dload
     423              :          character (len=*), intent(in) :: op_mono_data_path, op_mono_data_cache_filename
     424              :          integer, intent(out) :: ierr
     425            0 :          if (.not. kap_is_initialized) then
     426            0 :             ierr=-1
     427              :             return
     428              :          end if
     429            0 :          call op_dload(op_mono_data_path, op_mono_data_cache_filename, ierr)
     430            0 :       end subroutine load_op_mono_data
     431              : 
     432            0 :       subroutine call_load_op_master(emesh_data_for_op_mono_path, ierr)
     433            0 :       use op_load_master, only: load_op_master
     434              : 
     435              :       character (len=*), intent(in) :: emesh_data_for_op_mono_path
     436              :       integer, intent(inout) :: ierr
     437              : 
     438            0 :       call load_op_master(emesh_data_for_op_mono_path, izz,ite,jne,epatom,amamu,sig,eumesh,ierr)
     439              : 
     440            0 :       end subroutine call_load_op_master
     441              : 
     442              : 
     443              :       ! sizes for work arrays
     444            0 :       subroutine get_op_mono_params(op_nptot, op_ipe, op_nrad)
     445              :          use kap_def
     446              :          use op_def, only: nptot, ipe, nrad
     447              :          integer, intent(out) :: op_nptot, op_ipe, op_nrad
     448            0 :          op_nptot = nptot
     449            0 :          op_ipe = ipe
     450            0 :          op_nrad = nrad
     451            0 :       end subroutine get_op_mono_params
     452              : 
     453              : 
     454              : ! HH: Based on "op_ax.f"
     455              : ! Input:   kk = number of elements to calculate g_rad for
     456              : !          iz1(kk) = charge of element to calculate g_rad for
     457              : !          nel = number of elements in mixture
     458              : !          izzp(nel) = charge of elements
     459              : !          fap(nel) = number fractions of elements
     460              : !          fac(nel) = scale factors for element opacity
     461              : !          flux = local radiative flux (Lrad/4*pi*r^2)
     462              : !          fltp = log10 T
     463              : !          flrhop = log10 rho
     464              : !          screening   if true, use screening corrections
     465              : ! Output: g1 = log10 kappa
     466              : !         gx1 = d(log kappa)/d(log T)
     467              : !         gy1 = d(log kappa)/d(log rho)
     468              : !         gp1(kk) = d(log kappa)/d(log xi)
     469              : !         grl1(kk) = log10 grad
     470              : !         fx1(kk) = d(log grad)/d(log T)
     471              : !         fy1(kk) = d(log grad)/d(log rho)
     472              : !         grlp1(kk) = d(log grad)/d(log chi),
     473              : !              chi is the fraction with which the number fraction is varied, i.e.:
     474              : !                 chi = nf_new/nf_previous
     475              : !                 where nf is the number fraction
     476              : !         meanZ(nel) = average ionic charge of elements
     477              : !         zetx1(nel) = d(meanZ)/d(log T)
     478              : !         zety1(nel) = d(meanZ)/d(log rho)
     479              : !         ierr = 0 for correct use
     480              : !         ierr = 101 for rho out of range for this T
     481              : !         ierr = 102 for T out of range
     482            0 :       subroutine op_mono_get_radacc( &
     483            0 :             kk, izk, nel, izzp, fap, fac, flux, fltp, flrhop, screening, &
     484            0 :             g1, grl1, &
     485              :             umesh, semesh, ff, ta, rs, ierr)
     486              :          use kap_def
     487              :          use op_eval, only: eval_op_radacc
     488              :          integer, intent(in) :: kk, nel
     489              :          integer, intent(in) :: izk(kk), izzp(nel)
     490              :          real(dp), intent(in) :: fap(:)  ! (nel) number fractions of elements
     491              :          real(dp), intent(in) :: fac(:)  ! (nel) scale factors for element opacity
     492              :          real(dp), intent(in) :: flux, fltp
     493              :          real(dp), intent(in) :: flrhop
     494              :          logical, intent(in) :: screening
     495              :          real(dp), intent(out) :: g1
     496              :          real(dp), intent(inout) :: &
     497              :             grl1(kk)
     498              :          ! work arrays
     499              :          real, pointer :: umesh(:), semesh(:), ff(:,:,:,:), ta(:,:,:,:), rs(:,:,:)
     500              :             ! umesh(nptot)
     501              :             ! semesh(nptot)
     502              :             ! ff(nptot, ipe, 4, 4)
     503              :             ! ta(nptot, nrad, 4, 4),
     504              :             ! rs(nptot, 4, 4)
     505              :          integer,intent(out) :: ierr
     506            0 :          if (.not. kap_is_initialized) then
     507            0 :             ierr=-1
     508              :             return
     509              :          end if
     510              :          call eval_op_radacc( &
     511              :             kk, izk, nel, izzp, fap, fac, flux, fltp, flrhop, screening, &
     512              :             g1, grl1, &
     513            0 :             umesh, semesh, ff, ta, rs, ierr)
     514            0 :       end subroutine op_mono_get_radacc
     515              : 
     516              : 
     517              : ! note: for op mono, elements must come from the set given in op_mono_element_Z in kap_def.
     518              : 
     519              : ! HH: Based on "op_mx.f", opacity calculations to be used for stellar evolution calculations
     520              : ! Input:   nel = number of elements in mixture
     521              : !          izzp(nel) = charge of elements
     522              : !          fap(nel) = number fractions of elements
     523              : !          fac(nel) = scale factors for element opacity
     524              : !          fltp = log10 (temperature)
     525              : !          flrhop = log10 (mass density)
     526              : !          screening   if true, use screening corrections
     527              : ! Output: g1 = log10 kappa
     528              : !         gx1 = d(log kappa)/d(log T)
     529              : !         gy1 = d(log kappa)/d(log rho)
     530              : !         ierr = 0 for correct use
     531              : !         ierr = 101 for rho out of range for this T
     532              : !         ierr = 102 for T out of range
     533            0 :       subroutine op_mono_get_kap( &
     534            0 :             nel, izzp, fap, fac, fltp, flrhop, screening, &
     535              :             g1, gx1, gy1, &
     536              :             umesh, semesh, ff, rs, ierr)
     537            0 :          use kap_def
     538              :          use op_eval, only: eval_op_ev
     539              :          integer, intent(in) :: nel
     540              :          integer, intent(in) :: izzp(nel)
     541              :          real(dp), intent(in) :: fap(:)  ! (nel) number fractions of elements
     542              :          real(dp), intent(in) :: fac(:)  ! (nel) scale factors for element opacity
     543              :          real(dp), intent(in) :: fltp, flrhop
     544              :          logical, intent(in) :: screening
     545              :          real(dp), intent(inout) :: g1, gx1, gy1
     546              :          ! work arrays
     547              :          real, pointer :: umesh(:), semesh(:), ff(:,:,:,:), rs(:,:,:)
     548              :             ! umesh(nptot)
     549              :             ! semesh(nptot)
     550              :             ! ff(nptot, ipe, 4, 4)
     551              :             ! rs(nptot, 4, 4)
     552              :             ! s(nptot, nrad, 4, 4)
     553              :          integer,intent(out) :: ierr
     554            0 :          if (.not. kap_is_initialized) then
     555            0 :             ierr=-1
     556              :             return
     557              :          end if
     558              :          call eval_op_ev( &
     559              :             nel, izzp, fap, fac, fltp, flrhop, screening, &
     560              :             g1, gx1, gy1, &
     561            0 :             umesh, semesh, ff, rs, ierr)
     562            0 :       end subroutine op_mono_get_kap
     563              : 
     564              : 
     565              : ! HH: Based on "op_mx.f", opacity calculations to be used for non-adiabatic pulsation calculations
     566              : ! Special care is taken to ensure smoothness of opacity derivatives
     567              : ! Input:   nel = number of elements in mixture
     568              : !          izzp(nel) = charge of elements
     569              : !          fap(nel) = number fractions of elements
     570              : !          fac(nel) = scale factors for element opacity
     571              : !          fltp = log10 (temperature)
     572              : !          flrhop = log10 (mass density)
     573              : !          screening   if true, use screening corrections
     574              : ! Output: g1 = log10 kappa
     575              : !         gx1 = d(log kappa)/d(log T)
     576              : !         gy1 = d(log kappa)/d(log rho)
     577              : !         ierr = 0 for correct use
     578              : !         ierr = 101 for rho out of range for this T
     579              : !         ierr = 102 for T out of range
     580            0 :       subroutine op_mono_alt_get_kap( &
     581            0 :             nel, izzp, fap, fac, fltp, flrhop, screening, &
     582              :             g1, gx1, gy1, &
     583              :             umesh, semesh, ff, rs, ierr)
     584            0 :          use kap_def
     585              :          use op_eval, only: eval_alt_op
     586              :          integer, intent(in) :: nel
     587              :          integer, intent(in) :: izzp(nel)
     588              :          real(dp), intent(in) :: fap(:)  ! (nel) number fractions of elements
     589              :          real(dp), intent(in) :: fac(:)  ! (nel) scale factors for element opacity
     590              :          real(dp), intent(in) :: fltp, flrhop
     591              :          logical, intent(in) :: screening
     592              :          real(dp), intent(out) :: g1, gx1, gy1
     593              :          ! work arrays
     594              :          real, pointer :: umesh(:), semesh(:), ff(:,:,:,:), rs(:,:,:)
     595              :             ! umesh(nptot)
     596              :             ! semesh(nptot)
     597              :             ! ff(nptot, ipe, 0:5, 0:5)
     598              :             ! rs(nptot, 0:5, 0:5)
     599              :          integer,intent(out) :: ierr
     600            0 :          if (.not. kap_is_initialized) then
     601            0 :             ierr=-1
     602              :             return
     603              :          end if
     604              :          call eval_alt_op( &
     605              :             nel, izzp, fap, fac, fltp, flrhop, screening, &
     606              :             g1, gx1, gy1, &
     607            0 :             umesh, semesh, ff, rs, ierr)
     608            0 :       end subroutine op_mono_alt_get_kap
     609              : 
     610              : 
     611            0 :       subroutine get_op_mono_args( &
     612            0 :             species, X, min_X_to_include, chem_id, chem_factors, &
     613            0 :             nel, izzp, fap, fac, ierr)
     614            0 :          use chem_def, only: chem_isos
     615              :          use kap_def
     616              :          integer, intent(in) :: species, chem_id(:)
     617              :          real(dp), intent(in) :: X(:)  ! mass fractions (assumed baryonic)
     618              :          real(dp), intent(in) :: min_X_to_include  ! skip iso if X < this
     619              :          real(dp), intent(in) :: chem_factors(:)  ! (species)
     620              :          integer, intent(out) :: nel
     621              :          integer, intent(inout) :: izzp(:)
     622              :          real(dp), intent(inout) :: fap(:)
     623              :          real(dp), intent(inout) :: fac(:)
     624              :          integer,intent(out) :: ierr
     625              : 
     626              :          integer :: i, cid, j, Z, iel
     627            0 :          real(dp) :: tot
     628              : 
     629            0 :          ierr = 0
     630            0 :          if (.not. kap_is_initialized) then
     631            0 :             ierr=-1
     632            0 :             return
     633              :          end if
     634              : 
     635            0 :          nel = 0
     636            0 :          izzp(:) = 0
     637            0 :          fap(:) = 0d0
     638              : 
     639            0 :          do i=1,species
     640            0 :             if (X(i) < min_X_to_include) cycle
     641            0 :             cid = chem_id(i)
     642            0 :             Z = chem_isos% Z(cid)
     643            0 :             if (Z == 0) cycle
     644              :             ! change Z if necessary so that in op set
     645            0 :             do j=num_op_mono_elements,1,-1
     646            0 :                if (Z >= op_mono_element_Z(j)) then
     647              :                   Z = op_mono_element_Z(j)
     648              :                   exit
     649              :                end if
     650              :             end do
     651            0 :             iel = 0
     652            0 :             do j=1,nel
     653            0 :                if (izzp(j) == Z) then
     654              :                   iel = j
     655              :                   exit
     656              :                end if
     657              :             end do
     658            0 :             if (iel == 0) then
     659            0 :                nel = nel+1
     660            0 :                iel = nel
     661            0 :                izzp(nel) = Z
     662              :             end if
     663            0 :             fap(iel) = fap(iel) + X(i)/dble(chem_isos% Z_plus_N(cid))
     664            0 :             fac(iel) = chem_factors(i)
     665              :          end do
     666              : 
     667            0 :          tot = sum(fap(1:nel))
     668            0 :          if (tot <= 0d0) then
     669            0 :             ierr = -1
     670            0 :             return
     671              :          end if
     672              : 
     673            0 :          do j=1,nel
     674            0 :             fap(j) = fap(j)/tot  ! number fractions
     675              :          end do
     676              : 
     677            0 :       end subroutine get_op_mono_args
     678              : 
     679              : 
     680            0 :       subroutine kap_get_control_namelist(handle, name, val, ierr)
     681            0 :          use kap_def
     682              :          use kap_ctrls_io, only: get_kap_controls
     683              :          integer, intent(in) :: handle  ! kap handle; from star, pass s% kap_handle
     684              :          character(len=*),intent(in) :: name
     685              :          character(len=*),intent(out) :: val
     686              :          integer, intent(out) :: ierr
     687              :          type (kap_General_Info), pointer :: rq
     688              :          ierr = 0
     689            0 :          call kap_ptr(handle,rq,ierr)
     690            0 :          if(ierr/=0) return
     691            0 :          call get_kap_controls(rq, name, val, ierr)
     692              : 
     693            0 :       end subroutine kap_get_control_namelist
     694              : 
     695            0 :       subroutine kap_set_control_namelist(handle, name, val, ierr)
     696            0 :          use kap_def
     697              :          use kap_ctrls_io, only: set_kap_controls
     698              :          integer, intent(in) :: handle  ! kap handle; from star, pass s% kap_handle
     699              :          character(len=*),intent(in) :: name
     700              :          character(len=*),intent(in) :: val
     701              :          integer, intent(out) :: ierr
     702              :          type (kap_General_Info), pointer :: rq
     703              :          ierr = 0
     704            0 :          call kap_ptr(handle,rq,ierr)
     705            0 :          if(ierr/=0) return
     706            0 :          call set_kap_controls(rq, name, val, ierr)
     707              : 
     708            0 :       end subroutine kap_set_control_namelist
     709              : 
     710              : 
     711              : 
     712            0 :       subroutine call_compute_grad_mombarg(k, j, blend, fk, T_face, Rho_face,&
     713              :         l, r, logKappa, lgrad, ierr)
     714            0 :         use op_eval_mombarg, only : compute_grad, compute_grad_fast
     715              :         !use crlibm_lib
     716              : 
     717              :         integer, intent(in) :: k, j
     718              :         real(dp), intent(in) :: fk(:)
     719              :         real(dp), intent(in) ::  blend, T_face, Rho_face, l, r
     720              :         integer, intent(inout) :: ierr
     721              :         real(dp), intent(out) :: logKappa, lgrad(17)
     722            0 :         real(dp) :: logT_face, logRho_face, lgrad1(17), lgrad2(17)
     723              : 
     724              :         !write(*,*) 'calling compute_grad'
     725            0 :         logT_face   = log10(T_face)
     726            0 :         logRho_face = log10(Rho_face)
     727              : 
     728              :         !call compute_grad(k, fk, logT_face, logRho_face,&
     729              :         !  l, r, &
     730              :         !  logKappa,lgrad, ierr,&
     731              :         !  izz,ite,jne,epatom,amamu,sig,eumesh)
     732            0 :         if (j == -1) then
     733              :             call compute_grad_fast(k, &
     734              :               fk_grad_pcg(1,:), logT_face, logRho_face, l, r, &
     735              :               lgrad1, ierr,&
     736            0 :               ite,jne,epatom,amamu,logT_pcg(1,:),logRho_pcg(1,:),lgamm_pcg(1,:,:),lkap_face_pcg(1,:))
     737              :             call compute_grad_fast(k, &
     738              :               fk_grad_pcg(2,:), logT_face, logRho_face, l, r, &
     739              :               lgrad2, ierr,&
     740            0 :               ite,jne,epatom,amamu,logT_pcg(2,:),logRho_pcg(2,:),lgamm_pcg(2,:,:),lkap_face_pcg(2,:))
     741            0 :             lgrad = (lgrad1*blend + lgrad2*(1-blend))
     742              : 
     743              :         else
     744              :           call compute_grad_fast(k, &
     745              :                   fk_grad_pcg(j,:), logT_face, logRho_face, l, r, &
     746              :                   lgrad, ierr,&
     747            0 :                   ite,jne,epatom,amamu,logT_pcg(j,:),logRho_pcg(j,:),lgamm_pcg(j,:,:),lkap_face_pcg(j,:))
     748              :         end if
     749            0 :       end subroutine call_compute_grad_mombarg
     750              : 
     751            0 :       subroutine call_compute_gamma_grid_mombarg(j, fk, ierr)
     752              :         use op_eval_mombarg, only : compute_gamma_grid
     753              :         !use crlibm_lib
     754              : 
     755              :         integer, intent(in) :: j
     756              :         real(dp), intent(in) :: fk(:)
     757              :         integer, intent(inout) :: ierr
     758              : 
     759            0 :         fk_grad_pcg(j,:) = fk
     760              : 
     761              :         call compute_gamma_grid(ngp, fk, &
     762              :           lgamm_pcg(j,:,:), lkap_face_pcg(j,:), logT_pcg(j,:), logRho_pcg(j,:), ierr,&
     763            0 :           ite,jne,epatom,amamu,sig,eumesh)
     764              : 
     765              : 
     766            0 :       end subroutine call_compute_gamma_grid_mombarg
     767              : 
     768            0 :       subroutine call_compute_kappa_mombarg(handle, k,&
     769            0 :         fk, logT_cntr, logRho_cntr,&
     770              :         zbar, lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT, &
     771              :         kap, dlnkap_dlnT, dlnkap_dlnRho, log_kap_rad_cell, ierr)
     772              :         use kap_eval, only: combine_rad_with_conduction
     773              :         use kap_def, only : kap_is_initialized, Kap_General_Info
     774              :         use op_eval_mombarg, only : compute_kappa, compute_kappa_fast, interpolate_kappa
     775              :         use chem_def, only: chem_isos, ih1, ihe3, ihe4, ic12, in14, io16, ine20, ina23, &
     776              :         img24, ial27, isi28, is32, iar40, ica40, icr52, imn55, ife56, ini58
     777              : 
     778              :         integer, intent(in) :: handle  ! from alloc_kap_handle
     779              :         integer, intent(in) :: k
     780              :         real(dp), intent(in) :: fk(:)
     781              :         real(dp), intent(in) :: logT_cntr, logRho_cntr
     782              :         real(dp), intent(in) :: zbar  ! average ionic charge (for electron conduction)
     783              :         real(dp), intent(in) :: lnfree_e, d_lnfree_e_dlnRho, d_lnfree_e_dlnT
     784              :         integer, intent(inout) :: ierr
     785              :         real(dp), intent(out) :: log_kap_rad_cell, kap, dlnkap_dlnT, dlnkap_dlnRho
     786              : 
     787              :         integer ::  eid(17), ke
     788            0 :         real(dp) :: dlnkap_rad_dlnT, dlnkap_rad_dlnRho, kap_rad, delta, delta2  !,fk(17),fk_norm_fac
     789              :         type (Kap_General_Info), pointer :: rq
     790              : 
     791              :         ierr = 0
     792            0 :         if (.not. kap_is_initialized) then
     793            0 :            ierr=-1
     794            0 :            return
     795              :         end if
     796            0 :         call kap_ptr(handle,rq,ierr)
     797            0 :         if (ierr /= 0) return
     798              : 
     799              : 
     800              :         eid = [ ih1, ihe4, ic12, in14, io16, ine20, ina23, &
     801            0 :         img24, ial27, isi28, is32, iar40, ica40, icr52, imn55, ife56, ini58 ]
     802              : 
     803            0 :         if (initialize_fk_old) then
     804            0 :         fk_old = 0
     805            0 :         initialize_fk_old = .false.
     806              :         end if
     807              : 
     808              : 
     809            0 :         delta  = MAXVAL(ABS(fk - fk_pcg)/fk_pcg, MASK=fk_pcg>0 )
     810            0 :         delta2 = MAXVAL(ABS(fk - fk_old(k,:))/fk_old(k,:), MASK=fk_old(k,:)>0 )
     811            0 :         if (SUM(fk_old(k,:)) == 0) then
     812            0 :           delta2 = 1d99
     813              :         end if
     814              : 
     815              : 
     816              : 
     817            0 :         if (delta > 1d-4) then
     818              :           if (delta2 > 1d-4 .or. ABS(logT_cntr - logT_cntr_old(k)) > 0.01d0 &
     819            0 :           .or. ABS(logRho_cntr - logRho_cntr_old(k)) > 0.1d0) then
     820              :             call compute_kappa(k,&
     821              :               fk, logT_cntr, logRho_cntr, &
     822              :               log_kap_rad_cell, dlnkap_rad_dlnT, dlnkap_rad_dlnRho, ierr,&
     823              :               ite,jne,epatom,amamu,sig,logT_grid_old(k,:,:),logRho_grid_old(k,:,:),&
     824            0 :               lkap_grid_old(k,:,:))
     825            0 :               fk_old(k,:) = fk
     826            0 :               logT_cntr_old(k)   = logT_cntr
     827            0 :               logRho_cntr_old(k) = logRho_cntr
     828              :             else
     829              :               call interpolate_kappa(k,&
     830              :                 logT_cntr, logRho_cntr, &
     831              :                 log_kap_rad_cell, dlnkap_rad_dlnT, dlnkap_rad_dlnRho, ierr,&
     832              :                 logT_grid_old(k,:,:),logRho_grid_old(k,:,:),&
     833            0 :                 lkap_grid_old(k,:,:))
     834              :           end if
     835              :         else
     836              :           call compute_kappa_fast(k,&
     837              :               fk_pcg, logT_cntr, logRho_cntr, &
     838              :               log_kap_rad_cell, dlnkap_rad_dlnT, dlnkap_rad_dlnRho, ierr,&
     839            0 :               ite,jne,epatom,amamu,sig,lkap_ross_pcg)
     840              : 
     841              :         end if
     842              : 
     843            0 :         if (ierr == 1) return
     844              : 
     845            0 :         kap_rad = exp10(log_kap_rad_cell)
     846              : 
     847              :         call combine_rad_with_conduction( &
     848              :              rq, logRho_cntr, logT_cntr, zbar, &
     849              :              kap_rad, dlnkap_rad_dlnRho, dlnkap_rad_dlnT, &
     850            0 :              kap, dlnkap_dlnRho, dlnkap_dlnT, ierr)
     851              : 
     852            0 :       end subroutine call_compute_kappa_mombarg
     853              : 
     854            0 :       subroutine call_compute_kappa_grid_mombarg(fk, ierr)
     855            0 :         use op_eval_mombarg, only : compute_kappa_grid
     856              : 
     857              :         real(dp), intent(in) :: fk(:)
     858              :         integer, intent(inout) :: ierr
     859              : 
     860            0 :         fk_pcg = fk
     861              : 
     862              :         call compute_kappa_grid(fk, &
     863              :           lkap_ross_pcg, ierr,&
     864            0 :           ite,jne,epatom,amamu,sig)
     865              : 
     866            0 :       end subroutine call_compute_kappa_grid_mombarg
     867              : 
     868              :       end module kap_lib
        

Generated by: LCOV version 2.0-1