LCOV - code coverage report
Current view: top level - interp_1d/private - interp_1d_misc.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 34.2 % 301 103
Test Date: 2025-05-08 18:23:42 Functions: 44.4 % 18 8

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2010  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 interp_1d_misc
      21              : 
      22              :       use const_def, only: dp
      23              :       use auto_diff
      24              : 
      25              :       implicit none
      26              : 
      27              :       contains
      28              : 
      29            2 :       subroutine do_integrate_values(init_x, nx, f1, nv, x, vals, ierr)
      30              :          real(dp), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
      31              :          integer, intent(in) :: nx  ! length of init_x vector
      32              :          real(dp), intent(in), pointer :: f1(:)  ! =(4, nx)  ! data & interpolation coefficients
      33              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
      34              :          real(dp), intent(in) :: x(:)  ! (nv)
      35              :             ! strictly monotonic in same way as init_x
      36              :          real(dp), intent(inout) :: vals(:)  ! (nv)
      37              :             ! for i > 1, vals(i) = integral of interpolating poly from x(i-1) to x(i)
      38              :             ! vals(1) = 0
      39              :          integer, intent(out) :: ierr  ! 0 means aok
      40              : 
      41              :          integer :: k_old, k_new
      42            2 :          real(dp) :: xk_old, xkp1_old, xk_new, xk_prev, sum
      43              :          logical :: increasing
      44              :          real(dp), pointer :: f(:,:)  ! (4, nx)  ! data & interpolation coefficients
      45            2 :          f(1:4,1:nx) => f1(1:4*nx)
      46              : 
      47            2 :          increasing = (init_x(1) < init_x(nx))
      48              : 
      49              :          if (increasing .and. (x(1) < init_x(1) .or. x(nv) > init_x(nx)) &
      50            2 :              .or. ((.not. increasing) .and. (x(1) > init_x(1) .or. x(nv) < init_x(nx)))) then
      51            0 :             ierr = -1
      52            0 :             return
      53              :          end if
      54              : 
      55            2 :          ierr = 0
      56              : 
      57            2 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
      58            2 :          sum = 0; xk_prev = x(1); vals(1) = 0
      59              : 
      60           14 :          do k_new = 2, nv
      61              : 
      62           12 :             xk_new = x(k_new)
      63           74 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
      64           62 :                k_old = k_old + 1
      65           62 :                if (k_old >= nx) then
      66            0 :                   k_old = k_old - 1
      67            0 :                   xk_new = xkp1_old
      68            0 :                   exit
      69              :                end if
      70           62 :                call add_to_integral(k_old - 1, xkp1_old)
      71           62 :                xk_old = xkp1_old
      72           68 :                xkp1_old = init_x(k_old+1)
      73              :             end do
      74              : 
      75           12 :             call add_to_integral(k_old, xk_new)
      76           12 :             vals(k_new) = sum
      77           14 :             sum = 0
      78              : 
      79              :          end do
      80              : 
      81              :          contains
      82              : 
      83           74 :          subroutine add_to_integral(k, x2)
      84              :             integer, intent(in) :: k
      85              :             real(dp), intent(in) :: x2
      86              : 
      87           74 :             real(dp) :: x0, x1, a1, a2, d1, d2, area
      88              : 
      89           74 :             x0 = init_x(k)
      90           74 :             x1 = xk_prev
      91           74 :             if (x1 == x2) return
      92           74 :             d2 = x2 - x0
      93              :             a2 = d2*(f(1, k) + d2*(f(2, k)/2  &
      94           74 :                      + d2*(f(3, k)/3 + d2*f(4, k)/4)))
      95           74 :             if (x1 > x0) then
      96            5 :                d1 = x1 - x0
      97              :                a1 = d1*(f(1, k) + d1*(f(2, k)/2  &
      98            5 :                            + d1*(f(3, k)/3 + d1*f(4, k)/4)))
      99            5 :                area = a2 - a1
     100              :             else
     101           74 :                d1 = 0; a1 = 0; area = a2
     102              :             end if
     103           74 :             sum = sum + area
     104           74 :             xk_prev = x2
     105              : 
     106              :          end subroutine add_to_integral
     107              : 
     108              : 
     109              :       end subroutine do_integrate_values
     110              : 
     111              : 
     112         6337 :       subroutine do_interp_values(init_x, nx, f1, nv, x, vals, ierr)
     113              :          real(dp), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
     114              :          integer, intent(in) :: nx  ! length of init_x vector
     115              :          real(dp), intent(in), pointer :: f1(:)  ! =(4, nx)  ! data & interpolation coefficients
     116              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
     117              :          real(dp), intent(in) :: x(:)  ! (nv)  ! locations where want interpolated values
     118              :             ! strictly monotonic in same way as init_x
     119              :             ! values out of range of init_x's are clipped to boundaries of init_x's
     120              :          real(dp), intent(inout) :: vals(:)  ! (nv)
     121              :          integer, intent(out) :: ierr  ! 0 means aok
     122              : 
     123              :          integer :: k_old, k_new
     124         6337 :          real(dp) :: xk_old, xkp1_old, xk_new, delta
     125              :          logical :: increasing
     126         6337 :          real(dp), pointer :: f(:,:)  ! (4, nx)  ! data & interpolation coefficients
     127              : 
     128         6337 :          ierr = 0
     129              : 
     130         6337 :          if (nx == 1) then
     131            0 :             vals(1:nv) = f1(1)
     132              :             return
     133              :          end if
     134              : 
     135         6337 :          f(1:4,1:nx) => f1(1:4*nx)
     136              : 
     137         6337 :          increasing = (init_x(1) < init_x(nx))
     138              : 
     139         6337 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
     140              : 
     141        20557 :          do k_new = 1, nv
     142              : 
     143        14220 :             xk_new = x(k_new)
     144        14220 :             if (increasing) then
     145        14204 :                if (xk_new > init_x(nx)) then
     146        14220 :                   xk_new = init_x(nx)
     147        14200 :                else if (xk_new < init_x(1)) then
     148        14220 :                   xk_new = init_x(1)
     149              :                end if
     150              :             else  ! decreasing
     151           16 :                if (xk_new < init_x(nx)) then
     152              :                   xk_new = init_x(nx)
     153           16 :                else if (xk_new > init_x(1)) then
     154        14220 :                   xk_new = init_x(1)
     155              :                end if
     156              :             end if
     157        67151 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
     158        52931 :                k_old = k_old + 1
     159        52931 :                if (k_old >= nx) then
     160              :                   k_old = k_old - 1
     161              :                   xk_new = xkp1_old
     162              :                   exit
     163              :                end if
     164        52931 :                xk_old = xkp1_old
     165        52947 :                xkp1_old = init_x(k_old+1)
     166              :             end do
     167              : 
     168        14220 :             delta = xk_new - xk_old
     169              : 
     170              :             vals(k_new) =  &
     171              :                   f(1, k_old) + delta*(f(2, k_old)  &
     172        20557 :                      + delta*(f(3, k_old) + delta*f(4, k_old)))
     173              : 
     174              :          end do
     175              : 
     176              : 
     177         6337 :       end subroutine do_interp_values
     178              : 
     179            0 :       subroutine do_interp_values_autodiff(init_x, nx, f1, nv, x, vals, ierr)
     180              :          type(auto_diff_real_2var_order1), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
     181              :          integer, intent(in) :: nx  ! length of init_x vector
     182              :          type(auto_diff_real_2var_order1), intent(in), pointer :: f1(:)  ! =(4, nx)  ! data & interpolation coefficients
     183              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
     184              :          type(auto_diff_real_2var_order1), intent(in) :: x(:)  ! (nv)  ! locations where want interpolated values
     185              :             ! strictly monotonic in same way as init_x
     186              :             ! values out of range of init_x's are clipped to boundaries of init_x's
     187              :          type(auto_diff_real_2var_order1), intent(inout) :: vals(:)  ! (nv)
     188              :          integer, intent(out) :: ierr  ! 0 means aok
     189              : 
     190              :          integer :: k_old, k_new
     191              :          type(auto_diff_real_2var_order1) :: xk_old, xkp1_old, xk_new, delta
     192              :          logical :: increasing
     193            0 :          type(auto_diff_real_2var_order1), pointer :: f(:,:)  ! (4, nx)  ! data & interpolation coefficients
     194              : 
     195            0 :          ierr = 0
     196              : 
     197            0 :          if (nx == 1) then
     198            0 :             vals(1:nv) = f1(1)
     199            0 :             return
     200              :          end if
     201              : 
     202            0 :          f(1:4,1:nx) => f1(1:4*nx)
     203              : 
     204            0 :          if(init_x(1) < init_x(nx)) then
     205              :             increasing = .true.
     206              :          end if
     207              : 
     208            0 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
     209              : 
     210            0 :          do k_new = 1, nv
     211              : 
     212            0 :             xk_new = x(k_new)
     213              :             if (increasing) then
     214            0 :                if (xk_new > init_x(nx)) then
     215            0 :                   xk_new = init_x(nx)
     216            0 :                else if (xk_new < init_x(1)) then
     217            0 :                   xk_new = init_x(1)
     218              :                end if
     219              :             else  ! decreasing
     220              :                if (xk_new < init_x(nx)) then
     221              :                   xk_new = init_x(nx)
     222              :                else if (xk_new > init_x(1)) then
     223              :                   xk_new = init_x(1)
     224              :                end if
     225              :             end if
     226            0 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
     227            0 :                k_old = k_old + 1
     228            0 :                if (k_old >= nx) then
     229            0 :                   k_old = k_old - 1
     230            0 :                   xk_new = xkp1_old
     231            0 :                   exit
     232              :                end if
     233            0 :                xk_old = xkp1_old
     234            0 :                xkp1_old = init_x(k_old+1)
     235              :             end do
     236              : 
     237            0 :             delta = xk_new - xk_old
     238              : 
     239              :             vals(k_new) =  &
     240              :                   f(1, k_old) + delta*(f(2, k_old)  &
     241            0 :                      + delta*(f(3, k_old) + delta*f(4, k_old)))
     242              : 
     243              :          end do
     244              : 
     245              : 
     246            0 :       end subroutine do_interp_values_autodiff
     247              : 
     248           16 :       subroutine do_interp_values_and_slopes(init_x, nx, f1, nv, x, vals, slopes, ierr)
     249              :          real(dp), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
     250              :          integer, intent(in) :: nx  ! length of init_x vector
     251              :          real(dp), intent(in), pointer :: f1(:)  ! =(4, nx)  ! data & interpolation coefficients
     252              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
     253              :          real(dp), intent(in) :: x(:)  ! (nv)  ! locations where want interpolated values
     254              :             ! strictly monotonic in same way as init_x
     255              :             ! values out of range of init_x's are clipped to boundaries of init_x's
     256              :          real(dp), intent(inout) :: vals(:)  ! (nv)
     257              :          real(dp), intent(inout) :: slopes(:)  ! (nv)
     258              :          integer, intent(out) :: ierr  ! 0 means aok
     259              : 
     260              :          integer :: k_old, k_new
     261           16 :          real(dp) :: xk_old, xkp1_old, xk_new, delta
     262              :          logical :: increasing
     263           16 :          real(dp), pointer :: f(:,:)  ! (4, nx)  ! data & interpolation coefficients
     264           16 :          f(1:4,1:nx) => f1(1:4*nx)
     265              : 
     266           16 :          ierr = 0
     267              : 
     268           16 :          if (nx == 1) then
     269            0 :             vals(1:nv) = f(1,1)
     270            0 :             slopes(1:nv) = 0
     271              :             return
     272              :          end if
     273              : 
     274           16 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
     275              : 
     276           16 :          increasing = (init_x(1) < init_x(nx))
     277              : 
     278           32 :          do k_new = 1, nv
     279              : 
     280           16 :             xk_new = x(k_new)
     281           16 :             if (increasing) then
     282           16 :                if (xk_new > init_x(nx)) then
     283           16 :                   xk_new = init_x(nx)
     284           16 :                else if (xk_new < init_x(1)) then
     285            0 :                   xk_new = init_x(1)
     286              :                end if
     287              :             else  ! decreasing
     288            0 :                if (xk_new < init_x(nx)) then
     289              :                   xk_new = init_x(nx)
     290            0 :                else if (xk_new > init_x(1)) then
     291            0 :                   xk_new = init_x(1)
     292              :                end if
     293              :             end if
     294         4272 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
     295         4256 :                k_old = k_old + 1
     296         4256 :                if (k_old >= nx) then
     297              :                   k_old = k_old - 1
     298              :                   xk_new = xkp1_old
     299              :                   exit
     300              :                end if
     301         4256 :                xk_old = xkp1_old
     302         4256 :                xkp1_old = init_x(k_old+1)
     303              :             end do
     304              : 
     305           16 :             delta = xk_new - xk_old
     306              : 
     307              :             vals(k_new) =  &
     308              :                   f(1, k_old) + delta*(f(2, k_old)  &
     309           16 :                      + delta*(f(3, k_old) + delta*f(4, k_old)))
     310              : 
     311              :             slopes(k_new) =  &
     312           32 :                   f(2, k_old) + 2*delta*(f(3, k_old) + 1.5d0*delta*f(4, k_old))
     313              : 
     314              :          end do
     315              : 
     316              : 
     317           16 :       end subroutine do_interp_values_and_slopes
     318              : 
     319              : 
     320            0 :       subroutine do_interp2_values_and_slopes( &
     321            0 :             init_x, nx, f1_1, f1_2, nv, x, vals_1, slopes_1, vals_2, slopes_2, ierr)
     322              :          real(dp), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
     323              :          integer, intent(in) :: nx  ! length of init_x vector
     324              :          real(dp), intent(in), pointer :: f1_1(:), f1_2(:)  ! =(4,nx)  ! data & interpolation coefficients
     325              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
     326              :          real(dp), intent(in) :: x(:)  ! (nv)  ! locations where want interpolated values
     327              :             ! strictly monotonic in same way as init_x
     328              :             ! values out of range of init_x's are clipped to boundaries of init_x's
     329              :          real(dp), intent(inout) :: vals_1(:), vals_2(:)  ! (nv)
     330              :          real(dp), intent(inout) :: slopes_1(:), slopes_2(:)  ! (nv)
     331              :          integer, intent(out) :: ierr  ! 0 means aok
     332              : 
     333              :          integer :: k_old, k_new
     334            0 :          real(dp) :: xk_old, xkp1_old, xk_new, delta
     335              :          logical :: increasing
     336            0 :          real(dp), pointer :: f_1(:,:), f_2(:,:)  ! (4, nx)  ! data & interpolation coefficients
     337            0 :          f_1(1:4,1:nx) => f1_1(1:4*nx)
     338            0 :          f_2(1:4,1:nx) => f1_2(1:4*nx)
     339              : 
     340            0 :          ierr = 0
     341              : 
     342            0 :          if (nx == 1) then
     343            0 :             vals_1(1:nv) = f_1(1,1)
     344            0 :             slopes_1(1:nv) = 0
     345            0 :             vals_2(1:nv) = f_2(1,1)
     346            0 :             slopes_2(1:nv) = 0
     347              :             return
     348              :          end if
     349              : 
     350            0 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
     351              : 
     352            0 :          increasing = (init_x(1) < init_x(nx))
     353              : 
     354            0 :          do k_new = 1, nv
     355              : 
     356            0 :             xk_new = x(k_new)
     357            0 :             if (increasing) then
     358            0 :                if (xk_new > init_x(nx)) then
     359            0 :                   xk_new = init_x(nx)
     360            0 :                else if (xk_new < init_x(1)) then
     361            0 :                   xk_new = init_x(1)
     362              :                end if
     363              :             else  ! decreasing
     364            0 :                if (xk_new < init_x(nx)) then
     365              :                   xk_new = init_x(nx)
     366            0 :                else if (xk_new > init_x(1)) then
     367            0 :                   xk_new = init_x(1)
     368              :                end if
     369              :             end if
     370              : 
     371            0 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
     372            0 :                k_old = k_old + 1
     373            0 :                if (k_old >= nx) then
     374              :                   k_old = k_old - 1
     375              :                   xk_new = xkp1_old
     376              :                   exit
     377              :                end if
     378            0 :                xk_old = xkp1_old
     379            0 :                xkp1_old = init_x(k_old+1)
     380              :             end do
     381              : 
     382            0 :             delta = xk_new - xk_old
     383              : 
     384              :             vals_1(k_new) =  &
     385              :                   f_1(1, k_old) + delta*(f_1(2, k_old)  &
     386            0 :                      + delta*(f_1(3, k_old) + delta*f_1(4, k_old)))
     387              : 
     388              :             slopes_1(k_new) =  &
     389            0 :                   f_1(2, k_old) + 2*delta*(f_1(3, k_old) + 1.5d0*delta*f_1(4, k_old))
     390              : 
     391              :             vals_2(k_new) =  &
     392              :                   f_2(1, k_old) + delta*(f_2(2, k_old)  &
     393            0 :                      + delta*(f_2(3, k_old) + delta*f_2(4, k_old)))
     394              : 
     395              :             slopes_2(k_new) =  &
     396            0 :                   f_2(2, k_old) + 2*delta*(f_2(3, k_old) + 1.5d0*delta*f_2(4, k_old))
     397              : 
     398              :          end do
     399              : 
     400              : 
     401            0 :       end subroutine do_interp2_values_and_slopes
     402              : 
     403              : 
     404            0 :       subroutine do_interp3_values_and_slopes( &
     405            0 :             init_x, nx, f1_1, f1_2, f1_3, nv, x, &
     406            0 :             vals_1, slopes_1, vals_2, slopes_2, vals_3, slopes_3, ierr)
     407              :          real(dp), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
     408              :          integer, intent(in) :: nx  ! length of init_x vector
     409              :          real(dp), intent(in), pointer :: f1_1(:), f1_2(:), f1_3(:)  ! =(4,nx)  ! data & interpolation coefficients
     410              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
     411              :          real(dp), intent(in) :: x(:)  ! (nv)  ! locations where want interpolated values
     412              :             ! strictly monotonic in same way as init_x
     413              :             ! values out of range of init_x's are clipped to boundaries of init_x's
     414              :          real(dp), intent(inout) :: vals_1(:), vals_2(:), vals_3(:)  ! (nv)
     415              :          real(dp), intent(inout) :: slopes_1(:), slopes_2(:), slopes_3(:)  ! (nv)
     416              :          integer, intent(out) :: ierr  ! 0 means aok
     417              : 
     418              :          integer :: k_old, k_new
     419            0 :          real(dp) :: xk_old, xkp1_old, xk_new, delta
     420              :          logical :: increasing
     421            0 :          real(dp), pointer :: f_1(:,:), f_2(:,:), f_3(:,:)  ! (4, nx)  ! data & interpolation coefficients
     422            0 :          f_1(1:4,1:nx) => f1_1(1:4*nx)
     423            0 :          f_2(1:4,1:nx) => f1_2(1:4*nx)
     424            0 :          f_3(1:4,1:nx) => f1_3(1:4*nx)
     425              : 
     426            0 :          ierr = 0
     427              : 
     428            0 :          if (nx == 1) then
     429            0 :             vals_1(1:nv) = f_1(1,1)
     430            0 :             slopes_1(1:nv) = 0
     431            0 :             vals_2(1:nv) = f_2(1,1)
     432            0 :             slopes_2(1:nv) = 0
     433            0 :             vals_3(1:nv) = f_3(1,1)
     434            0 :             slopes_3(1:nv) = 0
     435              :             return
     436              :          end if
     437              : 
     438            0 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
     439              : 
     440            0 :          increasing = (init_x(1) < init_x(nx))
     441              : 
     442            0 :          do k_new = 1, nv
     443              : 
     444            0 :             xk_new = x(k_new)
     445            0 :             if (increasing) then
     446            0 :                if (xk_new > init_x(nx)) then
     447            0 :                   xk_new = init_x(nx)
     448            0 :                else if (xk_new < init_x(1)) then
     449            0 :                   xk_new = init_x(1)
     450              :                end if
     451              :             else  ! decreasing
     452            0 :                if (xk_new < init_x(nx)) then
     453              :                   xk_new = init_x(nx)
     454            0 :                else if (xk_new > init_x(1)) then
     455            0 :                   xk_new = init_x(1)
     456              :                end if
     457              :             end if
     458              : 
     459            0 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
     460            0 :                k_old = k_old + 1
     461            0 :                if (k_old >= nx) then
     462              :                   k_old = k_old - 1
     463              :                   xk_new = xkp1_old
     464              :                   exit
     465              :                end if
     466            0 :                xk_old = xkp1_old
     467            0 :                xkp1_old = init_x(k_old+1)
     468              :             end do
     469              : 
     470            0 :             delta = xk_new - xk_old
     471              : 
     472              :             vals_1(k_new) =  &
     473              :                   f_1(1, k_old) + delta*(f_1(2, k_old)  &
     474            0 :                      + delta*(f_1(3, k_old) + delta*f_1(4, k_old)))
     475              :             slopes_1(k_new) =  &
     476            0 :                   f_1(2, k_old) + 2*delta*(f_1(3, k_old) + 1.5d0*delta*f_1(4, k_old))
     477              : 
     478              :             vals_2(k_new) =  &
     479              :                   f_2(1, k_old) + delta*(f_2(2, k_old)  &
     480            0 :                      + delta*(f_2(3, k_old) + delta*f_2(4, k_old)))
     481              :             slopes_2(k_new) =  &
     482            0 :                   f_2(2, k_old) + 2*delta*(f_2(3, k_old) + 1.5d0*delta*f_2(4, k_old))
     483              : 
     484              :             vals_3(k_new) =  &
     485              :                   f_3(1, k_old) + delta*(f_3(2, k_old)  &
     486            0 :                      + delta*(f_3(3, k_old) + delta*f_3(4, k_old)))
     487              :             slopes_3(k_new) =  &
     488            0 :                   f_3(2, k_old) + 2*delta*(f_3(3, k_old) + 1.5d0*delta*f_3(4, k_old))
     489              : 
     490              :          end do
     491              : 
     492              : 
     493            0 :       end subroutine do_interp3_values_and_slopes
     494              : 
     495              : 
     496            0 :       subroutine do_interp6_values_and_slopes( &
     497            0 :             init_x, nx, f1_1, f1_2, f1_3, f1_4, f1_5, f1_6, nv, x, &
     498            0 :             vals_1, slopes_1, vals_2, slopes_2, vals_3, slopes_3, &
     499            0 :             vals_4, slopes_4, vals_5, slopes_5, vals_6, slopes_6, &
     500              :             ierr)
     501              :          real(dp), intent(in) :: init_x(:)  ! (nx) ! junction points, strictly monotonic
     502              :          integer, intent(in) :: nx  ! length of init_x vector
     503              :          real(dp), intent(in), pointer, dimension(:) :: f1_1, f1_2, f1_3, f1_4, f1_5, f1_6
     504              :          integer, intent(in) :: nv  ! length of new x vector and vals vector
     505              :          real(dp), intent(in) :: x(:)  ! (nv)  ! locations where want interpolated values
     506              :             ! strictly monotonic in same way as init_x
     507              :             ! values out of range of init_x's are clipped to boundaries of init_x's
     508              :          real(dp), intent(inout), dimension(:) :: &
     509              :             vals_1, slopes_1, vals_2, slopes_2, vals_3, slopes_3, &
     510              :             vals_4, slopes_4, vals_5, slopes_5, vals_6, slopes_6
     511              :          integer, intent(out) :: ierr  ! 0 means aok
     512              : 
     513              :          integer :: k_old, k_new
     514            0 :          real(dp) :: xk_old, xkp1_old, xk_new, delta
     515              :          logical :: increasing
     516            0 :          real(dp), pointer, dimension(:,:) :: f_1, f_2, f_3, f_4, f_5, f_6
     517            0 :          f_1(1:4,1:nx) => f1_1(1:4*nx)
     518            0 :          f_2(1:4,1:nx) => f1_2(1:4*nx)
     519            0 :          f_3(1:4,1:nx) => f1_3(1:4*nx)
     520            0 :          f_4(1:4,1:nx) => f1_4(1:4*nx)
     521            0 :          f_5(1:4,1:nx) => f1_5(1:4*nx)
     522            0 :          f_6(1:4,1:nx) => f1_6(1:4*nx)
     523              : 
     524            0 :          ierr = 0
     525              : 
     526            0 :          if (nx == 1) then
     527            0 :             vals_1(1:nv) = f_1(1,1); slopes_1(1:nv) = 0
     528            0 :             vals_2(1:nv) = f_2(1,1); slopes_2(1:nv) = 0
     529            0 :             vals_3(1:nv) = f_3(1,1); slopes_3(1:nv) = 0
     530            0 :             vals_4(1:nv) = f_4(1,1); slopes_4(1:nv) = 0
     531            0 :             vals_5(1:nv) = f_5(1,1); slopes_5(1:nv) = 0
     532            0 :             vals_6(1:nv) = f_6(1,1); slopes_6(1:nv) = 0
     533              :             return
     534              :          end if
     535              : 
     536            0 :          k_old = 1; xk_old = init_x(k_old); xkp1_old = init_x(k_old+1)
     537              : 
     538            0 :          increasing = (init_x(1) < init_x(nx))
     539              : 
     540            0 :          do k_new = 1, nv
     541              : 
     542            0 :             xk_new = x(k_new)
     543            0 :             if (increasing) then
     544            0 :                if (xk_new > init_x(nx)) then
     545            0 :                   xk_new = init_x(nx)
     546            0 :                else if (xk_new < init_x(1)) then
     547            0 :                   xk_new = init_x(1)
     548              :                end if
     549              :             else  ! decreasing
     550            0 :                if (xk_new < init_x(nx)) then
     551              :                   xk_new = init_x(nx)
     552            0 :                else if (xk_new > init_x(1)) then
     553            0 :                   xk_new = init_x(1)
     554              :                end if
     555              :             end if
     556              : 
     557            0 :             do while ((increasing .and. xk_new > xkp1_old) .or. ((.not. increasing) .and. xk_new < xkp1_old))
     558            0 :                k_old = k_old + 1
     559            0 :                if (k_old >= nx) then
     560              :                   k_old = k_old - 1
     561              :                   xk_new = xkp1_old
     562              :                   exit
     563              :                end if
     564            0 :                xk_old = xkp1_old
     565            0 :                xkp1_old = init_x(k_old+1)
     566              :             end do
     567              : 
     568            0 :             delta = xk_new - xk_old
     569              : 
     570              :             vals_1(k_new) =  &
     571              :                   f_1(1, k_old) + delta*(f_1(2, k_old)  &
     572            0 :                      + delta*(f_1(3, k_old) + delta*f_1(4, k_old)))
     573              :             slopes_1(k_new) =  &
     574            0 :                   f_1(2, k_old) + 2*delta*(f_1(3, k_old) + 1.5d0*delta*f_1(4, k_old))
     575              : 
     576              :             vals_2(k_new) =  &
     577              :                   f_2(1, k_old) + delta*(f_2(2, k_old)  &
     578            0 :                      + delta*(f_2(3, k_old) + delta*f_2(4, k_old)))
     579              :             slopes_2(k_new) =  &
     580            0 :                   f_2(2, k_old) + 2*delta*(f_2(3, k_old) + 1.5d0*delta*f_2(4, k_old))
     581              : 
     582              :             vals_3(k_new) =  &
     583              :                   f_3(1, k_old) + delta*(f_3(2, k_old)  &
     584            0 :                      + delta*(f_3(3, k_old) + delta*f_3(4, k_old)))
     585              :             slopes_3(k_new) =  &
     586            0 :                   f_3(2, k_old) + 2*delta*(f_3(3, k_old) + 1.5d0*delta*f_3(4, k_old))
     587              : 
     588              :             vals_4(k_new) =  &
     589              :                   f_4(1, k_old) + delta*(f_4(2, k_old)  &
     590            0 :                      + delta*(f_4(3, k_old) + delta*f_4(4, k_old)))
     591              :             slopes_4(k_new) =  &
     592            0 :                   f_4(2, k_old) + 2*delta*(f_4(3, k_old) + 1.5d0*delta*f_4(4, k_old))
     593              : 
     594              :             vals_5(k_new) =  &
     595              :                   f_5(1, k_old) + delta*(f_5(2, k_old)  &
     596            0 :                      + delta*(f_5(3, k_old) + delta*f_5(4, k_old)))
     597              :             slopes_5(k_new) =  &
     598            0 :                   f_5(2, k_old) + 2*delta*(f_5(3, k_old) + 1.5d0*delta*f_5(4, k_old))
     599              : 
     600              :             vals_6(k_new) =  &
     601              :                   f_6(1, k_old) + delta*(f_6(2, k_old)  &
     602            0 :                      + delta*(f_6(3, k_old) + delta*f_6(4, k_old)))
     603              :             slopes_6(k_new) =  &
     604            0 :                   f_6(2, k_old) + 2*delta*(f_6(3, k_old) + 1.5d0*delta*f_6(4, k_old))
     605              : 
     606              :          end do
     607              : 
     608            0 :       end subroutine do_interp6_values_and_slopes
     609              : 
     610              : 
     611         2630 :       real(dp) function minmod1(f1, f2)
     612              :          real(dp), intent(in) :: f1, f2
     613         2630 :          minmod1 = 0.5d0 * (sign(1d0, f1) + sign(1d0, f2)) * min(abs(f1), abs(f2))
     614         2630 :       end function minmod1
     615              : 
     616              : 
     617            0 :       real(dp) function median1(f1, f2, f3)
     618              :          real(dp), intent(in) :: f1, f2, f3
     619            0 :          median1 = f1 + minmod1(f2 - f1, f3 - f1)
     620            0 :       end function median1
     621              : 
     622              : 
     623         9205 :       subroutine minmod(z, n, f1, f2)
     624              :          real(dp), intent(inout) :: z(:)
     625              :          integer, intent(in) :: n       ! length of vectors
     626              :          real(dp), intent(in) :: f1(:), f2(:)
     627     91775919 :          z(1:n) = 0.5d0 * (sign(1d0, f1(1:n)) + sign(1d0, f2(1:n))) * min(abs(f1(1:n)), abs(f2(1:n)))
     628         9205 :       end subroutine minmod
     629              : 
     630              : 
     631         1315 :       subroutine minmod4(z, n, f1, f2, f3, f4)
     632              :          real(dp), intent(inout) :: z(:)
     633              :          integer, intent(in) :: n       ! length of vectors
     634              :          real(dp), intent(in) :: f1(:), f2(:), f3(:), f4(:)
     635         1315 :          call minmod(z, n, f1, f2)
     636         1315 :          call minmod(z, n, z, f3)
     637         1315 :          call minmod(z, n, z, f4)
     638         1315 :       end subroutine minmod4
     639              : 
     640              : 
     641         1315 :       subroutine median(z, n, f1, f2, f3)
     642              :          real(dp), intent(inout) :: z(:)
     643              :          integer, intent(in) :: n       ! length of vectors
     644              :          real(dp), intent(in) :: f1(:), f2(:), f3(:)
     645     26220564 :          real(dp), target :: tmp1_ary(n), tmp2_ary(n)
     646         1315 :          real(dp), pointer :: tmp1(:), tmp2(:)
     647         1315 :          tmp1 => tmp1_ary
     648         1315 :          tmp2 => tmp2_ary
     649     13110282 :          tmp1(1:n) = f2(1:n) - f1(1:n)
     650     13110282 :          tmp2(1:n) = f3(1:n) - f1(1:n)
     651         1315 :          call minmod(z(1:n), n, tmp1(1:n), tmp2(1:n))
     652     13110282 :          z(1:n) = z(1:n) + f1(1:n)
     653         1315 :       end subroutine median
     654              : 
     655              : 
     656            0 :       type(auto_diff_real_2var_order1) function minmod1_autodiff(f1, f2)
     657              :          use auto_diff
     658              :          type(auto_diff_real_2var_order1), intent(in) :: f1, f2
     659            0 :          minmod1_autodiff = 0.5d0 * (sign(f1) + sign(f2)) * min(abs(f1), abs(f2))
     660            0 :       end function minmod1_autodiff
     661              : 
     662              : 
     663            0 :       type(auto_diff_real_2var_order1) function median1_autodiff(f1, f2, f3)
     664            0 :          use auto_diff
     665              :          type(auto_diff_real_2var_order1), intent(in) :: f1, f2, f3
     666            0 :          median1_autodiff = f1 + minmod1_autodiff(f2 - f1, f3 - f1)
     667            0 :       end function median1_autodiff
     668              : 
     669              : 
     670            0 :       subroutine minmod_autodiff(z, n, f1, f2)
     671            0 :          use auto_diff
     672              :          type(auto_diff_real_2var_order1), intent(inout) :: z(:)
     673              :          integer, intent(in) :: n       ! length of vectors
     674              :          integer :: k
     675              :          type(auto_diff_real_2var_order1), intent(in) :: f1(:), f2(:)
     676            0 :          do k =1, n
     677            0 :          z(k) = 0.5d0 * (sign(f1(k)) + sign(f2(k))) * min(abs(f1(k)), abs(f2(k)))
     678              :          end do
     679            0 :       end subroutine minmod_autodiff
     680              : 
     681            0 :       subroutine minmod4_autodiff(z, n, f1, f2, f3, f4)
     682            0 :          use auto_diff
     683              :          type(auto_diff_real_2var_order1), intent(inout) :: z(:)
     684              :          integer, intent(in) :: n       ! length of vectors
     685              :          type(auto_diff_real_2var_order1), intent(in) :: f1(:), f2(:), f3(:), f4(:)
     686            0 :          call minmod_autodiff(z, n, f1, f2)
     687            0 :          call minmod_autodiff(z, n, z, f3)
     688            0 :          call minmod_autodiff(z, n, z, f4)
     689            0 :       end subroutine minmod4_autodiff
     690              : 
     691              : 
     692            0 :       subroutine median_autodiff(z, n, f1, f2, f3)
     693            0 :          use auto_diff
     694              :          type(auto_diff_real_2var_order1), intent(inout) :: z(:)
     695              :          integer, intent(in) :: n       ! length of vectors
     696              :          integer :: k
     697              :          type(auto_diff_real_2var_order1), intent(in) :: f1(:), f2(:), f3(:)
     698            0 :          type(auto_diff_real_2var_order1), target :: tmp1_ary(n), tmp2_ary(n)
     699              :          type(auto_diff_real_2var_order1), pointer :: tmp1(:), tmp2(:)
     700            0 :          tmp1 => tmp1_ary
     701            0 :          tmp2 => tmp2_ary
     702            0 :          do k =1,n
     703            0 :          tmp1(k) = f2(k) - f1(k)
     704            0 :          tmp2(k) = f3(k) - f1(k)
     705              :          end do
     706            0 :          call minmod_autodiff(z, n, tmp1, tmp2)
     707            0 :          do k =1,n
     708            0 :          z(k) = z(k) + f1(k)
     709              :          end do
     710            0 :       end subroutine median_autodiff
     711              : 
     712              :       end module interp_1d_misc
        

Generated by: LCOV version 2.0-1