NADCON5-ng  0.0.2
NADCON5 Next Generation Documentation
bicubic.f
Go to the documentation of this file.
1 c> \ingroup core
2 c> \if MANPAGE
3 c> \page bicubic
4 c> \endif
5 c>
6 c> Subroutine to perform a 2-D cubic ("bicubic") interpolation
7 c>
8 c> Performs interpolation at location "xla,xlo" off of grid "z", whose
9 c> header information is the standard ".b" header
10 c> information with additional inputs
11 c>
12 c> \param[in] z Input Grid
13 c> \param[in] glamn minimum latitude (real*8 decimal degrees)
14 c> \param[in] glomn minimum longitude (real*8 decimal degrees)
15 c> \param[in] dla latitude spacing (real*8 decimal degrees)
16 c> \param[in] dlo longitude spacing (real*8 decimal degrees)
17 c> \param[in] nla number of lat rows (integer*4)
18 c> \param[in] nlo number of lon cols (integer*4)
19 c> \param[in] maxla actual dimensioned size of "z" in rows
20 c> \param[in] maxlo actual dimensioned size of "z" in cols
21 c> \param[in] xla lat of pt for interpolation (real*8 dec. deg)
22 c> \param[in] xlo lon of pt for interpolation (real*8 dec. deg)
23 c> \param[out] val interpolated value (real*8)
24 c>
25 c> ### Method:
26 c> Fit a 4x4 window over the random point. Unless the point
27 c> is less than one grid spacing from the edge of the grid,
28 c> it will fall in the inner 2x2 cell, and the 4x4 cell will
29 c> be centered upon that.
30 c>
31 c> Thus, if our point of interest is the asterisk, the window
32 c> will look like this:
33 c>
34 c> . . . .
35 c> . . . .
36 c> . .* . .
37 c> . . . .
38 c>
39  subroutine bicubic(z,glamn,glomn,dla,dlo,
40  *nla,nlo,maxla,maxlo,xla,xlo,val)
41 
42 c - Data is assumed real*4
43  implicit real*8 (a-h,o-z)
44  real*4 z(maxla,maxlo)
45 
46 c - Internal use
47  real*4 x,y,fx0,fx1,fx2,fx3,cubterp
48 
49 c - Find which row should be LEAST when fitting
50 c - a 4x4 window around xla.
51  difla = (xla - glamn)
52  ratla = difla / dla
53  jla = int(ratla)
54 c - Fix any edge overlaps
55  if(jla.lt.1)jla = 1
56  if(jla.gt.nla-3)jla = nla-3
57 
58 c - Find which column should be LEAST when fitting
59 c - a 4x4 window around xlo.
60  diflo = (xlo - glomn)
61  ratlo = diflo / dlo
62  jlo = int(ratlo)
63 c - Fix any edge overlaps
64  if(jlo.lt.1)jlo = 1
65  if(jlo.gt.nlo-3)jlo = nlo-3
66 
67 c - In the range of 0(westernmost) to
68 c - 3(easternmost) col, where is our
69 c - random lon value? That is, x must
70 c - be real and fall between 0 and 3.
71 c - (Note, unless it is near an edge,
72 c - it will always be between 1 and 2)
73 
74  x=(xlo-dlo*(jlo-1)-glomn)/dlo
75 
76  if(x.lt.0.0)then
77  write(6,100)x
78  stop
79  endif
80  100 format(
81  *'FATAL in bicubic: x<0 : ',f20.10)
82 
83  if(x.gt.3.0)then
84  write(6,101)x
85  stop
86  endif
87  101 format(
88  *'FATAL in bicubic: x>3 : ',f20.10)
89 
90 c - In the range of 0(southernmost) to
91 c - 3(northernmost) row, where is our
92 c - random lat value? That is, x must
93 c - be real and fall between 0 and 3.
94 c - (Note, unless it is near an edge,
95 c - it will always be between 1 and 2)
96 
97  y=(xla-dla*(jla-1)-glamn)/dla
98 
99  if(y.lt.0.0)then
100  write(6,102)y
101  stop
102  endif
103  102 format(
104  *'FATAL in bicubic: y<0 : ',f20.10)
105 
106  if(y.gt.3.0)then
107  write(6,103)y
108  stop
109  endif
110  103 format(
111  *'FATAL in bicubic: y>3 : ',f20.10)
112 
113 c - Now do the interpolation. First, build a 1-D cubic function
114 c - east-west in the southermost row and interpolate to longitude
115 c - "xlo" (at "x" for 0<x<3). Then do it in the 2nd row,
116 c - then again in the 3rd, and finally the 4th and most northern row.
117 c - The last step is to fit a 1-D cubic function north-south at the
118 c - four previous interpolations, but this time to interpolate to
119 c - latitude "xla" (at "y" for 0<y<3). Obviously we
120 c - could reverse the order, doing 4 north-south cubics
121 c - followed by one east-east and we'd get the same answer.
122 
123 
124  fx0=cubterp(x,z(jla ,jlo ),z(jla ,jlo+1),
125  * z(jla ,jlo+2),z(jla ,jlo+3))
126 
127  fx1=cubterp(x,z(jla+1,jlo ),z(jla+1,jlo+1),
128  * z(jla+1,jlo+2),z(jla+1,jlo+3))
129 
130  fx2=cubterp(x,z(jla+2,jlo ),z(jla+2,jlo+1),
131  * z(jla+2,jlo+2),z(jla+2,jlo+3))
132 
133  fx3=cubterp(x,z(jla+3,jlo ),z(jla+3,jlo+1),
134  * z(jla+3,jlo+2),z(jla+3,jlo+3))
135 
136  val=dble(cubterp(y,fx0,fx1,fx2,fx3))
137 
138 
139 c write(6,1001)glamn,xla,jla,y
140 c write(6,1002)glomn,xlo,jlo,x
141 c write(6,1003)z(jla+3,jlo ),z(jla+3,jlo+1),
142 c * z(jla+3,jlo+2),z(jla+3,jlo+3)
143 c write(6,1003)z(jla+2,jlo ),z(jla+2,jlo+1),
144 c * z(jla+2,jlo+2),z(jla+2,jlo+3)
145 c write(6,1003)z(jla+1,jlo ),z(jla+1,jlo+1),
146 c * z(jla+1,jlo+2),z(jla+1,jlo+3)
147 c write(6,1003)z(jla ,jlo ),z(jla ,jlo+1),
148 c * z(jla ,jlo+2),z(jla ,jlo+3)
149 c write(6,1004)fx0,fx1,fx2,fx3,val
150 c pause
151 
152  1001 format(f14.10,1x,f14.10,1x,i8,1x,f8.5)
153  1002 format(f14.10,1x,f14.10,1x,i8,1x,f8.5)
154  1003 format(4(f15.8,1x))
155  1004 format(
156  *'fx0 = ',f15.8,/,
157  *'fx1 = ',f15.8,/,
158  *'fx2 = ',f15.8,/,
159  *'fx3 = ',f15.8,/,
160  *'val = ',f15.8)
161 
162 
163 
164  return
165  end
166  include 'cubterp.f'
subroutine bicubic(z, glamn, glomn, dla, dlo, nla, nlo, maxla, maxlo, xla, xlo, val)
Subroutine to perform a 2-D cubic ("bicubic") interpolation.
Definition: bicubic.f:41