LCOV - code coverage report
Current view: top level - kap/private - kap_eval_support.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.5 % 96 59
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 4 4

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010-2019  The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              :       module kap_eval_support
      21              : 
      22              :       use const_def, only: dp, one_sixth
      23              :       use math_lib
      24              : 
      25              :       implicit none
      26              : 
      27              :       private
      28              :       public :: do_kap_interpolations
      29              :       public :: locate_logT
      30              :       public :: locate_logR
      31              : 
      32              :       contains
      33              : 
      34       520556 :       subroutine locate_log( &
      35              :             rq, num_logs, log_min_in, log_max_in, ili_logs, logs, log_find, i, log0, log1, ierr)
      36              :          use kap_def
      37              :          use utils_lib, only: is_bad
      38              :          use num_lib, only: binary_search
      39              :          type (Kap_General_Info), pointer :: rq
      40              :          integer, intent(in) :: num_logs, ili_logs
      41              :          real(dp), intent(in) :: log_min_in, log_max_in
      42              :          real(dp), intent(in), pointer :: logs(:)  ! (num_logs)
      43              :          real(dp), intent(inout) :: log_find  ! can change log_find if clipping to table boundaries
      44              :          integer, intent(out) :: i  ! index in logs s.t. logs(i) <= log_find < logs(i+1)
      45              :             ! one exception: if log_find == log_max then will get i = num_logs-1
      46              :          real(dp), intent(out) :: log0, log1
      47              :          integer, intent(out) :: ierr
      48       520556 :          real(dp) :: dlog, log_min, log_max
      49              :          integer :: j
      50       520556 :          ierr = 0
      51       520556 :          log_min = max(log_min_in, logs(1))
      52       520556 :          log_max = min(log_max_in, logs(num_logs))
      53       520556 :          if (num_logs == 1) then
      54            0 :             i = 1
      55            0 :             log_find = log_min
      56            0 :             log0 = log_find
      57            0 :             log1 = log_find
      58            0 :             return
      59              :          end if
      60       520556 :          if (log_find < log_min .or. log_find > log_max) then
      61            0 :             if (.not. clip_to_kap_table_boundaries) then
      62            0 :                ierr = -1
      63            0 :                return
      64              :             end if
      65            0 :             if (log_find < log_min) then
      66            0 :                i = 1
      67            0 :                log_find = log_min
      68              :             else
      69            0 :                i = num_logs-1
      70            0 :                log_find = log_max
      71              :             end if
      72       520556 :          else if (abs(log_find-log_max) < 1d-7) then
      73            0 :             i = num_logs-1
      74            0 :             log_find = log_max
      75       520556 :          else if (ili_logs == 1) then  ! logs equally spaced
      76       260278 :             dlog = (log_max-log_min)/(num_logs-1)
      77       260278 :             i = int((log_find-log_min) / dlog) + 1
      78              :             ! might not be exactly evenly spaced, so minor fixup if necessary
      79       260278 :             if (logs(i) > log_find .and. i > 1) then
      80            0 :                i = i-1
      81       260278 :             else if (log_find >= logs(i+1) .and. i+1 < num_logs) then
      82            0 :                i = i+1
      83              :             end if
      84              :          else
      85       260278 :             i = binary_search(num_logs, logs, 0, log_find)
      86       260278 :             if (i >= num_logs) then
      87            0 :                ierr = -1
      88            0 :                return
      89              : !$OMP critical (kap_eval_crit1)
      90              :                write(*,*) 'i', i
      91              :                write(*,*) 'num_logs', num_logs
      92              :                call mesa_error(__FILE__,__LINE__,'locate_log')
      93              : !$OMP end critical (kap_eval_crit1)
      94              :             end if
      95              :          end if
      96              : 
      97       520556 :          if (i < 1 .or. i >= num_logs) then
      98            0 :             ierr = -1
      99            0 :             return
     100              :             write(*,*) 'i', i
     101              :             write(*,*) 'num_logs', num_logs
     102              :             call mesa_error(__FILE__,__LINE__,'locate_log')
     103              :          end if
     104              : 
     105       520556 :          if (logs(i) > log_find .or. log_find > logs(i+1)) then
     106            0 :             ierr = -1
     107            0 : !$OMP critical (kap_eval_crit2)
     108            0 :             write(*,*) 'dlog', (log_max-log_min)/(num_logs-1)
     109            0 :             write(*,*) 'log_max', log_max
     110            0 :             write(*,*) 'log_min', log_min
     111            0 :             write(*,*) 'log_max_in', log_max_in
     112            0 :             write(*,*) 'log_min_in', log_min_in
     113            0 :             write(*,*) 'logs(i)', logs(i)
     114            0 :             write(*,*) 'log_find', log_find
     115            0 :             write(*,*) 'logs(i+1)', logs(i+1)
     116            0 :             write(*,*) 'i', i
     117            0 :             write(*,*) 'num_logs', num_logs
     118            0 :             write(*,*) 'ili_logs', ili_logs
     119              : !$OMP end critical (kap_eval_crit2)
     120            0 :             return
     121              :             call mesa_error(__FILE__,__LINE__,'error in locate_log')
     122              :          end if
     123       520556 :          log0 = logs(i)
     124       520556 :          log1 = logs(i+1)
     125       520556 :          if (is_bad(log0) .or. is_bad(log1)) then
     126            0 :             ierr = -1
     127            0 :             return
     128              : !$OMP critical (kap_eval_crit3)
     129              :             write(*,*) 'logs(i)', logs(i)
     130              :             write(*,*) 'log_find', log_find
     131              :             write(*,*) 'logs(i+1)', logs(i+1)
     132              :             write(*,*) 'i', i
     133              :             write(*,*) 'num_logs', num_logs
     134              :             call mesa_error(__FILE__,__LINE__,'error in locate_log')
     135              : !$OMP end critical (kap_eval_crit3)
     136              :          end if
     137       520556 :       end subroutine locate_log
     138              : 
     139              : 
     140       260278 :       subroutine locate_logT( &
     141              :             rq, num_logTs, logT_min, logT_max, ili_logTs, logTs, logT, iT, logT0, logT1, ierr)
     142       520556 :          use kap_def
     143              :          type (Kap_General_Info), pointer :: rq
     144              :          integer, intent(in) :: num_logTs, ili_logTs
     145              :          real(dp), intent(in) :: logT_min, logT_max
     146              :          real(dp), intent(in), pointer :: logTs(:)  ! (num_logTs)
     147              :          real(dp), intent(inout) :: logT  ! can change logT if clipping to table boundaries
     148              :          integer, intent(out) :: iT  ! index in logTs s.t. logTs(i) <= logT < logTs(i+1)
     149              :          real(dp), intent(out) :: logT0, logT1
     150              :          integer, intent(out) :: ierr
     151              :          call locate_log( &
     152       260278 :             rq, num_logTs, logT_min, logT_max, ili_logTs, logTs, logT, iT, logT0, logT1, ierr)
     153       260278 :       end subroutine locate_logT
     154              : 
     155              : 
     156       260278 :       subroutine locate_logR( &
     157              :             rq, num_logRs, logR_min, logR_max, ili_logRs, logRs, logR, iR, logR0, logR1, ierr)
     158              :          use kap_def
     159              :          type (Kap_General_Info), pointer :: rq
     160              :          integer, intent(in) :: num_logRs, ili_logRs
     161              :          real(dp), intent(in) :: logR_min, logR_max
     162              :          real(dp), intent(in), pointer :: logRs(:)  ! (num_logRs)
     163              :          real(dp), intent(inout) :: logR  ! can change logR if clipping to table boundaries
     164              :          integer, intent(out) :: iR  ! index in logRs s.t. logRs(i) <= logR < logRs(i+1)
     165              :          real(dp), intent(out) :: logR0, logR1
     166              :          integer, intent(out) :: ierr
     167              :          call locate_log( &
     168       260278 :             rq, num_logRs, logR_min, logR_max, ili_logRs, logRs, logR, iR, logR0, logR1, ierr)
     169       260278 :       end subroutine locate_logR
     170              : 
     171              : 
     172       432710 :       subroutine do_kap_interpolations( &
     173              :             fin1, nx, ny, i, j, x0, xget, x1, y0, yget, y1, fval, df_dx, df_dy)
     174              :          ! derived from routines in the PSPLINE package written by Doug McCune
     175              : 
     176              :          real(dp), dimension(:), pointer :: fin1  ! the spline data array, dimensions (4, nx, ny)
     177              :          integer, intent(in) :: nx, ny, i, j           ! target cell in the spline data
     178              :          real(dp), intent(in) :: x0, xget, x1      ! x0 <= xget <= x1;  x0 = xs(i), x1 = xs(i+1)
     179              :          real(dp), intent(in) :: y0, yget, y1      ! y0 <= yget <= y1;  y0 = ys(j), y1 = ys(j+1)
     180              :          real(dp), intent(out) :: fval, df_dx, df_dy
     181              : 
     182              :          real(dp), parameter :: z36th = 1d0 / 36d0
     183              : 
     184       432710 :          real(dp), pointer :: fin(:,:,:)
     185              : 
     186       432710 :          real(dp) :: xp, xpi, xp2, xpi2, cx, cxi, hx2, cxd, cxdi, hx, hxi
     187       432710 :          real(dp) :: yp, ypi, yp2, ypi2, cy, cyi, hy2, cyd, cydi, hy, hyi
     188              : 
     189              :          logical, parameter :: dbg = .false.
     190              : 
     191              :          include 'formats'
     192              : 
     193       432710 :          fin(1:4,1:nx,1:ny) => fin1(1:4*nx*ny)
     194              : 
     195       432710 :          hx=x1-x0
     196       432710 :          hxi=1d0/hx
     197       432710 :          hx2=hx*hx
     198              : 
     199       432710 :          xp=(xget-x0)*hxi
     200       432710 :          xpi=1d0-xp
     201       432710 :          xp2=xp*xp
     202       432710 :          xpi2=xpi*xpi
     203              : 
     204       432710 :          cx=xp*(xp2-1d0)
     205       432710 :          cxi=xpi*(xpi2-1d0)
     206       432710 :          cxd=3d0*xp2-1d0
     207       432710 :          cxdi=-3d0*xpi2+1d0
     208              : 
     209       432710 :          hy=y1-y0
     210       432710 :          hyi=1d0/hy
     211       432710 :          hy2=hy*hy
     212              : 
     213       432710 :          yp=(yget-y0)*hyi
     214       432710 :          ypi=1d0-yp
     215       432710 :          yp2=yp*yp
     216       432710 :          ypi2=ypi*ypi
     217              : 
     218       432710 :          cy=yp*(yp2-1d0)
     219       432710 :          cyi=ypi*(ypi2-1d0)
     220       432710 :          cyd=3d0*yp2-1d0
     221       432710 :          cydi=-3d0*ypi2+1d0
     222              : 
     223              :          ! bicubic spline interpolation
     224              :          fval = &
     225              :             xpi*(ypi*fin(1,i,j)  +yp*fin(1,i,j+1)) &
     226              :             +xp*(ypi*fin(1,i+1,j)+yp*fin(1,i+1,j+1)) &
     227              :             +one_sixth*hx2*( &
     228              :                cxi*(ypi*fin(2,i,j) +yp*fin(2,i,j+1))+ &
     229              :                cx*(ypi*fin(2,i+1,j)+yp*fin(2,i+1,j+1))) &
     230              :             +one_sixth*hy2*( &
     231              :                xpi*(cyi*fin(3,i,j) +cy*fin(3,i,j+1))+ &
     232              :                xp*(cyi*fin(3,i+1,j)+cy*fin(3,i+1,j+1))) &
     233              :             +z36th*hx2*hy2*( &
     234              :                cxi*(cyi*fin(4,i,j) +cy*fin(4,i,j+1))+ &
     235       432710 :                cx*(cyi*fin(4,i+1,j)+cy*fin(4,i+1,j+1)))
     236              : 
     237              :          if (.false.) then
     238              :             write(*,3) 'fin(1,i,j)', i, j, fin(1,i,j)
     239              :             write(*,3) 'fin(1,i,j+1)', i, j+1, fin(1,i,j+1)
     240              :             write(*,3) 'fin(1,i+1,j)', i+1, j, fin(1,i+1,j)
     241              :             write(*,3) 'fin(1,i+1,j+1)', i+1, j+1, fin(1,i+1,j+1)
     242              :             write(*,3) 'fin(2,i,j)', i, j, fin(2,i,j)
     243              :             write(*,3) 'fin(2,i,j+1)', i, j+1, fin(2,i,j+1)
     244              :             write(*,3) 'fin(2,i+1,j)', i+1, j, fin(2,i+1,j)
     245              :             write(*,3) 'fin(2,i+1,j+1)', i+1, j+1, fin(2,i+1,j+1)
     246              :             write(*,3) 'fin(3,i,j)', i, j, fin(3,i,j)
     247              :             write(*,3) 'fin(3,i,j+1)', i, j+1, fin(3,i,j+1)
     248              :             write(*,3) 'fin(3,i+1,j)', i+1, j, fin(3,i+1,j)
     249              :             write(*,3) 'fin(3,i+1,j+1)', i+1, j+1, fin(3,i+1,j+1)
     250              :             write(*,3) 'fin(4,i,j)', i, j, fin(4,i,j)
     251              :             write(*,3) 'fin(4,i,j+1)', i, j+1, fin(4,i,j+1)
     252              :             write(*,3) 'fin(4,i+1,j)', i+1, j, fin(4,i+1,j)
     253              :             write(*,3) 'fin(4,i+1,j+1)', i+1, j+1, fin(4,i+1,j+1)
     254              :             write(*,1) 'ypi', ypi
     255              :             write(*,1) 'yp', yp
     256              :             write(*,1) 'xp', xp
     257              :             write(*,1) 'yp', yp
     258              :             write(*,1) 'hx2', hx2
     259              :             write(*,1) 'cxi', cxi
     260              :             write(*,1) 'cx', cx
     261              :             write(*,1) 'hy2', hy2
     262              :             write(*,1) 'cy', cy
     263              :             write(*,1) 'cyi', cyi
     264              :             write(*,1) 'one_sixth', one_sixth
     265              :             write(*,1) 'z36th', z36th
     266              :             write(*,1) 't1', xpi*(ypi*fin(1,i,j)  +yp*fin(1,i,j+1))
     267              :             write(*,1) 't2', xp*(ypi*fin(1,i+1,j)+yp*fin(1,i+1,j+1))
     268              :             write(*,1) 't3', one_sixth*hx2*( &
     269              :                cxi*(ypi*fin(2,i,j) +yp*fin(2,i,j+1))+ &
     270              :                cx*(ypi*fin(2,i+1,j)+yp*fin(2,i+1,j+1)))
     271              :             write(*,1) 't4', one_sixth*hy2*( &
     272              :                xpi*(cyi*fin(3,i,j) +cy*fin(3,i,j+1))+ &
     273              :                xp*(cyi*fin(3,i+1,j)+cy*fin(3,i+1,j+1)))
     274              :             write(*,1) 't5', z36th*hx2*hy2*( &
     275              :                cxi*(cyi*fin(4,i,j) +cy*fin(4,i,j+1))+ &
     276              :                cx*(cyi*fin(4,i+1,j)+cy*fin(4,i+1,j+1)))
     277              :             write(*,1) 'fval', fval
     278              :          end if
     279              : 
     280              :          ! derivatives of bicubic splines
     281              :          df_dx = &
     282              :             hxi*( &
     283              :                -(ypi*fin(1,i,j)  +yp*fin(1,i,j+1)) &
     284              :                +(ypi*fin(1,i+1,j)+yp*fin(1,i+1,j+1))) &
     285              :             +one_sixth*hx*( &
     286              :                cxdi*(ypi*fin(2,i,j) +yp*fin(2,i,j+1))+ &
     287              :                cxd*(ypi*fin(2,i+1,j)+yp*fin(2,i+1,j+1))) &
     288              :             +one_sixth*hxi*hy2*( &
     289              :                -(cyi*fin(3,i,j)  +cy*fin(3,i,j+1)) &
     290              :                +(cyi*fin(3,i+1,j)+cy*fin(3,i+1,j+1))) &
     291              :             +z36th*hx*hy2*( &
     292              :                cxdi*(cyi*fin(4,i,j) +cy*fin(4,i,j+1))+ &
     293       432710 :                cxd*(cyi*fin(4,i+1,j)+cy*fin(4,i+1,j+1)))
     294              : 
     295              :          df_dy = &
     296              :             hyi*( &
     297              :                xpi*(-fin(1,i,j) +fin(1,i,j+1))+ &
     298              :                xp*(-fin(1,i+1,j)+fin(1,i+1,j+1))) &
     299              :             +one_sixth*hx2*hyi*( &
     300              :                cxi*(-fin(2,i,j) +fin(2,i,j+1))+ &
     301              :                cx*(-fin(2,i+1,j)+fin(2,i+1,j+1))) &
     302              :             +one_sixth*hy*( &
     303              :                xpi*(cydi*fin(3,i,j) +cyd*fin(3,i,j+1))+ &
     304              :                xp*(cydi*fin(3,i+1,j)+cyd*fin(3,i+1,j+1))) &
     305              :             +z36th*hx2*hy*( &
     306              :                cxi*(cydi*fin(4,i,j) +cyd*fin(4,i,j+1))+ &
     307       432710 :                cx*(cydi*fin(4,i+1,j)+cyd*fin(4,i+1,j+1)))
     308              : 
     309       432710 :       end subroutine do_kap_interpolations
     310              : 
     311              :       end module kap_eval_support
        

Generated by: LCOV version 2.0-1