1 ! This file contains the following subroutines, related to interpolations
2 ! of input data, addition of points to arrays, and zeroing of arrays:
10 !=============================================================================*
12 SUBROUTINE inter1(ng,xg,yg, n,x,y)
13 !-----------------------------------------------------------------------------*
15 != Map input data given on single, discrete points, onto a discrete target =*
17 != The original input data are given on single, discrete points of an =*
18 != arbitrary grid and are being linearly interpolated onto a specified =*
19 != discrete target grid. A typical example would be the re-gridding of a =*
20 != given data set for the vertical temperature profile to match the speci- =*
21 != fied altitude grid. =*
22 != Some caution should be used near the end points of the grids. If the =*
23 != input data set does not span the range of the target grid, the remaining =*
24 != points will be set to zero, as extrapolation is not permitted. =*
25 != If the input data does not encompass the target grid, use ADDPNT to =*
26 != expand the input array. =*
27 !-----------------------------------------------------------------------------*
29 != NG - INTEGER, number of points in the target grid (I)=*
30 != XG - REAL, target grid (e.g. altitude grid) (I)=*
31 != YG - REAL, y-data re-gridded onto XG (O)=*
32 != N - INTEGER, number of points in the input data set (I)=*
33 != X - REAL, grid on which input data are defined (I)=*
34 != Y - REAL, input y-data (I)=*
35 !-----------------------------------------------------------------------------*
56 IF ((x(j) .GT. xg(i)) .OR. (xg(i) .GE. x(j+1))) THEN
58 IF (j .LE. n-1) GOTO 10
59 ! ---- end of loop 10 ----
61 slope = (y(j+1)-y(j)) / (x(j+1)-x(j))
62 yg(i) = y(j) + slope * (xg(i) - x(j))
69 !=============================================================================*
71 SUBROUTINE inter2(ng,xg,yg,n,x,y,ierr)
73 !-----------------------------------------------------------------------------*
75 != Map input data given on single, discrete points onto a set of target =*
77 != The original input data are given on single, discrete points of an =*
78 != arbitrary grid and are being linearly interpolated onto a specified set =*
79 != of target bins. In general, this is the case for most of the weighting =*
80 != functions (action spectra, molecular cross section, and quantum yield =*
81 != data), which have to be matched onto the specified wavelength intervals. =*
82 != The average value in each target bin is found by averaging the trapezoi- =*
83 != dal area underneath the input data curve (constructed by linearly connec-=*
84 != ting the discrete input values). =*
85 != Some caution should be used near the endpoints of the grids. If the =*
86 != input data set does not span the range of the target grid, an error =*
87 != message is printed and the execution is stopped, as extrapolation of the =*
88 != data is not permitted. =*
89 != If the input data does not encompass the target grid, use ADDPNT to =*
90 != expand the input array. =*
91 !-----------------------------------------------------------------------------*
93 != NG - INTEGER, number of bins + 1 in the target grid (I)=*
94 != XG - REAL, target grid (e.g., wavelength grid); bin i is defined (I)=*
95 != as [XG(i),XG(i+1)] (i = 1..NG-1) =*
96 != YG - REAL, y-data re-gridded onto XG, YG(i) specifies the value for (O)=*
97 != bin i (i = 1..NG-1) =*
98 != N - INTEGER, number of points in input grid (I)=*
99 != X - REAL, grid on which input data are defined (I)=*
100 != Y - REAL, input y-data (I)=*
101 !-----------------------------------------------------------------------------*
107 REAL x(n), y(n), xg(ng)
122 ! test for correct ordering of data, by increasing value of x
125 IF (x(i) .LE. x(i-1)) THEN
127 call wrf_debug( 0,'inter2: ERROR <<< x-grid not sorted' )
133 IF (xg(i) .LE. xg(i-1)) THEN
135 call wrf_debug( 0,'inter2: ERROR <<< xg-grid not sorted!' )
140 ! check for xg-values outside the x-range
142 IF ( (x(1) .GT. xg(1)) .OR. (x(n) .LT. xg(ng)) ) THEN
143 call wrf_error_fatal( 'inter2: <<< Data do not span grid; Use ADDPNT to expand data and re-run.' )
146 ! find the integral of each grid interval and use this to
147 ! calculate the average y value for the interval
148 ! xgl and xgu are the lower and upper limits of the grid interval
159 ! discard data before the first grid interval and after the
161 ! for internal grid intervals, start calculating area by interpolating
162 ! between the last point which lies in the previous interval and the
163 ! first point inside the current interval
168 ! if both points are before the first grid, go to the next point
170 IF (x(k+1) .LE. xgl) THEN
173 IF (k .LE. n-1) GO TO 30
176 ! if the last point is beyond the end of the grid, complete and go to the next
179 IF ((k .LE. n-1) .AND. (x(k) .LT. xgu)) THEN
181 ! compute x-coordinates of increment
184 ! if points coincide, contribution is zero
185 IF (x(k+1).EQ.x(k)) THEN
188 slope = (y(k+1) - y(k))/(x(k+1) - x(k))
189 b1 = y(k) + slope*(a1 - x(k))
190 b2 = y(k) + slope*(a2 - x(k))
191 darea = (a2 - a1)*(b2 + b1)/2.
194 ! find the area under the trapezoid from a1 to a2
202 ! calculate the average y after summing the areas in the interval
203 yg(i) = area/(xgu - xgl)
207 END SUBROUTINE inter2
209 !=============================================================================*
211 SUBROUTINE inter3(ng,xg,yg, n,x,y, FoldIn)
212 !-----------------------------------------------------------------------------*
214 != Map input data given on a set of bins onto a different set of target =*
216 != The input data are given on a set of bins (representing the integral =*
217 != of the input quantity over the range of each bin) and are being matched =*
218 != onto another set of bins (target grid). A typical example would be an =*
219 != input data set spcifying the extra-terrestrial flux on wavelength inter- =*
220 != vals, that has to be matched onto the working wavelength grid. =*
221 != The resulting area in a given bin of the target grid is calculated by =*
222 != simply adding all fractional areas of the input data that cover that =*
223 != particular target bin. =*
224 != Some caution should be used near the endpoints of the grids. If the =*
225 != input data do not span the full range of the target grid, the area in =*
226 != the "missing" bins will be assumed to be zero. If the input data extend =*
227 != beyond the upper limit of the target grid, the user has the option to =*
228 != integrate the "overhang" data and fold the remaining area back into the =*
229 != last target bin. Using this option is recommended when re-gridding =*
230 != vertical profiles that directly affect the total optical depth of the =*
231 != model atmosphere. =*
232 !-----------------------------------------------------------------------------*
234 != NG - INTEGER, number of bins + 1 in the target grid (I)=*
235 != XG - REAL, target grid (e.g. working wavelength grid); bin i (I)=*
236 != is defined as [XG(i),XG(i+1)] (i = 1..NG-1) =*
237 != YG - REAL, y-data re-gridded onto XG; YG(i) specifies the (O)=*
238 != y-value for bin i (i = 1..NG-1) =*
239 != N - INTEGER, number of bins + 1 in the input grid (I)=*
240 != X - REAL, input grid (e.g. data wavelength grid); bin i is (I)=*
241 != defined as [X(i),X(i+1)] (i = 1..N-1) =*
242 != Y - REAL, input y-data on grid X; Y(i) specifies the (I)=*
243 != y-value for bin i (i = 1..N-1) =*
244 != FoldIn - Switch for folding option of "overhang" data (I)=*
245 != FoldIn = 0 -> No folding of "overhang" data =*
246 != FoldIn = 1 -> Integerate "overhang" data and fold back into =*
247 != last target bin =*
248 !-----------------------------------------------------------------------------*
265 INTEGER jstart, i, j, k
267 ! check whether flag given is legal
268 IF ((FoldIn .NE. 0) .AND. (FoldIn .NE. 1)) THEN
269 call wrf_error_fatal( 'inter3: ERROR <<< Value for FOLDIN invalid. Must be 0 or 1' )
282 IF (x(j+1) .LT. xg(i)) THEN
285 IF (j .LE. n-1) GO TO 20
290 IF ((x(j) .LE. xg(i+1)) .AND. (j .LE. n-1)) THEN
292 a2 = MIN(x(j+1),xg(i+1))
293 sum = sum + y(j) * (a2-a1)/(x(j+1)-x(j))
302 ! if wanted, integrate data "overhang" and fold back into last bin
304 IF (FoldIn .EQ. 1) THEN
306 a1 = xg(ng) ! upper limit of last interpolated bin
307 a2 = x(j+1) ! upper limit of last input bin considered
308 ! do folding only if grids don't match up and there is more input
309 IF ((a2 .GT. a1) .OR. (j+1 .LT. n)) THEN
310 tail = y(j) * (a2-a1)/(x(j+1)-x(j))
312 tail = tail + y(k) * (x(k+1)-x(k))
314 yg(ng-1) = yg(ng-1) + tail
318 END SUBROUTINE inter3
320 !=============================================================================*
322 SUBROUTINE inter4(ng,xg,yg, n,x,y, FoldIn)
323 !-----------------------------------------------------------------------------*
325 != Map input data given on a set of bins onto a different set of target =*
327 != The input data are given on a set of bins (representing the integral =*
328 != of the input quantity over the range of each bin) and are being matched =*
329 != onto another set of bins (target grid). A typical example would be an =*
330 != input data set spcifying the extra-terrestrial flux on wavelength inter- =*
331 != vals, that has to be matched onto the working wavelength grid. =*
332 != The resulting area in a given bin of the target grid is calculated by =*
333 != simply adding all fractional areas of the input data that cover that =*
334 != particular target bin. =*
335 != Some caution should be used near the endpoints of the grids. If the =*
336 != input data do not span the full range of the target grid, the area in =*
337 != the "missing" bins will be assumed to be zero. If the input data extend =*
338 != beyond the upper limit of the target grid, the user has the option to =*
339 != integrate the "overhang" data and fold the remaining area back into the =*
340 != last target bin. Using this option is recommended when re-gridding =*
341 != vertical profiles that directly affect the total optical depth of the =*
342 != model atmosphere. =*
343 !-----------------------------------------------------------------------------*
345 != NG - INTEGER, number of bins + 1 in the target grid (I)=*
346 != XG - REAL, target grid (e.g. working wavelength grid); bin i (I)=*
347 != is defined as [XG(i),XG(i+1)] (i = 1..NG-1) =*
348 != YG - REAL, y-data re-gridded onto XG; YG(i) specifies the (O)=*
349 != y-value for bin i (i = 1..NG-1) =*
350 != N - INTEGER, number of bins + 1 in the input grid (I)=*
351 != X - REAL, input grid (e.g. data wavelength grid); bin i is (I)=*
352 != defined as [X(i),X(i+1)] (i = 1..N-1) =*
353 != Y - REAL, input y-data on grid X; Y(i) specifies the (I)=*
354 != y-value for bin i (i = 1..N-1) =*
355 != FoldIn - Switch for folding option of "overhang" data (I)=*
356 != FoldIn = 0 -> No folding of "overhang" data =*
357 != FoldIn = 1 -> Integerate "overhang" data and fold back into =*
358 != last target bin =*
359 !-----------------------------------------------------------------------------*
376 INTEGER jstart, i, j, k
378 ! check whether flag given is legal
379 IF ((FoldIn .NE. 0) .AND. (FoldIn .NE. 1)) THEN
380 call wrf_error_fatal( 'inter3: ERROR <<< Value for FOLDIN invalid. Must be 0 or 1' )
392 IF (x(j+1) .LT. xg(i)) THEN
395 IF (j .LE. n-1) GO TO 20
398 IF ((x(j) .LE. xg(i+1)) .AND. (j .LE. n-1)) THEN
400 a2 = MIN(x(j+1),xg(i+1))
401 sum = sum + y(j) * (a2-a1)
405 yg(i) = sum /(xg(i+1)-xg(i))
410 ! if wanted, integrate data "overhang" and fold back into last bin
412 IF (FoldIn .EQ. 1) THEN
414 a1 = xg(ng) ! upper limit of last interpolated bin
415 a2 = x(j+1) ! upper limit of last input bin considered
416 ! do folding only if grids don't match up and there is more input
417 IF ((a2 .GT. a1) .OR. (j+1 .LT. n)) THEN
418 tail = y(j) * (a2-a1)/(x(j+1)-x(j))
420 tail = tail + y(k) * (x(k+1)-x(k))
422 yg(ng-1) = yg(ng-1) + tail
426 END SUBROUTINE inter4
428 !=============================================================================*
430 SUBROUTINE addpnt ( x, y, ld, n, xnew, ynew )
431 !-----------------------------------------------------------------------------*
433 != Add a point <xnew,ynew> to a set of data pairs <x,y>. x must be in =*
434 != ascending order =*
435 !-----------------------------------------------------------------------------*
437 != X - REAL vector of length LD, x-coordinates (IO)=*
438 != Y - REAL vector of length LD, y-values (IO)=*
439 != LD - INTEGER, dimension of X, Y exactly as declared in the calling (I)=*
441 != N - INTEGER, number of elements in X, Y. On entry, it must be: (IO)=*
442 != N < LD. On exit, N is incremented by 1. =*
443 != XNEW - REAL, x-coordinate at which point is to be added (I)=*
444 != YNEW - REAL, y-value of point to be added (I)=*
445 !-----------------------------------------------------------------------------*
451 INTEGER, intent(in) :: ld
452 INTEGER, intent(inout) :: n
453 REAL, intent(inout) :: x(ld), y(ld)
454 REAL, intent(in) :: xnew, ynew
460 CHARACTER(len=256) :: emsg
462 ! check n<ld to make sure x will hold another point
464 call wrf_error_fatal( 'addpnt: ERROR <<< Cannot expand array All elements used.' )
470 ! check whether x is already sorted.
471 ! also, use this loop to find the point at which xnew needs to be inserted
472 ! into vector x, if x is sorted.
476 IF (x(i) .LT. x(i-1)) THEN
477 call wrf_error_fatal( 'addpnt: ERROR <<< x-data must be in ascending order!' )
479 IF (xnew .GT. x(i-1)) insert = i
485 ! if <xnew,ynew> needs to be appended at the end, just do so,
486 ! otherwise, insert <xnew,ynew> at position INSERT
488 IF ( xnew .GT. x(n) ) THEN
492 ! shift all existing points one index up
502 ! increase total number of elements in x, y
506 END SUBROUTINE addpnt