LCOV - code coverage report
Current view: top level - eos/private - helm_alloc.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.2 % 274 258
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 6 6

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2006, 2007-2019  Frank Timmes & 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 helm_alloc
      21              : 
      22              :          use const_def, only: dp, use_mesa_temp_cache
      23              :       use math_lib
      24              : 
      25              :       implicit none
      26              : 
      27              :       contains
      28              : 
      29           13 :       subroutine alloc_helm_table(h, imax, jmax, ierr)
      30              :          ! This routine allocates a Helm_Table and places pointer to it in h.
      31              :          ! It also allocates the arrays in the Helm_Table record.
      32              : 
      33              :          use eos_def
      34              : 
      35              :          type (Helm_Table), pointer :: h
      36              :          integer, intent(in) :: imax, jmax
      37              :          integer, intent(out) :: ierr  ! 0 means AOK.
      38              : 
      39              :          ierr = 0
      40              : 
      41           13 :          allocate(h,stat=ierr)
      42           13 :          if (ierr /= 0) return
      43              : 
      44           13 :          h% imax = imax
      45           13 :          h% jmax = jmax
      46           13 :          h% with_coulomb_corrections = .true.
      47              : 
      48           13 :          call alloc_1d_array(h% d, imax)
      49           13 :          call alloc_1d_array(h% t, jmax)
      50              : 
      51              :          !..for the helmholtz free energy tables
      52           13 :          call alloc_2d_array(h% f, imax, jmax)
      53           13 :          call alloc_2d_array(h% fd, imax, jmax)
      54           13 :          call alloc_2d_array(h% ft, imax, jmax)
      55           13 :          call alloc_2d_array(h% fdd, imax, jmax)
      56           13 :          call alloc_2d_array(h% ftt, imax, jmax)
      57           13 :          call alloc_2d_array(h% fdt, imax, jmax)
      58           13 :          call alloc_2d_array(h% fddt, imax, jmax)
      59           13 :          call alloc_2d_array(h% fdtt, imax, jmax)
      60           13 :          call alloc_2d_array(h% fddtt, imax, jmax)
      61              : 
      62              :          !..for the pressure derivative with density tables
      63           13 :          call alloc_2d_array(h% dpdf, imax, jmax)
      64           13 :          call alloc_2d_array(h% dpdfd, imax, jmax)
      65           13 :          call alloc_2d_array(h% dpdft, imax, jmax)
      66           13 :          call alloc_2d_array(h% dpdfdt, imax, jmax)
      67              : 
      68              :          !..for chemical potential tables
      69           13 :          call alloc_2d_array(h% ef, imax, jmax)
      70           13 :          call alloc_2d_array(h% efd, imax, jmax)
      71           13 :          call alloc_2d_array(h% eft, imax, jmax)
      72           13 :          call alloc_2d_array(h% efdt, imax, jmax)
      73              : 
      74              :          !..for the number density tables
      75           13 :          call alloc_2d_array(h% xf, imax, jmax)
      76           13 :          call alloc_2d_array(h% xfd, imax, jmax)
      77           13 :          call alloc_2d_array(h% xft, imax, jmax)
      78           13 :          call alloc_2d_array(h% xfdt, imax, jmax)
      79              : 
      80              :          !..for storing the differences
      81           13 :          call alloc_1d_array(h% dt_sav, jmax)
      82           13 :          call alloc_1d_array(h% dt2_sav, jmax)
      83           13 :          call alloc_1d_array(h% dti_sav, jmax)
      84           13 :          call alloc_1d_array(h% dt2i_sav, jmax)
      85           13 :          call alloc_1d_array(h% dt3i_sav, jmax)
      86              : 
      87           13 :          call alloc_1d_array(h% dd_sav, imax)
      88           13 :          call alloc_1d_array(h% dd2_sav, imax)
      89           13 :          call alloc_1d_array(h% ddi_sav, imax)
      90           13 :          call alloc_1d_array(h% dd2i_sav, imax)
      91           13 :          call alloc_1d_array(h% dd3i_sav, imax)
      92              : 
      93              :          contains
      94              : 
      95          156 :          subroutine alloc_1d_array(ptr,sz)
      96              :             real(dp), dimension(:), pointer :: ptr
      97              :             integer, intent(in) :: sz
      98          156 :             allocate(ptr(sz),stat=ierr)
      99           13 :          end subroutine alloc_1d_array
     100              : 
     101          273 :          subroutine alloc_2d_array(ptr,sz1,sz2)
     102              :             real(dp), dimension(:,:), pointer :: ptr
     103              :             integer, intent(in) :: sz1,sz2
     104          546 :             allocate(ptr(sz1,sz2),stat=ierr)
     105          273 :          end subroutine alloc_2d_array
     106              : 
     107              : 
     108              :       end subroutine alloc_helm_table
     109              : 
     110              : 
     111           13 :       subroutine setup_td_deltas(h, imax, jmax)
     112              :          use eos_def
     113              :          type (Helm_Table), pointer :: h
     114              :          integer, intent(in) :: imax, jmax
     115              :          integer :: i, j
     116           13 :          real(dp) :: dth,dt2,dti,dt2i,dt3i,dd,dd2,ddi,dd2i,dd3i
     117              :          !..construct the temperature and density deltas and their inverses
     118        13013 :          do j=1,jmax-1
     119        13000 :             dth         = h% t(j+1) - h% t(j)
     120        13000 :             dt2         = dth * dth
     121        13000 :             dti         = 1.0d0/dth
     122        13000 :             dt2i        = 1.0d0/dt2
     123        13000 :             dt3i        = dt2i*dti
     124        13000 :             h% dt_sav(j)   = dth
     125        13000 :             h% dt2_sav(j)  = dt2
     126        13000 :             h% dti_sav(j)  = dti
     127        13000 :             h% dt2i_sav(j) = dt2i
     128        13013 :             h% dt3i_sav(j) = dt3i
     129              :          end do
     130        35113 :          do i=1,imax-1
     131        35100 :             dd          = h% d(i+1) - h% d(i)
     132        35100 :             dd2         = dd * dd
     133        35100 :             ddi         = 1.0d0/dd
     134        35100 :             dd2i        = 1.0d0/dd2
     135        35100 :             dd3i        = dd2i*ddi
     136        35100 :             h% dd_sav(i)   = dd
     137        35100 :             h% dd2_sav(i)  = dd2
     138        35100 :             h% ddi_sav(i)  = ddi
     139        35100 :             h% dd2i_sav(i) = dd2i
     140        35113 :             h% dd3i_sav(i) = dd3i
     141              :          end do
     142           13 :       end subroutine setup_td_deltas
     143              : 
     144              : 
     145           13 :       subroutine read_helm_table(h, data_dir, cache_dir, temp_cache_dir, use_cache, ierr)
     146           13 :       use eos_def
     147              :       use utils_lib, only: mv, switch_str
     148              : 
     149              : 
     150              :       type (Helm_Table), pointer :: h
     151              :       character(*), intent(IN) :: data_dir, cache_dir, temp_cache_dir
     152              :       logical, intent(IN) :: use_cache
     153              :       integer, intent(out) :: ierr
     154              : 
     155              : !..this routine reads the helmholtz eos file, and
     156              : !..must be called once before the helmeos routine is invoked.
     157              : 
     158              : !..declare local variables
     159              :       character (len=256) :: filename, message, temp_filename
     160              :       character (len=500) :: buf
     161              :       character (len=26) :: s26
     162          273 :       real(dp), target :: vec_ary(20)
     163              :       real(dp), pointer :: vec(:)
     164              :       integer          :: i,j,k,ios,imax,jmax,n
     165           13 :       real(dp) :: tsav,dsav
     166              :       logical, parameter :: dmp = .false.
     167              : 
     168           13 :        ierr = 0
     169           13 :        vec => vec_ary
     170              : 
     171              : !..read the normal helmholtz free energy table
     172           13 :        h% logtlo   = 3.0d0
     173           13 :        h% logthi   = 13.0d0
     174           13 :        h% logdlo   = -12.0d0
     175           13 :        h% logdhi   = 15.0d0
     176              : 
     177           13 :        h% templo = exp10(h% logtlo)
     178           13 :        h% temphi = exp10(h% logthi)
     179           13 :        h% denlo = exp10(h% logdlo)
     180           13 :        h% denhi = exp10(h% logdhi)
     181              : 
     182           13 :        imax = h% imax
     183           13 :        jmax = h% jmax
     184           13 :        h% logtstp  = (h% logthi - h% logtlo)/real(jmax-1,kind=dp)
     185           13 :        h% logtstpi = 1.0d0/h% logtstp
     186           13 :        h% logdstp  = (h% logdhi - h% logdlo)/real(imax-1,kind=dp)
     187           13 :        h% logdstpi = 1.0d0/h% logdstp
     188              : 
     189           13 :        ios = -1
     190           13 :        if (use_cache) then
     191           12 :          write(filename,'(2a)') trim(cache_dir), '/helm_table.bin'
     192              :          open(unit=19,file=trim(filename), &
     193           12 :                action='read',status='old',iostat=ios,form='unformatted')
     194              :        end if
     195              : 
     196           13 :        if (ios == 0) then
     197              : 
     198           11 :           read(19) imax
     199           11 :           read(19) jmax
     200              : 
     201           11 :          if (imax /= h% imax .or. jmax /= h% jmax) then
     202            0 :             ios = 1  ! wrong cached info
     203              :          else
     204           11 :              read(19) h% f(1:imax,1:jmax)
     205           11 :              read(19) h% fd(1:imax,1:jmax)
     206           11 :              read(19) h% ft(1:imax,1:jmax)
     207           11 :              read(19) h% fdd(1:imax,1:jmax)
     208           11 :              read(19) h% ftt(1:imax,1:jmax)
     209           11 :              read(19) h% fdt(1:imax,1:jmax)
     210           11 :              read(19) h% fddt(1:imax,1:jmax)
     211           11 :              read(19) h% fdtt(1:imax,1:jmax)
     212           11 :              read(19) h% fddtt(1:imax,1:jmax)
     213           11 :              read(19) h% dpdf(1:imax,1:jmax)
     214           11 :              read(19) h% dpdfd(1:imax,1:jmax)
     215           11 :              read(19) h% dpdft(1:imax,1:jmax)
     216           11 :              read(19) h% dpdfdt(1:imax,1:jmax)
     217           11 :              read(19) h% ef(1:imax,1:jmax)
     218           11 :              read(19) h% efd(1:imax,1:jmax)
     219           11 :              read(19) h% eft(1:imax,1:jmax)
     220           11 :              read(19) h% efdt(1:imax,1:jmax)
     221           11 :              read(19) h% xf(1:imax,1:jmax)
     222           11 :              read(19) h% xfd(1:imax,1:jmax)
     223           11 :              read(19) h% xft(1:imax,1:jmax)
     224           11 :              read(19) h% xfdt(1:imax,1:jmax)
     225              : 
     226        11022 :             do j=1,jmax
     227        11011 :                tsav = h% logtlo + (j-1)*h% logtstp
     228        11022 :                h% t(j) = exp10(tsav)
     229              :             end do
     230        29722 :             do i=1,imax
     231        29711 :                dsav = h% logdlo + (i-1)*h% logdstp
     232        29722 :                h% d(i) = exp10(dsav)
     233              :             end do
     234              :          end if
     235              : 
     236           11 :          close(unit=19)
     237              :        end if
     238              : 
     239           13 :        if (ios /= 0) then
     240              : 
     241            2 :           write(filename,'(2a)') trim(data_dir), '/helm_table.dat'
     242            2 :           write(*,*) 'read  ', trim(filename)
     243              : 
     244            2 :           ios = 0
     245            2 :           open(unit=19,file=trim(filename),action='read',status='old',iostat=ios)
     246            2 :           if (ios /= 0) then
     247            0 :             write(*,'(3a,i6)') 'failed to open ', trim(filename), ' : ios ', ios
     248            0 :             ierr = -1
     249            0 :             return
     250              :           end if
     251              : 
     252         2004 :           do j=1,jmax
     253         2002 :             tsav = h% logtlo + (j-1)*h% logtstp
     254         2002 :             h% t(j) = exp10(tsav)
     255      5409406 :             do i=1,imax
     256      5407402 :                dsav = h% logdlo + (i-1)*h% logdstp
     257      5407402 :                h% d(i) = exp10(dsav)
     258      5407402 :                read(19,'(a)',iostat=ierr) buf
     259      5407402 :                if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     260      5407402 :                if (ierr /= 0 .or. n /= 9) then
     261            0 :                   write(*,'(a)') 'failed while reading ' // trim(filename)
     262            0 :                   close(19)
     263            0 :                   return
     264              :                end if
     265      5407402 :                h% f(i,j) = vec(1)
     266      5407402 :                h% fd(i,j) = vec(2)
     267      5407402 :                h% ft(i,j) = vec(3)
     268      5407402 :                h% fdd(i,j) = vec(4)
     269      5407402 :                h% ftt(i,j) = vec(5)
     270      5407402 :                h% fdt(i,j) = vec(6)
     271      5407402 :                h% fddt(i,j) = vec(7)
     272      5407402 :                h% fdtt(i,j) = vec(8)
     273      5407402 :                h% fddtt(i,j) = vec(9)
     274         2002 :                if (dmp) then
     275              :                   do k=1,9
     276              :                      write(*,'(1pd24.16)',advance='no') vec(k)
     277              :                   end do
     278              :                   write(*,'(A)')
     279              :                end if
     280              :             end do
     281              :           end do
     282              : 
     283              :          !..read the pressure derivative with density table
     284         2004 :           do j=1,jmax
     285      5409406 :            do i=1,imax
     286      5407402 :             read(19,'(a)',iostat=ierr) buf
     287      5407402 :             if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     288      5407402 :             if (ierr /= 0 .or. n /= 4) then
     289            0 :                write(*,'(a)') 'failed while reading ' // trim(filename)
     290            0 :                close(19)
     291            0 :                return
     292              :             end if
     293      5407402 :             h% dpdf(i,j) = vec(1)
     294      5407402 :             h% dpdfd(i,j) = vec(2)
     295      5407402 :             h% dpdft(i,j) = vec(3)
     296      5407402 :             h% dpdfdt(i,j) = vec(4)
     297         2002 :             if (dmp) then
     298              :                do k=1,4
     299              :                   write(*,'(1pd24.16)',advance='no') vec(k)
     300              :                end do
     301              :                write(*,'(A)')
     302              :             end if
     303              :            end do
     304              :           end do
     305              : 
     306              :          !..read the electron chemical potential table
     307         2004 :           do j=1,jmax
     308      5409406 :            do i=1,imax
     309      5407402 :             read(19,'(a)',iostat=ierr) buf
     310      5407402 :             if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     311      5407402 :             if (ierr /= 0 .or. n /= 4) then
     312            0 :                write(*,'(a)') 'failed while reading ' // trim(filename)
     313            0 :                close(19)
     314            0 :                return
     315              :             end if
     316      5407402 :             h% ef(i,j) = vec(1)
     317      5407402 :             h% efd(i,j) = vec(2)
     318      5407402 :             h% eft(i,j) = vec(3)
     319      5407402 :             h% efdt(i,j) = vec(4)
     320         2002 :             if (dmp) then
     321              :                do k=1,4
     322              :                   write(*,'(1pd24.16)',advance='no') vec(k)
     323              :                end do
     324              :                write(*,'(A)')
     325              :             end if
     326              :            end do
     327              :           end do
     328              : 
     329              :          !..read the number density table
     330         2004 :           do j=1,jmax
     331      5409406 :            do i=1,imax
     332      5407402 :             read(19,'(a)',iostat=ierr) buf
     333      5407402 :             if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     334      5407402 :             if (ierr /= 0 .or. n /= 4) then
     335            0 :                write(*,'(a)') 'failed while reading ' // trim(filename)
     336            0 :                close(19)
     337            0 :                return
     338              :             end if
     339      5407402 :             h% xf(i,j) = vec(1)
     340      5407402 :             h% xfd(i,j) = vec(2)
     341      5407402 :             h% xft(i,j) = vec(3)
     342      5407402 :             h% xfdt(i,j) = vec(4)
     343         2002 :             if (dmp) then
     344              :                do k=1,4
     345              :                   write(*,'(1pd24.16)',advance='no') vec(k)
     346              :                end do
     347              :                write(*,'(A)')
     348              :             end if
     349              :            end do
     350              :           end do
     351              : 
     352            2 :           close(unit=19)
     353              :           !..write cachefile
     354              : 
     355              :           if (dmp) call mesa_error(__FILE__,__LINE__,'helm_alloc')
     356              : 
     357            2 :           ios = -1
     358            2 :           if (use_cache) then
     359            1 :             write(filename,'(2a)') trim(cache_dir), '/helm_table.bin'
     360            1 :             write(temp_filename,'(2a)') trim(temp_cache_dir), '/helm_table.bin'
     361            1 :             write(*,*) 'write ', trim(filename)
     362              :             open(unit=19,file=trim(switch_str(temp_filename, filename, use_mesa_temp_cache)),  &
     363            1 :              status='replace', iostat=ios,action='write',form='unformatted')
     364              :           end if
     365              : 
     366            2 :           if (ios == 0) then
     367            1 :              write(19) imax
     368            1 :              write(19) jmax
     369            1 :              write(19) h% f(1:imax,1:jmax)
     370            1 :              write(19) h% fd(1:imax,1:jmax)
     371            1 :              write(19) h% ft(1:imax,1:jmax)
     372            1 :              write(19) h% fdd(1:imax,1:jmax)
     373            1 :              write(19) h% ftt(1:imax,1:jmax)
     374            1 :              write(19) h% fdt(1:imax,1:jmax)
     375            1 :              write(19) h% fddt(1:imax,1:jmax)
     376            1 :              write(19) h% fdtt(1:imax,1:jmax)
     377            1 :              write(19) h% fddtt(1:imax,1:jmax)
     378            1 :              write(19) h% dpdf(1:imax,1:jmax)
     379            1 :              write(19) h% dpdfd(1:imax,1:jmax)
     380            1 :              write(19) h% dpdft(1:imax,1:jmax)
     381            1 :              write(19) h% dpdfdt(1:imax,1:jmax)
     382            1 :              write(19) h% ef(1:imax,1:jmax)
     383            1 :              write(19) h% efd(1:imax,1:jmax)
     384            1 :              write(19) h% eft(1:imax,1:jmax)
     385            1 :              write(19) h% efdt(1:imax,1:jmax)
     386            1 :              write(19) h% xf(1:imax,1:jmax)
     387            1 :              write(19) h% xfd(1:imax,1:jmax)
     388            1 :              write(19) h% xft(1:imax,1:jmax)
     389            1 :              write(19) h% xfdt(1:imax,1:jmax)
     390            1 :              close(unit=19)
     391              : 
     392            1 :              if (use_mesa_temp_cache) call mv(temp_filename,filename,.true.)
     393              : 
     394              :           end if
     395              : 
     396              :        end if
     397              : 
     398           13 :        call setup_td_deltas(h, imax, jmax)
     399              : 
     400           13 :       end subroutine read_helm_table
     401              : 
     402              : 
     403            5 :       subroutine free_helm_table(h)
     404           13 :          use eos_def
     405              : 
     406              :          type (Helm_Table), pointer :: h
     407              : 
     408           10 :          call do_free(h% d)
     409           10 :          call do_free(h% t)
     410              : 
     411           10 :          call do_free2(h% f)
     412           10 :          call do_free2(h% fd)
     413           10 :          call do_free2(h% ft)
     414           10 :          call do_free2(h% fdd)
     415           10 :          call do_free2(h% ftt)
     416           10 :          call do_free2(h% fdt)
     417           10 :          call do_free2(h% fddt)
     418           10 :          call do_free2(h% fdtt)
     419           10 :          call do_free2(h% fddtt)
     420              : 
     421              :          !..for the pressure derivative with density tables
     422           10 :          call do_free2(h% dpdf)
     423           10 :          call do_free2(h% dpdfd)
     424           10 :          call do_free2(h% dpdft)
     425           10 :          call do_free2(h% dpdfdt)
     426              : 
     427              :          !..for chemical potential tables
     428           10 :          call do_free2(h% ef)
     429           10 :          call do_free2(h% efd)
     430           10 :          call do_free2(h% eft)
     431           10 :          call do_free2(h% efdt)
     432              : 
     433              :          !..for the number density tables
     434           10 :          call do_free2(h% xf)
     435           10 :          call do_free2(h% xfd)
     436           10 :          call do_free2(h% xft)
     437           10 :          call do_free2(h% xfdt)
     438              : 
     439              :          !..for storing the differences
     440           10 :          call do_free(h% dt_sav)
     441           10 :          call do_free(h% dt2_sav)
     442           10 :          call do_free(h% dti_sav)
     443           10 :          call do_free(h% dt2i_sav)
     444           10 :          call do_free(h% dt3i_sav)
     445           10 :          call do_free(h% dd_sav)
     446           10 :          call do_free(h% dd2_sav)
     447           10 :          call do_free(h% ddi_sav)
     448           10 :          call do_free(h% dd2i_sav)
     449           10 :          call do_free(h% dd3i_sav)
     450              : 
     451            5 :          deallocate(h)
     452            5 :          nullify(h)
     453              : 
     454              :          contains
     455              : 
     456           60 :          subroutine do_free(array_ptr)
     457              :             real(dp), pointer :: array_ptr(:)
     458           10 :             if (associated(array_ptr)) deallocate(array_ptr)
     459            5 :          end subroutine do_free
     460              : 
     461          105 :          subroutine do_free2(array_ptr)
     462              :             real(dp), pointer :: array_ptr(:,:)
     463            5 :             if (associated(array_ptr)) deallocate(array_ptr)
     464              :          end subroutine do_free2
     465              : 
     466              :       end subroutine free_helm_table
     467              : 
     468              :       end module helm_alloc
        

Generated by: LCOV version 2.0-1