LCOV - code coverage report
Current view: top level - interp_2d/private - renka790_db.f (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 510 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 9 0

            Line data    Source code
       1            0 :       subroutine do_CSHEP2_db (N,X,Y,F,NC,NW,NR, LCELL,LNEXT,XMIN,
       2            0 :      &                   YMIN,DX,DY,RMAX,RW,A,IER)
       3              :       integer :: N, NC, NW, NR, LCELL(NR,NR), LNEXT(N), IER
       4              :       double precision :: X(N), Y(N), F(N), XMIN, YMIN, DX,
       5              :      &                  DY, RMAX, RW(N), A(9,N)
       6              : 
       7              : ! **********************************************************
       8              : 
       9              : !                                               From CSHEP2D
      10              : !                                            Robert J. Renka
      11              : !                                  Dept. of Computer Science
      12              : !                                       Univ. of North Texas
      13              : !                                           renka@cs.unt.edu
      14              : !                                                   02/13/97
      15              : 
      16              : !   This subroutine computes a set of parameters defining a
      17              : ! C2 (twice continuously differentiable) bivariate function
      18              : ! C(X,Y) which interpolates data values F at a set of N
      19              : ! arbitrarily distributed points (X,Y) in the plane (nodes).
      20              : ! The interpolant C may be evaluated at an arbitrary point
      21              : ! by function CS2VAL, and its first partial derivatives are
      22              : ! computed by Subroutine CS2GRD.
      23              : 
      24              : !   The interpolation scheme is a modified Cubic Shepard
      25              : ! method:
      26              : 
      27              : ! C = [W(1)*C(1)+W(2)*C(2)+..+W(N)*C(N)]/[W(1)+W(2)+..+W(N)]
      28              : 
      29              : ! for bivariate functions W(k) and C(k).  The nodal func-
      30              : ! tions are given by
      31              : 
      32              : !  C(k)(x,y) = A(1,k)*(x-X(k))**3 +
      33              : !              A(2,k)*(x-X(k))**2*(y-Y(k)) +
      34              : !              A(3,k)*(x-X(k))*(y-Y(k))**2 +
      35              : !              A(4,k)*(y-Y(k))**3 + A(5,k)*(x-X(k))**2 +
      36              : !              A(6,k)*(x-X(k))*(y-Y(k)) + A(7,k)*(y-Y(k))**2
      37              : !              + A(8,k)*(x-X(k)) + A(9,k)*(y-Y(k)) + F(k) .
      38              : 
      39              : ! Thus, C(k) is a cubic function which interpolates the data
      40              : ! value at node k.  Its coefficients A(,k) are obtained by a
      41              : ! weighted least squares fit to the closest NC data points
      42              : ! with weights similar to W(k).  Note that the radius of
      43              : ! influence for the least squares fit is fixed for each k,
      44              : ! but varies with k.
      45              : 
      46              : ! The weights are taken to be
      47              : 
      48              : !   W(k)(x,y) = ( (R(k)-D(k))+ / R(k)*D(k) )**3 ,
      49              : 
      50              : ! where (R(k)-D(k))+ = 0 if R(k) < D(k), and D(k)(x,y) is
      51              : ! the Euclidean distance between (x,y) and (X(k),Y(k)).  The
      52              : ! radius of influence R(k) varies with k and is chosen so
      53              : ! that NW nodes are within the radius.  Note that W(k) is
      54              : ! not defined at node (X(k),Y(k)), but C(x,y) has limit F(k)
      55              : ! as (x,y) approaches (X(k),Y(k)).
      56              : 
      57              : ! On input:
      58              : 
      59              : !       N = Number of nodes and data values.  N >= 10.
      60              : 
      61              : !       X,Y = Arrays of length N containing the Cartesian
      62              : !             coordinates of the nodes.
      63              : 
      64              : !       F = Array of length N containing the data values
      65              : !           in one-to-one correspondence with the nodes.
      66              : 
      67              : !       NC = Number of data points to be used in the least
      68              : !            squares fit for coefficients defining the nodal
      69              : !            functions C(k).  Values found to be optimal for
      70              : !            test data sets ranged from 11 to 25.  A recom-
      71              : !            mended value for general data sets is NC = 17.
      72              : !            For nodes lying on (or close to) a rectangular
      73              : !            grid, the recommended value is NC = 11.  In any
      74              : !            case, NC must be in the range 9 to Min(40,N-1).
      75              : 
      76              : !       NW = Number of nodes within (and defining) the radii
      77              : !            of influence R(k) which enter into the weights
      78              : !            W(k).  For N sufficiently large, a recommended
      79              : !            value is NW = 30.  In general, NW should be
      80              : !            about 1.5*NC.  1 <= NW <= Min(40,N-1).
      81              : 
      82              : !       NR = Number of rows and columns in the cell grid de-
      83              : !            fined in Subroutine STORE2_db.  A rectangle con-
      84              : !            taining the nodes is partitioned into cells in
      85              : !            order to increase search efficiency.  NR =
      86              : !            Sqrt(N/3) is recommended.  NR >= 1.
      87              : 
      88              : ! The above parameters are not altered by this routine.
      89              : 
      90              : !       LCELL = Array of length >= NR**2.
      91              : 
      92              : !       LNEXT = Array of length >= N.
      93              : 
      94              : !       RW = Array of length >= N.
      95              : 
      96              : !       A = Array of length >= 9N.
      97              : 
      98              : ! On output:
      99              : 
     100              : !       LCELL = NR by NR array of nodal indexes associated
     101              : !               with cells.  Refer to Subroutine STORE2_db.
     102              : 
     103              : !       LNEXT = Array of length N containing next-node
     104              : !               indexes.  Refer to Subroutine STORE2_db.
     105              : 
     106              : !       XMIN,YMIN,DX,DY = Minimum nodal coordinates and cell
     107              : !                         dimensions.  Refer to Subroutine
     108              : !                         STORE2_db.
     109              : 
     110              : !       RMAX = Largest element in RW -- maximum radius R(k).
     111              : 
     112              : !       RW = Array containing the the radii R(k) which enter
     113              : !            into the weights W(k).
     114              : 
     115              : !       A = 9 by N array containing the coefficients for
     116              : !           cubic nodal function C(k) in column k.
     117              : 
     118              : !   Note that the output parameters described above are not
     119              : ! defined unless IER = 0.
     120              : 
     121              : !       IER = Error indicator:
     122              : !             IER = 0 if no errors were encountered.
     123              : !             IER = 1 if N, NC, NW, or NR is outside its
     124              : !                     valid range.
     125              : !             IER = 2 if duplicate nodes were encountered.
     126              : !             IER = 3 if all nodes are collinear.
     127              : 
     128              : ! Modules required by CSHEP2:  GETNP2_db, GIVENS_db, ROTATE_db,
     129              : !                                SETUP2_db, STORE2_db
     130              : 
     131              : ! Intrinsic functions called by CSHEP2:  ABS, DBLE, MAX,
     132              : !                                          MIN, SQRT
     133              : 
     134              : ! **********************************************************
     135              : 
     136              :       integer :: LMX
     137              :       parameter (LMX=40)
     138              :       integer :: I, IERR, IP1, IRM1, IROW, J, JP1, K, LMAX,
     139              :      &        LNP, NEQ, NN, NNC, NNR, NNW, NP, NPTS(LMX),
     140              :      &        NCWMAX
     141            0 :       double precision :: B(10,10), C, DDX, DDY, DMIN, DTOL,
     142            0 :      &                 FK, RC, RS, RSMX, RSOLD, RTOL, RWS,
     143            0 :      &                 S, SF, SFC, SFS, STF, SUM, T, XK,
     144            0 :      &                 XMN, YK, YMN
     145              : 
     146              : !      DATA    RTOL/1.D-5/, DTOL/.01/
     147              :       DATA    RTOL/1.D-5/, DTOL/1.D-5/
     148              : 
     149              : ! Local parameters:
     150              : 
     151              : ! B =          Transpose of the augmented regression matrix
     152              : ! C =          First component of the plane rotation used to
     153              : !                zero the lower triangle of B**T -- computed
     154              : !                by Subroutine GIVENS_db
     155              : ! DDX,DDY =    Local variables for DX and DY
     156              : ! DMIN =       Minimum of the magnitudes of the diagonal
     157              : !                elements of the regression matrix after
     158              : !                zeros are introduced below the diagonal
     159              : ! DTOL =       Tolerance for detecting an ill-conditioned
     160              : !                system.  The system is accepted when
     161              : !                DMIN*RC >= DTOL.
     162              : ! FK =         Data value at mode K -- F(K)
     163              : ! I =          Index for A, B, and NPTS
     164              : ! IERR =       Error flag for the call to Subroutine STORE2_db
     165              : ! IP1 =        I+1
     166              : ! IRM1 =       IROW-1
     167              : ! IROW =       Row index for B
     168              : ! J =          Index for A and B
     169              : ! JP1 =        J+1
     170              : ! K =          Nodal function index and column index for A
     171              : ! LMAX =       Maximum number of NPTS elements
     172              : ! LMX =        Maximum value of LMAX
     173              : ! LNP =        Current length of NPTS
     174              : ! NEQ =        Number of equations in the least squares fit
     175              : ! NN,NNC,NNR = Local copies of N, NC, and NR
     176              : ! NNW =        Local copy of NW
     177              : ! NP =         NPTS element
     178              : ! NPTS =       Array containing the indexes of a sequence of
     179              : !                nodes to be used in the least squares fit
     180              : !                or to compute RW.  The nodes are ordered
     181              : !                by distance from K, and the last element
     182              : !                (usually indexed by LNP) is used only to
     183              : !                determine RC, or RW(K) if NW > NC.
     184              : ! NCWMAX =     Max(NC,NW)
     185              : ! RC =         Radius of influence which enters into the
     186              : !                weights for C(K) (see Subroutine SETUP2_db)
     187              : ! RS =         Squared distance between K and NPTS(LNP) --
     188              : !                used to compute RC and RW(K)
     189              : ! RSMX =       Maximum squared RW element encountered
     190              : ! RSOLD =      Squared distance between K and NPTS(LNP-1) --
     191              : !                used to compute a relative change in RS
     192              : !                between succeeding NPTS elements
     193              : ! RTOL =       Tolerance for detecting a sufficiently large
     194              : !                relative change in RS.  If the change is
     195              : !                not greater than RTOL, the nodes are
     196              : !                treated as being the same distance from K
     197              : ! RWS =        Current squared value of RW(K)
     198              : ! S =          Second component of the plane rotation deter-
     199              : !                mined by subroutine GIVENS_db
     200              : ! SF =        Scale factor for the linear terms (columns 8
     201              : !               and 9) in the least squares fit -- inverse
     202              : !               of the root-mean-square distance between K
     203              : !               and the nodes (other than K) in the least
     204              : !               squares fit
     205              : ! SFS =       Scale factor for the quadratic terms (columns
     206              : !               5, 6, and 7) in the least squares fit --
     207              : !               SF*SF
     208              : ! SFC =       Scale factor for the cubic terms (first 4
     209              : !               columns) in the least squares fit -- SF**3
     210              : ! STF =        Marquardt stabilization factor used to damp
     211              : !                out the first 4 solution components (third
     212              : !                partials of the cubic) when the system is
     213              : !                ill-conditioned.  As STF increases, the
     214              : !                fitting function approaches a quadratic
     215              : !                polynomial.
     216              : ! SUM =        Sum of squared Euclidean distances between
     217              : !                node K and the nodes used in the least
     218              : !                squares fit (unless additional nodes are
     219              : !                added for stability)
     220              : ! T =          Temporary variable for accumulating a scalar
     221              : !                product in the back solve
     222              : ! XK,YK =      Coordinates of node K -- X(K), Y(K)
     223              : ! XMN,YMN =    Local variables for XMIN and YMIN
     224              : 
     225            0 :       NN = N
     226            0 :       NNC = NC
     227            0 :       NNW = NW
     228            0 :       NNR = NR
     229            0 :       NCWMAX = MAX(NNC,NNW)
     230            0 :       LMAX = MIN(LMX,NN-1)
     231              :       if (NNC < 9 .or. NNW < 1 .or. NCWMAX >
     232            0 :      &    LMAX .or. NNR < 1) GOTO 21
     233              : 
     234              : ! Create the cell data structure, and initialize RSMX.
     235              : 
     236            0 :       call STORE2_db (NN,X,Y,NNR, LCELL,LNEXT,XMN,YMN,DDX,DDY,IERR)
     237            0 :       if (IERR /= 0) GOTO 23
     238              :       RSMX = 0.
     239              : 
     240              : ! Outer loop on node K:
     241              : 
     242            0 :       do 16 K = 1,NN
     243            0 :         XK = X(K)
     244            0 :         YK = Y(K)
     245            0 :         FK = F(K)
     246              : 
     247              : ! Mark node K to exclude it from the search for nearest
     248              : !   neighbors.
     249              : 
     250            0 :         LNEXT(K) = -LNEXT(K)
     251              : 
     252              : ! Initialize for loop on NPTS.
     253              : 
     254            0 :         RS = 0.
     255            0 :         SUM = 0.
     256            0 :         RWS = 0.
     257            0 :         RC = 0.
     258            0 :         LNP = 0
     259              : 
     260              : ! Compute NPTS, LNP, RWS, NEQ, RC, and SFS.
     261              : 
     262            0 :     1   SUM = SUM + RS
     263            0 :           if (LNP == LMAX) GOTO 2
     264            0 :           LNP = LNP + 1
     265            0 :           RSOLD = RS
     266              :           call GETNP2_db (XK,YK,X,Y,NNR,LCELL,LNEXT,XMN,YMN,
     267            0 :      &                 DDX,DDY, NP,RS)
     268            0 :           if (RS == 0.) GOTO 22
     269            0 :           NPTS(LNP) = NP
     270            0 :           if ( (RS-RSOLD)/RS < RTOL ) GOTO 1
     271            0 :           if (RWS == 0. .and. LNP > NNW) RWS = RS
     272            0 :           if (RC == 0. .and. LNP > NNC) then
     273              : 
     274              : !   RC = 0 (not yet computed) and LNP > NC.  RC = Sqrt(RS)
     275              : !     is sufficiently large to (strictly) include NC nodes.
     276              : !     The least squares fit will include NEQ = LNP - 1
     277              : !     equations for 9 <= NC <= NEQ < LMAX <= N-1.
     278              : 
     279            0 :             NEQ = LNP - 1
     280            0 :             RC = SQRT(RS)
     281            0 :             SFS = DBLE(NEQ)/SUM
     282              :           end if
     283              : 
     284              : !   Bottom of loop -- test for termination.
     285              : 
     286            0 :           if (LNP > NCWMAX) GOTO 3
     287            0 :           GOTO 1
     288              : 
     289              : ! All LMAX nodes are included in NPTS.  RWS and/or RC**2 is
     290              : !   (arbitrarily) taken to be 10 percent larger than the
     291              : !   distance RS to the last node included.
     292              : 
     293            0 :     2   if (RWS == 0.) RWS = 1.1*RS
     294            0 :         if (RC == 0.) then
     295            0 :           NEQ = LMAX
     296            0 :           RC = SQRT(1.1*RS)
     297            0 :           SFS = DBLE(NEQ)/SUM
     298              :         end if
     299              : 
     300              : ! Store RW(K), update RSMX if necessary, and compute SF
     301              : !   and SFC.
     302              : 
     303            0 :     3   RW(K) = SQRT(RWS)
     304            0 :         if (RWS > RSMX) RSMX = RWS
     305            0 :         SF = SQRT(SFS)
     306            0 :         SFC = SF*SFS
     307              : 
     308              : ! A Q-R decomposition is used to solve the least squares
     309              : !   system.  The transpose of the augmented regression
     310              : !   matrix is stored in B with columns (rows of B) defined
     311              : !   as follows:  1-4 are the cubic terms, 5-7 are the quad-
     312              : !   ratic terms, 8 and 9 are the linear terms, and the last
     313              : !   column is the right hand side.
     314              : 
     315              : ! Set up the equations and zero out the lower triangle with
     316              : !   Givens rotations.
     317              : 
     318            0 :         I = 0
     319            0 :     4     I = I + 1
     320            0 :           NP = NPTS(I)
     321            0 :           IROW = MIN(I,10)
     322              :           call SETUP2_db (XK,YK,FK,X(NP),Y(NP),F(NP),SF,SFS,
     323            0 :      &                 SFC,RC, B(1,IROW))
     324            0 :           if (I == 1) GOTO 4
     325              :           IRM1 = IROW-1
     326            0 :           do 5 J = 1,IRM1
     327            0 :             JP1 = J + 1
     328            0 :             call GIVENS_db (B(J,J),B(J,IROW),C,S)
     329            0 :             call ROTATE_db (10-J,C,S,B(JP1,J),B(JP1,IROW))
     330            0 :     5       continue
     331            0 :           if (I < NEQ) GOTO 4
     332              : 
     333              : ! Test the system for ill-conditioning.
     334              : 
     335              :         DMIN = MIN( ABS(B(1,1)),ABS(B(2,2)),ABS(B(3,3)),
     336              :      &              ABS(B(4,4)),ABS(B(5,5)),ABS(B(6,6)),
     337            0 :      &              ABS(B(7,7)),ABS(B(8,8)),ABS(B(9,9)) )
     338            0 :         if (DMIN*RC >= DTOL) GOTO 11
     339            0 :         if (NEQ == LMAX) GOTO 7
     340              : 
     341              : ! Increase RC and add another equation to the system to
     342              : !   improve the conditioning.  The number of NPTS elements
     343              : !   is also increased if necessary.
     344              : 
     345            0 :     6   RSOLD = RS
     346            0 :         NEQ = NEQ + 1
     347            0 :         if (NEQ == LMAX) then
     348            0 :           RC = SQRT(1.1*RS)
     349            0 :           GOTO 4
     350              :         end if
     351            0 :         if (NEQ < LNP) then
     352              : 
     353              : !   NEQ < LNP.
     354              : 
     355            0 :           NP = NPTS(NEQ+1)
     356            0 :           RS = (X(NP)-XK)**2 + (Y(NP)-YK)**2
     357            0 :           if ( (RS-RSOLD)/RS < RTOL ) GOTO 6
     358            0 :           RC = SQRT(RS)
     359            0 :           GOTO 4
     360              :         end if
     361              : 
     362              : !   NEQ = LNP.  Add an element to NPTS.
     363              : 
     364            0 :         LNP = LNP + 1
     365              :         call GETNP2_db (XK,YK,X,Y,NNR,LCELL,LNEXT,XMN,YMN,
     366            0 :      &               DDX,DDY, NP,RS)
     367            0 :         if (NP == 0) GOTO 22
     368            0 :         NPTS(LNP) = NP
     369            0 :         if ( (RS-RSOLD)/RS < RTOL ) GOTO 6
     370            0 :         RC = SQRT(RS)
     371            0 :         GOTO 4
     372              : 
     373              : ! Stabilize the system by damping third partials -- add
     374              : !   multiples of the first four unit vectors to the first
     375              : !   four equations.
     376              : 
     377            0 :     7   STF = 1.0/RC
     378            0 :         do I = 1,4
     379            0 :           B(I,10) = STF
     380            0 :           IP1 = I + 1
     381            0 :           do J = IP1,10
     382            0 :             B(J,10) = 0.
     383              :           end do
     384            0 :           do J = I,9
     385            0 :             JP1 = J + 1
     386            0 :             call GIVENS_db (B(J,J),B(J,10),C,S)
     387            0 :             call ROTATE_db (10-J,C,S,B(JP1,J),B(JP1,10))
     388              :           end do
     389              :          end do
     390              : 
     391              : ! Test the damped system for ill-conditioning.
     392              : 
     393              :         DMIN = MIN( ABS(B(5,5)),ABS(B(6,6)),ABS(B(7,7)),
     394            0 :      &              ABS(B(8,8)),ABS(B(9,9)) )
     395            0 :         if (DMIN*RC < DTOL) then
     396              :             !write(*,*) 'DMIN*RC < DTOL', DMIN*RC < DTOL
     397              :             !write(*,*) 'DMIN', DMIN
     398              :             !write(*,*) 'RC', RC
     399              :             !write(*,*) 'DTOL', DTOL
     400              :             !write(*,*) 'DMIN*RC', DMIN*RC
     401              :             GOTO 23
     402              :         end if
     403              : 
     404              : ! Solve the 9 by 9 triangular system for the coefficients.
     405              : 
     406            0 :    11   do 13 I = 9,1,-1
     407            0 :           T = 0.
     408            0 :           if (I /= 9) then
     409            0 :             IP1 = I + 1
     410            0 :             do 12 J = IP1,9
     411            0 :               T = T + B(J,I)*A(J,K)
     412            0 :    12         continue
     413              :           end if
     414            0 :           A(I,K) = (B(10,I)-T)/B(I,I)
     415            0 :    13     continue
     416              : 
     417              : ! Scale the coefficients to adjust for the column scaling.
     418              : 
     419            0 :         do 14 I = 1,4
     420            0 :           A(I,K) = A(I,K)*SFC
     421            0 :    14     continue
     422            0 :         A(5,K) = A(5,K)*SFS
     423            0 :         A(6,K) = A(6,K)*SFS
     424            0 :         A(7,K) = A(7,K)*SFS
     425            0 :         A(8,K) = A(8,K)*SF
     426            0 :         A(9,K) = A(9,K)*SF
     427              : 
     428              : ! Unmark K and the elements of NPTS.
     429              : 
     430            0 :         LNEXT(K) = -LNEXT(K)
     431            0 :         do 15 I = 1,LNP
     432            0 :           NP = NPTS(I)
     433            0 :           LNEXT(NP) = -LNEXT(NP)
     434            0 :    15     continue
     435            0 :    16   continue
     436              : 
     437              : ! No errors encountered.
     438              : 
     439            0 :       XMIN = XMN
     440            0 :       YMIN = YMN
     441            0 :       DX = DDX
     442            0 :       DY = DDY
     443            0 :       RMAX = SQRT(RSMX)
     444            0 :       IER = 0
     445            0 :       return
     446              : 
     447              : ! N, NC, NW, or NR is outside its valid range.
     448              : 
     449            0 :    21 IER = 1
     450            0 :       return
     451              : 
     452              : ! Duplicate nodes were encountered by GETNP2_db.
     453              : 
     454            0 :    22 IER = 2
     455            0 :       return
     456              : 
     457              : ! No unique solution due to collinear nodes.
     458              : 
     459            0 :    23 XMIN = XMN
     460            0 :       YMIN = YMN
     461            0 :       DX = DDX
     462            0 :       DY = DDY
     463            0 :       IER = 3
     464              :       !write(*,*) 'do_CSHEP2_db ier = 3'
     465              :       !write(*,*) 'XMN', XMN
     466              :       !write(*,*) 'YMN', YMN
     467              :       !write(*,*) 'DDX', DDX
     468              :       !write(*,*) 'DDY', DDY
     469            0 :       return
     470              :       end subroutine do_CSHEP2_db
     471              : 
     472            0 :       double precision FUNCTION do_CS2VAL_db (PX,PY,N,X,Y,F,NR,
     473            0 :      &                LCELL,LNEXT,XMIN,YMIN,DX,DY,RMAX,RW,A,IER)
     474              :       integer :: N, NR, LCELL(NR,NR), LNEXT(N), IER
     475              :       double precision :: PX, PY, X(N), Y(N), F(N), XMIN, YMIN,
     476              :      &                 DX, DY, RMAX, RW(N), A(9,N)
     477              : 
     478              : ! **********************************************************
     479              : 
     480              : !                                               From CSHEP2D
     481              : !                                            Robert J. Renka
     482              : !                                  Dept. of Computer Science
     483              : !                                       Univ. of North Texas
     484              : !                                           renka@cs.unt.edu
     485              : !                                                   02/03/97
     486              : 
     487              : !   This function returns the value C(PX,PY), where C is the
     488              : ! weighted sum of cubic nodal functions defined in Subrou-
     489              : ! tine CSHEP2.  CS2GRD may be called to compute a gradient
     490              : ! of C along with the value, and/or to test for errors.
     491              : ! CS2HES_db may be called to compute a value, first partial
     492              : ! derivatives, and second partial derivatives at a point.
     493              : 
     494              : ! On input:
     495              : 
     496              : !       PX,PY = Cartesian coordinates of the point P at
     497              : !               which C is to be evaluated.
     498              : 
     499              : !       N = Number of nodes and data values defining C.
     500              : !           N >= 10.
     501              : 
     502              : !       X,Y,F = Arrays of length N containing the nodes and
     503              : !               data values interpolated by C.
     504              : 
     505              : !       NR = Number of rows and columns in the cell grid.
     506              : !            Refer to Subroutine STORE2_db.  NR >= 1.
     507              : 
     508              : !       LCELL = NR by NR array of nodal indexes associated
     509              : !               with cells.  Refer to Subroutine STORE2_db.
     510              : 
     511              : !       LNEXT = Array of length N containing next-node
     512              : !               indexes.  Refer to Subroutine STORE2_db.
     513              : 
     514              : !       XMIN,YMIN,DX,DY = Minimum nodal coordinates and cell
     515              : !                         dimensions.  DX and DY must be
     516              : !                         positive.  Refer to Subroutine
     517              : !                         STORE2_db.
     518              : 
     519              : !       RMAX = Largest element in RW -- maximum radius R(k).
     520              : 
     521              : !       RW = Array containing the the radii R(k) which enter
     522              : !            into the weights W(k) defining C.
     523              : 
     524              : !       A = 9 by N array containing the coefficients for
     525              : !           cubic nodal function C(k) in column k.
     526              : 
     527              : !   Input parameters are not altered by this function.  The
     528              : ! parameters other than PX and PY should be input unaltered
     529              : ! from their values on output from CSHEP2.  This function
     530              : ! should not be called if a nonzero error flag was returned
     531              : ! by CSHEP2.
     532              : 
     533              : ! On output:
     534              : 
     535              : !       CS2VAL = Function value C(PX,PY) unless N, NR, DX,
     536              : !                DY, or RMAX is invalid, in which case no
     537              : !                value is returned.
     538              : 
     539              : ! Modules required by CS2VAL:  NONE
     540              : 
     541              : ! Intrinsic functions called by CS2VAL:  INT, SQRT
     542              : 
     543              : ! **********************************************************
     544              : 
     545              :       integer :: I, IMAX, IMIN, J, JMAX, JMIN, K, KP
     546            0 :       double precision :: D, DELX, DELY, R, SW, SWC, W, XP, YP
     547              : 
     548              : ! Local parameters:
     549              : 
     550              : ! D =         Distance between P and node K
     551              : ! DELX =      XP - X(K)
     552              : ! DELY =      YP - Y(K)
     553              : ! I =         Cell row index in the range IMIN to IMAX
     554              : ! IMIN,IMAX = Range of cell row indexes of the cells
     555              : !               intersected by a disk of radius RMAX
     556              : !               centered at P
     557              : ! J =         Cell column index in the range JMIN to JMAX
     558              : ! JMIN,JMAX = Range of cell column indexes of the cells
     559              : !               intersected by a disk of radius RMAX
     560              : !               centered at P
     561              : ! K =         Index of a node in cell (I,J)
     562              : ! KP =        Previous value of K in the sequence of nodes
     563              : !               in cell (I,J)
     564              : ! R =         Radius of influence for node K
     565              : ! SW =        Sum of weights W(K)
     566              : ! SWC =       Sum of weighted nodal function values at P
     567              : ! W =         Weight W(K) value at P:  ((R-D)+/(R*D))**3,
     568              : !               where (R-D)+ = 0 if R < D
     569              : ! XP,YP =     Local copies of PX and PY -- coordinates of P
     570              : 
     571            0 :       XP = PX
     572            0 :       YP = PY
     573            0 :       IER = -1
     574              :       if (N < 10 .or. NR < 1 .or. DX <= 0.  .or.
     575            0 :      &    DY <= 0. .or. RMAX < 0.) return
     576            0 :       IER = 0
     577              : 
     578              : ! Set IMIN, IMAX, JMIN, and JMAX to cell indexes defining
     579              : !   the range of the search for nodes whose radii include
     580              : !   P.  The cells which must be searched are those inter-
     581              : !   sected by (or contained in) a circle of radius RMAX
     582              : !   centered at P.
     583              : 
     584            0 :       IMIN = INT((XP-XMIN-RMAX)/DX) + 1
     585            0 :       IMAX = INT((XP-XMIN+RMAX)/DX) + 1
     586            0 :       if (IMIN < 1) IMIN = 1
     587            0 :       if (IMAX > NR) IMAX = NR
     588            0 :       JMIN = INT((YP-YMIN-RMAX)/DY) + 1
     589            0 :       JMAX = INT((YP-YMIN+RMAX)/DY) + 1
     590            0 :       if (JMIN < 1) JMIN = 1
     591            0 :       if (JMAX > NR) JMAX = NR
     592              : 
     593              : ! The following is a test for no cells within the circle
     594              : !   of radius RMAX.
     595              : 
     596            0 :       if (IMIN > IMAX .or. JMIN > JMAX) GOTO 6
     597              : 
     598              : ! Accumulate weight values in SW and weighted nodal function
     599              : !   values in SWC.  The weights are W(K) = ((R-D)+/(R*D))**3
     600              : !   for R = RW(K) and D = distance between P and node K.
     601              : 
     602              :       SW = 0.
     603              :       SWC = 0.
     604              : 
     605              : ! Outer loop on cells (I,J).
     606              : 
     607            0 :       do 4 J = JMIN,JMAX
     608            0 :         do 3 I = IMIN,IMAX
     609            0 :           K = LCELL(I,J)
     610            0 :           if (K == 0) GOTO 3
     611              : 
     612              : ! Inner loop on nodes K.
     613              : 
     614            0 :     1     DELX = XP - X(K)
     615            0 :           DELY = YP - Y(K)
     616            0 :           D = SQRT(DELX*DELX + DELY*DELY)
     617            0 :           R = RW(K)
     618            0 :           if (D >= R) GOTO 2
     619            0 :           if (D == 0.) GOTO 5
     620            0 :           W = (1.0/D - 1.0/R)*(1.0/D - 1.0/R)*(1.0/D - 1.0/R)
     621            0 :           SW = SW + W
     622              :           SWC = SWC + W*( ( (A(1,K)*DELX+A(2,K)*DELY+
     623              :      &                       A(5,K))*DELX + (A(3,K)*DELY+
     624              :      &                       A(6,K))*DELY + A(8,K) )*DELX +
     625              :      &                    ( (A(4,K)*DELY+A(7,K))*DELY +
     626            0 :      &                      A(9,K) )*DELY + F(K) )
     627              : 
     628              : ! Bottom of loop on nodes in cell (I,J).
     629              : 
     630            0 :     2     KP = K
     631            0 :           K = LNEXT(KP)
     632            0 :           if (K /= KP) GOTO 1
     633            0 :     3     continue
     634            0 :     4   continue
     635              : 
     636              : ! SW = 0 iff P is not within the radius R(K) for any node K.
     637              : 
     638            0 :       if (SW == 0.) GOTO 6
     639            0 :       do_CS2VAL_db = SWC/SW
     640            0 :       return
     641              : 
     642              : ! (PX,PY) = (X(K),Y(K)).
     643              : 
     644            0 :     5 do_CS2VAL_db = F(K)
     645            0 :       return
     646              : 
     647              : ! All weights are 0 at P.
     648              : 
     649            0 :     6 do_CS2VAL_db = 0.
     650              :       return
     651              :       end function do_CS2VAL_db
     652              : 
     653            0 :       subroutine do_CS2GRD_db (PX,PY,N,X,Y,F,NR,LCELL,LNEXT,XMIN,
     654            0 :      &                   YMIN,DX,DY,RMAX,RW,A, C,CX,CY,IER)
     655              :       integer :: N, NR, LCELL(NR,NR), LNEXT(N), IER
     656              :       double precision :: PX, PY, X(N), Y(N), F(N), XMIN, YMIN,
     657              :      &                 DX, DY, RMAX, RW(N), A(9,N), C, CX,
     658              :      &                 CY
     659              : 
     660              : ! **********************************************************
     661              : 
     662              : !                                               From CSHEP2D
     663              : !                                            Robert J. Renka
     664              : !                                  Dept. of Computer Science
     665              : !                                       Univ. of North Texas
     666              : !                                           renka@cs.unt.edu
     667              : !                                                   02/03/97
     668              : 
     669              : !   This subroutine computes the value and gradient at P =
     670              : ! (PX,PY) of the interpolatory function C defined in Sub-
     671              : ! routine CSHEP2.  C is a weighted sum of cubic nodal
     672              : ! functions.
     673              : 
     674              : ! On input:
     675              : 
     676              : !       PX,PY = Cartesian coordinates of the point P at
     677              : !               which C and its partial derivatives are
     678              : !               to be evaluated.
     679              : 
     680              : !       N = Number of nodes and data values defining C.
     681              : !           N >= 10.
     682              : 
     683              : !       X,Y,F = Arrays of length N containing the nodes and
     684              : !               data values interpolated by C.
     685              : 
     686              : !       NR = Number of rows and columns in the cell grid.
     687              : !            Refer to Subroutine STORE2_db.  NR >= 1.
     688              : 
     689              : !       LCELL = NR by NR array of nodal indexes associated
     690              : !               with cells.  Refer to Subroutine STORE2_db.
     691              : 
     692              : !       LNEXT = Array of length N containing next-node
     693              : !               indexes.  Refer to Subroutine STORE2_db.
     694              : 
     695              : !       XMIN,YMIN,DX,DY = Minimum nodal coordinates and cell
     696              : !                         dimensions.  DX and DY must be
     697              : !                         positive.  Refer to Subroutine
     698              : !                         STORE2_db.
     699              : 
     700              : !       RMAX = Largest element in RW -- maximum radius R(k).
     701              : 
     702              : !       RW = Array of length N containing the the radii R(k)
     703              : !            which enter into the weights W(k) defining C.
     704              : 
     705              : !       A = 9 by N array containing the coefficients for
     706              : !           cubic nodal function C(k) in column k.
     707              : 
     708              : !   Input parameters are not altered by this subroutine.
     709              : ! The parameters other than PX and PY should be input
     710              : ! unaltered from their values on output from CSHEP2.  This
     711              : ! subroutine should not be called if a nonzero error flag
     712              : ! was returned by CSHEP2.
     713              : 
     714              : ! On output:
     715              : 
     716              : !       C = Value of C at (PX,PY) unless IER == 1, in
     717              : !           which case no values are returned.
     718              : 
     719              : !       CX,CY = First partial derivatives of C at (PX,PY)
     720              : !               unless IER == 1.
     721              : 
     722              : !       IER = Error indicator:
     723              : !             IER = 0 if no errors were encountered.
     724              : !             IER = 1 if N, NR, DX, DY or RMAX is invalid.
     725              : !             IER = 2 if no errors were encountered but
     726              : !                     (PX,PY) is not within the radius R(k)
     727              : !                     for any node k (and thus C=CX=CY=0).
     728              : 
     729              : ! Modules required by CS2GRD:  None
     730              : 
     731              : ! Intrinsic functions called by CS2GRD:  INT, SQRT
     732              : 
     733              : ! **********************************************************
     734              : 
     735              :       integer :: I, IMAX, IMIN, J, JMAX, JMIN, K, KP
     736            0 :       double precision :: CK, CKX, CKY, D, DELX, DELY, R, SW,
     737            0 :      &                 SWC, SWCX, SWCY, SWS, SWX, SWY, T, W,
     738            0 :      &                 WX, WY, XP, YP
     739              : 
     740              : ! Local parameters:
     741              : 
     742              : ! CK =        Value of cubic nodal function C(K) at P
     743              : ! CKX,CKY =   Partial derivatives of C(K) with respect to X
     744              : !               and Y, respectively
     745              : ! D =         Distance between P and node K
     746              : ! DELX =      XP - X(K)
     747              : ! DELY =      YP - Y(K)
     748              : ! I =         Cell row index in the range IMIN to IMAX
     749              : ! IMIN,IMAX = Range of cell row indexes of the cells
     750              : !               intersected by a disk of radius RMAX
     751              : !               centered at P
     752              : ! J =         Cell column index in the range JMIN to JMAX
     753              : ! JMIN,JMAX = Range of cell column indexes of the cells
     754              : !               intersected by a disk of radius RMAX
     755              : !               centered at P
     756              : ! K =         Index of a node in cell (I,J)
     757              : ! KP =        Previous value of K in the sequence of nodes
     758              : !               in cell (I,J)
     759              : ! R =         Radius of influence for node K
     760              : ! SW =        Sum of weights W(K)
     761              : ! SWC =       Sum of weighted nodal function values at P
     762              : ! SWCX,SWCY = Partial derivatives of SWC with respect to X
     763              : !               and Y, respectively
     764              : ! SWS =       SW**2
     765              : ! SWX,SWY =   Partial derivatives of SW with respect to X
     766              : !               and Y, respectively
     767              : ! T =         Temporary variable
     768              : ! W =         Weight W(K) value at P:  ((R-D)+/(R*D))**3,
     769              : !               where (R-D)+ = 0 if R < D
     770              : ! WX,WY =     Partial derivatives of W with respect to X
     771              : !               and Y, respectively
     772              : ! XP,YP =     Local copies of PX and PY -- coordinates of P
     773              : 
     774            0 :       XP = PX
     775            0 :       YP = PY
     776              :       if (N < 10 .or. NR < 1 .or. DX <= 0.  .or.
     777            0 :      &    DY <= 0. .or. RMAX < 0.) GOTO 6
     778              : 
     779              : ! Set IMIN, IMAX, JMIN, and JMAX to cell indexes defining
     780              : !   the range of the search for nodes whose radii include
     781              : !   P.  The cells which must be searched are those inter-
     782              : !   sected by (or contained in) a circle of radius RMAX
     783              : !   centered at P.
     784              : 
     785            0 :       IMIN = INT((XP-XMIN-RMAX)/DX) + 1
     786            0 :       IMAX = INT((XP-XMIN+RMAX)/DX) + 1
     787            0 :       if (IMIN < 1) IMIN = 1
     788            0 :       if (IMAX > NR) IMAX = NR
     789            0 :       JMIN = INT((YP-YMIN-RMAX)/DY) + 1
     790            0 :       JMAX = INT((YP-YMIN+RMAX)/DY) + 1
     791            0 :       if (JMIN < 1) JMIN = 1
     792            0 :       if (JMAX > NR) JMAX = NR
     793              : 
     794              : ! The following is a test for no cells within the circle
     795              : !   of radius RMAX.
     796              : 
     797            0 :       if (IMIN > IMAX .or. JMIN > JMAX) GOTO 7
     798              : 
     799              : ! C = SWC/SW = Sum(W(K)*C(K))/Sum(W(K)), where the sum is
     800              : !   from K = 1 to N, C(K) is the cubic nodal function value,
     801              : !   and W(K) = ((R-D)+/(R*D))**3 for radius R(K) and dist-
     802              : !   ance D(K).  Thus
     803              : 
     804              : !        CX = (SWCX*SW - SWC*SWX)/SW**2  and
     805              : !        CY = (SWCY*SW - SWC*SWY)/SW**2
     806              : 
     807              : !   where SWCX and SWX are partial derivatives with respect
     808              : !   to X of SWC and SW, respectively.  SWCY and SWY are de-
     809              : !   fined similarly.
     810              : 
     811              :       SW = 0.
     812              :       SWX = 0.
     813              :       SWY = 0.
     814              :       SWC = 0.
     815              :       SWCX = 0.
     816              :       SWCY = 0.
     817              : 
     818              : ! Outer loop on cells (I,J).
     819              : 
     820            0 :       do 4 J = JMIN,JMAX
     821            0 :         do 3 I = IMIN,IMAX
     822            0 :           K = LCELL(I,J)
     823            0 :           if (K == 0) GOTO 3
     824              : 
     825              : ! Inner loop on nodes K.
     826              : 
     827            0 :     1     DELX = XP - X(K)
     828            0 :           DELY = YP - Y(K)
     829            0 :           D = SQRT(DELX*DELX + DELY*DELY)
     830            0 :           R = RW(K)
     831            0 :           if (D >= R) GOTO 2
     832            0 :           if (D == 0.) GOTO 5
     833            0 :           T = (1.0/D - 1.0/R)
     834            0 :           W = T*T*T
     835            0 :           T = -3.0*T*T/(D*D*D)
     836            0 :           WX = DELX*T
     837            0 :           WY = DELY*T
     838            0 :           T = A(2,K)*DELX + A(3,K)*DELY + A(6,K)
     839              :           CKY = ( 3.0*A(4,K)*DELY + A(3,K)*DELX +
     840            0 :      &            2.0*A(7,K) )*DELY + T*DELX + A(9,K)
     841            0 :           T = T*DELY + A(8,K)
     842              :           CKX = ( 3.0*A(1,K)*DELX + A(2,K)*DELY +
     843            0 :      &            2.0*A(5,K) )*DELX + T
     844              :           CK = ( (A(1,K)*DELX+A(5,K))*DELX + T )*DELX +
     845              :      &         ( (A(4,K)*DELY+A(7,K))*DELY + A(9,K) )*DELY +
     846            0 :      &         F(K)
     847            0 :           SW = SW + W
     848            0 :           SWX = SWX + WX
     849            0 :           SWY = SWY + WY
     850            0 :           SWC = SWC + W*CK
     851            0 :           SWCX = SWCX + WX*CK + W*CKX
     852            0 :           SWCY = SWCY + WY*CK + W*CKY
     853              : 
     854              : ! Bottom of loop on nodes in cell (I,J).
     855              : 
     856            0 :     2     KP = K
     857            0 :           K = LNEXT(KP)
     858            0 :           if (K /= KP) GOTO 1
     859            0 :     3     continue
     860            0 :     4   continue
     861              : 
     862              : ! SW = 0 iff P is not within the radius R(K) for any node K.
     863              : 
     864            0 :       if (SW == 0.) GOTO 7
     865            0 :       C = SWC/SW
     866            0 :       SWS = SW*SW
     867            0 :       CX = (SWCX*SW - SWC*SWX)/SWS
     868            0 :       CY = (SWCY*SW - SWC*SWY)/SWS
     869            0 :       IER = 0
     870            0 :       return
     871              : 
     872              : ! (PX,PY) = (X(K),Y(K)).
     873              : 
     874            0 :     5 C = F(K)
     875            0 :       CX = A(8,K)
     876            0 :       CY = A(9,K)
     877            0 :       IER = 0
     878            0 :       return
     879              : 
     880              : ! Invalid input parameter.
     881              : 
     882            0 :     6 IER = 1
     883            0 :       return
     884              : 
     885              : ! No cells contain a point within RMAX of P, or
     886              : !   SW = 0 and thus D >= RW(K) for all K.
     887              : 
     888            0 :     7 C = 0.
     889            0 :       CX = 0.
     890            0 :       CY = 0.
     891            0 :       IER = 2
     892            0 :       return
     893              :       end subroutine do_CS2GRD_db
     894            0 :       subroutine CS2HES_db (PX,PY,N,X,Y,F,NR,LCELL,LNEXT,XMIN,
     895            0 :      &                   YMIN,DX,DY,RMAX,RW,A, C,CX,CY,CXX,
     896              :      &                   CXY,CYY,IER)
     897              :       integer :: N, NR, LCELL(NR,NR), LNEXT(N), IER
     898              :       double precision :: PX, PY, X(N), Y(N), F(N), XMIN, YMIN,
     899              :      &                 DX, DY, RMAX, RW(N), A(9,N), C, CX,
     900              :      &                 CY, CXX, CXY, CYY
     901              : 
     902              : ! **********************************************************
     903              : 
     904              : !                                               From CSHEP2D
     905              : !                                            Robert J. Renka
     906              : !                                  Dept. of Computer Science
     907              : !                                       Univ. of North Texas
     908              : !                                           renka@cs.unt.edu
     909              : !                                                   02/03/97
     910              : 
     911              : !   This subroutine computes the value, gradient, and
     912              : ! Hessian at P = (PX,PY) of the interpolatory function C
     913              : ! defined in Subroutine CSHEP2.  C is a weighted sum of
     914              : ! cubic nodal functions.
     915              : 
     916              : ! On input:
     917              : 
     918              : !       PX,PY = Cartesian coordinates of the point P at
     919              : !               which C and its partial derivatives are
     920              : !               to be evaluated.
     921              : 
     922              : !       N = Number of nodes and data values defining C.
     923              : !           N >= 10.
     924              : 
     925              : !       X,Y,F = Arrays of length N containing the nodes and
     926              : !               data values interpolated by C.
     927              : 
     928              : !       NR = Number of rows and columns in the cell grid.
     929              : !            Refer to Subroutine STORE2_db.  NR >= 1.
     930              : 
     931              : !       LCELL = NR by NR array of nodal indexes associated
     932              : !               with cells.  Refer to Subroutine STORE2_db.
     933              : 
     934              : !       LNEXT = Array of length N containing next-node
     935              : !               indexes.  Refer to Subroutine STORE2_db.
     936              : 
     937              : !       XMIN,YMIN,DX,DY = Minimum nodal coordinates and cell
     938              : !                         dimensions.  DX and DY must be
     939              : !                         positive.  Refer to Subroutine
     940              : !                         STORE2_db.
     941              : 
     942              : !       RMAX = Largest element in RW -- maximum radius R(k).
     943              : 
     944              : !       RW = Array of length N containing the the radii R(k)
     945              : !            which enter into the weights W(k) defining C.
     946              : 
     947              : !       A = 9 by N array containing the coefficients for
     948              : !           cubic nodal function C(k) in column k.
     949              : 
     950              : !   Input parameters are not altered by this subroutine.
     951              : ! The parameters other than PX and PY should be input
     952              : ! unaltered from their values on output from CSHEP2.  This
     953              : ! subroutine should not be called if a nonzero error flag
     954              : ! was returned by CSHEP2.
     955              : 
     956              : ! On output:
     957              : 
     958              : !       C = Value of C at (PX,PY) unless IER == 1, in
     959              : !           which case no values are returned.
     960              : 
     961              : !       CX,CY = First partial derivatives of C at (PX,PY)
     962              : !               unless IER == 1.
     963              : 
     964              : !       CXX,CXY,CYY = Second partial derivatives of C at
     965              : !                     (PX,PY) unless IER == 1.
     966              : 
     967              : !       IER = Error indicator:
     968              : !             IER = 0 if no errors were encountered.
     969              : !             IER = 1 if N, NR, DX, DY or RMAX is invalid.
     970              : !             IER = 2 if no errors were encountered but
     971              : !                     (PX,PY) is not within the radius R(k)
     972              : !                     for any node k (and thus C = 0).
     973              : 
     974              : ! Modules required by CS2HES_db:  None
     975              : 
     976              : ! Intrinsic functions called by CS2HES_db:  INT, SQRT
     977              : 
     978              : ! **********************************************************
     979              : 
     980              :       integer :: I, IMAX, IMIN, J, JMAX, JMIN, K, KP
     981            0 :       double precision :: CK, CKX, CKXX, CKXY, CKY, CKYY, D,
     982            0 :      &                 DELX, DELY, DXSQ, DYSQ, R, SW, SWC,
     983            0 :      &                 SWCX, SWCXX, SWCXY, SWCY, SWCYY, SWS,
     984            0 :      &                 SWX, SWXX, SWXY, SWY, SWYY, T1, T2,
     985            0 :      &                 T3, T4, W, WX, WXX, WXY, WY, WYY, XP,
     986            0 :      &                 YP, D6
     987              : 
     988              : ! Local parameters:
     989              : 
     990              : ! CK =        Value of cubic nodal function C(K) at P
     991              : ! CKX,CKY =   Partial derivatives of C(K) with respect to X
     992              : !               and Y, respectively
     993              : ! CKXX,CKXY,CKYY = Second partial derivatives of CK
     994              : ! D =         Distance between P and node K
     995              : ! DELX =      XP - X(K)
     996              : ! DELY =      YP - Y(K)
     997              : ! DXSQ,DYSQ = DELX**2, DELY**2
     998              : ! I =         Cell row index in the range IMIN to IMAX
     999              : ! IMIN,IMAX = Range of cell row indexes of the cells
    1000              : !               intersected by a disk of radius RMAX
    1001              : !               centered at P
    1002              : ! J =         Cell column index in the range JMIN to JMAX
    1003              : ! JMIN,JMAX = Range of cell column indexes of the cells
    1004              : !               intersected by a disk of radius RMAX
    1005              : !               centered at P
    1006              : ! K =         Index of a node in cell (I,J)
    1007              : ! KP =        Previous value of K in the sequence of nodes
    1008              : !               in cell (I,J)
    1009              : ! R =         Radius of influence for node K
    1010              : ! SW =        Sum of weights W(K)
    1011              : ! SWC =       Sum of weighted nodal function values at P
    1012              : ! SWCX,SWCY = Partial derivatives of SWC with respect to X
    1013              : !               and Y, respectively
    1014              : ! SWCXX,SWCXY,SWCYY = Second partial derivatives of SWC
    1015              : ! SWS =       SW**2
    1016              : ! SWX,SWY =   Partial derivatives of SW with respect to X
    1017              : !               and Y, respectively
    1018              : ! SWXX,SWXY,SWYY = Second partial derivatives of SW
    1019              : ! T1,T2,T3,T4 = Temporary variables
    1020              : ! W =         Weight W(K) value at P:  ((R-D)+/(R*D))**3,
    1021              : !               where (R-D)+ = 0 if R < D
    1022              : ! WX,WY =     Partial derivatives of W with respect to X
    1023              : !               and Y, respectively
    1024              : ! WXX,WXY,WYY = Second partial derivatives of W
    1025              : ! XP,YP =     Local copies of PX and PY -- coordinates of P
    1026              : 
    1027            0 :       XP = PX
    1028            0 :       YP = PY
    1029              :       if (N < 10 .or. NR < 1 .or. DX <= 0.  .or.
    1030            0 :      &    DY <= 0. .or. RMAX < 0.) GOTO 6
    1031              : 
    1032              : ! Set IMIN, IMAX, JMIN, and JMAX to cell indexes defining
    1033              : !   the range of the search for nodes whose radii include
    1034              : !   P.  The cells which must be searched are those inter-
    1035              : !   sected by (or contained in) a circle of radius RMAX
    1036              : !   centered at P.
    1037              : 
    1038            0 :       IMIN = INT((XP-XMIN-RMAX)/DX) + 1
    1039            0 :       IMAX = INT((XP-XMIN+RMAX)/DX) + 1
    1040            0 :       if (IMIN < 1) IMIN = 1
    1041            0 :       if (IMAX > NR) IMAX = NR
    1042            0 :       JMIN = INT((YP-YMIN-RMAX)/DY) + 1
    1043            0 :       JMAX = INT((YP-YMIN+RMAX)/DY) + 1
    1044            0 :       if (JMIN < 1) JMIN = 1
    1045            0 :       if (JMAX > NR) JMAX = NR
    1046              : 
    1047              : ! The following is a test for no cells within the circle
    1048              : !   of radius RMAX.
    1049              : 
    1050            0 :       if (IMIN > IMAX .or. JMIN > JMAX) GOTO 7
    1051              : 
    1052              : ! C = SWC/SW = Sum(W(K)*C(K))/Sum(W(K)), where the sum is
    1053              : !   from K = 1 to N, C(K) is the cubic nodal function value,
    1054              : !   and W(K) = ((R-D)+/(R*D))**3 for radius R(K) and dist-
    1055              : !   ance D(K).  Thus
    1056              : 
    1057              : !        CX = (SWCX*SW - SWC*SWX)/SW**2  and
    1058              : !        CY = (SWCY*SW - SWC*SWY)/SW**2
    1059              : 
    1060              : !   where SWCX and SWX are partial derivatives with respect
    1061              : !   to x of SWC and SW, respectively.  SWCY and SWY are de-
    1062              : !   fined similarly.  The second partials are
    1063              : 
    1064              : !        CXX = ( SW*(SWCXX -    2*SWX*CX) - SWC*SWXX )/SW**2
    1065              : !        CXY = ( SW*(SWCXY-SWX*CY-SWY*CX) - SWC*SWXY )/SW**2
    1066              : !        CYY = ( SW*(SWCYY -    2*SWY*CY) - SWC*SWYY )/SW**2
    1067              : 
    1068              : !   where SWCXX and SWXX are second partials with respect
    1069              : !   to x, SWCXY and SWXY are mixed partials, and SWCYY and
    1070              : !   SWYY are second partials with respect to y.
    1071              : 
    1072              :       SW = 0.
    1073              :       SWX = 0.
    1074              :       SWY = 0.
    1075              :       SWXX = 0.
    1076              :       SWXY = 0.
    1077              :       SWYY = 0.
    1078              :       SWC = 0.
    1079              :       SWCX = 0.
    1080              :       SWCY = 0.
    1081              :       SWCXX = 0.
    1082              :       SWCXY = 0.
    1083              :       SWCYY = 0.
    1084              : 
    1085              : ! Outer loop on cells (I,J).
    1086              : 
    1087            0 :       do 4 J = JMIN,JMAX
    1088            0 :         do 3 I = IMIN,IMAX
    1089            0 :           K = LCELL(I,J)
    1090            0 :           if (K == 0) GOTO 3
    1091              : 
    1092              : ! Inner loop on nodes K.
    1093              : 
    1094            0 :     1     DELX = XP - X(K)
    1095            0 :           DELY = YP - Y(K)
    1096            0 :           DXSQ = DELX*DELX
    1097            0 :           DYSQ = DELY*DELY
    1098            0 :           D = SQRT(DXSQ + DYSQ)
    1099            0 :           R = RW(K)
    1100            0 :           if (D >= R) GOTO 2
    1101            0 :           if (D == 0.) GOTO 5
    1102            0 :           T1 = (1.0/D - 1.0/R)
    1103            0 :           W = T1*T1*T1
    1104            0 :           T2 = -3.0*T1*T1/(D*D*D)
    1105            0 :           WX = DELX*T2
    1106            0 :           WY = DELY*T2
    1107            0 :           D6 = D*D*D*D*D*D
    1108            0 :           T1 = 3.0*T1*(2.0+3.0*D*T1)/D6
    1109            0 :           WXX = T1*DXSQ + T2
    1110            0 :           WXY = T1*DELX*DELY
    1111            0 :           WYY = T1*DYSQ + T2
    1112            0 :           T1 = A(1,K)*DELX + A(2,K)*DELY + A(5,K)
    1113            0 :           T2 = T1 + T1 + A(1,K)*DELX
    1114            0 :           T3 = A(4,K)*DELY + A(3,K)*DELX + A(7,K)
    1115            0 :           T4 = T3 + T3 + A(4,K)*DELY
    1116              :           CK = (T1*DELX + A(6,K)*DELY + A(8,K))*DELX +
    1117            0 :      &         (T3*DELY + A(9,K))*DELY + F(K)
    1118            0 :           CKX = T2*DELX + (A(3,K)*DELY+A(6,K))*DELY + A(8,K)
    1119            0 :           CKY = T4*DELY + (A(2,K)*DELX+A(6,K))*DELX + A(9,K)
    1120            0 :           CKXX = T2 + 3.0*A(1,K)*DELX
    1121            0 :           CKXY = 2.0*(A(2,K)*DELX + A(3,K)*DELY) + A(6,K)
    1122            0 :           CKYY = T4 + 3.0*A(4,K)*DELY
    1123            0 :           SW = SW + W
    1124            0 :           SWX = SWX + WX
    1125            0 :           SWY = SWY + WY
    1126            0 :           SWXX = SWXX + WXX
    1127            0 :           SWXY = SWXY + WXY
    1128            0 :           SWYY = SWYY + WYY
    1129            0 :           SWC = SWC + W*CK
    1130            0 :           SWCX = SWCX + WX*CK + W*CKX
    1131            0 :           SWCY = SWCY + WY*CK + W*CKY
    1132            0 :           SWCXX = SWCXX + W*CKXX + 2.0*WX*CKX + CK*WXX
    1133            0 :           SWCXY = SWCXY + W*CKXY + WX*CKY + WY*CKX + CK*WXY
    1134            0 :           SWCYY = SWCYY + W*CKYY + 2.0*WY*CKY + CK*WYY
    1135              : 
    1136              : ! Bottom of loop on nodes in cell (I,J).
    1137              : 
    1138            0 :     2     KP = K
    1139            0 :           K = LNEXT(KP)
    1140            0 :           if (K /= KP) GOTO 1
    1141            0 :     3     continue
    1142            0 :     4   continue
    1143              : 
    1144              : ! SW = 0 iff P is not within the radius R(K) for any node K.
    1145              : 
    1146            0 :       if (SW == 0.) GOTO 7
    1147            0 :       C = SWC/SW
    1148            0 :       SWS = SW*SW
    1149            0 :       CX = (SWCX*SW - SWC*SWX)/SWS
    1150            0 :       CY = (SWCY*SW - SWC*SWY)/SWS
    1151            0 :       CXX = (SW*(SWCXX-2.0*SWX*CX) - SWC*SWXX)/SWS
    1152            0 :       CXY = (SW*(SWCXY-SWY*CX-SWX*CY) - SWC*SWXY)/SWS
    1153            0 :       CYY = (SW*(SWCYY-2.0*SWY*CY) - SWC*SWYY)/SWS
    1154            0 :       IER = 0
    1155            0 :       return
    1156              : 
    1157              : ! (PX,PY) = (X(K),Y(K)).
    1158              : 
    1159            0 :     5 C = F(K)
    1160            0 :       CX = A(8,K)
    1161            0 :       CY = A(9,K)
    1162            0 :       CXX = 2.0*A(5,K)
    1163            0 :       CXY = A(6,K)
    1164            0 :       CYY = 2.0*A(7,K)
    1165            0 :       IER = 0
    1166            0 :       return
    1167              : 
    1168              : ! Invalid input parameter.
    1169              : 
    1170            0 :     6 IER = 1
    1171            0 :       return
    1172              : 
    1173              : ! No cells contain a point within RMAX of P, or
    1174              : !   SW = 0 and thus D >= RW(K) for all K.
    1175              : 
    1176            0 :     7 C = 0.
    1177            0 :       CX = 0.
    1178            0 :       CY = 0.
    1179            0 :       CXX = 0.
    1180            0 :       CXY = 0.
    1181            0 :       CYY = 0.
    1182            0 :       IER = 2
    1183            0 :       return
    1184              :       end subroutine CS2HES_db
    1185            0 :       subroutine GETNP2_db (PX,PY,X,Y,NR,LCELL,LNEXT,XMIN,YMIN,
    1186              :      &                   DX,DY, NP,DSQ)
    1187              :       integer :: NR, LCELL(NR,NR), LNEXT(*), NP
    1188              :       double precision :: PX, PY, X(*), Y(*), XMIN, YMIN, DX,
    1189              :      &                 DY, DSQ
    1190              : 
    1191              : ! **********************************************************
    1192              : 
    1193              : !                                               From CSHEP2D
    1194              : !                                            Robert J. Renka
    1195              : !                                  Dept. of Computer Science
    1196              : !                                       Univ. of North Texas
    1197              : !                                           renka@cs.unt.edu
    1198              : !                                                   02/03/97
    1199              : 
    1200              : !   Given a set of N nodes and the data structure defined in
    1201              : ! Subroutine STORE2_db, this subroutine uses the cell method to
    1202              : ! find the closest unmarked node NP to a specified point P.
    1203              : ! NP is then marked by setting LNEXT(NP) to -LNEXT(NP).  (A
    1204              : ! node is marked if and only if the corresponding LNEXT element
    1205              : ! is negative.  The absolute values of LNEXT elements,
    1206              : ! however, must be preserved.)  Thus, the closest M nodes to
    1207              : ! P may be determined by a sequence of M calls to this rou-
    1208              : ! tine.  Note that if the nearest neighbor to node K is to
    1209              : ! be determined (PX = X(K) and PY = Y(K)), then K should be
    1210              : ! marked before the call to this routine.
    1211              : 
    1212              : !   The search is begun in the cell containing (or closest
    1213              : ! to) P and proceeds outward in rectangular layers until all
    1214              : ! cells which contain points within distance R of P have
    1215              : ! been searched, where R is the distance from P to the first
    1216              : ! unmarked node encountered (infinite if no unmarked nodes
    1217              : ! are present).
    1218              : 
    1219              : !   This code is essentially unaltered from the subroutine
    1220              : ! of the same name in QSHEP2D.
    1221              : 
    1222              : ! On input:
    1223              : 
    1224              : !       PX,PY = Cartesian coordinates of the point P whose
    1225              : !               nearest unmarked neighbor is to be found.
    1226              : 
    1227              : !       X,Y = Arrays of length N, for N >= 2, containing
    1228              : !             the Cartesian coordinates of the nodes.
    1229              : 
    1230              : !       NR = Number of rows and columns in the cell grid.
    1231              : !            Refer to Subroutine STORE2_db.  NR >= 1.
    1232              : 
    1233              : !       LCELL = NR by NR array of nodal indexes associated
    1234              : !               with cells.  Refer to Subroutine STORE2_db.
    1235              : 
    1236              : !       LNEXT = Array of length N containing next-node
    1237              : !               indexes (or their negatives).  Refer to
    1238              : !               Subroutine STORE2_db.
    1239              : 
    1240              : !       XMIN,YMIN,DX,DY = Minimum nodal coordinates and cell
    1241              : !                         dimensions.  DX and DY must be
    1242              : !                         positive.  Refer to Subroutine
    1243              : !                         STORE2_db.
    1244              : 
    1245              : !   Input parameters other than LNEXT are not altered by
    1246              : ! this routine.  With the exception of (PX,PY) and the signs
    1247              : ! of LNEXT elements, these parameters should be unaltered
    1248              : ! from their values on output from Subroutine STORE2_db.
    1249              : 
    1250              : ! On output:
    1251              : 
    1252              : !       NP = Index (for X and Y) of the nearest unmarked
    1253              : !            node to P, or 0 if all nodes are marked or NR
    1254              : !            < 1 or DX <= 0 or DY <= 0.  LNEXT(NP)
    1255              : !            < 0 if NP /= 0.
    1256              : 
    1257              : !       DSQ = Squared Euclidean distance between P and node
    1258              : !             NP, or 0 if NP = 0.
    1259              : 
    1260              : ! Modules required by GETNP2_db:  None
    1261              : 
    1262              : ! Intrinsic functions called by GETNP2_db:  ABS, INT, SQRT
    1263              : 
    1264              : ! **********************************************************
    1265              : 
    1266              :       integer :: I, I0, I1, I2, IMAX, IMIN, J, J0, J1, J2,
    1267              :      &        JMAX, JMIN, L, LMIN, LN
    1268              :       LOGICAL :: FIRST
    1269            0 :       double precision :: DELX, DELY, R, RSMIN, RSQ, XP, YP
    1270              : 
    1271              : ! Local parameters:
    1272              : 
    1273              : ! DELX,DELY =   PX-XMIN, PY-YMIN
    1274              : ! FIRST =       Logical variable with value TRUE iff the
    1275              : !                 first unmarked node has yet to be
    1276              : !                 encountered
    1277              : ! I,J =         Cell indexes in the range [I1,I2] X [J1,J2]
    1278              : ! I0,J0 =       Indexes of the cell containing or closest
    1279              : !                 to P
    1280              : ! I1,I2,J1,J2 = Range of cell indexes defining the layer
    1281              : !                 whose intersection with the range
    1282              : !                 [IMIN,IMAX] X [JMIN,JMAX] is currently
    1283              : !                 being searched
    1284              : ! IMIN,IMAX =   Cell row indexes defining the range of the
    1285              : !                 search
    1286              : ! JMIN,JMAX =   Cell column indexes defining the range of
    1287              : !                 the search
    1288              : ! L,LN =        Indexes of nodes in cell (I,J)
    1289              : ! LMIN =        Current candidate for NP
    1290              : ! R =           Distance from P to node LMIN
    1291              : ! RSMIN =       Squared distance from P to node LMIN
    1292              : ! RSQ =         Squared distance from P to node L
    1293              : ! XP,YP =       Local copy of PX,PY -- coordinates of P
    1294              : 
    1295            0 :       XP = PX
    1296            0 :       YP = PY
    1297              : 
    1298              : ! Test for invalid input parameters.
    1299              : 
    1300            0 :       if (NR < 1 .or. DX <= 0. .or. DY <= 0.)
    1301              :      &  GOTO 9
    1302              : 
    1303              : ! Initialize parameters.
    1304              : 
    1305            0 :       FIRST = .true.
    1306            0 :       IMIN = 1
    1307            0 :       IMAX = NR
    1308            0 :       JMIN = 1
    1309            0 :       JMAX = NR
    1310            0 :       DELX = XP - XMIN
    1311            0 :       DELY = YP - YMIN
    1312            0 :       I0 = INT(DELX/DX) + 1
    1313            0 :       if (I0 < 1) I0 = 1
    1314            0 :       if (I0 > NR) I0 = NR
    1315            0 :       J0 = INT(DELY/DY) + 1
    1316            0 :       if (J0 < 1) J0 = 1
    1317            0 :       if (J0 > NR) J0 = NR
    1318            0 :       I1 = I0
    1319            0 :       I2 = I0
    1320            0 :       J1 = J0
    1321            0 :       J2 = J0
    1322              : 
    1323              : ! Outer loop on layers, inner loop on layer cells, excluding
    1324              : !   those outside the range [IMIN,IMAX] X [JMIN,JMAX].
    1325              : 
    1326            0 :     1 do 6 J = J1,J2
    1327            0 :         if (J > JMAX) GOTO 7
    1328            0 :         if (J < JMIN) GOTO 6
    1329            0 :         do 5 I = I1,I2
    1330            0 :           if (I > IMAX) GOTO 6
    1331            0 :           if (I < IMIN) GOTO 5
    1332              :           if (J /= J1 .and. J /= J2 .and. I /= I1
    1333            0 :      &       .and. I /= I2) GOTO 5
    1334              : 
    1335              : ! Search cell (I,J) for unmarked nodes L.
    1336              : 
    1337            0 :           L = LCELL(I,J)
    1338            0 :           if (L == 0) GOTO 5
    1339              : 
    1340              : !   Loop on nodes in cell (I,J).
    1341              : 
    1342            0 :     2     LN = LNEXT(L)
    1343            0 :           if (LN < 0) GOTO 4
    1344              : 
    1345              : !   Node L is not marked.
    1346              : 
    1347            0 :           RSQ = (X(L)-XP)**2 + (Y(L)-YP)**2
    1348            0 :           if (.not. FIRST) GOTO 3
    1349              : 
    1350              : !   Node L is the first unmarked neighbor of P encountered.
    1351              : !     Initialize LMIN to the current candidate for NP, and
    1352              : !     RSMIN to the squared distance from P to LMIN.  IMIN,
    1353              : !     IMAX, JMIN, and JMAX are updated to define the smal-
    1354              : !     lest rectangle containing a circle of radius R =
    1355              : !     Sqrt(RSMIN) centered at P, and contained in [1,NR] X
    1356              : !     [1,NR] (except that, if P is outside the rectangle
    1357              : !     defined by the nodes, it is possible that IMIN > NR,
    1358              : !     IMAX < 1, JMIN > NR, or JMAX < 1).  FIRST is reset to
    1359              : !     FALSE.
    1360              : 
    1361            0 :           LMIN = L
    1362            0 :           RSMIN = RSQ
    1363            0 :           R = SQRT(RSMIN)
    1364            0 :           IMIN = INT((DELX-R)/DX) + 1
    1365            0 :           if (IMIN < 1) IMIN = 1
    1366            0 :           IMAX = INT((DELX+R)/DX) + 1
    1367            0 :           if (IMAX > NR) IMAX = NR
    1368            0 :           JMIN = INT((DELY-R)/DY) + 1
    1369            0 :           if (JMIN < 1) JMIN = 1
    1370            0 :           JMAX = INT((DELY+R)/DY) + 1
    1371            0 :           if (JMAX > NR) JMAX = NR
    1372              :           FIRST = .false.
    1373            0 :           GOTO 4
    1374              : 
    1375              : !   Test for node L closer than LMIN to P.
    1376              : 
    1377            0 :     3     if (RSQ >= RSMIN) GOTO 4
    1378              : 
    1379              : !   Update LMIN and RSMIN.
    1380              : 
    1381            0 :           LMIN = L
    1382            0 :           RSMIN = RSQ
    1383              : 
    1384              : !   Test for termination of loop on nodes in cell (I,J).
    1385              : 
    1386            0 :     4     if (ABS(LN) == L) GOTO 5
    1387              :           L = ABS(LN)
    1388            0 :           GOTO 2
    1389            0 :     5     continue
    1390            0 :     6   continue
    1391              : 
    1392              : ! Test for termination of loop on cell layers.
    1393              : 
    1394              :     7 if (I1 <= IMIN .and. I2 >= IMAX  .and.
    1395            0 :      &    J1 <= JMIN .and. J2 >= JMAX) GOTO 8
    1396            0 :       I1 = I1 - 1
    1397            0 :       I2 = I2 + 1
    1398            0 :       J1 = J1 - 1
    1399            0 :       J2 = J2 + 1
    1400            0 :       GOTO 1
    1401              : 
    1402              : ! Unless no unmarked nodes were encountered, LMIN is the
    1403              : !   closest unmarked node to P.
    1404              : 
    1405            0 :     8 if (FIRST) GOTO 9
    1406            0 :       NP = LMIN
    1407            0 :       DSQ = RSMIN
    1408            0 :       LNEXT(LMIN) = -LNEXT(LMIN)
    1409            0 :       return
    1410              : 
    1411              : ! Error:  NR, DX, or DY is invalid or all nodes are marked.
    1412              : 
    1413            0 :     9 NP = 0
    1414            0 :       DSQ = 0.
    1415            0 :       return
    1416              :       end subroutine GETNP2_db
    1417            0 :       subroutine GIVENS_db ( A,B, C,S)
    1418              :       double precision :: A, B, C, S
    1419              : 
    1420              : ! **********************************************************
    1421              : 
    1422              : !                                               From SRFPACK
    1423              : !                                            Robert J. Renka
    1424              : !                                  Dept. of Computer Science
    1425              : !                                       Univ. of North Texas
    1426              : !                                           renka@cs.unt.edu
    1427              : !                                                   09/01/88
    1428              : 
    1429              : !   This subroutine constructs the Givens plane rotation,
    1430              : 
    1431              : !           ( C  S)
    1432              : !       G = (     ) , where C*C + S*S = 1,
    1433              : !           (-S  C)
    1434              : 
    1435              : ! which zeros the second component of the vector (A,B)**T
    1436              : ! (transposed).  Subroutine ROTATE_db may be called to apply
    1437              : ! the transformation to a 2 by N matrix.
    1438              : 
    1439              : !   This routine is identical to subroutine SROTG from the
    1440              : ! LINPACK BLAS (Basic Linear Algebra Subroutines).
    1441              : 
    1442              : ! On input:
    1443              : 
    1444              : !       A,B = Components of the vector defining the rota-
    1445              : !             tion.  These are overwritten by values R
    1446              : !             and Z (described below) which define C and S.
    1447              : 
    1448              : ! On output:
    1449              : 
    1450              : !       A = Signed Euclidean norm R of the input vector:
    1451              : !           R = +/-SQRT(A*A + B*B)
    1452              : 
    1453              : !       B = Value Z such that:
    1454              : !             C = SQRT(1-Z*Z) and S=Z if ABS(Z) <= 1, and
    1455              : !             C = 1/Z and S = SQRT(1-C*C) if ABS(Z) > 1.
    1456              : 
    1457              : !       C = +/-(A/R) or 1 if R = 0.
    1458              : 
    1459              : !       S = +/-(B/R) or 0 if R = 0.
    1460              : 
    1461              : ! Modules required by GIVENS_db:  None
    1462              : 
    1463              : ! Intrinsic functions called by GIVENS_db:  ABS, SQRT
    1464              : 
    1465              : ! **********************************************************
    1466              : 
    1467            0 :       double precision :: AA, BB, R, U, V
    1468              : 
    1469              : ! Local parameters:
    1470              : 
    1471              : ! AA,BB = Local copies of A and B
    1472              : ! R =     C*A + S*B = +/-SQRT(A*A+B*B)
    1473              : ! U,V =   Variables used to scale A and B for computing R
    1474              : 
    1475            0 :       AA = A
    1476            0 :       BB = B
    1477            0 :       if (ABS(AA) <= ABS(BB)) GOTO 1
    1478              : 
    1479              : ! ABS(A) > ABS(B).
    1480              : 
    1481            0 :       U = AA + AA
    1482            0 :       V = BB/U
    1483            0 :       R = SQRT(.25 + V*V) * U
    1484            0 :       C = AA/R
    1485            0 :       S = V * (C + C)
    1486              : 
    1487              : ! Note that R has the sign of A, C > 0, and S has
    1488              : !   SIGN(A)*SIGN(B).
    1489              : 
    1490            0 :       B = S
    1491            0 :       A = R
    1492            0 :       return
    1493              : 
    1494              : ! ABS(A) <= ABS(B).
    1495              : 
    1496            0 :     1 if (BB == 0.) GOTO 2
    1497            0 :       U = BB + BB
    1498            0 :       V = AA/U
    1499              : 
    1500              : ! Store R in A.
    1501              : 
    1502            0 :       A = SQRT(.25 + V*V) * U
    1503            0 :       S = BB/A
    1504            0 :       C = V * (S + S)
    1505              : 
    1506              : ! Note that R has the sign of B, S > 0, and C has
    1507              : !   SIGN(A)*SIGN(B).
    1508              : 
    1509            0 :       B = 1.
    1510            0 :       if (C /= 0.) B = 1./C
    1511            0 :       return
    1512              : 
    1513              : ! A = B = 0.
    1514              : 
    1515            0 :     2 C = 1.
    1516            0 :       S = 0.
    1517            0 :       return
    1518              :       end subroutine GIVENS_db
    1519            0 :       subroutine ROTATE_db (N,C,S, X,Y )
    1520              :       integer :: N
    1521              :       double precision :: C, S, X(N), Y(N)
    1522              : 
    1523              : ! **********************************************************
    1524              : 
    1525              : !                                               From SRFPACK
    1526              : !                                            Robert J. Renka
    1527              : !                                  Dept. of Computer Science
    1528              : !                                       Univ. of North Texas
    1529              : !                                           renka@cs.unt.edu
    1530              : !                                                   09/01/88
    1531              : 
    1532              : !                                                ( C  S)
    1533              : !   This subroutine applies the Givens rotation  (     )  to
    1534              : !                                                (-S  C)
    1535              : !                    (X(1) ... X(N))
    1536              : ! the 2 by N matrix  (             ) .
    1537              : !                    (Y(1) ... Y(N))
    1538              : 
    1539              : !   This routine is identical to subroutine SROT from the
    1540              : ! LINPACK BLAS (Basic Linear Algebra Subroutines).
    1541              : 
    1542              : ! On input:
    1543              : 
    1544              : !       N = Number of columns to be rotated.
    1545              : 
    1546              : !       C,S = Elements of the Givens rotation.  Refer to
    1547              : !             subroutine GIVENS_db.
    1548              : 
    1549              : ! The above parameters are not altered by this routine.
    1550              : 
    1551              : !       X,Y = Arrays of length >= N containing the compo-
    1552              : !             nents of the vectors to be rotated.
    1553              : 
    1554              : ! On output:
    1555              : 
    1556              : !       X,Y = Arrays containing the rotated vectors (not
    1557              : !             altered if N < 1).
    1558              : 
    1559              : ! Modules required by ROTATE_db:  None
    1560              : 
    1561              : ! **********************************************************
    1562              : 
    1563              :       integer :: I
    1564            0 :       double precision :: XI, YI
    1565              : 
    1566            0 :       do 1 I = 1,N
    1567            0 :         XI = X(I)
    1568            0 :         YI = Y(I)
    1569            0 :         X(I) = C*XI + S*YI
    1570            0 :         Y(I) = -S*XI + C*YI
    1571            0 :     1   continue
    1572            0 :       return
    1573              :       end subroutine ROTATE_db
    1574            0 :       subroutine SETUP2_db (XK,YK,ZK,XI,YI,ZI,S1,S2,S3,R, ROW)
    1575              :       double precision :: XK, YK, ZK, XI, YI, ZI, S1, S2, S3,
    1576              :      &                 R, ROW(10)
    1577              : 
    1578              : ! **********************************************************
    1579              : 
    1580              : !                                               From CSHEP2D
    1581              : !                                            Robert J. Renka
    1582              : !                                  Dept. of Computer Science
    1583              : !                                       Univ. of North Texas
    1584              : !                                           renka@cs.unt.edu
    1585              : !                                                   02/03/97
    1586              : 
    1587              : !   This subroutine sets up the I-th row of an augmented re-
    1588              : ! gression matrix for a weighted least squares fit of a
    1589              : ! cubic function f(x,y) to a set of data values z, where
    1590              : ! f(XK,YK) = ZK.  The first four columns (cubic terms) are
    1591              : ! scaled by S3, the next three columns (quadratic terms)
    1592              : ! are scaled by S2, and the eighth and ninth columns (lin-
    1593              : ! ear terms) are scaled by S1.
    1594              : 
    1595              : ! On input:
    1596              : 
    1597              : !       XK,YK = Coordinates of node K.
    1598              : 
    1599              : !       ZK = Data value at node K to be interpolated by f.
    1600              : 
    1601              : !       XI,YI,ZI = Coordinates and data value at node I.
    1602              : 
    1603              : !       S1,S2,S3 = Scale factors.
    1604              : 
    1605              : !       R = Radius of influence about node K defining the
    1606              : !           weight.
    1607              : 
    1608              : ! The above parameters are not altered by this routine.
    1609              : 
    1610              : !       ROW = Array of length 10.
    1611              : 
    1612              : ! On output:
    1613              : 
    1614              : !       ROW = Array containing a row of the augmented re-
    1615              : !             gression matrix.
    1616              : 
    1617              : ! Modules required by SETUP2_db:  None
    1618              : 
    1619              : ! Intrinsic function called by SETUP2_db:  SQRT
    1620              : 
    1621              : ! **********************************************************
    1622              : 
    1623              :       integer :: I
    1624            0 :       double precision :: D, DX, DXSQ, DY, DYSQ, W, W1, W2, W3
    1625              : 
    1626              : ! Local parameters:
    1627              : 
    1628              : ! D =    Distance between nodes K and I
    1629              : ! DX =   XI - XK
    1630              : ! DXSQ = DX*DX
    1631              : ! DY =   YI - YK
    1632              : ! DYSQ = DY*DY
    1633              : ! I =    DO-loop index
    1634              : ! W =    Weight associated with the row:  (R-D)/(R*D)
    1635              : !          (0 if D = 0 or D > R)
    1636              : ! W1 =   S1*W
    1637              : ! W2 =   S2*W
    1638              : ! W3 =   W3*W
    1639              : 
    1640            0 :       DX = XI - XK
    1641            0 :       DY = YI - YK
    1642            0 :       DXSQ = DX*DX
    1643            0 :       DYSQ = DY*DY
    1644            0 :       D = SQRT(DXSQ + DYSQ)
    1645            0 :       if (D <= 0. .or. D >= R) GOTO 1
    1646            0 :       W = (R-D)/R/D
    1647            0 :       W1 = S1*W
    1648            0 :       W2 = S2*W
    1649            0 :       W3 = S3*W
    1650            0 :       ROW(1) = DXSQ*DX*W3
    1651            0 :       ROW(2) = DXSQ*DY*W3
    1652            0 :       ROW(3) = DX*DYSQ*W3
    1653            0 :       ROW(4) = DYSQ*DY*W3
    1654            0 :       ROW(5) = DXSQ*W2
    1655            0 :       ROW(6) = DX*DY*W2
    1656            0 :       ROW(7) = DYSQ*W2
    1657            0 :       ROW(8) = DX*W1
    1658            0 :       ROW(9) = DY*W1
    1659            0 :       ROW(10) = (ZI - ZK)*W
    1660            0 :       return
    1661              : 
    1662              : ! Nodes K and I coincide or node I is outside of the radius
    1663              : !   of influence.  Set ROW to the zero vector.
    1664              : 
    1665            0 :     1 do 2 I = 1,10
    1666            0 :         ROW(I) = 0.
    1667            0 :     2   continue
    1668              :       return
    1669              :       end subroutine SETUP2_db
    1670            0 :       subroutine STORE2_db (N,X,Y,NR, LCELL,LNEXT,XMIN,YMIN,DX,
    1671              :      &                   DY,IER)
    1672              :       integer :: N, NR, LCELL(NR,NR), LNEXT(N), IER
    1673              :       double precision :: X(N), Y(N), XMIN, YMIN, DX, DY
    1674              : 
    1675              : ! **********************************************************
    1676              : 
    1677              : !                                               From CSHEP2D
    1678              : !                                            Robert J. Renka
    1679              : !                                  Dept. of Computer Science
    1680              : !                                       Univ. of North Texas
    1681              : !                                           renka@cs.unt.edu
    1682              : !                                                   03/28/97
    1683              : 
    1684              : !   Given a set of N arbitrarily distributed nodes in the
    1685              : ! plane, this subroutine creates a data structure for a
    1686              : ! cell-based method of solving closest-point problems.  The
    1687              : ! smallest rectangle containing the nodes is partitioned
    1688              : ! into an NR by NR uniform grid of cells, and nodes are as-
    1689              : ! sociated with cells.  In particular, the data structure
    1690              : ! stores the indexes of the nodes contained in each cell.
    1691              : ! For a uniform random distribution of nodes, the nearest
    1692              : ! node to an arbitrary point can be determined in constant
    1693              : ! expected time.
    1694              : 
    1695              : !   This code is essentially unaltered from the subroutine
    1696              : ! of the same name in QSHEP2D.
    1697              : 
    1698              : ! On input:
    1699              : 
    1700              : !       N = Number of nodes.  N >= 2.
    1701              : 
    1702              : !       X,Y = Arrays of length N containing the Cartesian
    1703              : !             coordinates of the nodes.
    1704              : 
    1705              : !       NR = Number of rows and columns in the grid.  The
    1706              : !            cell density (average number of nodes per cell)
    1707              : !            is D = N/(NR**2).  A recommended value, based
    1708              : !            on empirical evidence, is D = 3 -- NR =
    1709              : !            Sqrt(N/3).  NR >= 1.
    1710              : 
    1711              : ! The above parameters are not altered by this routine.
    1712              : 
    1713              : !       LCELL = Array of length >= NR**2.
    1714              : 
    1715              : !       LNEXT = Array of length >= N.
    1716              : 
    1717              : ! On output:
    1718              : 
    1719              : !       LCELL = NR by NR cell array such that LCELL(I,J)
    1720              : !               contains the index (for X and Y) of the
    1721              : !               first node (node with smallest index) in
    1722              : !               cell (I,J), or LCELL(I,J) = 0 if no nodes
    1723              : !               are contained in the cell.  The upper right
    1724              : !               corner of cell (I,J) has coordinates (XMIN+
    1725              : !               I*DX,YMIN+J*DY).  LCELL is not defined if
    1726              : !               IER /= 0.
    1727              : 
    1728              : !       LNEXT = Array of next-node indexes such that
    1729              : !               LNEXT(K) contains the index of the next node
    1730              : !               in the cell which contains node K, or
    1731              : !               LNEXT(K) = K if K is the last node in the
    1732              : !               cell for K = 1,...,N.  (The nodes contained
    1733              : !               in a cell are ordered by their indexes.)
    1734              : !               If, for example, cell (I,J) contains nodes
    1735              : !               2, 3, and 5 (and no others), then LCELL(I,J)
    1736              : !               = 2, LNEXT(2) = 3, LNEXT(3) = 5, and
    1737              : !               LNEXT(5) = 5.  LNEXT is not defined if
    1738              : !               IER /= 0.
    1739              : 
    1740              : !       XMIN,YMIN = Cartesian coordinates of the lower left
    1741              : !                   corner of the rectangle defined by the
    1742              : !                   nodes (smallest nodal coordinates) un-
    1743              : !                   less IER = 1.  The upper right corner is
    1744              : !                   (XMAX,YMAX) for XMAX = XMIN + NR*DX and
    1745              : !                   YMAX = YMIN + NR*DY.
    1746              : 
    1747              : !       DX,DY = Dimensions of the cells unless IER = 1.  DX
    1748              : !               = (XMAX-XMIN)/NR and DY = (YMAX-YMIN)/NR,
    1749              : !               where XMIN, XMAX, YMIN, and YMAX are the
    1750              : !               extrema of X and Y.
    1751              : 
    1752              : !       IER = Error indicator:
    1753              : !             IER = 0 if no errors were encountered.
    1754              : !             IER = 1 if N < 2 or NR < 1.
    1755              : !             IER = 2 if DX = 0 or DY = 0.
    1756              : 
    1757              : ! Modules required by STORE2_db:  None
    1758              : 
    1759              : ! Intrinsic functions called by STORE2_db:  DBLE, INT
    1760              : 
    1761              : ! **********************************************************
    1762              : 
    1763              :       integer :: I, J, K, L, NN, NNR
    1764            0 :       double precision :: DELX, DELY, XMN, XMX, YMN, YMX
    1765              : 
    1766              : ! Local parameters:
    1767              : 
    1768              : ! DELX,DELY = Components of the cell dimensions -- local
    1769              : !               copies of DX,DY
    1770              : ! I,J =       Cell indexes
    1771              : ! K =         Nodal index
    1772              : ! L =         Index of a node in cell (I,J)
    1773              : ! NN =        Local copy of N
    1774              : ! NNR =       Local copy of NR
    1775              : ! XMN,XMX =   Range of nodal X coordinates
    1776              : ! YMN,YMX =   Range of nodal Y coordinates
    1777              : 
    1778            0 :       NN = N
    1779            0 :       NNR = NR
    1780            0 :       if (NN < 2 .or. NNR < 1) then
    1781              :          !write(*,*) 'NN', NN
    1782              :          !write(*,*) 'NNR', NNR
    1783              :          GOTO 5
    1784              :       end if
    1785              : 
    1786              : ! Compute the dimensions of the rectangle containing the
    1787              : !   nodes.
    1788              : 
    1789            0 :       XMN = X(1)
    1790            0 :       XMX = XMN
    1791            0 :       YMN = Y(1)
    1792            0 :       YMX = YMN
    1793            0 :       do 1 K = 2,NN
    1794            0 :         if (X(K) < XMN) XMN = X(K)
    1795            0 :         if (X(K) > XMX) XMX = X(K)
    1796            0 :         if (Y(K) < YMN) YMN = Y(K)
    1797            0 :         if (Y(K) > YMX) YMX = Y(K)
    1798            0 :     1   continue
    1799            0 :       XMIN = XMN
    1800            0 :       YMIN = YMN
    1801              : 
    1802              : ! Compute cell dimensions and test for zero area.
    1803              : 
    1804            0 :       DELX = (XMX-XMN)/DBLE(NNR)
    1805            0 :       DELY = (YMX-YMN)/DBLE(NNR)
    1806            0 :       DX = DELX
    1807            0 :       DY = DELY
    1808            0 :       if (DELX == 0. .or. DELY == 0.) then
    1809              :          !write(*,*) 'XMX', XMX
    1810              :          !write(*,*) 'XMN', XMN
    1811              :          !write(*,*) 'YMX', YMX
    1812              :          !write(*,*) 'YMN', YMN
    1813              :          !write(*,*) 'DELY', DELY
    1814              :          !write(*,*) 'DELY', DELY
    1815              :          GOTO 6
    1816              :       end if
    1817              : 
    1818              : ! Initialize LCELL.
    1819              : 
    1820            0 :       do 3 J = 1,NNR
    1821            0 :         do 2 I = 1,NNR
    1822            0 :           LCELL(I,J) = 0
    1823            0 :     2     continue
    1824            0 :     3   continue
    1825              : 
    1826              : ! Loop on nodes, storing indexes in LCELL and LNEXT.
    1827              : 
    1828            0 :       do 4 K = NN,1,-1
    1829            0 :         I = INT((X(K)-XMN)/DELX) + 1
    1830            0 :         if (I > NNR) I = NNR
    1831            0 :         J = INT((Y(K)-YMN)/DELY) + 1
    1832            0 :         if (J > NNR) J = NNR
    1833            0 :         L = LCELL(I,J)
    1834            0 :         LNEXT(K) = L
    1835            0 :         if (L == 0) LNEXT(K) = K
    1836            0 :         LCELL(I,J) = K
    1837            0 :     4   continue
    1838              : 
    1839              : ! No errors encountered.
    1840              : 
    1841            0 :       IER = 0
    1842              :       !write(*,*) 'STORE2_db -- no errors encountered'
    1843            0 :       return
    1844              : 
    1845              : ! Invalid input parameter.
    1846              : 
    1847            0 :     5 IER = 1
    1848            0 :       return
    1849              : 
    1850              : ! DX = 0 or DY = 0.
    1851              : 
    1852            0 :     6 IER = 2
    1853            0 :       return
    1854              :       end subroutine STORE2_db
        

Generated by: LCOV version 2.0-1