SURFEX v8.1
General documentation of Surfex
bilin_coef.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 bilin_coef (KLUOUT,PX1,PY1,PX2,PY2,PCX,PCY,KCI,KCJ)
7 ! #########################################################################
8 !
9 !!**** *BILIN_COEFEAR * - subroutine to interpolate surface FIELD
10 !!
11 !! PURPOSE
12 !! -------
13 !!
14 !!
15 !!** METHOD
16 !! ------
17 !!
18 !! Interpolation is bilinear, and uses 9 grid points, located in the
19 !! center of model 1 grid mesh, and at the boundaries of this grid
20 !! mesh (2 X limits, 2 Y limits and 4 corners).
21 !! This implies that the grid mesh values located around the model 1
22 !! grid mesh are not used directly. The values at the boundaries of the
23 !! grid mesh are defined by the average between the middle point
24 !! (this grid mesh value), and the one in the considered direction.
25 !! So the eight grid meshes around the considered grid mesh are used
26 !! equally.
27 !! This is important to note that these average values are erased
28 !! and replaced by zero if they are at the limit of any grid
29 !! mesh with the zero value. This allows to insure zero value in model 2
30 !! grid meshes where there was not the considered class in corresponding
31 !! model 1 grid mesh, and to insure continuity of the FIELD type
32 !! at such boundaries.
33 !!
34 !!
35 !! The arrays and array index are defined on the following (model1) grid:
36 !!
37 !!
38 !! XFIELD XFIELD XFIELD
39 !! * * *
40 !! i-1,j+1 i,j+1 i+1,j+1
41 !!
42 !!
43 !!
44 !! ZFIELD_XY ZFIELD_Y ZFIELD_XY
45 !! * * *
46 !! i,j+1 i,j+1 i+1,j+1
47 !!
48 !!
49 !!
50 !! XFIELD ZFIELD_X XFIELD ZFIELD_X XFIELD
51 !! * * * * *
52 !! i-1,j i,j i,j i+1,j i+1,j
53 !!
54 !!
55 !!
56 !! ZFIELD_XY ZFIELD_Y ZFIELD_XY
57 !! * * *
58 !! i,j i,j i+1,j
59 !!
60 !!
61 !!
62 !! XFIELD XFIELD XFIELD
63 !! * * *
64 !! i-1,j-1 i,j-1 i+1,j-1
65 !!
66 !!
67 !!
68 !!
69 !!
70 !! AUTHOR
71 !! ------
72 !!
73 !! V. Masson * METEO-FRANCE *
74 !!
75 !! MODIFICATIONS
76 !! -------------
77 !!
78 !! Original 01/2004
79 ! TD&DD: added OpenMP directives
80 
81 !-------------------------------------------------------------------------------
82 !
83 !* 0. DECLARATIONS
84 ! ------------
85 !
86 USE modd_surfex_mpi, ONLY : nrank
87 USE modd_surf_par, ONLY : xundef
88 !
89 USE yomhook ,ONLY : lhook, dr_hook
90 USE parkind1 ,ONLY : jprb
91 !
92 IMPLICIT NONE
93 !
94 !* 0.1 Declarations of dummy arguments :
95 !
96 INTEGER, INTENT(IN) :: KLUOUT ! output listing logical unit
97 REAL, DIMENSION(:), INTENT(IN) :: PX1 ! X coordinate of the regular input grid
98 REAL, DIMENSION(:), INTENT(IN) :: PY1 ! Y coordinate of the regular input grid
99 REAL, DIMENSION(:), INTENT(IN) :: PX2 ! X coordinate of all points of output grid
100 REAL, DIMENSION(:), INTENT(IN) :: PY2 ! Y coordinate of all points of output grid
101 REAL, DIMENSION(:,:), INTENT(OUT) :: PCX, PCY
102 INTEGER, DIMENSION(:), INTENT(OUT):: KCI, KCJ
103 
104 !
105 !* 0.2 Declarations of local variables for print on FM file
106 !
107 !
108 REAL, DIMENSION (SIZE(PX1)+1) :: ZX ! X coordinate of left limit of input meshes
109 REAL, DIMENSION (SIZE(PY1)+1) :: ZY ! Y coordinate of bottom limit of input meshes
110 !
111 !
112 INTEGER :: IIU ! model 1 X size
113 INTEGER :: IJU ! model 1 Y size
114 !
115 INTEGER :: IDMIN, IDMAX
116 INTEGER :: JI ! grid 1 x index
117 INTEGER :: JJ ! grid 1 y index
118 INTEGER :: IIN ! loop counter on all input points
119 !
120 INTEGER :: JL ! grid 2 index
121 !
122 REAL :: ZEPS=1.e-3
123 REAL(KIND=JPRB) :: ZHOOK_HANDLE, ZHOOK_HANDLE_OMP
124 !-------------------------------------------------------------------------------
125 !
126 IF (lhook) CALL dr_hook('BILIN_COEF_1',0,zhook_handle)
127 
128 iiu=SIZE(px1)
129 iju=SIZE(py1)
130 !
131 !* 4. Coordinates of points between input grid points
132 ! -----------------------------------------------
133 !
134 IF (iiu>1) THEN
135  zx(1) = 1.5*px1(1) -0.5*px1(2)
136  zx(iiu+1) = 1.5*px1(iiu)-0.5*px1(iiu-1)
137  DO jj = 2,iiu
138  zx(jj) = 0.5*(px1(jj-1)+px1(jj))
139  ENDDO
140 ELSE
141  zx(1) = px1(1) - 1.e6 ! uniform field in X direction if only 1 point is
142  zx(2) = px1(1) + 1.e6 ! available. Arbitrary mesh length of 2000km assumed
143 END IF
144 !
145 IF (iju>1) THEN
146  zy(1) = 1.5*py1(1) -0.5*py1(2)
147  zy(iju+1) = 1.5*py1(iju)-0.5*py1(iju-1)
148  DO jj = 2,iju
149  zy(jj) = 0.5*(py1(jj-1)+py1(jj))
150  ENDDO
151 ELSE
152  zy(1) = py1(1) - 1.e6 ! uniform field in Y direction if only 1 point is
153  zy(2) = py1(1) + 1.e6 ! available. Arbitrary mesh length of 2000km assumed
154 END IF
155 !
156 !-------------------------------------------------------------------------------
157 !
158 !* 5. Interpolation
159 ! -------------
160 !
161 !* loop on all output grid points
162 !
163 kci(:) = 1
164 kcj(:) = 1
165 !
166 IF (lhook) CALL dr_hook('BILIN_COEF_1',1,zhook_handle)
167 !
168 !$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
169 IF (lhook) CALL dr_hook('BILIN_COEF_2',0,zhook_handle_omp)
170 !$OMP DO PRIVATE(JL,JJ)
171 DO jl=1,SIZE(px2)
172  DO jj=SIZE(zx),1,-1
173  IF (zx(jj)<=px2(jl)) THEN
174  kci(jl) = jj
175  EXIT
176  ENDIF
177  ENDDO
178  DO jj=SIZE(zy),1,-1
179  IF (zy(jj)<=py2(jl)) THEN
180  kcj(jl) = jj
181  EXIT
182  ENDIF
183  ENDDO
184 ENDDO
185 !$OMP END DO
186 IF (lhook) CALL dr_hook('BILIN_COEF_2',1,zhook_handle_omp)
187 !$OMP END PARALLEL
188 !
189 IF (lhook) CALL dr_hook('BILIN_COEF_3',0,zhook_handle)
190 
191 DO jl=1,SIZE(px2)
192 !
193 !* interpolation weights in X direction
194 !
195  ji=kci(jl)
196  ji=max(min(ji,iiu),0)
197  IF (px1(ji)<=px2(jl)) THEN
198  pcx(jl,2) = (px2(jl)-zx(ji+1))/(px1(ji)-zx(ji+1))
199  pcx(jl,2) = max(min(pcx(jl,2),1.),0.)
200  pcx(jl,3) = 1. - pcx(jl,2)
201  pcx(jl,1) = 0.
202  ELSE
203  pcx(jl,2) = (px2(jl)-zx(ji))/(px1(ji)-zx(ji))
204  pcx(jl,2) = max(min(pcx(jl,2),1.),0.)
205  pcx(jl,1) = 1. - pcx(jl,2)
206  pcx(jl,3) = 0.
207  END IF
208 !
209 ! interpolation weights in Y direction
210 !
211  jj=kcj(jl)
212  jj=max(min(jj,iju),0)
213  IF (py1(jj)<=py2(jl)) THEN
214  pcy(jl,2) = (py2(jl)-zy(jj+1))/(py1(jj)-zy(jj+1))
215  pcy(jl,2) = max(min(pcy(jl,2),1.),0.)
216  pcy(jl,3) = 1. - pcy(jl,2)
217  pcy(jl,1) = 0.
218  ELSE
219  pcy(jl,2) = (py2(jl)-zy(jj))/(py1(jj)-zy(jj))
220  pcy(jl,2) = max(min(pcy(jl,2),1.),0.)
221  pcy(jl,1) = 1. - pcy(jl,2)
222  pcy(jl,3) = 0.
223  END IF
224 !
225 END DO
226 !
227 IF (lhook) CALL dr_hook('BILIN_COEF_3',1,zhook_handle)
228 !-------------------------------------------------------------------------------
229 !
230 END SUBROUTINE bilin_coef
real, parameter xundef
subroutine bilin_coef(KLUOUT, PX1, PY1, PX2, PY2, PCX, PCY, KCI, KCJ)
Definition: bilin_coef.F90:7
integer, parameter jprb
Definition: parkind1.F90:32
logical lhook
Definition: yomhook.F90:15