LCOV - code coverage report
Current view: top level - src/common - splines.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 0.0 % 151 0
Test Date: 2025-12-04 06:27:48 Functions: 0.0 % 12 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 spline3
      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 spline3ders
      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 spline3pars
     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 spline3valder
     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 iix
     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 iixmin
     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 iixun
     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 iixexp
     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 poly3
     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 dpoly3
     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 d2poly3
     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 stop_error
     522              : 
     523              : END MODULE splines
        

Generated by: LCOV version 2.0-1