!-------------------------------------- LICENCE BEGIN ------------------------------------ !Environment Canada - Atmospheric Science and Technology License/Disclaimer, ! version 3; Last Modified: May 7, 2008. !This is free but copyrighted software; you can use/redistribute/modify it under the terms !of the Environment Canada - Atmospheric Science and Technology License/Disclaimer !version 3 or (at your option) any later version that should be found at: !http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html ! !This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; !without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. !See the above mentioned License/Disclaimer for more details. !You should have received a copy of the License/Disclaimer along with this software; !if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec), !CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca !-------------------------------------- LICENCE END -------------------------------------- ***s/r vterp1 - Finds the x point in f *subroutine vterp1 (F_x, F_fx, F_f, F_g, F_y, F_acc, np, nn) 1 #include "impnone.cdk"
* integer nn,np real F_x(np), F_fx(np), F_f(np,nn), F_g(np,nn), F_y(nn), F_acc * *AUTEUR * *revision * v2_30 Corbeil L. - vectorized version * *OBJECT * Given the values of a monotonic function F and the values of its * derivative G at NN points Y(1) TO Y(NN), this routine finds X * point at which F assumes the specified value FX. * AT INPUT A FIRST GUESS SHOULD BE PROVIDED FOR X. * WE ASSUME FX LE F(1) * *ARGUMENTS * Name I/O Description *---------------------------------------------------------------- * F_X O X point to find * F_F I function * F_FX I value at one point of the function * F_G I slopes of points * F_Y I value of points * F_ACC I accuracy requested for the interpolation *---------------------------------------------------------------------- * ** integer n,i real f0, g0, y0, dy, a, c, p, er, der, root, X f1, g1, y1, cd, b, r, q * * --------------------------------------------------------------- * do i=1,np * if (F_fx(i) .eq. F_f(i,nn)) then F_x(i) = F_y(nn) elseif (F_fx(i) .lt. F_f(i,nn)) then * EXTRAPOLATION f1 = F_f(i,nn-1) f0 = F_f(i,nn) g1 = F_g(i,nn-1) g0 = F_g(i,nn) y1 = F_y(nn-1) y0 = F_y(nn) root = g0**2 - 2.*(g0-g1)*(f0-F_fx(i))/(y0-y1) * * IF ROOT GE 0 USE QUADRATIC EXTRAPOLATION * * IF ROOT LT 0 .OR. G0 = G1 USE LINEAR FORMULA if (root.ge.0.0 .and. abs((g0-g1)/g0).gt.0.01) then root = sqrt(root) F_x(i) = y0-(y0-y1)*(g0+root)/(g0-g1) else F_x(i) = y0+(F_fx(i)-f0)/g0 endif elseif (F_fx(i) .gt. F_f(i,1)) then WRITE(*,*)'1 VTERP1 VALEUR A INTERPOLER TROP GRANDE' stop else * INTERPOLATION do 20 n=2,nn if (F_fx(i) .gt. F_f(i,n)) then f1 = F_f(i,n-1) f0 = F_f(i,n) g1 = F_g(i,n-1) g0 = F_g(i,n) y1 = F_y(n-1) y0 = F_y(n) dy = y1-y0 a = +f1/dy b = -f0/dy c = (g0+g1)/dy**2 - 2.*(f1-f0)/dy**3 cd = (y1*g0+y0*g1-(a+b)*(y1+y0))/dy**2 * * NEWTON FORMULA ITERATION LOOP 10 p = F_x(i)-y0 q = F_x(i)-y1 r = c*F_x(i)-cd er = a*p+b*q+p*q*r-F_fx(i) if (abs(er) .lt. F_acc) goto 40 der= a+b+p*r+q*r+c*p*q F_x(i) = F_x(i) -er/der go to 10 endif 20 continue endif * 40 continue * enddo * * --------------------------------------------------------------- * return end