LCOV - code coverage report
Current view: top level - chem/private - chem_isos_io.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.1 % 112 102
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 4 4

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  Ed Brown & 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 chem_isos_io
      21              : 
      22              :       use chem_def
      23              :       use math_lib
      24              :       use const_def, only: dp, amu, clight, five_thirds, mev_to_ergs
      25              : 
      26              :       implicit none
      27              : 
      28              :       contains
      29              : 
      30           16 :       subroutine do_read_chem_isos(isotopes_filename, ierr)
      31              :          use utils_lib
      32              :          use const_def, only: mesa_data_dir
      33              :          character (len=*), intent(in) :: isotopes_filename
      34              :          integer, intent(out) :: ierr
      35              :          integer :: i, j, k, iounit, pass, nvec, Z, N
      36              :          character (len=256) :: filename, buf
      37         4112 :          real(dp), target :: vec_ary(256)
      38              :          real(dp), pointer :: vec(:)
      39              : 
      40           16 :          ierr = 0
      41           16 :          vec => vec_ary
      42              : 
      43           16 :          filename = trim(mesa_data_dir) // '/chem_data/' // trim(isotopes_filename)
      44           16 :          num_chem_isos = 0
      45              : 
      46           48 :          do pass = 1, 2
      47              : 
      48           32 :             open(newunit=iounit, file=trim(filename), iostat=ierr, status='old',action='read')
      49           32 :             if ( ierr /= 0 ) then
      50            0 :                write(*,*) 'unable to open '// trim(filename)
      51            0 :                return
      52              :             end if
      53           32 :             read(iounit,'(A)') buf  ! skip line 1
      54              : 
      55           32 :             if (pass == 1) then
      56              : 
      57       125696 :                do  ! 4 lines per nuclide
      58       125712 :                   read(iounit, *, iostat=ierr)
      59       125712 :                   if (ierr /= 0) exit
      60       125696 :                   read(iounit, *, iostat=ierr)
      61       125696 :                   if (ierr /= 0) exit
      62       125696 :                   read(iounit, *, iostat=ierr)
      63       125696 :                   if (ierr /= 0) exit
      64       125696 :                   read(iounit, *, iostat=ierr)
      65       125696 :                   if (ierr /= 0) exit
      66       125696 :                   num_chem_isos = num_chem_isos+1
      67              :                end do
      68           16 :                if (num_chem_isos == 0) then
      69            0 :                   write (*,*) 'unable to retrieve isotopes from '//trim(filename)
      70            0 :                   return
      71              :                end if
      72              :             else
      73              : 
      74           16 :                call allocate_nuclide_data(chem_isos, num_chem_isos, ierr)
      75           16 :                if (ierr /= 0) then
      76            0 :                   write(*,*) 'unable to allocate nuclide data'
      77            0 :                   return
      78              :                end if
      79              : 
      80       125712 :                do i = 1, num_chem_isos
      81              : 
      82       125696 :                   read(iounit, '(A)',iostat=ierr) buf
      83       125696 :                   if (ierr /= 0) exit
      84       125696 :                   call parse_line(buf,i,ierr)
      85       125696 :                   if (ierr /= 0) exit
      86              : 
      87       502784 :                   do k=1,3
      88       377088 :                      read(iounit,'(a)',iostat=ierr) buf
      89       377088 :                      if (ierr == 0) then
      90       377088 :                         call str_to_vector(buf, vec, nvec, ierr)
      91       377088 :                         if (nvec /= 8) ierr = -1
      92              :                      end if
      93       377088 :                      if (ierr /= 0) exit
      94      3519488 :                      do j=1,8
      95      3393792 :                         chem_isos% pfcn(j+(k-1)*8, i) = vec(j)
      96              :                      end do
      97              :                   end do
      98       125696 :                   if (ierr /= 0) exit
      99              : 
     100       125696 :                   chem_isos% chem_id(i) = i
     101       125696 :                   chem_isos% nuclide(i) = i
     102       125712 :                   chem_isos% isomeric_state(i) = get_isomeric_state(chem_isos% name(i), ierr)
     103              : 
     104              :                end do
     105           16 :                if (ierr /= 0) then
     106            0 :                   write (*,*) 'something went wrong in read of '//trim(filename)
     107            0 :                   return
     108              :                end if
     109              : 
     110              :             end if
     111              : 
     112           48 :             close(iounit)
     113              : 
     114              :          end do
     115              : 
     116           16 :          if (ierr /= 0) return
     117              : 
     118           16 :          call do_create_nuclides_dict(chem_isos, chem_isos_dict, ierr)
     119           16 :          if (ierr /= 0) return
     120              : 
     121              :          !Set mass excess of proton and neutron
     122       125712 :          do i = 1, num_chem_isos
     123       125696 :             Z = chem_isos% Z(i)
     124       125696 :             N = chem_isos% N(i)
     125       125696 :             if(Z==1 .and. N==0) del_Mp=chem_isos% mass_excess(i)
     126       125712 :             if(N==1 .and. Z==0) del_Mn=chem_isos% mass_excess(i)
     127              :          end do
     128              : 
     129       125712 :          chem_isos% Z_plus_N = chem_isos% Z + chem_isos% N
     130              : 
     131              :          ! pre-calculate Z^5/3
     132       125712 :          do i = 1, num_chem_isos
     133       125712 :             chem_isos% Z53(i) = pow(real(chem_isos% Z(i), dp), five_thirds)
     134              :          end do
     135              : 
     136       125712 :          chem_isos% binding_energy = chem_isos% Z*del_Mp + chem_isos% N*del_Mn - chem_isos% mass_excess
     137              : 
     138              :          ! Recompute Atomic masses for double precision consistency.
     139       125712 :          chem_isos% W = chem_isos% Z_plus_N + chem_isos% mass_excess*(mev_to_ergs/amu/(clight*clight))
     140              : 
     141         1824 :          element_min_N = 99999
     142         1824 :          element_max_N = -1
     143       125712 :          do i = 1, num_chem_isos
     144       125696 :             Z = chem_isos% Z(i)
     145       125696 :             N = chem_isos% N(i)
     146       125696 :             if (N < element_min_N(Z)) element_min_N(Z) = N
     147       125712 :             if (N > element_max_N(Z)) element_max_N(Z) = N
     148              :          end do
     149              : 
     150              :          contains
     151              : 
     152       125696 :          integer function get_isomeric_state(name, ierr)
     153              :             character (len=*), intent(in) :: name
     154              :             integer, intent(out) :: ierr
     155              :             integer :: i, len
     156       125696 :             ierr = 0
     157       125696 :             get_isomeric_state = 0
     158       125696 :             len = len_trim(name)
     159       720560 :             do i=1,len
     160       720560 :                if (name(i:i) == '-') then
     161           32 :                   read(name(i+1:len),*,iostat=ierr) get_isomeric_state
     162           32 :                   if (ierr /= 0 .or. get_isomeric_state < 0 .or. get_isomeric_state > 99) then
     163            0 :                      write(*,*) 'ERROR: invalid name for iso ' // trim(name) // ' in ' // trim(filename)
     164            0 :                      return
     165              :                   end if
     166              :                   return
     167              :                end if
     168              :             end do
     169              :          end function get_isomeric_state
     170              : 
     171              : 
     172       502784 :          subroutine parse_line(line,i,ierr)
     173              :             character(len=*),intent(in) :: line
     174              :             integer, intent(in) :: i
     175              :             integer, intent(inout) :: ierr
     176              :             integer :: j,k
     177              :             integer, parameter :: num_cols=6
     178              :             character(len=256),dimension(num_cols) :: tmp
     179              :             character(len=256) :: tmp2
     180              : 
     181       125696 :             k=1
     182       125696 :             tmp2=''
     183       879872 :             tmp=''
     184      6410496 :             do j=1,len(line)
     185      6410496 :                if(line(j:j)==' ') cycle
     186      4512400 :                tmp2=trim(tmp2)//line(j:j)
     187      4512400 :                if(j<len(line))then
     188      4512400 :                   if(line(j+1:j+1)==' ') then
     189       754176 :                      tmp(k)=tmp2(1:len_trim(tmp2))
     190       754176 :                      k=k+1
     191       754176 :                      tmp2=''
     192              :                   end if
     193              :                end if
     194      4512400 :                if(k==num_cols+1) exit
     195              :             end do
     196              : 
     197       125696 :             chem_isos% name(i)=tmp(1)
     198       125696 :             call str_to_double(tmp(2),chem_isos% W(i),ierr)
     199       125696 :             if (ierr /= 0) return
     200       125696 :             read(tmp(3),*) chem_isos% Z(i)
     201       125696 :             if (ierr /= 0) return
     202       125696 :             read(tmp(4),*) chem_isos% N(i)
     203       125696 :             if (ierr /= 0) return
     204       125696 :             call str_to_double(tmp(5),chem_isos% spin(i),ierr)
     205       125696 :             if (ierr /= 0) return
     206       125696 :             call str_to_double(tmp(6),chem_isos% mass_excess(i),ierr)
     207       125696 :             if (ierr /= 0) return
     208              : 
     209              :          end subroutine parse_line
     210              : 
     211              :       end subroutine do_read_chem_isos
     212              : 
     213              : 
     214           32 :       subroutine do_create_nuclides_dict(nuclides, nuclides_dict, ierr)
     215              :          use utils_lib, only: integer_dict_define, integer_dict_create_hash, integer_dict_lookup
     216              :          type(nuclide_data), intent(in) :: nuclides
     217              :          type (integer_dict), pointer :: nuclides_dict  ! will be allocated
     218              :          integer, intent(out) :: ierr
     219              :          integer :: i
     220              : 
     221              :          ierr = 0
     222           16 :          nullify(nuclides_dict)
     223       125712 :          do i=1,nuclides% nnuclides
     224       125696 :             call integer_dict_define(nuclides_dict, nuclides% name(i), i, ierr)
     225       125712 :             if (ierr /= 0) return
     226              :          end do
     227              : 
     228           16 :          call integer_dict_create_hash(nuclides_dict, ierr)
     229           16 :          if (ierr /= 0) return
     230              : 
     231              :       end subroutine do_create_nuclides_dict
     232              : 
     233              :       end module chem_isos_io
        

Generated by: LCOV version 2.0-1