SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
oi_hor_extrapol_surf.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 ! ###################################################################
7  SUBROUTINE oi_hor_extrapol_surf(NDIM,PLAT_IN,PLON_IN,PFIELD_IN, &
8  plat,plon,pfield,ointerp,pzs,ndim2)
9 ! ###################################################################
10 !
11 !!**** *OI_HOR_EXTRAPOL_SURF* extrapolate a surface field
12 !!
13 !! PURPOSE
14 !! -------
15 !!
16 !!
17 !! METHOD
18 !! ------
19 !!
20 !! For each point to interpolate, the nearest valid point value is set.
21 !!
22 !! EXTERNAL
23 !! --------
24 !!
25 !! IMPLICIT ARGUMENTS
26 !! ------------------
27 !!
28 !! REFERENCE
29 !! ---------
30 !!
31 !! AUTHOR
32 !! ------
33 !!
34 !! V. Masson Meteo-France
35 !!
36 !! MODIFICATION
37 !! ------------
38 !!
39 !! Original 01/12/98
40 !! V. Masson 01/2004 extrapolation in latitude and longitude
41 !! J.-F. Mahfouf 03/2010 adaptation for OI soil analysis
42 !----------------------------------------------------------------------------
43 !
44 !* 0. DECLARATION
45 ! -----------
46 !
47 USE modd_surf_par, ONLY : xundef
48 USE modd_csts, ONLY : xpi
49 !
50 USE yomhook ,ONLY : lhook, dr_hook
51 USE parkind1 ,ONLY : jprb
52 USE modi_abor1_sfx
53 !
54 IMPLICIT NONE
55 !
56 !* 0.1 Declaration of arguments
57 ! ------------------------
58 !
59 INTEGER, INTENT(IN) :: ndim ! dimension of arrays
60 REAL, DIMENSION(NDIM), INTENT(IN) :: plat_in ! input lat. of each grid mesh.
61 REAL, DIMENSION(NDIM), INTENT(IN) :: plon_in ! input lon. of each grid mesh.
62 REAL, DIMENSION(NDIM), INTENT(IN) :: pfield_in! input field on grid mesh
63 REAL, DIMENSION(NDIM), INTENT(IN) :: plat ! latitude of each grid mesh.
64 REAL, DIMENSION(NDIM), INTENT(IN) :: plon ! longitude of each grid mesh.
65 REAL, DIMENSION(NDIM), INTENT(INOUT) :: pfield ! field on grid mesh
66 LOGICAL,DIMENSION(NDIM), INTENT(IN) :: ointerp ! .true. where physical value is needed
67 REAL, DIMENSION(NDIM), OPTIONAL, INTENT(IN) :: pzs ! surface height
68 INTEGER, OPTIONAL, INTENT(IN) :: ndim2 ! Optional subdomain to search in
69 !
70 !* 0.2 Declaration of local variables
71 ! ------------------------------
72 !
73 REAL :: zlat ! latitude of point to define
74 REAL :: zlon ! longitude of point to define
75 REAL :: zdist ! current distance to valid point (in lat/lon grid)
76 REAL :: zfield ! current found field value
77 REAL :: zndist ! smallest distance to valid point
78 REAL :: zcosla ! cosine of latitude
79 REAL :: zzs_out ! altitude of nearest grid point
80 REAL,PARAMETER :: zlimmax = 1. ! Maximum distance allowed (in degrees)
81 !
82 INTEGER :: ji ! loop index on points
83 INTEGER :: jisc ! loop index on valid points
84 INTEGER :: jisc1,jisc2,jzlimcnt
85 !
86 REAL :: zlonsc, zdlat, zdlon, zconv, zr_earth
87 REAL(KIND=JPRB) :: zhook_handle
88 !
89 LOGICAL :: lndim2
90 !
91 ! Earth radius
92 !
93 IF (lhook) CALL dr_hook('OI_HOR_EXTRAPOL_SURF',0,zhook_handle)
94 zr_earth = 6371598.0
95 !
96 ! Angle conversion factor
97 !
98 zconv = xpi/180.0
99 !-------------------------------------------------------------------------------
100 !
101 !* 3. No data point
102 ! -------------
103 !
104 IF (count(pfield_in(:)/=xundef)==0 .AND. lhook) CALL dr_hook('OI_HOR_EXTRAPOL_SURF',1,zhook_handle)
105 IF (count(pfield_in(:)/=xundef)==0) RETURN
106 !
107 !-------------------------------------------------------------------------------
108 !
109 !* 4. Loop on points to define
110 ! ------------------------
111 !
112 jzlimcnt = 0
113 !
114 DO ji=1,ndim
115  IF (pfield(ji)/=xundef) cycle
116  IF (.NOT. ointerp(ji)) cycle
117 !
118 !* 4.1 initialisation
119 ! --------------
120 !
121  zndist=xundef
122  zlat=plat(ji)
123  zlon=plon(ji)
124  zfield=pfield(ji)
125  zcosla=cos(zlat*zconv)
126  IF (present(pzs)) zzs_out=pzs(ji)
127  IF ( present(ndim2)) THEN
128  jisc1=max((ji-ndim2),1)
129  jisc2=min((ji+ndim2),ndim)
130  lndim2=.true.
131  ELSE
132  jisc1=1
133  jisc2=ndim
134  lndim2=.false.
135  ENDIF
136 !
137 !* 4.2 extrapolation with nearest valid point
138 ! --------------------------------------
139 !
140  DO jisc=jisc1,jisc2
141  IF (pfield_in(jisc)/=xundef) THEN
142  zlonsc = plon_in(jisc)
143  IF (zlonsc-zlon> 180.) zlonsc = zlonsc - 360.0
144  IF (zlonsc-zlon<-180.) zlonsc = zlonsc + 360.0
145  zdlat = (plat_in(jisc)-zlat)*zconv
146  zdlon = (zlonsc-zlon)*zconv
147  zdist = zdlat*zdlat + zdlon*zdlon*zcosla*zcosla
148  IF (zdist<=zndist) THEN
149  zfield=pfield_in(jisc)
150  IF (present(pzs)) zzs_out=pzs(jisc)
151  zndist=zdist
152  END IF
153  END IF
154  END DO
155 
156  ! Check if we got values
157  IF ( zndist == xundef ) THEN
158  CALL abor1_sfx("Extrapolated point is undefined! No nearby point found.")
159  ELSEIF ( zndist > (zlimmax*zconv) ) THEN
160  IF ( lndim2 ) &
161  & CALL abor1_sfx("Distance to extrapolated point is to large. Increase ZLIMMAX or NDIM2")
162  jzlimcnt = jzlimcnt + 1
163  ENDIF
164  IF (present(pzs)) THEN
165  pfield(ji) = zfield + (zzs_out - pzs(ji))*0.0065
166  ELSE
167  pfield(ji) = zfield
168  ENDIF
169 
170 END DO
171 
172 IF ( jzlimcnt > 0 ) THEN
173  print *,'Points with extrapolation distance > ',zlimmax,' degrees are ',jzlimcnt
174 ENDIF
175 
176 IF (lhook) CALL dr_hook('OI_HOR_EXTRAPOL_SURF',1,zhook_handle)
177 !
178 !-------------------------------------------------------------------------------
179 !
180 END SUBROUTINE oi_hor_extrapol_surf
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:6
subroutine oi_hor_extrapol_surf(NDIM, PLAT_IN, PLON_IN, PFIELD_IN, PLAT, PLON, PFIELD, OINTERP, PZS, NDIM2)