LCOV - code coverage report
Current view: top level - src/common - splines.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4c33f95) Lines: 0 151 0.0 %
Date: 2025-01-30 06:53:08 Functions: 0 12 0.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Simple splines
      10             : !> Splines are fully specified by the interpolation points, except that
      11             : !> at the ends, we have the freedom to prescribe the second derivatives.
      12             : !> If we know a derivative at an end (exactly), then best is to impose that.
      13             : !> Otherwise, it is better to use the "consistent" end conditions: the second
      14             : !> derivative is determined such that it is smooth.
      15             : !>
      16             : !> High level API: spline3, spline3ders.
      17             : !> Low level API: the rest of public soubroutines.
      18             : !>
      19             : !> Use the high level API to obtain cubic spline fit with consistent boundary
      20             : !> conditions and optionally the derivatives. Use the low level API if more fine
      21             : !> grained control is needed.
      22             : !>
      23             : !> This module is based on a code written by John E. Pask, LLNL.
      24             : !> \par History
      25             : !>      Adapted for use in CP2K  (30.12.2016,JGH)
      26             : !> \author JGH
      27             : ! **************************************************************************************************
      28             : MODULE splines
      29             : 
      30             :    USE kinds,                           ONLY: dp
      31             : #include "../base/base_uses.f90"
      32             : 
      33             :    IMPLICIT NONE
      34             : 
      35             :    PRIVATE
      36             : 
      37             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'splines'
      38             : 
      39             :    PUBLIC :: spline3, spline3ders
      40             : 
      41             : CONTAINS
      42             : 
      43             : ! **************************************************************************************************
      44             : !> \brief ...
      45             : !> \param x ...
      46             : !> \param y ...
      47             : !> \param xnew ...
      48             : !> \return ...
      49             : ! **************************************************************************************************
      50           0 :    FUNCTION spline3(x, y, xnew) RESULT(ynew)
      51             :       ! Takes the function values 'y' on the grid 'x' and returns new values 'ynew'
      52             :       ! at the given grid 'xnew' using cubic splines interpolation with such
      53             :       ! boundary conditions so that the 2nd derivative is consistent with the
      54             :       ! interpolating cubic.
      55             :       REAL(dp), INTENT(in)                               :: x(:), y(:), xnew(:)
      56             :       REAL(dp)                                           :: ynew(SIZE(xnew))
      57             : 
      58             :       INTEGER                                            :: i, ip
      59           0 :       REAL(dp)                                           :: c(0:4, SIZE(x) - 1)
      60             : 
      61             :       ! get spline parameters: 2nd derivs at ends determined by cubic interpolation
      62           0 :       CALL spline3pars(x, y, [2, 2], [0._dp, 0._dp], c)
      63             : 
      64           0 :       ip = 0
      65           0 :       DO i = 1, SIZE(xnew)
      66           0 :          ip = iixmin(xnew(i), x, ip)
      67           0 :          ynew(i) = poly3(xnew(i), c(:, ip))
      68             :       END DO
      69           0 :    END FUNCTION
      70             : 
      71             : ! **************************************************************************************************
      72             : !> \brief ...
      73             : !> \param x ...
      74             : !> \param y ...
      75             : !> \param xnew ...
      76             : !> \param ynew ...
      77             : !> \param dynew ...
      78             : !> \param d2ynew ...
      79             : ! **************************************************************************************************
      80           0 :    SUBROUTINE spline3ders(x, y, xnew, ynew, dynew, d2ynew)
      81             :       ! Just like 'spline', but also calculate 1st and 2nd derivatives
      82             :       REAL(dp), INTENT(in)                               :: x(:), y(:), xnew(:)
      83             :       REAL(dp), INTENT(out), OPTIONAL                    :: ynew(:), dynew(:), d2ynew(:)
      84             : 
      85             :       INTEGER                                            :: i, ip
      86           0 :       REAL(dp)                                           :: c(0:4, SIZE(x) - 1)
      87             : 
      88           0 :       CALL spline3pars(x, y, [2, 2], [0._dp, 0._dp], c)
      89             : 
      90           0 :       ip = 0
      91           0 :       DO i = 1, SIZE(xnew)
      92           0 :          ip = iixmin(xnew(i), x, ip)
      93           0 :          IF (PRESENT(ynew)) ynew(i) = poly3(xnew(i), c(:, ip))
      94           0 :          IF (PRESENT(dynew)) dynew(i) = dpoly3(xnew(i), c(:, ip))
      95           0 :          IF (PRESENT(d2ynew)) d2ynew(i) = d2poly3(xnew(i), c(:, ip))
      96             :       END DO
      97           0 :    END SUBROUTINE
      98             : 
      99             : ! **************************************************************************************************
     100             : !> \brief ...
     101             : !> \param xi ...
     102             : !> \param yi ...
     103             : !> \param bctype ...
     104             : !> \param bcval ...
     105             : !> \param c ...
     106             : ! **************************************************************************************************
     107           0 :    SUBROUTINE spline3pars(xi, yi, bctype, bcval, c)
     108             :       ! Returns parameters c defining cubic spline interpolating x-y data xi, yi, with
     109             :       ! boundary conditions specified by bcytpe, bcvals
     110             :       REAL(dp), INTENT(in)                               :: xi(:), yi(:)
     111             :       INTEGER, INTENT(in)                                :: bctype(2)
     112             :       REAL(dp), INTENT(in)                               :: bcval(2)
     113             :       REAL(dp), INTENT(out)                              :: c(0:, :)
     114             : 
     115             :       INTEGER                                            :: i, i2, info, ipiv(4), j, n
     116             :       REAL(dp) :: Ae(4, 4), be(4), bemat(4, 1), c1, c2, c3, c4, ce(4), d2p1, d2pn, x0, xe(4), &
     117           0 :          ye(4), hi(SIZE(c, 2)), cs(2*SIZE(c, 2)), bs(2*SIZE(c, 2)), bmat(2*SIZE(c, 2), 1), &
     118           0 :          As(5, 2*SIZE(c, 2))
     119           0 :       INTEGER                                            :: ipiv2(2*SIZE(c, 2))
     120             : 
     121             :       ! x values of data
     122             :       ! y values of data
     123             :       ! type of boundary condition at each end:
     124             :       ! bctype(1) = type at left end, bctype(2) = type at right end.
     125             :       ! 1 = specified 2nd derivative, 2 = 2nd derivative consistent with interpolating cubic.
     126             :       ! boundary condition values at each end:
     127             :       ! bcval(1) = value at left end, bcval(2) = value at right end
     128             :       ! parameters defining spline: c(i,j) = ith parameter of jth
     129             :       ! spline polynomial, p_j = sum_{i=1}^4 c(i,j) (x-c(0,j))^(i-1), j = 1..n-1, n = # of data pts.
     130             :       ! dimensions: c(0:4,1:n-1)
     131             :       ! spline eq. matrix -- LAPACK band form
     132             :       ! spline eq. rhs vector
     133             :       ! spline eq. solution vector
     134             :       ! spline intervals
     135             :       ! end-cubic eq. matrix
     136             :       ! end-cubic eq. rhs vector
     137             :       ! end-cubic eq. solution vector
     138             :       ! x,y values at ends
     139             :       ! 2nd derivatives at ends
     140             :       ! expansion center
     141             :       ! expansion coefficients
     142             :       ! number of data points
     143             :       ! lapack variables
     144             : 
     145             :       ! check input parameters
     146           0 :       IF (bctype(1) < 1 .OR. bctype(1) > 2) CALL stop_error("spline3pars error: bctype /= 1 or 2.")
     147           0 :       IF (bctype(2) < 1 .OR. bctype(2) > 2) CALL stop_error("spline3pars error: bctype /= 1 or 2.")
     148           0 :       IF (SIZE(c, 1) /= 5) CALL stop_error("spline3pars error: size(c,1) /= 5.")
     149           0 :       IF (SIZE(c, 2) /= SIZE(xi) - 1) CALL stop_error("spline3pars error: size(c,2) /= size(xi)-1.")
     150           0 :       IF (SIZE(xi) /= SIZE(yi)) CALL stop_error("spline3pars error: size(xi) /= size(yi)")
     151             : 
     152             :       ! To get rid of compiler warnings:
     153           0 :       d2p1 = 0
     154           0 :       d2pn = 0
     155             : 
     156             :       ! initializations
     157           0 :       n = SIZE(xi)
     158           0 :       DO i = 1, n - 1
     159           0 :          hi(i) = xi(i + 1) - xi(i)
     160             :       END DO
     161             : 
     162             :       ! compute interpolating-cubic 2nd derivs at ends, if required
     163             :       ! left end
     164           0 :       IF (bctype(1) == 2) THEN
     165           0 :          IF (n < 4) CALL stop_error("spline3pars error: n < 4")
     166           0 :          xe = xi(1:4)
     167           0 :          ye = yi(1:4)
     168           0 :          x0 = xe(1) ! center at end
     169           0 :          DO i = 1, 4
     170           0 :             DO j = 1, 4
     171           0 :                Ae(i, j) = (xe(i) - x0)**(j - 1)
     172             :             END DO
     173             :          END DO
     174           0 :          Ae(:, 1) = 1 ! set 0^0 = 1
     175           0 :          be = ye; bemat(:, 1) = be
     176           0 :          CALL dgesv(4, 1, Ae, 4, ipiv, bemat, 4, info)
     177           0 :          IF (info /= 0) CALL stop_error("spline3pars error: dgesv error.")
     178           0 :          ce = bemat(:, 1)
     179           0 :          d2p1 = 2*ce(3)
     180             :       END IF
     181             :       ! right end
     182           0 :       IF (bctype(2) == 2) THEN
     183           0 :          IF (n < 4) CALL stop_error("spline3pars error: n < 4")
     184           0 :          xe = xi(n - 3:n)
     185           0 :          ye = yi(n - 3:n)
     186           0 :          x0 = xe(4) ! center at end
     187           0 :          DO i = 1, 4
     188           0 :             DO j = 1, 4
     189           0 :                Ae(i, j) = (xe(i) - x0)**(j - 1)
     190             :             END DO
     191             :          END DO
     192           0 :          Ae(:, 1) = 1 ! set 0^0 = 1
     193           0 :          be = ye; bemat(:, 1) = be
     194           0 :          CALL dgesv(4, 1, Ae, 4, ipiv, bemat, 4, info)
     195           0 :          IF (info /= 0) CALL stop_error("spline3pars error: dgesv error.")
     196           0 :          ce = bemat(:, 1)
     197           0 :          d2pn = 2*ce(3)
     198             :       END IF
     199             : 
     200             :       ! set 2nd derivs at ends
     201           0 :       IF (bctype(1) == 1) d2p1 = bcval(1)
     202           0 :       IF (bctype(2) == 1) d2pn = bcval(2)
     203             : 
     204             :       ! construct spline equations -- LAPACK band form
     205             :       ! basis: phi1 = -(x-x_i)/h_i, phi2 = (x-x_{i+1})/h_i, phi3 = phi1^3-phi1, phi4 = phi2^3-phi2
     206             :       ! on interval [x_i,x_{i+1}] of length h_i = x_{i+1}-x_i
     207             :       !A=0  ! full matrix
     208           0 :       As = 0
     209             :       ! left end condition
     210           0 :       As(4, 1) = 6/hi(1)**2
     211           0 :       bs(1) = d2p1
     212             :       ! internal knot conditions
     213           0 :       DO i = 2, n - 1
     214           0 :          i2 = 2*(i - 1)
     215           0 :          As(5, i2 - 1) = 1/hi(i - 1)
     216           0 :          As(4, i2) = 2/hi(i - 1)
     217           0 :          As(3, i2 + 1) = 2/hi(i)
     218           0 :          As(2, i2 + 2) = 1/hi(i)
     219           0 :          As(5, i2) = 1/hi(i - 1)**2
     220           0 :          As(4, i2 + 1) = -1/hi(i)**2
     221           0 :          bs(i2) = (yi(i + 1) - yi(i))/hi(i) - (yi(i) - yi(i - 1))/hi(i - 1)
     222           0 :          bs(i2 + 1) = 0
     223             :       END DO
     224             :       ! right end condition
     225           0 :       As(4, 2*(n - 1)) = 6/hi(n - 1)**2
     226           0 :       bs(2*(n - 1)) = d2pn
     227             : 
     228             :       ! solve spline equations -- LAPACK band form
     229           0 :       bmat(:, 1) = bs
     230           0 :       CALL dgbsv(2*(n - 1), 1, 2, 1, As, 5, ipiv2, bmat, 2*(n - 1), info)
     231           0 :       IF (info /= 0) CALL stop_error("spline3pars error: dgbsv error.")
     232           0 :       cs = bmat(:, 1)
     233             : 
     234             :       ! transform to (x-x0)^(i-1) basis and return
     235           0 :       DO i = 1, n - 1
     236             :          ! coefficients in spline basis:
     237           0 :          c1 = yi(i)
     238           0 :          c2 = yi(i + 1)
     239           0 :          c3 = cs(2*i - 1)
     240           0 :          c4 = cs(2*i)
     241             :          ! coefficients in (x-x0)^(i-1) basis
     242           0 :          c(0, i) = xi(i)
     243           0 :          c(1, i) = c1
     244           0 :          c(2, i) = -(c1 - c2 + 2*c3 + c4)/hi(i)
     245           0 :          c(3, i) = 3*c3/hi(i)**2
     246           0 :          c(4, i) = (-c3 + c4)/hi(i)**3
     247             :       END DO
     248           0 :    END SUBROUTINE
     249             : 
     250             : !--------------------------------------------------------------------------------------------------!
     251             : 
     252             : ! **************************************************************************************************
     253             : !> \brief ...
     254             : !> \param x ...
     255             : !> \param xi ...
     256             : !> \param c ...
     257             : !> \param val ...
     258             : !> \param der ...
     259             : ! **************************************************************************************************
     260           0 :    SUBROUTINE spline3valder(x, xi, c, val, der)
     261             :       ! Returns value and 1st derivative of spline defined by knots xi and parameters c
     262             :       ! returned by spline3pars
     263             :       REAL(dp), INTENT(in)                               :: x, xi(:), c(0:, :)
     264             :       REAL(dp), INTENT(out)                              :: val, der
     265             : 
     266             :       INTEGER                                            :: i1, n
     267             : 
     268             :       ! point at which to evaluate spline
     269             :       ! spline knots (x values of data)
     270             :       ! spline parameters: c(i,j) = ith parameter of jth
     271             :       ! spline polynomial, p_j = sum_{i=1}^4 c(i,j) (x-c(0,j))^(i-1), j = 1..n-1, n = # of data pts.
     272             :       ! dimensions: c(0:4,1:n-1)
     273             :       ! value of spline at x
     274             :       ! 1st derivative of spline at x
     275             :       ! number of knots
     276             : 
     277             :       ! initialize, check input parameters
     278           0 :       n = SIZE(xi)
     279           0 :       IF (SIZE(c, 1) /= 5) CALL stop_error("spline3 error: size(c,1) /= 5.")
     280           0 :       IF (SIZE(c, 2) /= SIZE(xi) - 1) CALL stop_error("spline3 error: size(c,2) /= size(xi)-1.")
     281             :       ! find interval containing x
     282           0 :       i1 = iix(x, xi)
     283             :       ! return value and derivative
     284           0 :       val = poly3(x, c(:, i1))
     285           0 :       der = dpoly3(x, c(:, i1))
     286           0 :    END SUBROUTINE
     287             : 
     288             : !--------------------------------------------------------------------------------------------------!
     289             : 
     290             : ! **************************************************************************************************
     291             : !> \brief ...
     292             : !> \param x ...
     293             : !> \param xi ...
     294             : !> \return ...
     295             : ! **************************************************************************************************
     296           0 :    INTEGER FUNCTION iix(x, xi) RESULT(i1)
     297             :       ! Returns index i of interval [xi(i),xi(i+1)] containing x in mesh xi,
     298             :       ! with intervals indexed by left-most points.
     299             :       ! N.B.: x outside [x1,xn] are indexed to nearest end.
     300             :       ! Uses bisection, except if "x" lies in the first or second elements (which is
     301             :       ! often the case)
     302             :       REAL(dp), INTENT(in)                               :: x, xi(:)
     303             : 
     304             :       INTEGER                                            :: i2, ic, n
     305             : 
     306             : ! target value
     307             : ! mesh, xi(i) < xi(i+1)
     308             : ! number of mesh points
     309             : 
     310           0 :       n = SIZE(xi)
     311           0 :       i1 = 1
     312           0 :       IF (n < 2) THEN
     313           0 :          CALL stop_error("error in iix: n < 2")
     314           0 :       ELSEIF (n == 2) THEN
     315             :          i1 = 1
     316           0 :       ELSEIF (n == 3) THEN
     317           0 :          IF (x <= xi(2)) THEN ! first element
     318             :             i1 = 1
     319             :          ELSE
     320           0 :             i1 = 2
     321             :          END IF
     322           0 :       ELSEIF (x <= xi(1)) THEN ! left end
     323             :          i1 = 1
     324           0 :       ELSEIF (x <= xi(2)) THEN ! first element
     325             :          i1 = 1
     326           0 :       ELSEIF (x <= xi(3)) THEN ! second element
     327             :          i1 = 2
     328           0 :       ELSEIF (x >= xi(n)) THEN ! right end
     329           0 :          i1 = n - 1
     330             :       ELSE
     331             :          ! bisection: xi(i1) <= x < xi(i2)
     332             :          i1 = 3; i2 = n
     333             :          DO
     334           0 :             IF (i2 - i1 == 1) EXIT
     335           0 :             ic = i1 + (i2 - i1)/2
     336           0 :             IF (x >= xi(ic)) THEN
     337             :                i1 = ic
     338             :             ELSE
     339           0 :                i2 = ic
     340             :             END IF
     341             :          END DO
     342             :       END IF
     343           0 :    END FUNCTION
     344             : 
     345             : ! **************************************************************************************************
     346             : !> \brief ...
     347             : !> \param x ...
     348             : !> \param xi ...
     349             : !> \param i_min ...
     350             : !> \return ...
     351             : ! **************************************************************************************************
     352           0 :    INTEGER FUNCTION iixmin(x, xi, i_min) RESULT(ip)
     353             :       ! Just like iix, but assumes that x >= xi(i_min)
     354             :       REAL(dp), INTENT(in)                               :: x, xi(:)
     355             :       INTEGER, INTENT(in)                                :: i_min
     356             : 
     357           0 :       IF (i_min >= 1 .AND. i_min <= SIZE(xi) - 1) THEN
     358           0 :          ip = iix(x, xi(i_min:)) + i_min - 1
     359             :       ELSE
     360           0 :          ip = iix(x, xi)
     361             :       END IF
     362           0 :    END FUNCTION
     363             : 
     364             : !--------------------------------------------------------------------------------------------------!
     365             : 
     366             : ! **************************************************************************************************
     367             : !> \brief ...
     368             : !> \param x ...
     369             : !> \param n ...
     370             : !> \param x1 ...
     371             : !> \param xn ...
     372             : !> \return ...
     373             : ! **************************************************************************************************
     374           0 :    FUNCTION iixun(x, n, x1, xn)
     375             :       ! Returns index i of interval [x(i),x(i+1)] containing x in uniform mesh defined by
     376             :       !   x(i) = x1 + (i-1)/(n-1)*(xn-x1), i = 1 .. n,
     377             :       ! with intervals indexed by left-most points.
     378             :       ! N.B.: x outside [x1,xn] are indexed to nearest end.
     379             :       REAL(dp), INTENT(in)                               :: x
     380             :       INTEGER, INTENT(in)                                :: n
     381             :       REAL(dp), INTENT(in)                               :: x1, xn
     382             :       INTEGER                                            :: iixun
     383             : 
     384             :       INTEGER                                            :: i
     385             : 
     386             :       ! index i of interval [x(i),x(i+1)] containing x
     387             :       ! target value
     388             :       ! number of mesh points
     389             :       ! initial point of mesh
     390             :       ! final point of mesh
     391             : 
     392             :       ! compute index
     393           0 :       i = INT((x - x1)/(xn - x1)*(n - 1)) + 1
     394             :       ! reset if outside 1..n
     395           0 :       IF (i < 1) i = 1
     396           0 :       IF (i > n - 1) i = n - 1
     397           0 :       iixun = i
     398           0 :    END FUNCTION
     399             : 
     400             : !--------------------------------------------------------------------------------------------------!
     401             : 
     402             : ! **************************************************************************************************
     403             : !> \brief ...
     404             : !> \param x ...
     405             : !> \param n ...
     406             : !> \param x1 ...
     407             : !> \param alpha ...
     408             : !> \param beta ...
     409             : !> \return ...
     410             : ! **************************************************************************************************
     411           0 :    FUNCTION iixexp(x, n, x1, alpha, beta)
     412             :       ! Returns index i of interval [x(i),x(i+1)] containing x in exponential mesh defined by
     413             :       !   x(i) = x1 + alpha [ exp(beta(i-1)) - 1 ], i = 1 .. n,
     414             :       ! where alpha = (x(n) - x(1))/[ exp(beta(n-1)) - 1 ],
     415             :       ! beta = log(r)/(n-2), r = (x(n)-x(n-1))/(x(2)-x(1)) = ratio of last to first interval,
     416             :       ! and intervals indexed by left-most points.
     417             :       ! N.B.: x outside [x1,xn] are indexed to nearest end.
     418             :       REAL(dp), INTENT(in)                               :: x
     419             :       INTEGER, INTENT(in)                                :: n
     420             :       REAL(dp), INTENT(in)                               :: x1, alpha, beta
     421             :       INTEGER                                            :: iixexp
     422             : 
     423             :       INTEGER                                            :: i
     424             : 
     425             :       ! index i of interval [x(i),x(i+1)] containing x
     426             :       ! target value
     427             :       ! number of mesh points
     428             :       ! initial point of mesh
     429             :       ! mesh parameter:
     430             :       !   x(i) = x1 + alpha [ exp(beta(i-1)) - 1 ], i = 1 .. n,
     431             :       ! where alpha = (x(n) - x(1))/[ exp(beta(n-1)) - 1 ],
     432             :       ! beta = log(r)/(n-2), r = (x(n)-x(n-1))/(x(2)-x(1)) = ratio of last to first interval,
     433             :       ! mesh parameter
     434             : 
     435             :       ! compute index
     436           0 :       i = INT(LOG((x - x1)/alpha + 1)/beta) + 1
     437             :       ! reset if outside 1..n
     438           0 :       IF (i < 1) i = 1
     439           0 :       IF (i > n - 1) i = n - 1
     440           0 :       iixexp = i
     441           0 :    END FUNCTION
     442             : 
     443             : !--------------------------------------------------------------------------------------------------!
     444             : 
     445             : ! **************************************************************************************************
     446             : !> \brief ...
     447             : !> \param x ...
     448             : !> \param c ...
     449             : !> \return ...
     450             : ! **************************************************************************************************
     451           0 :    FUNCTION poly3(x, c)
     452             :       ! returns value of polynomial \sum_{i=1}^4 c(i) (x-c(0))^(i-1)
     453             :       REAL(dp), INTENT(in)                               :: x, c(0:)
     454             :       REAL(dp)                                           :: poly3
     455             : 
     456             :       REAL(dp)                                           :: dx
     457             : 
     458             :       ! point at which to evaluate polynomial
     459             :       ! coefficients: poly = \sum_{i=1}^4 c(i) (x-c(0))^(i-1)
     460             : 
     461           0 :       dx = x - c(0)
     462           0 :       poly3 = c(1) + c(2)*dx + c(3)*dx**2 + c(4)*dx**3
     463           0 :    END FUNCTION
     464             : 
     465             : !--------------------------------------------------------------------------------------------------!
     466             : 
     467             : ! **************************************************************************************************
     468             : !> \brief ...
     469             : !> \param x ...
     470             : !> \param c ...
     471             : !> \return ...
     472             : ! **************************************************************************************************
     473           0 :    FUNCTION dpoly3(x, c)
     474             :       ! returns 1st derivative of polynomial \sum_{i=1}^4 c(i) (x-c(0))^(i-1)
     475             :       REAL(dp), INTENT(in)                               :: x, c(0:)
     476             :       REAL(dp)                                           :: dpoly3
     477             : 
     478             :       REAL(dp)                                           :: dx
     479             : 
     480             :       ! point at which to evaluate polynomial
     481             :       ! coefficients: poly = \sum_{i=1}^4 c(i) (x-c(0))^(i-1)
     482             : 
     483           0 :       dx = x - c(0)
     484           0 :       dpoly3 = c(2) + 2*c(3)*dx + 3*c(4)*dx**2
     485           0 :    END FUNCTION
     486             : 
     487             : !--------------------------------------------------------------------------------------------------!
     488             : 
     489             : ! **************************************************************************************************
     490             : !> \brief ...
     491             : !> \param x ...
     492             : !> \param c ...
     493             : !> \return ...
     494             : ! **************************************************************************************************
     495           0 :    FUNCTION d2poly3(x, c)
     496             :       ! returns 2nd derivative of polynomial \sum_{i=1}^4 c(i) (x-c(0))^(i-1)
     497             :       REAL(dp), INTENT(in)                               :: x, c(0:)
     498             :       REAL(dp)                                           :: d2poly3
     499             : 
     500             :       REAL(dp)                                           :: dx
     501             : 
     502             :       ! point at which to evaluate polynomial
     503             :       ! coefficients: poly = \sum_{i=1}^4 c(i) (x-c(0))^(i-1)
     504             : 
     505           0 :       dx = x - c(0)
     506           0 :       d2poly3 = 2*c(3) + 6*c(4)*dx
     507           0 :    END FUNCTION
     508             : 
     509             : !--------------------------------------------------------------------------------------------------!
     510             : 
     511             : ! **************************************************************************************************
     512             : !> \brief ...
     513             : !> \param msg ...
     514             : ! **************************************************************************************************
     515           0 :    SUBROUTINE stop_error(msg)
     516             :       ! Aborts the program
     517             :       CHARACTER(LEN=*)                                   :: msg
     518             : 
     519             : ! Message to print on stdout
     520           0 :       CPABORT(msg)
     521           0 :    END SUBROUTINE
     522             : 
     523             : END MODULE splines

Generated by: LCOV version 1.15