SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
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  SUBROUTINE hor_extrapol_surf(KLUOUT,HCOORTYPE,PLAT_IN,PLON_IN,PFIELD_IN, &
7  plat,plon,pfield,ointerp)
8 ! ###################################################################
9 !
10 !!**** *HOR_EXTRAPOL_SURF* 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 !----------------------------------------------------------------------------
40 !
41 !* 0. DECLARATION
42 ! -----------
43 !
44 USE modd_surf_par, ONLY : xundef
45 USE modd_csts, ONLY : xpi
46 !
47 USE yomhook ,ONLY : lhook, dr_hook
48 USE parkind1 ,ONLY : jprb
49 !
50 IMPLICIT NONE
51 !
52 !* 0.1 Declaration of arguments
53 ! ------------------------
54 !
55 INTEGER, INTENT(IN) :: kluout ! output listing logical unit
56  CHARACTER(LEN=4), INTENT(IN) :: hcoortype! type of coordinate
57 REAL, DIMENSION(:), INTENT(IN) :: plat_in ! input lat. of each grid mesh.
58 REAL, DIMENSION(:), INTENT(IN) :: plon_in ! input lon. of each grid mesh.
59 REAL, DIMENSION(:), INTENT(IN) :: pfield_in! input field on grid mesh
60 REAL, DIMENSION(:), INTENT(IN) :: plat ! latitude of each grid mesh.
61 REAL, DIMENSION(:), INTENT(IN) :: plon ! longitude of each grid mesh.
62 REAL, DIMENSION(:), INTENT(INOUT) :: pfield ! field on grid mesh
63 LOGICAL,DIMENSION(:), INTENT(IN) :: ointerp ! .true. where physical value is needed
64 !
65 !* 0.2 Declaration of local variables
66 ! ------------------------------
67 !
68 INTEGER :: ino ! output array size
69 INTEGER :: ino_in ! input array size
70 !
71 REAL :: zlat ! latitude of point to define
72 REAL :: zlon ! longitude of point to define
73 REAL :: zdist ! current distance to valid point (in lat/lon grid)
74 REAL :: zfield! current found field value
75 REAL :: zndist! smallest distance to valid point
76 REAL :: zcosla! cosine of latitude
77 !
78 INTEGER :: ji ! loop index on points
79 INTEGER :: jisc ! loop index on valid points
80 REAL :: zlonsc! longitude of valid point
81 LOGICAL :: glalo ! flag true is second coordinate is a longitude or pseudo-lon.
82  ! false if metric coordinates
83 !
84 REAL(KIND=JPRB) :: zrad ! conversion degrees to radians
85 !
86 REAL(KIND=JPRB) :: zhook_handle, zhook_handle_omp
87 !-------------------------------------------------------------------------------
88 IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF',0,zhook_handle)
89 !
90 ino = SIZE(pfield,1)
91 !
92 WHERE (.NOT. ointerp(:)) pfield(:) = xundef
93 !
94 !-------------------------------------------------------------------------------
95 !
96 ino_in = SIZE(pfield_in)
97 !
98 glalo = hcoortype=='LALO'
99 !
100 !-------------------------------------------------------------------------------
101 !
102 !* 3. No data point
103 ! -------------
104 !
105 IF (count(pfield_in(:)/=xundef)==0 .AND. lhook) CALL dr_hook('HOR_EXTRAPOL_SURF',1,zhook_handle)
106 IF (count(pfield_in(:)/=xundef)==0) RETURN
107 !
108 !-------------------------------------------------------------------------------
109 !
110 !* 4. Loop on points to define
111 ! ------------------------
112 !
113 zrad=xpi/180.0_jprb
114 !
115 !$OMP PARALLEL DO SCHEDULE(DYNAMIC,1) PRIVATE(JI,JISC,ZLAT,ZLON,ZFIELD,ZCOSLA,ZLONSC,ZDIST,ZNDIST,ZHOOK_HANDLE_OMP)
116 DO ji=1,ino
117  IF (pfield(ji)/=xundef) cycle
118  IF (.NOT. ointerp(ji)) cycle
119 !
120 !* 4.1 initialisation
121 ! --------------
122 !
123  IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF OMP',0,zhook_handle_omp)
124  zndist=1.e20
125  zlat=plat(ji)
126  zlon=plon(ji)
127  zfield=pfield(ji)
128  zcosla=cos(zlat*zrad)
129 !
130 !* 4.2 extrapolation with nearest valid point
131 ! --------------------------------------
132 !
133  DO jisc=1,ino_in
134  IF (pfield_in(jisc)/=xundef) THEN
135  zlonsc = plon_in(jisc)
136  IF (glalo) THEN
137  IF (zlonsc-zlon> 180.) zlonsc = zlonsc - 360.
138  IF (zlonsc-zlon<-180.) zlonsc = zlonsc + 360.
139  zdist= (plat_in(jisc)-zlat) ** 2 + ((zlonsc-zlon)*zcosla) ** 2
140  ELSE
141  zdist= (plat_in(jisc)-zlat) ** 2 + (zlonsc-zlon) ** 2
142  END IF
143  IF (zdist<=zndist) THEN
144  zfield=pfield_in(jisc)
145  zndist=zdist
146  END IF
147  END IF
148  END DO
149  pfield(ji) = zfield
150 
151  IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF OMP',1,zhook_handle_omp)
152 END DO
153 !$OMP END PARALLEL DO
154 !-------------------------------------------------------------------------------
155 IF (lhook) CALL dr_hook('HOR_EXTRAPOL_SURF',1,zhook_handle)
156 !
157 END SUBROUTINE hor_extrapol_surf
subroutine hor_extrapol_surf(KLUOUT, HCOORTYPE, PLAT_IN, PLON_IN, PFIELD_IN, PLAT, PLON, PFIELD, OINTERP)