LCOV - code coverage report
Current view: top level - kap/private - kap_ctrls_io.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 33.9 % 189 64
Test Date: 2026-08-20 21:51:39 Functions: 50.0 % 8 4

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : ! Copyright (C) 2020 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 kap_ctrls_io
      21              : 
      22              :    use const_def, only: dp
      23              :    use utils_namelist, only: max_extra_inlists
      24              :    use kap_def
      25              :    use math_lib
      26              : 
      27              :    implicit none
      28              : 
      29              :    public :: read_kap_namelist, write_namelist, get_kap_controls, set_kap_controls
      30              :    private
      31              : 
      32              :    real(dp) :: Zbase
      33              : 
      34              :    integer :: kap_option, kap_CO_option, kap_lowT_option
      35              : 
      36              :    character(len=strlen) :: kap_file_prefix, kap_CO_prefix, kap_lowT_prefix
      37              : 
      38              :    ! user table info
      39              :    integer :: user_num_kap_Xs = 0
      40              :    real(dp), dimension(kap_max_dim) :: user_kap_Xs = -1d0
      41              :    integer :: user_num_kap_Zs = 0
      42              :    real(dp), dimension(kap_max_dim) :: user_kap_Zs= -1d0
      43              :    integer, dimension(kap_max_dim) :: user_num_kap_Xs_for_this_Z = 0
      44              : 
      45              :    integer :: user_num_kap_CO_Xs = 0
      46              :    real(dp), dimension(kap_max_dim) :: user_kap_CO_Xs = -1d0
      47              :    integer :: user_num_kap_CO_Zs = 0
      48              :    real(dp), dimension(kap_max_dim) :: user_kap_CO_Zs= -1d0
      49              :    integer, dimension(kap_max_dim) :: user_num_kap_CO_Xs_for_this_Z = 0
      50              : 
      51              :    integer :: user_num_kap_lowT_Xs = 0
      52              :    real(dp), dimension(kap_max_dim) :: user_kap_lowT_Xs = -1d0
      53              :    integer :: user_num_kap_lowT_Zs = 0
      54              :    real(dp), dimension(kap_max_dim) :: user_kap_lowT_Zs= -1d0
      55              :    integer, dimension(kap_max_dim) :: user_num_kap_lowT_Xs_for_this_Z = 0
      56              : 
      57              : 
      58              :    real(dp) :: kap_blend_logT_upper_bdy, kap_blend_logT_lower_bdy
      59              : 
      60              :    logical :: cubic_interpolation_in_X
      61              :    logical :: cubic_interpolation_in_Z
      62              :    logical :: include_electron_conduction
      63              :    logical :: use_blouin_conductive_opacities
      64              : 
      65              :    logical :: use_Zbase_for_Type1
      66              :    logical :: use_Type2_opacities
      67              : 
      68              :    real(dp) :: kap_Type2_full_off_X, kap_Type2_full_on_X
      69              :    real(dp) :: kap_Type2_full_off_dZ, kap_Type2_full_on_dZ
      70              : 
      71              :    logical :: show_info
      72              : 
      73              :    ! hooks
      74              :    logical :: use_other_elect_cond_opacity, &
      75              :       use_other_compton_opacity, use_other_radiative_opacity
      76              : 
      77              :    ! debugging
      78              :    logical :: dbg
      79              :    real(dp) :: logT_lo, logT_hi
      80              :    real(dp) :: logRho_lo, logRho_hi
      81              :    real(dp) :: X_lo, X_hi
      82              :    real(dp) :: Z_lo, Z_hi
      83              : 
      84              :    logical, dimension(max_extra_inlists) :: read_extra_kap_inlist
      85              :    character (len=strlen), dimension(max_extra_inlists) :: extra_kap_inlist_name
      86              : 
      87              :    ! User supplied inputs
      88              :    real(dp) :: kap_ctrl(10)
      89              :    integer :: kap_integer_ctrl(10)
      90              :    logical :: kap_logical_ctrl(10)
      91              :    character(len=strlen) :: kap_character_ctrl(10)
      92              : 
      93              :    namelist /kap/ &
      94              : 
      95              :       Zbase, &
      96              : 
      97              :       kap_file_prefix, kap_CO_prefix, kap_lowT_prefix, aesopus_filename, &
      98              : 
      99              :       user_num_kap_Xs, user_kap_Xs, &
     100              :       user_num_kap_Zs, user_kap_Zs, user_num_kap_Xs_for_this_Z, &
     101              : 
     102              :       user_num_kap_CO_Xs, user_kap_CO_Xs, &
     103              :       user_num_kap_CO_Zs, user_kap_CO_Zs, user_num_kap_CO_Xs_for_this_Z, &
     104              : 
     105              :       user_num_kap_lowT_Xs, user_kap_lowT_Xs, &
     106              :       user_num_kap_lowT_Zs, user_kap_lowT_Zs, user_num_kap_lowT_Xs_for_this_Z, &
     107              : 
     108              :       kap_blend_logT_upper_bdy, kap_blend_logT_lower_bdy, &
     109              : 
     110              :       cubic_interpolation_in_X, cubic_interpolation_in_Z, &
     111              : 
     112              :       include_electron_conduction, use_blouin_conductive_opacities, &
     113              : 
     114              :       use_Zbase_for_Type1, use_Type2_opacities, &
     115              : 
     116              :       kap_Type2_full_off_X, kap_Type2_full_on_X, &
     117              :       kap_Type2_full_off_dZ, kap_Type2_full_on_dZ, &
     118              : 
     119              :       show_info, &
     120              : 
     121              :       use_other_elect_cond_opacity, &
     122              :       use_other_compton_opacity, &
     123              :       use_other_radiative_opacity, &
     124              : 
     125              :    ! User supplied inputs
     126              :       kap_ctrl, &
     127              :       kap_integer_ctrl, &
     128              :       kap_logical_ctrl, &
     129              :       kap_character_ctrl,&
     130              : 
     131              :       read_extra_kap_inlist, extra_kap_inlist_name
     132              : 
     133              :    contains
     134              : 
     135              : 
     136              :    ! read a "namelist" file and set parameters
     137            5 :    subroutine read_kap_namelist(handle, inlist, ierr)
     138              :       use utils_namelist, only: read_namelist, missing_namelist_warning
     139              :       integer, intent(in) :: handle
     140              :       character (len=*), intent(in) :: inlist
     141              :       integer, intent(out) :: ierr  ! 0 means AOK.
     142              :       type (Kap_General_Info), pointer :: rq
     143              : 
     144            5 :       call get_kap_ptr(handle,rq,ierr)
     145              : 
     146            5 :       if (ierr /= 0) return
     147              : 
     148            5 :       call set_default_controls
     149              : 
     150            5 :       if (inlist /= '') then
     151            4 :          call read_namelist(inlist, read_kap_file, "kap", ierr, missing_namelist_warning)
     152              :       end if
     153              : 
     154            5 :       if (ierr /= 0) return
     155              : 
     156            5 :       call store_controls(rq, ierr)
     157              :    end subroutine read_kap_namelist
     158              : 
     159            4 :    subroutine read_kap_file(unit, iostat, iomsg, extra_inlists, extra_inlists_mask)
     160              :       use const_def, only: strlen
     161              :       use utils_namelist, only: max_extra_inlists
     162              : 
     163              :       integer, intent(in) :: unit
     164              :       integer, intent(out) :: iostat
     165              :       character(len=strlen), intent(out) :: iomsg
     166              :       character(len=strlen), dimension(max_extra_inlists), intent(out) :: extra_inlists
     167              :       logical, dimension(max_extra_inlists), intent(out) :: extra_inlists_mask
     168              : 
     169              :       integer :: i
     170              : 
     171            4 :       read_extra_kap_inlist(:) = .false.
     172              : 
     173            4 :       read(unit, nml=kap, iostat=iostat, iomsg=iomsg)
     174              : 
     175            4 :       if (iostat /= 0) then
     176              :          return
     177              :       end if
     178              : 
     179           24 :       do i=1, max_extra_inlists
     180           20 :          extra_inlists(i) = extra_kap_inlist_name(i)
     181           24 :          extra_inlists_mask(i) = read_extra_kap_inlist(i)
     182              :       end do
     183              : 
     184              :    end subroutine read_kap_file
     185              : 
     186            5 :    subroutine set_default_controls
     187              :       include 'kap.defaults'
     188            5 :    end subroutine set_default_controls
     189              : 
     190              : 
     191            5 :    subroutine store_controls(rq, ierr)
     192              :       type (Kap_General_Info), pointer :: rq
     193              : 
     194              :       integer :: i, ierr
     195              : 
     196            5 :       rq% Zbase = Zbase
     197              : 
     198            5 :       rq% cubic_interpolation_in_X = cubic_interpolation_in_X
     199            5 :       rq% cubic_interpolation_in_Z = cubic_interpolation_in_Z
     200            5 :       rq% include_electron_conduction = include_electron_conduction
     201            5 :       rq% use_blouin_conductive_opacities = use_blouin_conductive_opacities
     202            5 :       rq% use_Zbase_for_Type1 = use_Zbase_for_Type1
     203            5 :       rq% use_Type2_opacities = use_Type2_opacities
     204              : 
     205              :       ! check for limits on full_off/on options
     206            5 :       if (kap_Type2_full_off_X > 0.71d0) then
     207            0 :          write(*,*) "kap_Type2_full_off_X must be smaller than 0.71"
     208            0 :          ierr = -1
     209            0 :          return
     210              :       end if
     211            5 :       if (kap_Type2_full_on_X > 0.71d0) then
     212            0 :          write(*,*) "kap_Type2_full_on_X must be smaller than 0.71"
     213            0 :          ierr = -1
     214            0 :          return
     215              :       end if
     216            5 :       if (kap_Type2_full_off_X < kap_Type2_full_on_X) then
     217            0 :          write(*,*) "kap_Type2_full_off_X has to be bigger than kap_Type2_full_on_X"
     218            0 :          ierr = -1
     219            0 :          return
     220              :       end if
     221            5 :       if (kap_Type2_full_off_dZ > kap_Type2_full_on_dZ) then
     222            0 :          write(*,*) "kap_Type2_full_off_dZ has to be smaller than kap_Type2_full_on_dZ"
     223            0 :          ierr = -1
     224            0 :          return
     225              :       end if
     226              : 
     227            5 :       rq% kap_Type2_full_off_X = kap_Type2_full_off_X
     228            5 :       rq% kap_Type2_full_on_X = kap_Type2_full_on_X
     229            5 :       rq% kap_Type2_full_off_dZ = kap_Type2_full_off_dZ
     230            5 :       rq% kap_Type2_full_on_dZ = kap_Type2_full_on_dZ
     231              : 
     232              : 
     233            5 :       if (kap_blend_logT_upper_bdy > 0) rq% kap_blend_logT_upper_bdy = kap_blend_logT_upper_bdy
     234            5 :       if (kap_blend_logT_lower_bdy > 0) rq% kap_blend_logT_lower_bdy = kap_blend_logT_lower_bdy
     235              : 
     236              : 
     237            5 :       kap_option = 0
     238           11 :       do i=1,kap_options_max
     239           11 :          if (kap_file_prefix == kap_option_str(i)) then
     240            5 :             kap_option = i
     241            5 :             exit
     242              :          end if
     243              :       end do
     244            5 :       if (kap_option == 0) then
     245            0 :          write(*,*) 'WARNING: unknown kap_file_prefix (assuming user table): ' // trim(kap_file_prefix)
     246            0 :          kap_option = kap_user
     247            0 :          kap_option_str(kap_user) = trim(kap_file_prefix)
     248              : 
     249            0 :          if (user_num_kap_Xs == 0 .or. user_num_kap_Zs == 0) then
     250            0 :             write(*,*) 'ERROR: must set user_num_kap_Xs, user_num_kap_Zs, and related variables'
     251            0 :             ierr = -1
     252            0 :             return
     253              :          end if
     254              : 
     255            0 :          if (user_num_kap_Xs > kap_max_dim .or. user_num_kap_Zs > kap_max_dim) then
     256            0 :             write(0,*) ' failed in kap_read_config_file: maximum X or Z dimensions exceeded'
     257            0 :             write(0,*) ' maximum dimension is ', kap_max_dim
     258            0 :             write(0,*) ' num_kap_Xs = ', num_kap_Xs
     259            0 :             write(0,*) ' num_kap_Zs = ', num_kap_Zs
     260            0 :             ierr = -1
     261            0 :             return
     262              :          end if
     263              : 
     264            0 :          num_kap_Xs(kap_user) = user_num_kap_Xs
     265            0 :          kap_Xs(:, kap_user) = user_kap_Xs
     266              : 
     267            0 :          num_kap_Zs(kap_user) = user_num_kap_Zs
     268            0 :          kap_Zs(:, kap_user) = user_kap_Zs
     269              : 
     270            0 :          num_kap_Xs_for_this_Z(:, kap_user) = user_num_kap_Xs_for_this_Z
     271              : 
     272              :       end if
     273            5 :       rq% kap_option = kap_option
     274              : 
     275              : 
     276            5 :       kap_CO_option = 0
     277           10 :       do i=1,kap_CO_options_max
     278           10 :          if (kap_CO_prefix == kap_CO_option_str(i)) then
     279            5 :             kap_CO_option = i
     280            5 :             exit
     281              :          end if
     282              :       end do
     283            5 :       if (kap_CO_option == 0) then
     284            0 :          write(*,*) 'WARNING: unknown kap_CO_prefix (assuming user table): ' // trim(kap_CO_prefix)
     285            0 :          kap_CO_option = kap_CO_user
     286            0 :          kap_CO_option_str(kap_CO_user) = trim(kap_CO_prefix)
     287              : 
     288            0 :          if (user_num_kap_CO_Xs == 0 .or. user_num_kap_CO_Zs == 0) then
     289            0 :             write(*,*) 'ERROR: must set user_num_kap_CO_Xs, user_num_kap_CO_Zs, and related variables'
     290            0 :             ierr = -1
     291            0 :             return
     292              :          end if
     293              : 
     294            0 :          num_kap_CO_Xs(kap_CO_user) = user_num_kap_CO_Xs
     295            0 :          kap_CO_Xs(:, kap_CO_user) = user_kap_CO_Xs
     296              : 
     297            0 :          num_kap_CO_Zs(kap_CO_user) = user_num_kap_CO_Zs
     298            0 :          kap_CO_Zs(:, kap_CO_user) = user_kap_CO_Zs
     299              : 
     300            0 :          num_kap_CO_Xs_for_this_Z(:, kap_CO_user) = user_num_kap_CO_Xs_for_this_Z
     301              : 
     302              :       end if
     303            5 :       rq% kap_CO_option = kap_CO_option
     304              : 
     305              : 
     306            5 :       kap_lowT_option = 0
     307           26 :       do i=1,kap_lowT_options_max
     308           26 :          if (kap_lowT_prefix == kap_lowT_option_str(i)) then
     309            5 :             kap_lowT_option = i
     310            5 :             exit
     311              :          end if
     312              :       end do
     313            5 :       if (kap_lowT_option == 0) then
     314            0 :          write(*,*) 'WARNING: unknown kap_lowT_prefix (assuming user table): ' // trim(kap_lowT_prefix)
     315            0 :          kap_lowT_option = kap_lowT_user
     316            0 :          kap_lowT_option_str(kap_lowT_user) = trim(kap_lowT_prefix)
     317              : 
     318            0 :          if (user_num_kap_lowT_Xs == 0 .or. user_num_kap_lowT_Zs == 0) then
     319            0 :             write(*,*) 'ERROR: must set user_num_kap_lowT_Xs, user_num_kap_lowT_Zs, and related variables'
     320            0 :             ierr = -1
     321            0 :             return
     322              :          end if
     323              : 
     324            0 :          if (user_num_kap_lowT_Xs > kap_max_dim .or. user_num_kap_lowT_Zs > kap_max_dim) then
     325            0 :             write(0,*) ' failed in kap_read_config_file: maximum X or Z dimensions exceeded'
     326            0 :             write(0,*) ' maximum dimension is ', kap_max_dim
     327            0 :             write(0,*) ' num_kap_lowT_Xs = ', num_kap_lowT_Xs
     328            0 :             write(0,*) ' num_kap_lowT_Zs = ', num_kap_lowT_Zs
     329            0 :             ierr = -1
     330            0 :             return
     331              :          end if
     332              : 
     333            0 :          num_kap_lowT_Xs(kap_lowT_user) = user_num_kap_lowT_Xs
     334            0 :          kap_lowT_Xs(:, kap_lowT_user) = user_kap_lowT_Xs
     335              : 
     336            0 :          num_kap_lowT_Zs(kap_lowT_user) = user_num_kap_lowT_Zs
     337            0 :          kap_lowT_Zs(:, kap_lowT_user) = user_kap_lowT_Zs
     338              : 
     339            0 :          num_kap_lowT_Xs_for_this_Z(:, kap_lowT_user) = user_num_kap_lowT_Xs_for_this_Z
     340              : 
     341              :       end if
     342            5 :       rq% kap_lowT_option = kap_lowT_option
     343              : 
     344            5 :       rq% show_info = show_info
     345              : 
     346            5 :       rq% use_other_elect_cond_opacity = use_other_elect_cond_opacity
     347            5 :       rq% use_other_compton_opacity = use_other_compton_opacity
     348            5 :       rq% use_other_radiative_opacity = use_other_radiative_opacity
     349              : 
     350              :       ! user inputs
     351           55 :       rq% kap_ctrl = kap_ctrl
     352           55 :       rq% kap_integer_ctrl = kap_integer_ctrl
     353           55 :       rq% kap_logical_ctrl = kap_logical_ctrl
     354           55 :       rq% kap_character_ctrl = kap_character_ctrl
     355              : 
     356              :    end subroutine store_controls
     357              : 
     358              : 
     359            0 :    subroutine write_namelist(handle, filename, ierr)
     360              :       integer, intent(in) :: handle
     361              :       character(*), intent(in) :: filename
     362              :       integer, intent(out) :: ierr
     363              :       type (Kap_General_Info), pointer :: rq
     364              :       integer :: iounit
     365              :       open(newunit=iounit, file=trim(filename), &
     366            0 :          action='write', status='replace', iostat=ierr)
     367            0 :       if (ierr /= 0) then
     368            0 :          write(*,*) 'failed to open ' // trim(filename)
     369            0 :          return
     370              :       end if
     371            0 :       call get_kap_ptr(handle,rq,ierr)
     372            0 :       if (ierr /= 0) then
     373            0 :          close(iounit)
     374            0 :          return
     375              :       end if
     376            0 :       call set_controls_for_writing(rq)
     377            0 :       write(iounit, nml=kap, iostat=ierr)
     378            0 :       close(iounit)
     379              :    end subroutine write_namelist
     380              : 
     381              : 
     382            0 :    subroutine set_controls_for_writing(rq)
     383              :       type (Kap_General_Info), pointer :: rq
     384              : 
     385            0 :       Zbase = rq% Zbase
     386              : 
     387            0 :       kap_blend_logT_upper_bdy = rq% kap_blend_logT_upper_bdy
     388            0 :       kap_blend_logT_lower_bdy = rq% kap_blend_logT_lower_bdy
     389              : 
     390            0 :       cubic_interpolation_in_X = rq% cubic_interpolation_in_X
     391            0 :       cubic_interpolation_in_Z = rq% cubic_interpolation_in_Z
     392              : 
     393            0 :       include_electron_conduction = rq% include_electron_conduction
     394            0 :       use_blouin_conductive_opacities = rq% use_blouin_conductive_opacities
     395              : 
     396            0 :       use_Zbase_for_Type1 = rq% use_Zbase_for_Type1
     397            0 :       use_Type2_opacities = rq% use_Type2_opacities
     398              : 
     399            0 :       kap_Type2_full_off_X = rq% kap_Type2_full_off_X
     400            0 :       kap_Type2_full_on_X = rq% kap_Type2_full_on_X
     401            0 :       kap_Type2_full_off_dZ = rq% kap_Type2_full_off_dZ
     402            0 :       kap_Type2_full_on_dZ = rq% kap_Type2_full_on_dZ
     403              : 
     404            0 :       show_info = rq% show_info
     405              : 
     406            0 :       use_other_elect_cond_opacity = rq% use_other_elect_cond_opacity
     407            0 :       use_other_compton_opacity = rq% use_other_compton_opacity
     408            0 :       use_other_radiative_opacity = rq% use_other_radiative_opacity
     409              : 
     410              :       ! user inputs
     411            0 :       kap_ctrl = rq% kap_ctrl
     412            0 :       kap_integer_ctrl = rq% kap_integer_ctrl
     413            0 :       kap_logical_ctrl = rq% kap_logical_ctrl
     414            0 :       kap_character_ctrl = rq% kap_character_ctrl
     415              : 
     416              : 
     417            0 :    end subroutine set_controls_for_writing
     418              : 
     419              : 
     420              : 
     421            0 :    subroutine get_kap_controls(rq, name, val, ierr)
     422              :       use utils_lib, only: StrUpCase
     423              :       type (kap_General_Info), pointer :: rq
     424              :       character(len=*),intent(in) :: name
     425              :       character(len=*), intent(out) :: val
     426              :       integer, intent(out) :: ierr
     427              : 
     428            0 :       character(len(name)+1) :: upper_name
     429              :       character(len=512) :: str
     430              :       integer :: iounit,iostat,ind,i
     431              : 
     432            0 :       ierr = 0
     433              : 
     434              : 
     435              :       ! First save current controls
     436            0 :       call set_controls_for_writing(rq)
     437              : 
     438              :       ! Write namelist to temporary file
     439            0 :       open(newunit=iounit,status='scratch')
     440            0 :       write(iounit,nml=kap)
     441            0 :       rewind(iounit)
     442              : 
     443              :       ! Namelists get written in capitals
     444            0 :       upper_name = trim(StrUpCase(name))//'='
     445            0 :       val = ''
     446              :       ! Search for name inside namelist
     447              :       do
     448            0 :          read(iounit,'(A)',iostat=iostat) str
     449            0 :          ind = index(trim(str),trim(upper_name))
     450            0 :          if( ind /= 0 ) then
     451            0 :             val = str(ind+len_trim(upper_name):len_trim(str)-1)  ! Remove final comma and starting =
     452            0 :             do i=1,len(val)
     453            0 :                if(val(i:i)=='"') val(i:i) = ' '
     454              :             end do
     455              :             exit
     456              :          end if
     457            0 :          if(is_iostat_end(iostat)) exit
     458              :       end do
     459              : 
     460            0 :       if(len_trim(val) == 0 .and. ind==0 ) ierr = -1
     461              : 
     462            0 :       close(iounit)
     463              : 
     464            0 :    end subroutine get_kap_controls
     465              : 
     466            0 :    subroutine set_kap_controls(rq, name, val, ierr)
     467              :       type (kap_General_Info), pointer :: rq
     468              :       character(len=*), intent(in) :: name, val
     469            0 :       character(len=len(name)+len(val)+8) :: tmp
     470              :       integer, intent(out) :: ierr
     471              : 
     472            0 :       ierr = 0
     473              : 
     474              :       ! First save current kap_controls
     475            0 :       call set_controls_for_writing(rq)
     476              : 
     477            0 :       tmp=''
     478            0 :       tmp = '&kap '//trim(name)//'='//trim(val)//' /'
     479              : 
     480              :       ! Load into namelist
     481            0 :       read(tmp, nml=kap)
     482              : 
     483              :       ! Add to kap
     484            0 :       call store_controls(rq,ierr)
     485            0 :       if(ierr/=0) return
     486              : 
     487              :    end subroutine set_kap_controls
     488              : 
     489              : 
     490              : 
     491              :    end module kap_ctrls_io
        

Generated by: LCOV version 2.0-1