SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
interpol_splines.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! #########
6  SUBROUTINE interpol_splines(KLUOUT,KCODE,PX,PY,PFIELD,KREP)
7 ! #########################################################
8 !
9 !!**** *INTERPOL_SPLINES* interpolates with spline f77 programs a 2D field
10 !! from all grid points valid values
11 !!
12 !! PURPOSE
13 !! -------
14 !!
15 !! The points are all on only one grid (defined with the coordinates
16 !! of all the points). The code to apply for each point is:
17 !!
18 !! KCODE>0 : data point (with field valid for interpolation)
19 !! KCODE=-1: point to ignore
20 !! KCODE=0 : point to interpolate
21 !!
22 !!
23 !!
24 !! METHOD
25 !! ------
26 !!
27 !! EXTERNAL
28 !! --------
29 !!
30 !! IMPLICIT ARGUMENTS
31 !! ------------------
32 !!
33 !!
34 !!
35 !! REFERENCE
36 !! ---------
37 !!
38 !! AUTHOR
39 !! ------
40 !!
41 !! V. Masson Meteo-France
42 !!
43 !! MODIFICATION
44 !! ------------
45 !!
46 !! Original 19/03/95
47 !! Modification
48 !! 25/05/96 (V Masson) W and IW defined in MODD_SPLINESWORK
49 !! 04/07/96 (V Masson) call with 1d dummy arguments
50 !! 30/10/96 (V Masson) add deallocations
51 !! 05/08/97 (V Masson) output listing as dummy argument
52 !! 17/09/97 (V Masson) routine performs ONLY the splines interpolation
53 !! 19/12/97 (V Masson) possibility to use the same splines for collocated
54 !! fields
55 !----------------------------------------------------------------------------
56 !
57 !* 0. DECLARATION
58 ! -----------
59 !
60 USE modd_surf_par, ONLY : xundef
61 !
62 USE mode_splines
63 !
64 USE yomhook ,ONLY : lhook, dr_hook
65 USE parkind1 ,ONLY : jprb
66 !
67 USE modi_abor1_sfx
68 !
69 IMPLICIT NONE
70 !
71 !* 0.1 Declaration of arguments
72 ! ------------------------
73 !
74 INTEGER, INTENT(IN) :: kluout ! output listing
75 INTEGER,DIMENSION(:), INTENT(INOUT) :: kcode ! code for each point
76  ! >0 point used for interpolation
77  ! 0 point to interpolate
78  ! -1 point not used
79  ! -2 point not used
80 ! ! -3 if spline is no computed
81 ! ! for this point
82 REAL, DIMENSION(:), INTENT(IN) :: px ! x of each grid mesh.
83 REAL, DIMENSION(:), INTENT(IN) :: py ! y of each grid mesh.
84 REAL, DIMENSION(:,:),INTENT(INOUT) :: pfield ! pgd field on grid mesh.
85 INTEGER, INTENT(OUT) :: krep ! error flag
86 !
87 !* 0.2 Declaration of local variables
88 ! ------------------------------
89 !
90 INTEGER, PARAMETER :: nd = 2 !
91 INTEGER :: iopt ! 0: splines recomputed
92 ! ! 1: splines deduced from W and IW
93 INTEGER :: jk ! loop control
94 INTEGER :: jin ! loop control
95 INTEGER :: jout ! loop control
96 INTEGER :: iverb = 10 ! verbosity level
97 INTEGER :: ifield ! number of colocated fields
98 INTEGER, PARAMETER :: idatamax = 2000 ! maximum number of data per blok
99 ! ! WARNING, if IDATAMAX is modified
100 ! ! MODIFY nmax in all splines.f routines
101 INTEGER, PARAMETER :: isdmax = 20 ! maximum number of subdomain in one direction
102 ! ! WARNING, if ISDMAX is modified
103 ! ! MODIFY ndmax in all splines.f routines
104 INTEGER, PARAMETER :: immax = 3 ! maximum number of monomes (order 2)
105 INTEGER :: idata ! total number of data
106 REAL, DIMENSION(2,ND) :: zxdom ! coordinates of the limits of the domain
107 REAL, DIMENSION(:,:), ALLOCATABLE :: zxdata ! coordinates of the available data
108 REAL, DIMENSION(:), ALLOCATABLE :: zdata ! available data
109 INTEGER,DIMENSION(ISDMAX,ISDMAX) :: ndomdata ! number of data in a subdomain
110 
111 INTEGER :: iout ! total number of points to interpolate
112 REAL, DIMENSION(:,:), ALLOCATABLE :: zxout ! coordinates of these points
113 REAL, DIMENSION(:), ALLOCATABLE :: zvalout ! values of these points
114 REAL :: zminval ! minimum value of the field
115 REAL :: zmaxval ! maximum value of the field
116 !
117 !* 0.3 Declaration for f77 routines
118 ! ----------------------------
119 !
120 INTEGER, PARAMETER :: iorder = 2 ! order of the spline
121 INTEGER, PARAMETER :: im = (iorder*(iorder+1))/2 ! number of monomes
122 INTEGER :: isdi,isdj ! number of subdomains in each
123 ! ! direction for spline computation
124 INTEGER :: iiorder
125 INTEGER :: iim
126 INTEGER :: jsdi,jsdj ! loop controls on subdomains
127 INTEGER :: iinter ! inverse ratio of the intersection of
128 ! ! 2 subdomains over one of the subdomain
129 REAL, DIMENSION(ND,ND) :: zg ! matrix of correspondance between
130 ! ! x and y units
131 REAL :: zp, zs2
132 !
133 REAL, DIMENSION(:,:,:), ALLOCATABLE :: zc ! coefficients of the spline
134 REAL, DIMENSION(IDATAMAX+3*IMMAX) :: zwe ! work array
135 !
136 !INTEGER, DIMENSION(2,IM) :: IW
137 REAL(KIND=JPRB) :: zhook_handle
138 !-------------------------------------------------------------------------------
139 !
140 !* 1. Miscellaneous Initializations
141 ! -----------------------------
142 !
143 IF (lhook) CALL dr_hook('INTERPOL_SPLINES',0,zhook_handle)
144 ifield=SIZE(pfield,2)
145 !
146 !IW = 0
147 iiorder=iorder
148 iim=im
149 !-------------------------------------------------------------------------------
150 !
151 !* 2. Splines initializations
152 ! -----------------------
153 !
154 !
155 !* 2.1 Coordinates of input data points
156 ! --------------------------------
157 !
158 idata=count(kcode>0)
159 ALLOCATE(zxdata(nd,idata))
160 ALLOCATE(zdata(idata))
161 !
162 zxdata(1,:)=pack(px(:),mask=(kcode(:)>0))
163 zxdata(2,:)=pack(py(:),mask=(kcode(:)>0))
164 !
165 !* 2.2 Coordinates of domain limits
166 ! ----------------------------
167 !
168 zxdom(1,1)=minval(px(:),mask=kcode(:)>=0)
169 zxdom(2,1)=maxval(px(:),mask=kcode(:)>=0)
170 zxdom(1,2)=minval(py(:),mask=kcode(:)>=0)
171 zxdom(2,2)=maxval(py(:),mask=kcode(:)>=0)
172 !
173 !* 2.3 Coordinates of output interpolated points
174 ! -----------------------------------------
175 !
176 iout=count(kcode==0)
177 ALLOCATE(zxout(nd,iout))
178 ALLOCATE(zvalout(iout))
179 !
180 zxout(1,:)=pack(px(:),mask=(kcode(:)==0))
181 zxout(2,:)=pack(py(:),mask=(kcode(:)==0))
182 !
183 !* 2.4 Matrix of unit correspondance
184 ! -----------------------------
185 !
186 zg(1,1)=1.
187 zg(2,2)=1.
188 zg(1,2)=0.
189 zg(2,1)=0.
190 !
191 !-------------------------------------------------------------------------------
192 !
193 !* 3. Subdomains generation
194 ! ---------------------
195 !
196 iinter=4
197 !
198 isdi=max(1,min(int( sqrt( idata/100+1 -1.e-6 )),isdmax))
199 isdj=isdi
200 !
201 !
202 subdomains: DO
203  DO jsdi=1,isdi
204  DO jsdj=1,isdj
205  ndomdata(jsdi,jsdj)= count( (kcode(:)>0) .AND. &
206  ( ( px(:) >= zxdom(1,1) + (jsdi-1-0.5/(iinter-1))*(zxdom(2,1)-zxdom(1,1))/isdi) &
207  .AND. ( px(:) <= zxdom(1,1) + (jsdi +0.5/(iinter-1))*(zxdom(2,1)-zxdom(1,1))/isdi) &
208  .AND. ( py(:) >= zxdom(1,2) + (jsdj-1-0.5/(iinter-1))*(zxdom(2,2)-zxdom(1,2))/isdj) &
209  .AND. ( py(:) <= zxdom(1,2) + (jsdj +0.5/(iinter-1))*(zxdom(2,2)-zxdom(1,2))/isdj) ) &
210  )
211  END DO
212  END DO
213  IF ( (isdi<isdmax) .AND. (isdj<isdmax) .AND. any(ndomdata(1:isdi,1:isdj) > idatamax/2) ) THEN
214  isdi=isdi+1
215  isdj=isdj+1
216  cycle subdomains
217  END IF
218  EXIT subdomains
219 END DO subdomains
220 !
221 IF ( any(ndomdata(1:isdi,1:isdj) > idatamax) ) THEN
222  WRITE(kluout,*) '**********************************************************'
223  WRITE(kluout,*) '* ERROR during data interpolation *'
224  WRITE(kluout,*) '* interpolation by splines routines is impossible *'
225  WRITE(kluout,*) '* please use an input data file with a better resolution *'
226  WRITE(kluout,*) '**********************************************************'
227  CALL abor1_sfx('INTERPOL_SPLINES: ERROR DURING DATA INTERPOLATION BY SPLINES')
228 END IF
229 !
230 WRITE(kluout,*) '----------------------------------'
231 !
232 !-------------------------------------------------------------------------------
233 !
234 !* 4. Computation of the spline in the subdomains (f77 routine)
235 ! -------------------------------------------
236 !
237 !* 4.1 Output printing
238 ! ---------------
239 !
240  IF (iverb>=7) THEN
241  DO jsdi=1,isdi
242  DO jsdj=1,isdj
243  WRITE(kluout,*) ' domain sdi=',jsdi,' sdj=',jsdj,' : ', &
244  ndomdata(jsdi,jsdj),' data points available'
245  END DO
246  END DO
247  END IF
248 !
249 !* 4.2 Choice between splines computation or deduction
250 ! -----------------------------------------------
251 !
252  IF (iverb>=7) WRITE(kluout,*) ' splines computations:'
253 !
254 !* 4.3 Allocations
255 ! -----------
256 !
257  ALLOCATE(zc( idatamax+immax , isdi , isdj ))
258  iopt=0
259 !
260 !* 4.4 Loop on fields
261 ! --------------
262 !
263  DO jk=1,ifield
264 !
265  zdata(:)=pack(pfield(:,jk),mask=(kcode(:)>0))
266 !
267 !* 4.5 special case of uniform input data
268 ! -----------------------------
269 !
270  zminval = minval(zdata)
271  zmaxval = maxval(zdata)
272 !-------------------------------------------------------------------------------
273  IF ( abs(zmaxval - zminval) <= 1.e-10 * max(abs(zmaxval),abs(zminval)) ) THEN
274 !-------------------------------------------------------------------------------
275 !
276  zvalout(:)=maxval(zdata)
277 !
278 !-------------------------------------------------------------------------------
279  ELSE
280 !-------------------------------------------------------------------------------
281 !
282 !* 4.6 Call for splines coefficients
283 ! -----------------------------
284 !
285 !
286  zp = 0.
287  zs2 = 0.
288 !
289  CALL splb2c(iiorder,iim,zxdata,zg,zdata,zs2,zp,0,iopt,isdi,isdj,iinter,zxdom,zc,krep)
290 ! CALL SPLB2C(IDATA,ZXDATA,ZG,ZDATA,0,0.,ZP,IORDER,IM,IOPT,ISDI,ISDJ,IINTER,ZXDOM, &
291 ! ZC,KREP,IW,W)
292 !
293  iopt=1
294 !
295  IF (krep/=0) THEN
296  WRITE(kluout,*) 'Routine INTERPOL_SPLINES: error in SPLB2C, KREP=',krep
297  WRITE(kluout,*) 'The field is interpolated from 3 nearest points'
298  IF (ALLOCATED(zxdata)) DEALLOCATE(zxdata)
299  IF (ALLOCATED(zdata)) DEALLOCATE(zdata)
300  IF (ALLOCATED(zc)) DEALLOCATE(zc)
301  IF (ALLOCATED(zvalout)) DEALLOCATE(zvalout)
302  IF (ALLOCATED(zxout)) DEALLOCATE(zxout)
303  IF (lhook) CALL dr_hook('INTERPOL_SPLINES',1,zhook_handle)
304  RETURN
305  END IF
306 !
307 !-------------------------------------------------------------------------------
308 !
309 !* 5. Evaluation of the spline (f77 routine)
310 ! ------------------------
311 !
312  zvalout(:)=xundef
313  !
314  IF (iverb>=7) WRITE(kluout,*) ' splines evaluations'
315  !CALL SPLB2E(IORDER,IM,ZG,ISDI,ISDJ,ZC,IOUT,ZXOUT,ZVALOUT,ZWE,IW,W)
316  CALL splb2e(iiorder,iim,isdi,isdj,zg,zc,zxout,zvalout)
317 !
318 !-------------------------------------------------------------------------------
319  END IF
320 !-------------------------------------------------------------------------------
321 !
322 !* 6. filling grid points
323 ! -------------------
324 !
325  jout=0
326  DO jin=1,SIZE(pfield,1)
327  IF (kcode(jin)/=0) cycle
328  jout=jout+1
329  pfield(jin,jk) = zvalout(jout)
330  pfield(jin,jk) = max(zminval, min(zmaxval,pfield(jin,jk))) ! control of extrema
331  END DO
332 !
333 !-------------------------------------------------------------------------------
334  END DO
335 !-------------------------------------------------------------------------------
336 !-------------------------------------------------------------------------------
337 !
338 !* 8. Deallocations
339 ! -------------
340 !
341 IF (ALLOCATED(zxdata)) DEALLOCATE(zxdata)
342 IF (ALLOCATED(zdata)) DEALLOCATE(zdata)
343 IF (ALLOCATED(zc)) DEALLOCATE(zc)
344 IF (ALLOCATED(zvalout)) DEALLOCATE(zvalout)
345 IF (ALLOCATED(zxout)) DEALLOCATE(zxout)
346 IF (lhook) CALL dr_hook('INTERPOL_SPLINES',1,zhook_handle)
347 !
348 !-------------------------------------------------------------------------------
349 !
350 END SUBROUTINE interpol_splines
subroutine interpol_splines(KLUOUT, KCODE, PX, PY, PFIELD, KREP)
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:6