SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
hor_extrapol_surf_cheap.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 hor_extrapol_surf_cheap(KLUOUT,HCOORTYPE,PLAT_IN,PLON_IN,PFIELD_IN, &
7  plat,plon,pfield,ointerp)
8 ! ###################################################################
9 !
10 !!**** *HOR_EXTRAPOL_SURF_CHEAP* extrapolate a surface field
11 !!
12 !! PURPOSE
13 !! -------
14 !!
15 !! METHOD
16 !! ------
17 !! For each point to interpolate, the nearest valid point value is set.
18 !!
19 !! EXTERNAL
20 !! --------
21 !!
22 !! IMPLICIT ARGUMENTS
23 !! ------------------
24 !!
25 !! REFERENCE
26 !! ---------
27 !!
28 !! AUTHOR
29 !! ------
30 !!
31 !! V. Masson Meteo-France
32 !!
33 !! MODIFICATION
34 !! ------------
35 !!
36 !! Original 01/12/98
37 !! V. Masson 01/2004 extrapolation in latitude and longitude
38 !! M. Jidane 11/2013 add OpenMP directives
39 !! L. Raynaudl 06/2014 cheap version : nearest point looked for in a
40 !! neighbourhood
41 !
42 !----------------------------------------------------------------------------
43 !
44 !* 0. DECLARATION
45 ! -----------
46 !
47 USE modd_surf_par, ONLY : xundef
48 USE modd_csts, ONLY : xpi, xradius
49 USE modn_prep_surf_atm, ONLY : nhalo_prep
50 !
51 USE yomhook ,ONLY : lhook, dr_hook
52 USE parkind1 ,ONLY : jprb
53 !
54 USE modi_abor1_sfx
55 !
56 IMPLICIT NONE
57 !
58 !* 0.1 Declaration of arguments
59 ! ------------------------
60 !
61 INTEGER, INTENT(IN) :: kluout ! output listing logical unit
62  CHARACTER(LEN=4), INTENT(IN) :: hcoortype
63 REAL, DIMENSION(:), INTENT(IN) :: plat_in ! input lat. of each grid mesh.
64 REAL, DIMENSION(:), INTENT(IN) :: plon_in ! input lon. of each grid mesh.
65 REAL, DIMENSION(:,:), INTENT(IN) :: pfield_in! input field on grid mesh
66 REAL, DIMENSION(:), INTENT(IN) :: plat ! latitude of each grid mesh.
67 REAL, DIMENSION(:), INTENT(IN) :: plon ! longitude of each grid mesh.
68 REAL, DIMENSION(:), INTENT(INOUT) :: pfield ! field on grid mesh
69 LOGICAL,DIMENSION(:), INTENT(IN) :: ointerp ! .true. where physical value is needed
70 !
71 !* 0.2 Declaration of local variables
72 ! ------------------------------
73 !
74 INTEGER :: ino ! output array size
75 !
76 REAL :: zlat ! latitude of point to define
77 REAL :: zlon ! longitude of point to define
78 REAL :: zdist ! current distance to valid point (in lat/lon grid)
79 REAL :: zfield! current found field value
80 REAL :: zndist! smallest distance to valid point
81 REAL :: zcosla! cosine of latitude
82 !
83 INTEGER :: ji,jii,jj,ici,icj,ici_min,ici_max,icj_min,icj_max,icompt ! loop index on points
84 REAL :: zlonsc! longitude of valid point
85 LOGICAL :: glalo ! flag true is second coordinate is a longitude or pseudo-lon.
86  ! false if metric coordinates
87 !
88 REAL(KIND=JPRB) :: zrad ! conversion degrees to radians
89 !
90 REAL(KIND=JPRB) :: zhook_handle, zhook_handle_omp
91 !-------------------------------------------------------------------------------
92 IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF_CHEAP',0,zhook_handle)
93 !
94 ino = SIZE(pfield,1)
95 !
96 WHERE (.NOT. ointerp(:)) pfield(:) = xundef
97 !
98 !-------------------------------------------------------------------------------
99 !
100 glalo = hcoortype=='LALO'
101 !
102 !-------------------------------------------------------------------------------
103 !
104 !* 3. No data point
105 ! -------------
106 !
107 IF (count(pfield_in(:,:)/=xundef)==0 .AND. lhook) CALL dr_hook('HOR_EXTRAPOL_SURF_CHEAP',1,zhook_handle)
108 IF (count(pfield_in(:,:)/=xundef)==0) RETURN
109 !
110 !-------------------------------------------------------------------------------
111 !
112 !* 4. Loop on points to define
113 ! ------------------------
114 !
115 zrad=xpi/180.0_jprb
116 !
117 !$OMP PARALLEL DO SCHEDULE(DYNAMIC,1) PRIVATE(JI,JII,JJ,ZLAT,ZLON,ZFIELD,ZCOSLA,ZLONSC,ZDIST,ZNDIST,ZHOOK_HANDLE_OMP)
118 DO ji=1,ino
119 
120  IF (pfield(ji)/=xundef) cycle
121  IF (.NOT. ointerp(ji)) cycle
122 !
123 !* 4.1 initialisation
124 ! --------------
125 !
126  IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF_CHEAP OMP',0,zhook_handle_omp)
127  zndist=1.e20
128  zlat=plat(ji)
129  zlon=plon(ji)
130  zfield=pfield(ji)
131  zcosla=cos(zlat*zrad)
132 
133  ! Locate surrounding input points around the interpolated output point
134  ! Size of the neighbourhood is given by NHALO_PREP
135  ici = 1
136  DO jj=SIZE(plon_in),1,-1
137  IF (plon_in(jj)<=zlon) THEN
138  ici = jj
139  EXIT
140  ENDIF
141  ENDDO
142  icj = 1
143  DO jj=SIZE(plat_in),1,-1
144  IF (plat_in(jj)<=zlat) THEN
145  icj = jj
146  EXIT
147  ENDIF
148  ENDDO
149 
150  ici_min=max(ici-nhalo_prep,1)
151  ici_max=min(ici+nhalo_prep,SIZE(plon_in))
152  icj_min=max(icj-nhalo_prep,1)
153  icj_max=min(icj+nhalo_prep,SIZE(plat_in))
154 !
155 !* 4.2 extrapolation with nearest valid point
156 ! --------------------------------------
157 
158  ! The nearest point is looked for in a neighbourhood
159  ! This helps reducing the cost
160  icompt=0
161  DO jj=icj_min,icj_max
162  DO jii=ici_min,ici_max
163  IF (pfield_in(jii,jj)/=xundef) THEN
164  icompt=icompt+1
165  zlonsc = plon_in(jii)
166  IF (glalo) THEN
167  IF (zlonsc-zlon> 180.) zlonsc = zlonsc - 360.
168  IF (zlonsc-zlon<-180.) zlonsc = zlonsc + 360.
169  zdist= (plat_in(jj)-zlat) ** 2 + ((zlonsc-zlon)*zcosla) ** 2
170  ELSE
171  zdist= (plat_in(jj)-zlat) ** 2 + (zlonsc-zlon) ** 2
172  END IF
173  IF (zdist<=zndist) THEN
174  zfield=pfield_in(jii,jj)
175  zndist=zdist
176  END IF
177  END IF
178  ENDDO
179  ENDDO
180  pfield(ji) = zfield
181  IF (icompt==0) THEN
182  WRITE(*,*) 'NO EXTRAPOLATION : INCREASE YOUR HALO_PREP IN NAM_PREP_SURF_ATM'
183  CALL abor1_sfx("HOR_EXTRAPOL_SURF_CHEAP: INCREASE YOUR HALO_PREP IN NAM_PREP_SURF_ATM")
184  ENDIF
185 
186  IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF_CHEAP OMP',1,zhook_handle_omp)
187 END DO
188 !$OMP END PARALLEL DO
189 !-------------------------------------------------------------------------------
190 IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF_CHEAP',1,zhook_handle)
191 !
192 END SUBROUTINE hor_extrapol_surf_cheap
subroutine hor_extrapol_surf_cheap(KLUOUT, HCOORTYPE, PLAT_IN, PLON_IN, PFIELD_IN, PLAT, PLON, PFIELD, OINTERP)
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:6