NADCON5-ng  0.0.1
NADCON5 Next Generation
biquad.f
Go to the documentation of this file.
1 c> \ingroup core
2 c> Subroutine to perform a 2-D quadratic ("biquadratic") interpolation
3 c>
4 c> Performs a biquadratic interpolation at location
5 c> `xla,xlo` off of grid `z`, whose
6 c> header information is the standard ".b" header
7 c> information
8 c>
9 c> \param[in] z Input Grid
10 c> \param[in] glamn minimum latitude (real*8 decimal degrees)
11 c> \param[in] glomn minimum longitude (real*8 decimal degrees)
12 c> \param[in] dla latitude spacing (real*8 decimal degrees)
13 c> \param[in] dlo longitude spacing (real*8 decimal degrees)
14 c> \param[in] nla number of lat rows (integer*4)
15 c> \param[in] nlo number of lon cols (integer*4)
16 c> \param[in] maxla actual dimensioned size of "z" in rows
17 c> \param[in] maxlo actual dimensioned size of "z" in cols
18 c> \param[in] xla lat of pt for interpolation (real*8 dec. deg)
19 c> \param[in] xlo lon of pt for interpolation (real*8 dec. deg)
20 c> \param[out] val interpolated value (real*8)
21 c>
22 c> ### Method:
23 c> Fit a 3x3 window over the random point. The closest
24 c> 2x2 points will surround the point. But based on which
25 c> quadrant of that 2x2 cell in which the point falls, the
26 c> 3x3 window could extend NW, NE, SW or SE from the 2x2 cell.
27  subroutine biquad(z,glamn,glomn,dla,dlo,
28  *nla,nlo,maxla,maxlo,xla,xlo,val)
29 
30 c - Subroutine to perform a 2-D quadratic ("biquadratic")
31 c - interpolation at location "xla,xlo" off of grid "z", whose
32 c - header information is the standard ".b" header
33 c - information of
34 c - glamn = minimum latitude (real*8 decimal degrees)
35 c - glomn = minimum longitude (real*8 decimal degrees)
36 c - dla = latitude spacing (real*8 decimal degrees)
37 c - dlo = longitude spacing (real*8 decimal degrees)
38 c - nla = number of lat rows (integer*4)
39 c - nlo = number of lon cols (integer*4)
40 c - maxla = actual dimensioned size of "z" in rows
41 c - maxlo = actual dimensioned size of "z" in cols
42 c - Further input:
43 c - xla = lat of pt for interpolation (real*8 dec. deg)
44 c - xlo = lon of pt for interpolation (real*8 dec. deg)
45 c - Output:
46 c - val = interpolated value (real*8)
47 c -
48 c - Method:
49 c - Fit a 3x3 window over the random point. The closest
50 c - 2x2 points will surround the point. But based on which
51 c - quadrant of that 2x2 cell in which the point falls, the
52 c - 3x3 window could extend NW, NE, SW or SE from the 2x2 cell.
53 
54 c - Data is assumed real*4
55  implicit real*8 (a-h,o-z)
56  real*4 z(maxla,maxlo)
57 
58 c - Internal use
59  real*4 x,y,fx0,fx1,fx2,qterp
60 
61 c - Find which row should be LEAST when fitting
62 c - a 3x3 window around xla.
63  difla = (xla - glamn)
64  ratla = difla / (dla/2.d0)
65  ila = int(ratla)+1
66  if(mod(ila,2).ne.0)then
67  jla = (ila+1)/2 - 1
68  else
69  jla = (ila )/2
70  endif
71 c - Fix any edge overlaps
72  if(jla.lt.1)jla = 1
73  if(jla.gt.nla-2)jla = nla-2
74 
75 c - Find which column should be LEAST when fitting
76 c - a 3x3 window around xlo.
77  diflo = (xlo - glomn)
78  ratlo = diflo / (dlo/2.d0)
79  ilo = int(ratlo)+1
80  if(mod(ilo,2).ne.0)then
81  jlo = (ilo+1)/2 - 1
82  else
83  jlo = (ilo )/2
84  endif
85 c - Fix any edge overlaps
86  if(jlo.lt.1)jlo = 1
87  if(jlo.gt.nlo-2)jlo = nlo-2
88 
89 c - In the range of 0(westernmost) to
90 c - 2(easternmost) col, where is our
91 c - random lon value? That is, x must
92 c - be real and fall between 0 and 2.
93 
94  x=(xlo-dlo*(jlo-1)-glomn)/dlo
95 
96  if(x.lt.0.0)then
97  val = 1.d30
98  write(6,100)x,val
99 c stop
100  return
101  endif
102  100 format(
103  *'FATAL in biquad: x<0 : ',f20.10,/,
104  *' --> Returning with val = ',f40.1)
105 
106  if(x.gt.2.0)then
107  val = 1.d30
108  write(6,101)x,val
109 c stop
110  return
111  endif
112  101 format(
113  *'FATAL in biquad: x>2 : ',f20.10,/,
114  *' --> Returning with val = ',f40.1)
115 
116 c - In the range of 0(southernmost) to
117 c - 2(northernmost) row, where is our
118 c - random lat value? That is, x must
119 c - be real and fall between 0 and 2.
120 
121  y=(xla-dla*(jla-1)-glamn)/dla
122 
123  if(y.lt.0.0)then
124  val = 1.d30
125  write(6,102)y,val
126 c stop
127  return
128  endif
129  102 format(
130  *'FATAL in biquad: y<0 : ',f20.10,/,
131  *' --> Returning with val = ',f40.1)
132 
133  if(y.gt.2.0)then
134  val = 1.d30
135  write(6,103)y,val
136 c stop
137  return
138  endif
139  103 format(
140  *'FATAL in biquad: y>2 : ',f20.10,/,
141  *' --> Returning with val = ',f40.1)
142 
143 c - Now do the interpolation. First, build a paraboloa
144 c - east-west the southermost row and interpolate to longitude
145 c - "xlo" (at "x" for 0<x<2). Then do it in the middle
146 c - row, then finally the northern row. The last step
147 c - is to fit a parabola north-south at the three previous
148 c - interpolations, but this time to interpolate to
149 c - latitude "xla" (at "y" for 0<y<2). Obviously we
150 c - could reverse the order, doing 3 north-south parabolas
151 c - followed by one east-east and we'd get the same answer.
152 
153  fx0=qterp(x,z(jla ,jlo),z(jla ,jlo+1),z(jla ,jlo+2))
154  fx1=qterp(x,z(jla+1,jlo),z(jla+1,jlo+1),z(jla+1,jlo+2))
155  fx2=qterp(x,z(jla+2,jlo),z(jla+2,jlo+1),z(jla+2,jlo+2))
156  val=dble(qterp(y,fx0,fx1,fx2))
157 
158 c goto 888
159 
160 c write(6,*) ' '
161 c write(6,*) ' ---------------------------------'
162 c write(6,*) ' Inside biquad.f'
163 c write(6,*) ' '
164 
165 c write(6,*) ' Southern Row of 3x3 window: '
166 c write(6,*) ' jla ,jlo ,z(jla ,jlo ) = ',
167 c *jla ,jlo ,z(jla ,jlo )
168 c write(6,*) ' jla ,jlo+1,z(jla ,jlo+1) = ',
169 c *jla ,jlo+1,z(jla ,jlo+1)
170 c write(6,*) ' jla ,jlo+2,z(jla ,jlo+2) = ',
171 c *jla ,jlo+2,z(jla ,jlo+2)
172 c write(6,*) ' fx0 = ',fx0
173 
174 c write(6,*) ' Middle Row of 3x3 window: '
175 c write(6,*) ' jla+1,jlo ,z(jla+1,jlo ) = ',
176 c *jla+1,jlo ,z(jla+1,jlo )
177 c write(6,*) ' jla+1,jlo+1,z(jla+1,jlo+1) = ',
178 c *jla+1,jlo+1,z(jla+1,jlo+1)
179 c write(6,*) ' jla+1,jlo+2,z(jla+1,jlo+2) = ',
180 c *jla+1,jlo+2,z(jla+1,jlo+2)
181 c write(6,*) ' fx1 = ',fx1
182 
183 c write(6,*) ' Northern Row of 3x3 window: '
184 c write(6,*) ' jla+2,jlo ,z(jla+2,jlo ) = ',
185 c *jla+2,jlo ,z(jla+2,jlo )
186 c write(6,*) ' jla+2,jlo+1,z(jla+2,jlo+1) = ',
187 c *jla+2,jlo+1,z(jla+2,jlo+1)
188 c write(6,*) ' jla+2,jlo+2,z(jla+2,jlo+2) = ',
189 c *jla+2,jlo+2,z(jla+2,jlo+2)
190 c write(6,*) ' fx2 = ',fx2
191 
192 c write(6,*) ' Final interpolated value = ',val
193 
194 c 888 continue
195 
196 
197  return
198  end
199  include 'qterp.f'
subroutine biquad(z, glamn, glomn, dla, dlo, nla, nlo, maxla, maxlo, xla, xlo, val)
Subroutine to perform a 2-D quadratic ("biquadratic") interpolation.
Definition: biquad.f:29