LCOV - code coverage report
Current view: top level - eos/private - helm_alloc.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.1 % 271 255
Test Date: 2026-01-06 18:03:11 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            6 :       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            6 :          allocate(h,stat=ierr)
      42            6 :          if (ierr /= 0) return
      43              : 
      44            6 :          h% imax = imax
      45            6 :          h% jmax = jmax
      46            6 :          h% with_coulomb_corrections = .true.
      47              : 
      48            6 :          call alloc_1d_array(h% d, imax)
      49            6 :          call alloc_1d_array(h% t, jmax)
      50              : 
      51              :          !..for the helmholtz free energy tables
      52            6 :          call alloc_2d_array(h% f, imax, jmax)
      53            6 :          call alloc_2d_array(h% fd, imax, jmax)
      54            6 :          call alloc_2d_array(h% ft, imax, jmax)
      55            6 :          call alloc_2d_array(h% fdd, imax, jmax)
      56            6 :          call alloc_2d_array(h% ftt, imax, jmax)
      57            6 :          call alloc_2d_array(h% fdt, imax, jmax)
      58            6 :          call alloc_2d_array(h% fddt, imax, jmax)
      59            6 :          call alloc_2d_array(h% fdtt, imax, jmax)
      60            6 :          call alloc_2d_array(h% fddtt, imax, jmax)
      61              : 
      62              :          !..for the pressure derivative with density tables
      63            6 :          call alloc_2d_array(h% dpdf, imax, jmax)
      64            6 :          call alloc_2d_array(h% dpdfd, imax, jmax)
      65            6 :          call alloc_2d_array(h% dpdft, imax, jmax)
      66            6 :          call alloc_2d_array(h% dpdfdt, imax, jmax)
      67              : 
      68              :          !..for chemical potential tables
      69            6 :          call alloc_2d_array(h% ef, imax, jmax)
      70            6 :          call alloc_2d_array(h% efd, imax, jmax)
      71            6 :          call alloc_2d_array(h% eft, imax, jmax)
      72            6 :          call alloc_2d_array(h% efdt, imax, jmax)
      73              : 
      74              :          !..for the number density tables
      75            6 :          call alloc_2d_array(h% xf, imax, jmax)
      76            6 :          call alloc_2d_array(h% xfd, imax, jmax)
      77            6 :          call alloc_2d_array(h% xft, imax, jmax)
      78            6 :          call alloc_2d_array(h% xfdt, imax, jmax)
      79              : 
      80              :          !..for storing the differences
      81            6 :          call alloc_1d_array(h% dt_sav, jmax)
      82            6 :          call alloc_1d_array(h% dt2_sav, jmax)
      83            6 :          call alloc_1d_array(h% dti_sav, jmax)
      84            6 :          call alloc_1d_array(h% dt2i_sav, jmax)
      85            6 :          call alloc_1d_array(h% dt3i_sav, jmax)
      86              : 
      87            6 :          call alloc_1d_array(h% dd_sav, imax)
      88            6 :          call alloc_1d_array(h% dd2_sav, imax)
      89            6 :          call alloc_1d_array(h% ddi_sav, imax)
      90            6 :          call alloc_1d_array(h% dd2i_sav, imax)
      91            6 :          call alloc_1d_array(h% dd3i_sav, imax)
      92              : 
      93              :          contains
      94              : 
      95           72 :          subroutine alloc_1d_array(ptr,sz)
      96              :             real(dp), dimension(:), pointer :: ptr
      97              :             integer, intent(in) :: sz
      98           72 :             allocate(ptr(sz),stat=ierr)
      99            6 :          end subroutine alloc_1d_array
     100              : 
     101          126 :          subroutine alloc_2d_array(ptr,sz1,sz2)
     102              :             real(dp), dimension(:,:), pointer :: ptr
     103              :             integer, intent(in) :: sz1,sz2
     104          252 :             allocate(ptr(sz1,sz2),stat=ierr)
     105          126 :          end subroutine alloc_2d_array
     106              : 
     107              : 
     108              :       end subroutine alloc_helm_table
     109              : 
     110              : 
     111            6 :       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              :          real(dp) :: dth,dt2,dti,dt2i,dt3i,dd,dd2,ddi,dd2i,dd3i
     117              :          !..construct the temperature and density deltas and their inverses
     118         6006 :          do j=1,jmax-1
     119         6000 :             dth         = h% t(j+1) - h% t(j)
     120         6000 :             dt2         = dth * dth
     121         6000 :             dti         = 1.0d0/dth
     122         6000 :             dt2i        = 1.0d0/dt2
     123         6000 :             dt3i        = dt2i*dti
     124         6000 :             h% dt_sav(j)   = dth
     125         6000 :             h% dt2_sav(j)  = dt2
     126         6000 :             h% dti_sav(j)  = dti
     127         6000 :             h% dt2i_sav(j) = dt2i
     128         6006 :             h% dt3i_sav(j) = dt3i
     129              :          end do
     130        16206 :          do i=1,imax-1
     131        16200 :             dd          = h% d(i+1) - h% d(i)
     132        16200 :             dd2         = dd * dd
     133        16200 :             ddi         = 1.0d0/dd
     134        16200 :             dd2i        = 1.0d0/dd2
     135        16200 :             dd3i        = dd2i*ddi
     136        16200 :             h% dd_sav(i)   = dd
     137        16200 :             h% dd2_sav(i)  = dd2
     138        16200 :             h% ddi_sav(i)  = ddi
     139        16200 :             h% dd2i_sav(i) = dd2i
     140        16206 :             h% dd3i_sav(i) = dd3i
     141              :          end do
     142            6 :       end subroutine setup_td_deltas
     143              : 
     144              : 
     145            6 :       subroutine read_helm_table(h, data_dir, cache_dir, temp_cache_dir, use_cache, ierr)
     146            6 :       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              :       real(dp), target :: vec_ary(20)
     163              :       real(dp), pointer :: vec(:)
     164              :       integer          :: i,j,k,ios,imax,jmax,n
     165              :       real(dp) :: tsav,dsav
     166              :       logical, parameter :: dmp = .false.
     167              : 
     168            6 :        ierr = 0
     169            6 :        vec => vec_ary
     170              : 
     171              : !..read the normal helmholtz free energy table
     172            6 :        h% logtlo   = 3.0d0
     173            6 :        h% logthi   = 13.0d0
     174            6 :        h% logdlo   = -12.0d0
     175            6 :        h% logdhi   = 15.0d0
     176              : 
     177            6 :        h% templo = exp10(h% logtlo)
     178            6 :        h% temphi = exp10(h% logthi)
     179            6 :        h% denlo = exp10(h% logdlo)
     180            6 :        h% denhi = exp10(h% logdhi)
     181              : 
     182            6 :        imax = h% imax
     183            6 :        jmax = h% jmax
     184            6 :        h% logtstp  = (h% logthi - h% logtlo)/real(jmax-1,kind=dp)
     185            6 :        h% logtstpi = 1.0d0/h% logtstp
     186            6 :        h% logdstp  = (h% logdhi - h% logdlo)/real(imax-1,kind=dp)
     187            6 :        h% logdstpi = 1.0d0/h% logdstp
     188              : 
     189            6 :        ios = -1
     190            6 :        if (use_cache) then
     191            5 :          write(filename,'(2a)') trim(cache_dir), '/helm_table.bin'
     192              :          open(unit=19,file=trim(filename), &
     193            5 :                action='read',status='old',iostat=ios,form='unformatted')
     194              :        end if
     195              : 
     196            6 :        if (ios == 0) then
     197              : 
     198            1 :           read(19) imax
     199            1 :           read(19) jmax
     200              : 
     201            1 :          if (imax /= h% imax .or. jmax /= h% jmax) then
     202            0 :             ios = 1  ! wrong cached info
     203              :          else
     204            1 :              read(19) h% f(1:imax,1:jmax)
     205            1 :              read(19) h% fd(1:imax,1:jmax)
     206            1 :              read(19) h% ft(1:imax,1:jmax)
     207            1 :              read(19) h% fdd(1:imax,1:jmax)
     208            1 :              read(19) h% ftt(1:imax,1:jmax)
     209            1 :              read(19) h% fdt(1:imax,1:jmax)
     210            1 :              read(19) h% fddt(1:imax,1:jmax)
     211            1 :              read(19) h% fdtt(1:imax,1:jmax)
     212            1 :              read(19) h% fddtt(1:imax,1:jmax)
     213            1 :              read(19) h% dpdf(1:imax,1:jmax)
     214            1 :              read(19) h% dpdfd(1:imax,1:jmax)
     215            1 :              read(19) h% dpdft(1:imax,1:jmax)
     216            1 :              read(19) h% dpdfdt(1:imax,1:jmax)
     217            1 :              read(19) h% ef(1:imax,1:jmax)
     218            1 :              read(19) h% efd(1:imax,1:jmax)
     219            1 :              read(19) h% eft(1:imax,1:jmax)
     220            1 :              read(19) h% efdt(1:imax,1:jmax)
     221            1 :              read(19) h% xf(1:imax,1:jmax)
     222            1 :              read(19) h% xfd(1:imax,1:jmax)
     223            1 :              read(19) h% xft(1:imax,1:jmax)
     224            1 :              read(19) h% xfdt(1:imax,1:jmax)
     225              : 
     226         1002 :             do j=1,jmax
     227         1001 :                tsav = h% logtlo + (j-1)*h% logtstp
     228         1002 :                h% t(j) = exp10(tsav)
     229              :             end do
     230         2702 :             do i=1,imax
     231         2701 :                dsav = h% logdlo + (i-1)*h% logdstp
     232         2702 :                h% d(i) = exp10(dsav)
     233              :             end do
     234              :          end if
     235              : 
     236            1 :          close(unit=19)
     237              :        end if
     238              : 
     239            6 :        if (ios /= 0) then
     240              : 
     241            5 :           write(filename,'(2a)') trim(data_dir), '/helm_table.dat'
     242            5 :           write(*,*) 'read  ', trim(filename)
     243              : 
     244            5 :           ios = 0
     245            5 :           open(unit=19,file=trim(filename),action='read',status='old',iostat=ios)
     246            5 :           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         5010 :           do j=1,jmax
     253         5005 :             tsav = h% logtlo + (j-1)*h% logtstp
     254         5005 :             h% t(j) = exp10(tsav)
     255     13523515 :             do i=1,imax
     256     13518505 :                dsav = h% logdlo + (i-1)*h% logdstp
     257     13518505 :                h% d(i) = exp10(dsav)
     258     13518505 :                read(19,'(a)',iostat=ierr) buf
     259     13518505 :                if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     260     13518505 :                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     13518505 :                h% f(i,j) = vec(1)
     266     13518505 :                h% fd(i,j) = vec(2)
     267     13518505 :                h% ft(i,j) = vec(3)
     268     13518505 :                h% fdd(i,j) = vec(4)
     269     13518505 :                h% ftt(i,j) = vec(5)
     270     13518505 :                h% fdt(i,j) = vec(6)
     271     13518505 :                h% fddt(i,j) = vec(7)
     272     13518505 :                h% fdtt(i,j) = vec(8)
     273     13518505 :                h% fddtt(i,j) = vec(9)
     274         5005 :                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         5010 :           do j=1,jmax
     285     13523515 :            do i=1,imax
     286     13518505 :             read(19,'(a)',iostat=ierr) buf
     287     13518505 :             if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     288     13518505 :             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     13518505 :             h% dpdf(i,j) = vec(1)
     294     13518505 :             h% dpdfd(i,j) = vec(2)
     295     13518505 :             h% dpdft(i,j) = vec(3)
     296     13518505 :             h% dpdfdt(i,j) = vec(4)
     297         5005 :             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         5010 :           do j=1,jmax
     308     13523515 :            do i=1,imax
     309     13518505 :             read(19,'(a)',iostat=ierr) buf
     310     13518505 :             if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     311     13518505 :             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     13518505 :             h% ef(i,j) = vec(1)
     317     13518505 :             h% efd(i,j) = vec(2)
     318     13518505 :             h% eft(i,j) = vec(3)
     319     13518505 :             h% efdt(i,j) = vec(4)
     320         5005 :             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         5010 :           do j=1,jmax
     331     13523515 :            do i=1,imax
     332     13518505 :             read(19,'(a)',iostat=ierr) buf
     333     13518505 :             if (ierr == 0) call str_to_vector(buf, vec, n, ierr)
     334     13518505 :             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     13518505 :             h% xf(i,j) = vec(1)
     340     13518505 :             h% xfd(i,j) = vec(2)
     341     13518505 :             h% xft(i,j) = vec(3)
     342     13518505 :             h% xfdt(i,j) = vec(4)
     343         5005 :             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            5 :           close(unit=19)
     353              :           !..write cachefile
     354              : 
     355              :           if (dmp) call mesa_error(__FILE__,__LINE__,'helm_alloc')
     356              : 
     357            5 :           ios = -1
     358            5 :           if (use_cache) then
     359            4 :             write(filename,'(2a)') trim(cache_dir), '/helm_table.bin'
     360            4 :             write(temp_filename,'(2a)') trim(temp_cache_dir), '/helm_table.bin'
     361            4 :             write(*,*) 'write ', trim(filename)
     362              :             open(unit=19,file=trim(switch_str(temp_filename, filename, use_mesa_temp_cache)),  &
     363            4 :              status='replace', iostat=ios,action='write',form='unformatted')
     364              :           end if
     365              : 
     366            5 :           if (ios == 0) then
     367            4 :              write(19) imax
     368            4 :              write(19) jmax
     369            4 :              write(19) h% f(1:imax,1:jmax)
     370            4 :              write(19) h% fd(1:imax,1:jmax)
     371            4 :              write(19) h% ft(1:imax,1:jmax)
     372            4 :              write(19) h% fdd(1:imax,1:jmax)
     373            4 :              write(19) h% ftt(1:imax,1:jmax)
     374            4 :              write(19) h% fdt(1:imax,1:jmax)
     375            4 :              write(19) h% fddt(1:imax,1:jmax)
     376            4 :              write(19) h% fdtt(1:imax,1:jmax)
     377            4 :              write(19) h% fddtt(1:imax,1:jmax)
     378            4 :              write(19) h% dpdf(1:imax,1:jmax)
     379            4 :              write(19) h% dpdfd(1:imax,1:jmax)
     380            4 :              write(19) h% dpdft(1:imax,1:jmax)
     381            4 :              write(19) h% dpdfdt(1:imax,1:jmax)
     382            4 :              write(19) h% ef(1:imax,1:jmax)
     383            4 :              write(19) h% efd(1:imax,1:jmax)
     384            4 :              write(19) h% eft(1:imax,1:jmax)
     385            4 :              write(19) h% efdt(1:imax,1:jmax)
     386            4 :              write(19) h% xf(1:imax,1:jmax)
     387            4 :              write(19) h% xfd(1:imax,1:jmax)
     388            4 :              write(19) h% xft(1:imax,1:jmax)
     389            4 :              write(19) h% xfdt(1:imax,1:jmax)
     390            4 :              close(unit=19)
     391              : 
     392            4 :              if (use_mesa_temp_cache) call mv(temp_filename,filename,.true.)
     393              : 
     394              :           end if
     395              : 
     396              :        end if
     397              : 
     398            6 :        call setup_td_deltas(h, imax, jmax)
     399              : 
     400            6 :       end subroutine read_helm_table
     401              : 
     402              : 
     403            2 :       subroutine free_helm_table(h)
     404            6 :          use eos_def
     405              : 
     406              :          type (Helm_Table), pointer :: h
     407              : 
     408            4 :          call do_free(h% d)
     409            4 :          call do_free(h% t)
     410              : 
     411            4 :          call do_free2(h% f)
     412            4 :          call do_free2(h% fd)
     413            4 :          call do_free2(h% ft)
     414            4 :          call do_free2(h% fdd)
     415            4 :          call do_free2(h% ftt)
     416            4 :          call do_free2(h% fdt)
     417            4 :          call do_free2(h% fddt)
     418            4 :          call do_free2(h% fdtt)
     419            4 :          call do_free2(h% fddtt)
     420              : 
     421              :          !..for the pressure derivative with density tables
     422            4 :          call do_free2(h% dpdf)
     423            4 :          call do_free2(h% dpdfd)
     424            4 :          call do_free2(h% dpdft)
     425            4 :          call do_free2(h% dpdfdt)
     426              : 
     427              :          !..for chemical potential tables
     428            4 :          call do_free2(h% ef)
     429            4 :          call do_free2(h% efd)
     430            4 :          call do_free2(h% eft)
     431            4 :          call do_free2(h% efdt)
     432              : 
     433              :          !..for the number density tables
     434            4 :          call do_free2(h% xf)
     435            4 :          call do_free2(h% xfd)
     436            4 :          call do_free2(h% xft)
     437            4 :          call do_free2(h% xfdt)
     438              : 
     439              :          !..for storing the differences
     440            4 :          call do_free(h% dt_sav)
     441            4 :          call do_free(h% dt2_sav)
     442            4 :          call do_free(h% dti_sav)
     443            4 :          call do_free(h% dt2i_sav)
     444            4 :          call do_free(h% dt3i_sav)
     445            4 :          call do_free(h% dd_sav)
     446            4 :          call do_free(h% dd2_sav)
     447            4 :          call do_free(h% ddi_sav)
     448            4 :          call do_free(h% dd2i_sav)
     449            4 :          call do_free(h% dd3i_sav)
     450              : 
     451            2 :          deallocate(h)
     452            2 :          nullify(h)
     453              : 
     454              :          contains
     455              : 
     456           24 :          subroutine do_free(array_ptr)
     457              :             real(dp), pointer :: array_ptr(:)
     458            4 :             if (associated(array_ptr)) deallocate(array_ptr)
     459            2 :          end subroutine do_free
     460              : 
     461           42 :          subroutine do_free2(array_ptr)
     462              :             real(dp), pointer :: array_ptr(:,:)
     463            2 :             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