source: LMDZ5/trunk/libf/phylmd/grid_noro_m.F90 @ 2501

Last change on this file since 2501 was 2346, checked in by Ehouarn Millour, 9 years ago

Physics/dynamics separation:

  • remove all references to dimensions.h from physics. nbp_lon (==iim) , nbp_lat (==jjm+1) and nbp_lev (==llm) from mod_grid_phy_lmdz should be used instead.
  • added module regular_lonlat_mod in phy_common to store information about the global (lon-lat) grid cell boundaries and centers.

EM

File size: 14.7 KB
RevLine 
[2293]1MODULE grid_noro_m
2!
3!*******************************************************************************
4
5  PRIVATE
6  PUBLIC :: grid_noro
7
8
9CONTAINS
10
11
12!-------------------------------------------------------------------------------
13!
14SUBROUTINE grid_noro(xd,yd,zd,x,y,zphi,zmea,zstd,zsig,zgam,zthe,zpic,zval,mask)
15!
16!-------------------------------------------------------------------------------
17! Author: F. Lott (see also Z.X. Li, A. Harzallah et L. Fairhead)
18!-------------------------------------------------------------------------------
19! Purpose: Compute the Parameters of the SSO scheme as described in LOTT &MILLER
20!         (1997) and LOTT(1999).
21!-------------------------------------------------------------------------------
22! Comments:
23!  * Target points are on a rectangular grid:
24!      iim+1 latitudes including North and South Poles;
25!      jjm+1 longitudes, with periodicity jjm+1=1.
26!  * At the poles, the fields value is repeated jjm+1 time.
27!  * The parameters a,b,c,d represent the limits of the target gridpoint region.
28!    The means over this region are calculated from USN data, ponderated by a
29!    weight proportional to the surface occupated by the data inside the model
30!    gridpoint area. In most circumstances, this weight is the ratio between the
31!    surfaces of the USN gridpoint area and the model gridpoint area.
32!
33!           (c)
34!        ----d-----
35!        | . . . .|
36!        |        |
37!     (b)a . * . .b(a)
38!        |        |
39!        | . . . .|
40!        ----c-----
41!           (d)
42!  * Hard-coded US Navy dataset dimensions (imdp=2160 ; jmdp=1080) have been
43!    removed (ALLOCATABLE used).
44!  * iext (currently 10% of imdp) represents the margin to ensure output cells
45!    on the edge are contained in input cells.
46!===============================================================================
47  USE assert_eq_m, ONLY: assert_eq
[2311]48  USE print_control_mod, ONLY: lunout
[2293]49  IMPLICIT NONE
50  REAL, PARAMETER :: epsfra = 1.e-5
51!-------------------------------------------------------------------------------
52! Arguments:
53  REAL, INTENT(IN)  :: xd(:), yd(:)  !--- INPUT  COORDINATES     (imdp) (jmdp)
54  REAL, INTENT(IN)  :: zd(:,:)       !--- INPUT  FIELD           (imdp,jmdp)
55  REAL, INTENT(IN)  :: x(:), y(:)    !--- OUTPUT COORDINATES     (imar+1) (jmar)
56  REAL, INTENT(OUT) :: zphi(:,:)     !--- GEOPOTENTIAL           (imar+1,jmar)
57  REAL, INTENT(OUT) :: zmea(:,:)     !--- MEAN OROGRAPHY         (imar+1,jmar)
58  REAL, INTENT(OUT) :: zstd(:,:)     !--- STANDARD DEVIATION     (imar+1,jmar)
59  REAL, INTENT(OUT) :: zsig(:,:)     !--- SLOPE                  (imar+1,jmar)
60  REAL, INTENT(OUT) :: zgam(:,:)     !--- ANISOTROPY             (imar+1,jmar)
61  REAL, INTENT(OUT) :: zthe(:,:)     !--- SMALL AXIS ORIENTATION (imar+1,jmar)
62  REAL, INTENT(OUT) :: zpic(:,:)     !--- MAXIMUM ALTITITUDE     (imar+1,jmar)
63  REAL, INTENT(OUT) :: zval(:,:)     !--- MINIMUM ALTITITUDE     (imar+1,jmar)
64  REAL, INTENT(OUT) :: mask(:,:)     !--- MASK                   (imar+1,jmar)
65!-------------------------------------------------------------------------------
66! Local variables:
67  CHARACTER(LEN=256) :: modname="grid_noro"
68  REAL, ALLOCATABLE :: xusn(:), yusn(:)           ! dim (imdp+2*iext) (jmdp+2)
69  REAL, ALLOCATABLE :: zusn(:,:)                  ! dim (imdp+2*iext,jmdp+2)
70! CORRELATIONS OF OROGRAPHY GRADIENT              ! dim (imar+1,jmar)
71  REAL, ALLOCATABLE :: ztz(:,:), zxtzx(:,:), zytzy(:,:), zxtzy(:,:), weight(:,:)
72! CORRELATIONS OF USN OROGRAPHY GRADIENTS         ! dim (imar+2*iext,jmdp+2)
73  REAL, ALLOCATABLE :: zxtzxusn(:,:), zytzyusn(:,:), zxtzyusn(:,:)
74  REAL, ALLOCATABLE :: mask_tmp(:,:), zmea0(:,:)  ! dim (imar+1,jmar)
75  REAL, ALLOCATABLE :: num_tot(:,:), num_lan(:,:) ! dim (imax,jmax)
76  REAL, ALLOCATABLE :: a(:), b(:)                 ! dim (imax)
77  REAL, ALLOCATABLE :: c(:), d(:)                 ! dim (jmax)
78  LOGICAL :: masque_lu
79  INTEGER :: i, ii, imdp, imar, iext
80  INTEGER :: j, jj, jmdp, jmar, nn
81  REAL    :: xpi, zdeltax, zlenx, weighx, xincr,  zmeanor0
82  REAL    :: rad, zdeltay, zleny, weighy, masque, zmeasud0
83  REAL    :: zbordnor, zmeanor, zstdnor, zsignor, zweinor, zpicnor, zvalnor
84  REAL    :: zbordsud, zmeasud, zstdsud, zsigsud, zweisud, zpicsud, zvalsud
85  REAL    :: zbordest, zbordoue, xk, xl, xm, xp, xq, xw
86!-------------------------------------------------------------------------------
87  imdp=assert_eq(SIZE(xd),SIZE(zd,1),TRIM(modname)//" imdp")
88  jmdp=assert_eq(SIZE(yd),SIZE(zd,2),TRIM(modname)//" jmdp")
89  imar=assert_eq([SIZE(x),SIZE(zphi,1),SIZE(zmea,1),SIZE(zstd,1),SIZE(zsig,1), &
90                          SIZE(zgam,1),SIZE(zthe,1),SIZE(zpic,1),SIZE(zval,1), &
91                          SIZE(mask,1)],TRIM(modname)//" imar")-1
92  jmar=assert_eq([SIZE(y),SIZE(zphi,2),SIZE(zmea,2),SIZE(zstd,2),SIZE(zsig,2), &
93                          SIZE(zgam,2),SIZE(zthe,2),SIZE(zpic,2),SIZE(zval,2), &
94                          SIZE(mask,2)],TRIM(modname)//" jmar")
[2311]95!  IF(imar/=iim)   CALL abort_physic(TRIM(modname),'imar/=iim'  ,1)
96!  IF(jmar/=jjm+1) CALL abort_physic(TRIM(modname),'jmar/=jjm+1',1)
[2293]97  iext=imdp/10                                !--- OK up to 36 degrees cell
98  xpi = ACOS(-1.)
99  rad = 6371229.
100  zdeltay=2.*xpi/REAL(jmdp)*rad
101  WRITE(lunout,*)"*** Orography parameters at sub-cell scale ***"
102
103!--- ARE WE USING A READ MASK ?
104  masque_lu=ANY(mask/=-99999.); IF(.NOT.masque_lu) mask=0.0
105  WRITE(lunout,*)'Masque lu: ',masque_lu
106
107!--- EXTENSION OF THE INPUT DATABASE TO PROCEED COMPUTATIONS AT BOUNDARIES:
108  ALLOCATE(xusn(imdp+2*iext))
109  xusn(1     +iext:imdp  +iext)=xd(:)
110  xusn(1          :       iext)=xd(1+imdp-iext:imdp)-2.*xpi
111  xusn(1+imdp+iext:imdp+2*iext)=xd(1          :iext)+2.*xpi
112
113  ALLOCATE(yusn(jmdp+2))
114  yusn(1       )=yd(1)   +(yd(1)   -yd(2))
115  yusn(2:jmdp+1)=yd(:)
116  yusn(  jmdp+2)=yd(jmdp)+(yd(jmdp)-yd(jmdp-1))
117
118  ALLOCATE(zusn(imdp+2*iext,jmdp+2))
119  zusn(1       +iext:imdp  +iext,2:jmdp+1)=zd  (:                   ,     :)
120  zusn(1            :       iext,2:jmdp+1)=zd  (imdp-iext+1:imdp    ,     :)
121  zusn(1+imdp  +iext:imdp+2*iext,2:jmdp+1)=zd  (1:iext              ,     :)
122  zusn(1            :imdp/2+iext,       1)=zusn(1+imdp/2:imdp  +iext,     2)
123  zusn(1+imdp/2+iext:imdp+2*iext,       1)=zusn(1       :imdp/2+iext,     2)
124  zusn(1            :imdp/2+iext,  jmdp+2)=zusn(1+imdp/2:imdp  +iext,jmdp+1)
125  zusn(1+imdp/2+iext:imdp+2*iext,  jmdp+2)=zusn(1       :imdp/2+iext,jmdp+1)
126
127!--- COMPUTE LIMITS OF MODEL GRIDPOINT AREA (REGULAR GRID)
128  ALLOCATE(a(imar+1),b(imar+1))
129  b(1:imar)=(x(1:imar  )+ x(2:imar+1))/2.0
130  b(imar+1)= x(  imar+1)+(x(  imar+1)-x(imar))/2.0
131  a(1)=x(1)-(x(2)-x(1))/2.0
132  a(2:imar+1)= b(1:imar)
133
134  ALLOCATE(c(jmar),d(jmar))
135  d(1:jmar-1)=(y(1:jmar-1)+ y(2:jmar))/2.0
136  d(  jmar  )= y(  jmar  )+(y(  jmar)-y(jmar-1))/2.0
137  c(1)=y(1)-(y(2)-y(1))/2.0
138  c(2:jmar)=d(1:jmar-1)
139
140!--- INITIALIZATIONS:
141  ALLOCATE(weight(imar+1,jmar)); weight(:,:)= 0.0
142  ALLOCATE(zxtzx (imar+1,jmar)); zxtzx (:,:)= 0.0
143  ALLOCATE(zytzy (imar+1,jmar)); zytzy (:,:)= 0.0
144  ALLOCATE(zxtzy (imar+1,jmar)); zxtzy (:,:)= 0.0
145  ALLOCATE(ztz   (imar+1,jmar)); ztz   (:,:)= 0.0
146  zmea(:,:)= 0.0
147  zpic(:,:)=-1.E+10
148  zval(:,:)= 1.E+10
149
150!--- COMPUTE SLOPES CORRELATIONS ON USN GRID
151! CORRELATIONS OF USN OROGRAPHY GRADIENTS  ! dim (imdp+2*iext,jmdp+2)
152  ALLOCATE(zytzyusn(imdp+2*iext,jmdp+2)); zytzyusn(:,:)=0.0
153  ALLOCATE(zxtzxusn(imdp+2*iext,jmdp+2)); zxtzxusn(:,:)=0.0
154  ALLOCATE(zxtzyusn(imdp+2*iext,jmdp+2)); zxtzyusn(:,:)=0.0
155  DO j = 2, jmdp+1
156    zdeltax=zdeltay*cos(yusn(j))
157    DO i = 2, imdp+2*iext-1
158      zytzyusn(i,j)=(zusn(i,j+1)-zusn(i,j-1))**2/zdeltay**2
159      zxtzxusn(i,j)=(zusn(i+1,j)-zusn(i-1,j))**2/zdeltax**2
160      zxtzyusn(i,j)=(zusn(i,j+1)-zusn(i,j-1))   /zdeltay  &
161     &             *(zusn(i+1,j)-zusn(i-1,j))   /zdeltax
162    END DO
163  END DO
164
165!--- SUMMATION OVER GRIDPOINT AREA
166  zleny=xpi/REAL(jmdp)*rad
167  xincr=xpi/REAL(jmdp)/2.
168  ALLOCATE(num_tot(imar+1,jmar)); num_tot(:,:)=0.
169  ALLOCATE(num_lan(imar+1,jmar)); num_lan(:,:)=0.
170  DO ii = 1, imar+1
171    DO jj = 1, jmar
172      DO j = 2,jmdp+1
173        zlenx  =zleny  *COS(yusn(j))
174        zdeltax=zdeltay*COS(yusn(j))
175        zbordnor=(xincr+c(jj)-yusn(j))*rad
176        zbordsud=(xincr-d(jj)+yusn(j))*rad
177        weighy=AMAX1(0.,AMIN1(zbordnor,zbordsud,zleny))
178        IF(weighy==0.) CYCLE
179        DO i = 2, imdp+2*iext-1
180          zbordest=(xusn(i)-a(ii)+xincr)*rad*COS(yusn(j))
181          zbordoue=(b(ii)+xincr-xusn(i))*rad*COS(yusn(j))
182          weighx=AMAX1(0.,AMIN1(zbordest,zbordoue,zlenx))
183          IF(weighx==0.) CYCLE
184          num_tot(ii,jj)=num_tot(ii,jj)+1.0
185          IF(zusn(i,j)>=1.)num_lan(ii,jj)=num_lan(ii,jj)+1.0
186          weight(ii,jj)=weight(ii,jj)+weighx*weighy
187          zxtzx(ii,jj)=zxtzx(ii,jj)+zxtzxusn(i,j)*weighx*weighy
188          zytzy(ii,jj)=zytzy(ii,jj)+zytzyusn(i,j)*weighx*weighy
189          zxtzy(ii,jj)=zxtzy(ii,jj)+zxtzyusn(i,j)*weighx*weighy
190          ztz  (ii,jj)=  ztz(ii,jj)+zusn(i,j)*zusn(i,j)*weighx*weighy
191          zmea (ii,jj)= zmea(ii,jj)+zusn(i,j)*weighx*weighy !--- MEAN
192          zpic (ii,jj)=AMAX1(zpic(ii,jj),zusn(i,j))         !--- PEAKS
193          zval (ii,jj)=AMIN1(zval(ii,jj),zusn(i,j))         !--- VALLEYS
194        END DO
195      END DO
196    END DO
197  END DO
198
199!--- COMPUTE PARAMETERS NEEDED BY LOTT & MILLER (1997) AND LOTT (1999) SSO SCHEME
200  IF(.NOT.masque_lu) THEN
201    WHERE(weight(:,1:jmar-1)/=0.0) mask=num_lan(:,:)/num_tot(:,:)
202  END IF
203  nn=COUNT(weight(:,1:jmar-1)==0.0)
204  IF(nn/=0) WRITE(lunout,*)'Problem with weight ; vanishing occurrences: ',nn
205  WHERE(weight(:,:)/=0.0)
206    zmea (:,:)=zmea (:,:)/weight(:,:)
207    zxtzx(:,:)=zxtzx(:,:)/weight(:,:)
208    zytzy(:,:)=zytzy(:,:)/weight(:,:)
209    zxtzy(:,:)=zxtzy(:,:)/weight(:,:)
210    ztz  (:,:)=ztz  (:,:)/weight(:,:)
211    zstd (:,:)=ztz  (:,:)-zmea(:,:)**2
212  END WHERE
213  WHERE(zstd(:,:)<0) zstd(:,:)=0.
214  zstd (:,:)=SQRT(zstd(:,:))
215
216!--- CORRECT VALUES OF HORIZONTAL SLOPE NEAR THE POLES:
217  zxtzx(:,   1)=zxtzx(:,     2)
218  zxtzx(:,jmar)=zxtzx(:,jmar-1)
219  zxtzy(:,   1)=zxtzy(:,     2)
220  zxtzy(:,jmar)=zxtzy(:,jmar-1)
221  zytzy(:,   1)=zytzy(:,     2)
222  zytzy(:,jmar)=zytzy(:,jmar-1)
223
224!=== FILTERS TO SMOOTH OUT FIELDS FOR INPUT INTO SSO SCHEME.
225!--- FIRST FILTER, MOVING AVERAGE OVER 9 POINTS.
226!-------------------------------------------------------------------------------
227  ALLOCATE(zmea0(imar+1,jmar))
228  zmea0(:,:)=zmea(:,:)                           ! GK211005 (CG) UNSMOOTHED TOPO
229  CALL MVA9(zmea);  CALL MVA9(zstd);  CALL MVA9(zpic);  CALL MVA9(zval)
230  CALL MVA9(zxtzx); CALL MVA9(zxtzy); CALL MVA9(zytzy)
231
232!--- MASK BASED ON GROUND MAXIMUM, 10% THRESHOLD. (SURFACE PARAMS MEANINGLESS)
233  ALLOCATE(mask_tmp(imar+1,jmar)); mask_tmp(:,:)=0.0
234  WHERE(mask>=0.1) mask_tmp = 1.
235  WHERE(weight(:,:)/=0.0)
236!   zphi (:,:)= mask_tmp(:,:)*zmea (:,:) ! GK211005 (CG) not necessarly smoothed
237    zphi (:,:)= mask_tmp(:,:)*zmea0(:,:)
238    zmea0(:,:)= mask_tmp(:,:)*zmea0(:,:)
239    zmea (:,:)= mask_tmp(:,:)*zmea (:,:)
240    zpic (:,:)= mask_tmp(:,:)*zpic (:,:)
241    zval (:,:)= mask_tmp(:,:)*zval (:,:)
242    zstd (:,:)= mask_tmp(:,:)*zstd (:,:)
243  END WHERE
244  DO ii = 1, imar
245    DO jj = 1, jmar
246      IF (weight(ii,jj)/=0.0) THEN
247      !--- Coefficients K, L et M:
248        xk=(zxtzx(ii,jj)+zytzy(ii,jj))/2.
249        xl=(zxtzx(ii,jj)-zytzy(ii,jj))/2.
250        xm=zxtzy(ii,jj)
251        xp=xk-SQRT(xl**2+xm**2)
252        xq=xk+SQRT(xl**2+xm**2)
253        xw=1.e-8
254        IF(xp<=xw) xp=0.
255        IF(xq<=xw) xq=xw
256        IF(ABS(xm)<=xw) xm=xw*SIGN(1.,xm)
257      !--- SLOPE
258        zsig(ii,jj)=SQRT(xq)*mask_tmp(ii,jj)
259      !---ISOTROPY
260        zgam(ii,jj)=xp/xq*mask_tmp(ii,jj)
261      !--- THETA ANGLE
262        zthe(ii,jj)=57.29577951*ATAN2(xm,xl)/2.*mask_tmp(ii,jj)
263      END IF
264    END DO
265  END DO
266  WRITE(lunout,*)'  MEAN ORO:' ,MAXVAL(zmea)
267  WRITE(lunout,*)'  ST. DEV.:' ,MAXVAL(zstd)
268  WRITE(lunout,*)'  PENTE:'    ,MAXVAL(zsig)
269  WRITE(lunout,*)'  ANISOTROP:',MAXVAL(zgam)
270  WRITE(lunout,*)'  ANGLE:'    ,MINVAL(zthe),MAXVAL(zthe)
271  WRITE(lunout,*)'  pic:'      ,MAXVAL(zpic)
272  WRITE(lunout,*)'  val:'      ,MAXVAL(zval)
273     
274!--- Values at poles
275  zmea0(imar+1,:)=zmea0(1,:)
276  zmea (imar+1,:)=zmea (1,:)
277  zphi (imar+1,:)=zphi (1,:)
278  zpic (imar+1,:)=zpic (1,:)
279  zval (imar+1,:)=zval (1,:)
280  zstd (imar+1,:)=zstd (1,:)
281  zsig (imar+1,:)=zsig (1,:)
282  zgam (imar+1,:)=zgam (1,:)
283  zthe (imar+1,:)=zthe (1,:)
284
285  zweinor =SUM(weight(1:imar,   1),DIM=1)
286  zweisud =SUM(weight(1:imar,jmar),DIM=1)
287  zmeanor0=SUM(weight(1:imar,   1)*zmea0(1:imar,   1),DIM=1)
288  zmeasud0=SUM(weight(1:imar,jmar)*zmea0(1:imar,jmar),DIM=1)
289  zmeanor =SUM(weight(1:imar,   1)*zmea (1:imar,   1),DIM=1)
290  zmeasud =SUM(weight(1:imar,jmar)*zmea (1:imar,jmar),DIM=1)
291  zstdnor =SUM(weight(1:imar,   1)*zstd (1:imar,   1),DIM=1)
292  zstdsud =SUM(weight(1:imar,jmar)*zstd (1:imar,jmar),DIM=1)
293  zsignor =SUM(weight(1:imar,   1)*zsig (1:imar,   1),DIM=1)
294  zsigsud =SUM(weight(1:imar,jmar)*zsig (1:imar,jmar),DIM=1)
295  zpicnor =SUM(weight(1:imar,   1)*zpic (1:imar,   1),DIM=1)
296  zpicsud =SUM(weight(1:imar,jmar)*zpic (1:imar,jmar),DIM=1)
297  zvalnor =SUM(weight(1:imar,   1)*zval (1:imar,   1),DIM=1)
298  zvalsud =SUM(weight(1:imar,jmar)*zval (1:imar,jmar),DIM=1)
299
300  zmea(:,1)=zmeanor /zweinor; zmea(:,jmar)=zmeasud /zweisud
301!  zphi(:,1)=zmeanor0/zweinor; zphi(:,jmar)=zmeasud0/zweisud   TO COMMIT
302  zphi(:,1)=zmeanor /zweinor; zphi(:,jmar)=zmeasud /zweisud
303  zpic(:,1)=zpicnor /zweinor; zpic(:,jmar)=zpicsud /zweisud
304  zval(:,1)=zvalnor /zweinor; zval(:,jmar)=zvalsud /zweisud
305  zstd(:,1)=zstdnor /zweinor; zstd(:,jmar)=zstdsud /zweisud
306  zsig(:,1)=zsignor /zweinor; zsig(:,jmar)=zsigsud /zweisud
307  zgam(:,1)=1.;               zgam(:,jmar)=1.
308  zthe(:,1)=0.;               zthe(:,jmar)=0.
309
310END SUBROUTINE grid_noro
311!
312!-------------------------------------------------------------------------------
313
314
315!-------------------------------------------------------------------------------
316!
317SUBROUTINE MVA9(x)
318!
319!-------------------------------------------------------------------------------
320  IMPLICIT NONE
321! MAKE A MOVING AVERAGE OVER 9 GRIDPOINTS OF THE X FIELDS
322!-------------------------------------------------------------------------------
323! Arguments:
324  REAL, INTENT(INOUT) :: x(:,:)
325!-------------------------------------------------------------------------------
326! Local variables:
327  REAL    :: xf(SIZE(x,DIM=1),SIZE(x,DIM=2)), WEIGHTpb(-1:1,-1:1)
328  INTEGER :: i, j, imar, jmar
329!-------------------------------------------------------------------------------
330  WEIGHTpb=RESHAPE([((1./REAL((1+i**2)*(1+j**2)),i=-1,1),j=-1,1)],SHAPE=[3,3])
331  WEIGHTpb=WEIGHTpb/SUM(WEIGHTpb)
332  imar=SIZE(X,DIM=1); jmar=SIZE(X,DIM=2)
333  DO j=2,jmar-1
334    DO i=2,imar-1
335      xf(i,j)=SUM(x(i-1:i+1,j-1:j+1)*WEIGHTpb(:,:))
336    END DO
337  END DO
338  DO j=2,jmar-1
339    xf(1,j)=SUM(x(imar-1,j-1:j+1)*WEIGHTpb(-1,:))
340    xf(1,j)=xf(1,j)+SUM(x(1:2,j-1:j+1)*WEIGHTpb(0:1,-1:1))
341    xf(imar,j)=xf(1,j)
342  END DO
343  xf(:,   1)=xf(:,     2)
344  xf(:,jmar)=xf(:,jmar-1)
345  x(:,:)=xf(:,:)
346
347END SUBROUTINE MVA9
348!
349!-------------------------------------------------------------------------------
350
351
352END MODULE grid_noro_m
353
Note: See TracBrowser for help on using the repository browser.