From 66dabe8cc4d33c4a84c8686b9599f33767b64536 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Sun, 1 Mar 2026 12:39:53 +0800 Subject: [PATCH] perf(polint): add ordn=6 specialized neville path --- AMSS_NCKU_source/fmisc.f90 | 98 +++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 16 deletions(-) diff --git a/AMSS_NCKU_source/fmisc.f90 b/AMSS_NCKU_source/fmisc.f90 index 17ce16b..64f3b43 100644 --- a/AMSS_NCKU_source/fmisc.f90 +++ b/AMSS_NCKU_source/fmisc.f90 @@ -1112,26 +1112,92 @@ end subroutine d2dump !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! common code for cell and vertex -!------------------------------------------------------------------------------ -! Lagrangian polynomial interpolation -!------------------------------------------------------------------------------ - -!DIR$ ATTRIBUTES FORCEINLINE :: polint - subroutine polint(xa, ya, x, y, dy, ordn) - implicit none - - integer, intent(in) :: ordn +!------------------------------------------------------------------------------ +! Lagrangian polynomial interpolation +!------------------------------------------------------------------------------ + +!DIR$ ATTRIBUTES FORCEINLINE :: polint6_neville + subroutine polint6_neville(xa, ya, x, y, dy) + implicit none + + real*8, dimension(6), intent(in) :: xa, ya + real*8, intent(in) :: x + real*8, intent(out) :: y, dy + + integer :: i, m, ns, n_m + real*8, dimension(6) :: c, d, ho + real*8 :: dif, dift, hp, h, den_val + + c = ya + d = ya + ho = xa - x + + ns = 1 + dif = abs(x - xa(1)) + + do i = 2, 6 + dift = abs(x - xa(i)) + if (dift < dif) then + ns = i + dif = dift + end if + end do + + y = ya(ns) + ns = ns - 1 + + do m = 1, 5 + n_m = 6 - m + do i = 1, n_m + hp = ho(i) + h = ho(i+m) + den_val = hp - h + + if (den_val == 0.0d0) then + write(*,*) 'failure in polint for point',x + write(*,*) 'with input points: ',xa + stop + end if + + den_val = (c(i+1) - d(i)) / den_val + + d(i) = h * den_val + c(i) = hp * den_val + end do + + if (2 * ns < n_m) then + dy = c(ns + 1) + else + dy = d(ns) + ns = ns - 1 + end if + y = y + dy + end do + + return + end subroutine polint6_neville + +!DIR$ ATTRIBUTES FORCEINLINE :: polint + subroutine polint(xa, ya, x, y, dy, ordn) + implicit none + + integer, intent(in) :: ordn real*8, dimension(ordn), intent(in) :: xa, ya real*8, intent(in) :: x real*8, intent(out) :: y, dy - integer :: i, m, ns, n_m - real*8, dimension(ordn) :: c, d, ho - real*8 :: dif, dift, hp, h, den_val - - c = ya - d = ya - ho = xa - x + integer :: i, m, ns, n_m + real*8, dimension(ordn) :: c, d, ho + real*8 :: dif, dift, hp, h, den_val + + if (ordn == 6) then + call polint6_neville(xa, ya, x, y, dy) + return + end if + + c = ya + d = ya + ho = xa - x ns = 1 dif = abs(x - xa(1))