SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
latlonmask_conf_proj.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 latlonmask_conf_proj(KGRID_PAR,PGRID_PAR,OLATLONMASK)
7 ! ##################################
8 !
9 !!**** *LATLONMASK* builds the latiude and longitude mask including the grid
10 !!
11 !! PURPOSE
12 !! -------
13 !!
14 !! METHOD
15 !! ------
16 !!
17 !! Two tests are performed:
18 !!
19 !! 1) test if the points of the mask are in the domain
20 !!
21 !! 2) fills the mask points corresponding to points scanning
22 !!
23 !! EXTERNAL
24 !! --------
25 !!
26 !!
27 !! IMPLICIT ARGUMENTS
28 !! ------------------
29 !!
30 !!
31 !! REFERENCE
32 !! ---------
33 !!
34 !! AUTHOR
35 !! ------
36 !!
37 !! V. Masson Meteo-France
38 !!
39 !! MODIFICATION
40 !! ------------
41 !!
42 !! Original 19/07/95
43 !----------------------------------------------------------------------------
44 !
45 !* 0. DECLARATION
46 ! -----------
47 !
49 !
50 !
51 USE yomhook ,ONLY : lhook, dr_hook
52 USE parkind1 ,ONLY : jprb
53 !
54 IMPLICIT NONE
55 !
56 !* 0.1 Declaration of arguments
57 ! ------------------------
58 !
59 INTEGER, INTENT(IN) :: kgrid_par ! size of PGRID_PAR
60 REAL, DIMENSION(KGRID_PAR), INTENT(IN) :: pgrid_par ! parameters defining this grid
61 LOGICAL, DIMENSION(720,360), INTENT(OUT) :: olatlonmask ! mask where data are to be read
62 !
63 !* 0.2 Declaration of local variables
64 ! ------------------------------
65 !
66 INTEGER :: iimax ! x coordinates array dimension
67 INTEGER :: ijmax ! y coordinates array dimension
68 INTEGER :: ji, jj ! loop counters
69 INTEGER :: jlon,jlat! loop counters
70 REAL :: zxmin ! minimum of X for domain
71 REAL :: zxmax ! maximum of X for domain
72 REAL :: zymin ! minimum of Y for domain
73 REAL :: zymax ! maximum of Y for domain
74 REAL, DIMENSION(:), ALLOCATABLE :: zdx ! X grid mesh size
75 REAL, DIMENSION(:), ALLOCATABLE :: zdy ! Y grid mesh size
76 REAL, DIMENSION(:), ALLOCATABLE :: zx ! X conformal coordinate of center of grid mesh
77 REAL, DIMENSION(:), ALLOCATABLE :: zy ! Y conformal coordinate of center of grid mesh
78 REAL, DIMENSION(:), ALLOCATABLE :: zxcorner ! X conformal coordinate of corner of grid mesh
79 REAL, DIMENSION(:), ALLOCATABLE :: zycorner ! Y conformal coordinate of corner of grid mesh
80 REAL, DIMENSION(:), ALLOCATABLE :: zlon ! corner points longitudes
81 REAL, DIMENSION(:), ALLOCATABLE :: zlat ! corner points latitudes
82 REAL, DIMENSION(:,:), ALLOCATABLE :: zlon2d ! corner points longitudes
83 REAL, DIMENSION(:,:), ALLOCATABLE :: zlat2d ! corner points latitudes
84 REAL, DIMENSION(720,360) :: zx_mask ! mask points X value
85 REAL, DIMENSION(720,360) :: zy_mask ! mask points Y value
86 INTEGER, DIMENSION(720,360) :: icount1 ! counter
87 INTEGER, DIMENSION(720,360) :: icount2 ! counter
88 REAL, DIMENSION(720) :: zlon_mask! mask points longitudes
89 REAL, DIMENSION(720) :: zlat_mask! mask points latitudes
90 REAL :: zlat0 ! reference latitude
91 REAL :: zlon0 ! reference longitude
92 REAL :: zrpk ! projection parameter
93 ! ! K=1 : stereographic north pole
94 ! ! 0<K<1 : Lambert, north hemisphere
95 ! ! K=0 : Mercator
96 ! !-1<K<0 : Lambert, south hemisphere
97 ! ! K=-1: stereographic south pole
98 REAL :: zbeta ! angle between grid and reference longitude
99 REAL :: zlator ! latitude of point of coordinates X=0, Y=0
100 REAL :: zlonor ! longitude of point of coordinates X=0, Y=0
101 !
102 INTEGER :: iverb=1 ! verbosity level
103 REAL(KIND=JPRB) :: zhook_handle
104 !----------------------------------------------------------------------------
105 !
106 IF (lhook) CALL dr_hook('LATLONMASK_CONF_PROJ',0,zhook_handle)
107  CALL get_gridtype_conf_proj(pgrid_par,kimax=iimax,kjmax=ijmax)
108 !
109 !
110 ALLOCATE(zx(iimax*ijmax))
111 ALLOCATE(zy(iimax*ijmax))
112 ALLOCATE(zdx(iimax*ijmax))
113 ALLOCATE(zdy(iimax*ijmax))
114 ALLOCATE(zxcorner((iimax+1)*(ijmax+1)))
115 ALLOCATE(zycorner((iimax+1)*(ijmax+1)))
116 ALLOCATE(zlon((iimax+1)*(ijmax+1)))
117 ALLOCATE(zlat((iimax+1)*(ijmax+1)))
118 !
119 !-------------------------------------------------------------------------------
120 !
121 olatlonmask(:,:) = .false.
122 !
123 !-------------------------------------------------------------------------------
124 !
125 !* 1. Limits of the domain conformal plane coordinates
126 ! ------------------------------------------------
127 !
128  CALL get_gridtype_conf_proj(pgrid_par,px=zx,py=zy,pdx=zdx,pdy=zdy)
129 !
130 zxmin = minval(zx) - 3.* maxval(zdx)/2.
131 zxmax = maxval(zx) + 3.* maxval(zdx)/2.
132 !
133 zymin = minval(zy) - 3.* maxval(zdy)/2.
134 zymax = maxval(zy) + 3.* maxval(zdy)/2.
135 !
136 DO jj=1,ijmax
137  DO ji=1,iimax
138  zxcorner(ji+(jj-1)*(iimax+1)) = zx(ji+(jj-1)*iimax) - 0.5*zdx(ji+(jj-1)*iimax)
139  zycorner(ji+(jj-1)*(iimax+1)) = zy(ji+(jj-1)*iimax) - 0.5*zdy(ji+(jj-1)*iimax)
140  END DO
141  zxcorner(iimax+1+(jj-1)*(iimax+1)) = zx(iimax+(jj-1)*iimax) + 0.5*zdx(iimax+(jj-1)*iimax)
142  zycorner(iimax+1+(jj-1)*(iimax+1)) = zy(iimax+(jj-1)*iimax) - 0.5*zdx(iimax+(jj-1)*iimax)
143 END DO
144 DO ji=1,iimax
145  zxcorner(ji+ijmax*(iimax+1)) = zx(ji+(ijmax-1)*iimax) - 0.5*zdx(ji+(ijmax-1)*iimax)
146  zycorner(ji+ijmax*(iimax+1)) = zy(ji+(ijmax-1)*iimax) + 0.5*zdy(ji+(ijmax-1)*iimax)
147 END DO
148 zxcorner((ijmax+1)*(iimax+1)) = zx(ijmax*iimax) + 0.5*zdx(ijmax*iimax)
149 zycorner((ijmax+1)*(iimax+1)) = zy(ijmax*iimax) + 0.5*zdy(ijmax*iimax)
150 !
151 DEALLOCATE(zdx)
152 DEALLOCATE(zdy)
153 DEALLOCATE(zx)
154 DEALLOCATE(zy)
155 !
156 !-------------------------------------------------------------------------------
157 !
158 !* 2. Definition of the coordinates at center of the mask meshes
159 ! ----------------------------------------------------------
160 !
161 zlon_mask(:)= (/ ( jlon /2. - 0.25 , jlon=1,720 ) /)
162 !
163 !* 3. Longitude correction / LON0
164 ! ---------------------------
165 !
166  CALL get_gridtype_conf_proj(pgrid_par, &
167  plat0=zlat0,plon0=zlon0,prpk=zrpk, &
168  pbeta=zbeta,plator=zlator,plonor=zlonor )
169 !
170 zlon_mask(:)=zlon_mask(:)+nint((zlon0-zlon_mask(:))/360.)*360.
171 !
172 !* 4. X and Y of the points of the mask
173 ! ---------------------------------
174 !
175 DO jlat=1,SIZE(olatlonmask,2)
176  zlat_mask(:) = (jlat-180)/2. - 0.25
177  CALL xy_conf_proj(zlat0,zlon0,zrpk,zbeta,zlator,zlonor, &
178  zx_mask(:,jlat),zy_mask(:,jlat), &
179  zlat_mask(:),zlon_mask(:) )
180 END DO
181 !
182 !* 5. Are the points in the domain?
183 ! ----------------------------
184 !
185 WHERE ( zx_mask(:,:) >= zxmin .AND. zx_mask(:,:) <= zxmax &
186  .AND. zy_mask(:,:) >= zymin .AND. zy_mask(:,:) <= zymax )
187  olatlonmask(:,:) = .true.
188 END WHERE
189 !
190 !-------------------------------------------------------------------------------
191 !
192 !* 6. Latitude and longitude of the points of the domain
193 ! --------------------------------------------------
194 !
195  CALL latlon_conf_proj(zlat0,zlon0,zrpk,zbeta,zlator,zlonor, &
196  zxcorner,zycorner,zlat,zlon )
197 !
198 !* 7. Longitudes between 0. and 360.
199 ! ------------------------------
200 !
201 zlon(:) = zlon(:) + nint((180.-zlon(:))/360.)*360.
202 !
203 !* 8. Loop on grid points
204 ! --------------------
205 !
206 icount1(:,:) = 0
207 icount2(:,:) = 0
208 !
209 ALLOCATE(zlat2d(iimax+1,ijmax+1))
210 ALLOCATE(zlon2d(iimax+1,ijmax+1))
211 !
212 DO jj=1,ijmax+1
213  DO ji=1,iimax+1
214  zlat2d(ji,jj) = zlat(ji+(jj-1)*(iimax+1))
215  zlon2d(ji,jj) = zlon(ji+(jj-1)*(iimax+1))
216  END DO
217 END DO
218 !
219 DO jj=1,ijmax+1
220  DO ji=1,iimax+1
221  !
222  !* 8.1 localisation of the point
223  ! -------------------------
224  !
225  jlat = min( 1 + int( ( zlat2d(ji,jj) + 90. ) * 2. ) ,360)
226  jlon = min( 1 + int( ( zlon2d(ji,jj) ) * 2. ) ,720)
227  !
228  icount1(jlon,jlat) = icount1(jlon,jlat) + 1
229  !
230  !* 8.2 Does point contain data?
231  ! ------------------------
232  !
233  !
234  !* 8.3 point contains data
235  ! -------------------
236  !
237  icount2(jlon,jlat) = icount2(jlon,jlat) + 1
238  !
239  !* 8.4 Boundary effects
240  ! ----------------
241  !
242  jlat = min( 1 + int( ( zlat2d(min(ji+1,iimax),jj) + 90. ) * 2. ) ,360)
243  jlon = min( 1 + int( ( zlon2d(min(ji+1,iimax),jj) ) * 2. ) ,720)
244  icount1(jlon,jlat) = icount1(jlon,jlat) + 1
245  icount2(jlon,jlat) = icount2(jlon,jlat) + 1
246  !
247  jlat = min( 1 + int( ( zlat2d(ji,min(jj+1,ijmax)) + 90. ) * 2. ) ,360)
248  jlon = min( 1 + int( ( zlon2d(ji,min(jj+1,ijmax)) ) * 2. ) ,720)
249  icount1(jlon,jlat) = icount1(jlon,jlat) + 1
250  icount2(jlon,jlat) = icount2(jlon,jlat) + 1
251  !
252  jlat = min( 1 + int( ( zlat2d(max(ji-1,1),jj) + 90. ) * 2. ) ,360)
253  jlon = min( 1 + int( ( zlon2d(max(ji-1,1),jj) ) * 2. ) ,720)
254  icount1(jlon,jlat) = icount1(jlon,jlat) + 1
255  icount2(jlon,jlat) = icount2(jlon,jlat) + 1
256  !
257  jlat = min( 1 + int( ( zlat2d(ji,max(jj-1,1)) + 90. ) * 2. ) ,360)
258  jlon = min( 1 + int( ( zlon2d(ji,max(jj-1,1)) ) * 2. ) ,720)
259  icount1(jlon,jlat) = icount1(jlon,jlat) + 1
260  icount2(jlon,jlat) = icount2(jlon,jlat) + 1
261  !
262  END DO
263 END DO
264 !
265 !* 9. Surface type check (if points are present in mask mesh)
266 ! ------------------
267 !
268 WHERE (icount1(:,:) > 0 .AND. icount2(:,:) == 0)
269  olatlonmask(:,:) = .false.
270 END WHERE
271 !
272 WHERE (icount1(:,:) > 0 .AND. icount2(:,:) > 0)
273  olatlonmask(:,:) = .true.
274 END WHERE
275 !
276 zlat_mask(1:360)= (/ ( (jlat-180)/2. - 0.25 , jlat=1,360 ) /)
277 !
278 DO jlon=1,720
279  DO jlat=1,360
280  IF ( (icount1(jlon,jlat) > 0 .OR. olatlonmask(jlon,jlat)) .AND. iverb > 1) &
281  WRITE(*,'(2(I3,1X),2(F6.2,1X),2(F8.0,1X),L1)') jlon,jlat,zlon_mask(jlon),zlat_mask(jlat), &
282  zx_mask(jlon,jlat),zy_mask(jlon,jlat),olatlonmask(jlon,jlat)
283 
284  END DO
285 END DO
286 !
287 !-------------------------------------------------------------------------------
288 !
289 DEALLOCATE(zlon )
290 DEALLOCATE(zlat )
291 DEALLOCATE(zlon2d)
292 DEALLOCATE(zlat2d)
293 DEALLOCATE(zxcorner)
294 DEALLOCATE(zycorner)
295 IF (lhook) CALL dr_hook('LATLONMASK_CONF_PROJ',1,zhook_handle)
296 !
297 !-------------------------------------------------------------------------------
298 !
299 END SUBROUTINE latlonmask_conf_proj
subroutine latlonmask_conf_proj(KGRID_PAR, PGRID_PAR, OLATLONMASK)
subroutine latlon_conf_proj(PLAT0, PLON0, PRPK, PBETA, PLATOR, PLONOR, PX, PY, PLAT, PLON)
subroutine xy_conf_proj(PLAT0, PLON0, PRPK, PBETA, PLATOR, PLONOR, PX, PY, PLAT, PLON)
subroutine get_gridtype_conf_proj(PGRID_PAR, PLAT0, PLON0, PRPK, PBETA, PLATOR, PLONOR, KIMAX, KJMAX, PX, PY, PDX, PDY, KL)