SURFEX v8.1
General documentation of Surfex
explicit_slope.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 explicit_slope (UG,KDIM_FULL, &
7  PZS,PSSO_SLOPE)
8 ! #########################################################################
9 !! AUTHOR
10 !! ------
11 !! M. Lafaysse * Meteo-France *
12 !!
13 !! MODIFICATIONS
14 !! -------------
15 !! Original 19/07/13
16 !
17 !* 0. DECLARATIONS
18 ! ------------
19 !
21 !
24 !
25 USE modi_get_grid_dim
26 USE modi_get_mesh_dim
27 
28 IMPLICIT NONE
29 !
30 !* 0.1 DECLARATIONS OF DUMMY ARGUMENTS :
31 !
32 TYPE(surf_atm_grid_t), INTENT(INOUT) :: UG
33 !
34 INTEGER, INTENT(IN) :: KDIM_FULL
35 REAL,DIMENSION(:),INTENT(IN)::PZS ! resolved model orography
36 REAL,DIMENSION(:),INTENT(OUT)::PSSO_SLOPE ! resolved slope tangent
37 
38 
39 
40 !
41 !
42 !* 0.2 DECLARATIONS OF LOCAL VARIABLES
43 !
44 
45 INTEGER :: IX ! number of points in X direction
46 INTEGER :: IY ! number of points in Y direction
47 
48 INTEGER :: INNX ! number of points in X direction for large domain
49 INTEGER :: INNY ! number of points in Y direction for large domain
50 
51 LOGICAL::GRECT=.true.
52 
53 INTEGER :: JX ! loop counter
54 INTEGER :: JY ! loop counter
55 
56 REAL, DIMENSION(:,:), ALLOCATABLE :: ZMAP ! map factor
57 REAL, DIMENSION(:,:), ALLOCATABLE :: ZZS ! orography in a 2D array
58 REAL, DIMENSION(:,:), ALLOCATABLE :: ZSSO_SLOPE ! explicit slope in a 2D array
59 REAL, DIMENSION(:,:), ALLOCATABLE :: ZZS_XY ! orography at southwest corner of the mesh
60 REAL, DIMENSION(:,:),ALLOCATABLE :: ZZSL ! orography in a 2D array
61 REAL, DIMENSION(:),ALLOCATABLE :: ZXHAT ! X coordinate
62 REAL, DIMENSION(:),ALLOCATABLE :: ZYHAT ! Y coordinate
63 
64 
65 REAL,DIMENSION(:), ALLOCATABLE :: ZDX ! grid mesh size in x direction
66 REAL,DIMENSION(:), ALLOCATABLE :: ZDY ! grid mesh size in y direction
67 
68 REAL, DIMENSION(:), ALLOCATABLE :: ZZS0
69 REAL, DIMENSION(:), ALLOCATABLE :: ZSSO_SLOPE0
70 !
71 ! parameters
72 REAL, PARAMETER :: XPI=4.*atan(1.) ! Pi
73 INTEGER, PARAMETER :: JPHEXT = 1 ! number of points around the physical domain
74 !
75 INTEGER :: IIB, IIE, IJB, IJE
76 INTEGER :: JI, JJ, JB
77 INTEGER :: JT
78 !
79 REAL :: ZDZSDX ! slope in X and Y direction
80 REAL :: ZDZSDY ! of a triangle surface
81 REAL :: ZSURF ! surface of 4 triangles
82 !
83 
84 
85 
86 !-------------------------------------------------------------------------------
87 !
88 !* 1.1 Gets the geometry of the grid
89 ! -----------------------------
90 !
91  CALL get_grid_dim(ug%G%CGRID,SIZE(ug%XGRID_FULL_PAR),ug%XGRID_FULL_PAR,grect,ix,iy)
92 !
93 innx=ix+2
94 inny=iy+2
95 
96 !
97 
98 !* 1.2 Grid dimension (meters)
99 ! -----------------------
100 !
101 ALLOCATE(zdx(ix*iy))
102 ALLOCATE(zdy(ix*iy))
103 
104  CALL get_mesh_dim(ug%G%CGRID,SIZE(ug%XGRID_FULL_PAR),ix*iy,ug%XGRID_FULL_PAR,zdx,zdy,ug%G%XMESH_SIZE)
105 
106 !
107 !* 2. If grid is not rectangular, nothing is done
108 ! -------------------------------------------
109 !
110  ALLOCATE(zzs0(kdim_full))
111  CALL gather_and_write_mpi(pzs,zzs0)
112  !
113 !IF (.NOT. GRECT) RETURN
114 !
115 IF (SIZE(zzs0) /= ix * iy) RETURN
116 !
117 !-------------------------------------------------------------------------------
118 !
119 !* 3.1 Grid rectangular: orography is put in a 2D array
120 ! ------------------------------------------------
121 !
122 ALLOCATE(zzs(ix,iy))
123 ALLOCATE(zzsl(innx,inny))
124 
125 DO jy=1,iy
126  DO jx=1,ix
127  zzs(jx,jy) = zzs0( jx + (jy-1)*ix )
128  END DO
129 END DO
130 
131 DEALLOCATE(zzs0)
132 !
133 zzsl(2:innx-1,2:inny-1) = zzs(:,:)
134 zzsl(1,:) = zzsl(2,:)
135 zzsl(innx,:) = zzsl(innx-1,:)
136 zzsl(:,1) = zzsl(:,2)
137 zzsl(:,inny) = zzsl(:,inny-1)
138 
139 !------------------------------------------------------------------------------------------
140 !
141 !* 3.2. Orography of SW corner of grid meshes
142 ! -------------------------------------
143 !
144 
145 ALLOCATE(zzs_xy(innx,inny))
146 
147 zzs_xy(2:innx,2:inny) = 0.25*( zzsl(2:innx,2:inny) + zzsl(1:innx-1,2:inny) &
148  + zzsl(2:innx,1:inny-1) + zzsl(1:innx-1,1:inny-1) )
149 !
150 zzs_xy(1,:) = zzs_xy(2,:)
151 zzs_xy(:,1) = zzs_xy(:,2)
152 
153 !
154 !* 3.3 Initialize Grid meshes
155 ! -----------
156 !
157 ALLOCATE(zxhat(innx))
158 ALLOCATE(zyhat(inny))
159 
160 DO jx=1,innx
161  zxhat(jx) = zdx(1)*jx
162 END DO
163 DO jy=1,inny
164  zyhat(jy) = zdy(1)*jy
165 END DO
166 
167 DEALLOCATE(zdx,zdy)
168 
169 !-------------------------------------------------------------------------------
170 !
171 iib= 1+jphext
172 iie=innx-jphext
173 ijb=1+jphext
174 ije=inny-jphext
175 !
176 ALLOCATE(zmap(innx,inny))
177 zmap(:,:)=1.0
178 ALLOCATE(zsso_slope(ix,iy))
179 
180 !-------------------------------------------------------------------------------
181 !
182 !* 1. LOOP ON GRID MESHES
183 ! -------------------
184 !
185 !* discretization of the grid mesh in four triangles
186 !
187 !
188 DO jj=ijb,ije
189  DO ji=iib,iie
190  zsurf=0.
191  DO jt=1,4
192 !
193 !* slopes in x and y
194 !
195  SELECT CASE (jt)
196  CASE (1)
197  zdzsdx=( 2.* zzsl(ji,jj) &
198  - (zzs_xy(ji,jj)+zzs_xy(ji,jj+1)) ) &
199  / (zxhat(ji+1)-zxhat(ji)) * zmap(ji,jj)
200  zdzsdy=( zzs_xy(ji,jj+1) - zzs_xy(ji,jj) ) &
201  / (zyhat(jj+1)-zyhat(jj)) * zmap(ji,jj)
202  CASE (2)
203  zdzsdx=( zzs_xy(ji+1,jj+1) -zzs_xy(ji,jj+1)) &
204  / (zxhat(ji+1)-zxhat(ji)) * zmap(ji,jj)
205  zdzsdy=( (zzs_xy(ji+1,jj+1)+zzs_xy(ji,jj+1)) &
206  - 2.* zzsl(ji,jj) ) &
207  / (zyhat(jj+1)-zyhat(jj)) * zmap(ji,jj)
208  CASE (3)
209  zdzsdx=( (zzs_xy(ji+1,jj)+zzs_xy(ji+1,jj+1)) &
210  - 2.* zzsl(ji,jj) ) &
211  / (zxhat(ji+1)-zxhat(ji)) * zmap(ji,jj)
212  zdzsdy=( zzs_xy(ji+1,jj+1) - zzs_xy(ji+1,jj) ) &
213  / (zyhat(jj+1)-zyhat(jj)) * zmap(ji,jj)
214  CASE (4)
215  zdzsdx=( zzs_xy(ji+1,jj) - zzs_xy(ji,jj) ) &
216  / (zxhat(ji+1)-zxhat(ji)) * zmap(ji,jj)
217  zdzsdy=( 2.* zzsl(ji,jj) &
218  - (zzs_xy(ji+1,jj)+zzs_xy(ji,jj)) ) &
219  / (zyhat(jj+1)-zyhat(jj)) * zmap(ji,jj)
220  END SELECT
221 !
222 !
223  ! If slope is higher than 60 degrees : numerical problems
224  zdzsdx=min(2.0,max(-2.0,zdzsdx))
225  zdzsdy=min(2.0,max(-2.0,zdzsdy))
226 
227  ! total surface of 4 triangles
228  zsurf=zsurf+0.25*sqrt(1. + zdzsdx**2 + zdzsdy**2)
229 
230  END DO
231 
232  !equivalent tangent slope of a homogeneous surface with the same area
233  zsso_slope(ji-jphext,jj-jphext)=sqrt(zsurf**2-1)
234 
235  END DO
236 END DO
237 DEALLOCATE(zzsl)
238 DEALLOCATE(zzs)
239 DEALLOCATE(zzs_xy)
240 DEALLOCATE(zmap)
241 !
242 ALLOCATE(zsso_slope0(kdim_full))
243 !
244 DO jy=1,iy
245  DO jx=1,ix
246  zsso_slope0( jx + (jy-1)*ix )=zsso_slope(jx,jy)
247  END DO
248 END DO
249 !
250  CALL read_and_send_mpi(zsso_slope0,psso_slope)
251 !
252 DEALLOCATE(zsso_slope0)
253 !
254 END SUBROUTINE explicit_slope
subroutine get_grid_dim(HGRID, KGRID_PAR, PGRID_PAR, ORECT, KDIM1, KDIM
Definition: get_grid_dim.F90:7
subroutine explicit_slope(UG, KDIM_FULL, PZS, PSSO_SLOPE)
subroutine get_mesh_dim(HGRID, KGRID_PAR, KL, PGRID_PAR, PDX, PDY, PMESH
Definition: get_mesh_dim.F90:7