SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
interpol_npts.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 interpol_npts (UG, U, &
7  hprogram,kluout,knpts,kcode,px,py,pfield,knear_nbr)
8 ! #########################################################
9 !
10 !!**** *INTERPOL_NPTS* interpolates with ###ine f77 programs a 2D field
11 !! from all grid points valid values
12 !!
13 !! PURPOSE
14 !! -------
15 !!
16 !! The points are all on only one grid (defined with the coordinates
17 !! of all the points). The code to apply for each point is:
18 !!
19 !! KCODE>0 : data point (with field valid for interpolation)
20 !! KCODE=-1: point to ignore
21 !! KCODE=0 : point to interpolate
22 !!
23 !!
24 !!
25 !! METHOD
26 !! ------
27 !!
28 !! EXTERNAL
29 !! --------
30 !!
31 !! IMPLICIT ARGUMENTS
32 !! ------------------
33 !!
34 !!
35 !!
36 !! REFERENCE
37 !! ---------
38 !!
39 !! AUTHOR
40 !! ------
41 !!
42 !! V. Masson Meteo-France
43 !!
44 !! MODIFICATION
45 !! ------------
46 !!
47 !! Original 03/2004
48 !! Modification
49 !! B. Decharme 2014 scan all point case if gaussien grid or NHALO = 0
50 !----------------------------------------------------------------------------
51 !
52 !* 0. DECLARATION
53 ! -----------
54 !
55 !
57 USE modd_surf_atm_n, ONLY : surf_atm_t
58 !
59 USE modd_surf_par, ONLY : xundef
60 !
61 USE modi_get_interp_halo
62 USE modi_get_near_meshes
63 USE modi_sum_on_all_procs
64 !
65 USE yomhook ,ONLY : lhook, dr_hook
66 USE parkind1 ,ONLY : jprb
67 !
68 IMPLICIT NONE
69 !
70 !* 0.1 Declaration of arguments
71 ! ------------------------
72 !
73 !
74 TYPE(surf_atm_grid_t), INTENT(INOUT) :: ug
75 TYPE(surf_atm_t), INTENT(INOUT) :: u
76 !
77  CHARACTER(LEN=6), INTENT(IN) :: hprogram ! host program
78 INTEGER, INTENT(IN) :: kluout ! output listing
79 INTEGER, INTENT(IN) :: knpts ! number of points to interpolate with
80 INTEGER,DIMENSION(:), INTENT(INOUT) :: kcode ! code for each point
81  ! >0 point used for interpolation
82  ! 0 point to interpolate
83  ! -1 point not used
84  ! -2 point not used
85 ! ! -3 if spline is no computed
86 ! ! for this point
87 REAL, DIMENSION(:), INTENT(IN) :: px ! x of each grid mesh.
88 REAL, DIMENSION(:), INTENT(IN) :: py ! y of each grid mesh.
89 REAL, DIMENSION(:,:),INTENT(INOUT) :: pfield ! pgd field on grid mesh.
90 INTEGER, INTENT(IN) :: knear_nbr
91 !
92 !* 0.2 Declaration of local variables
93 ! ------------------------------
94 !
95 INTEGER :: il ! number of points
96 INTEGER :: jd ! data point index
97 INTEGER :: js ! loop counter on data points
98 INTEGER :: jl ! loop counter on points to initialize
99 INTEGER :: jp, jpp ! loops counter on KNPTS
100 REAL :: zdist ! square distance between two interpolating and interpolated points
101 REAL, DIMENSION(0:KNPTS) :: zndist ! 3 nearest square distances
102 REAL, DIMENSION(0:KNPTS,SIZE(PFIELD,2)) :: znval ! 3 corresponding field values
103 REAL, DIMENSION(SIZE(PFIELD,2)) :: zsum
104 !
105 INTEGER :: ihalo
106 INTEGER :: jlist ! loop counter on points to interpolate
107 INTEGER :: icount ! counter
108 INTEGER :: inpts
109 INTEGER :: iscan ! number of points to scan
110 INTEGER :: iscan_all ! number of data points
111 INTEGER, DIMENSION(SIZE(PFIELD,1)) :: iindex ! list of index to scan
112 INTEGER, DIMENSION(SIZE(PFIELD,1)) :: iindex_all ! list of all data points
113 INTEGER, DIMENSION(SIZE(KCODE)) :: isize
114 INTEGER :: isize0
115 !
116 REAL(KIND=JPRB) :: zhook_handle
117 !-------------------------------------------------------------------------------
118 !
119 IF (lhook) CALL dr_hook('INTERPOL_NPTS',0,zhook_handle)
120 !
121 il = SIZE(pfield,1)
122 !
123 iindex(:) = 0
124 !
125  CALL get_interp_halo(hprogram,ug%CGRID,ihalo)
126 !
127 IF(ug%CGRID=='GAUSS'.OR.ihalo==0)THEN
128 !
129  isize(:) = 1.
130  isize0 = sum_on_all_procs(hprogram,ug%CGRID,isize(:)==1)
131 !
132  iindex_all(:) = 0
133 !
134  iscan_all = count(kcode(:)>0)
135 !
136  js = 0
137  DO jd=1,il
138  IF (kcode(jd)>0) THEN
139  js = js+1
140  iindex_all(js) = jd
141  END IF
142  END DO
143 !
144 ELSEIF (.NOT.ASSOCIATED(ug%NNEAR)) THEN
145  ALLOCATE(ug%NNEAR(il,knear_nbr))
146  ug%NNEAR(:,:) = 0
147  CALL get_near_meshes(ug%CGRID,ug%NGRID_PAR,u%NSIZE_FULL,ug%XGRID_PAR,knear_nbr,ug%NNEAR)
148 ENDIF
149 !
150 DO jl=1,il
151 
152  IF (kcode(jl)/=0) cycle
153 
154  zndist(1:knpts) = 1.e20
155  zndist(0) = 0.
156  znval(0:knpts,:) = 0.
157  !
158  IF(ug%CGRID=='GAUSS'.OR.ihalo==0)THEN
159  !
160  IF (u%NDIM_FULL/=isize0) THEN
161  ! point can not be interpolated further than halo in multiprocessor run
162  kcode(jl) = -4
163  cycle
164  END IF
165  inpts = knpts
166  iscan = iscan_all
167  iindex(:) = iindex_all(:)
168  !
169  ELSE
170  !
171  icount = 0
172  DO jd=1,knear_nbr
173  IF (ug%NNEAR(jl,jd)>0) THEN
174  IF (kcode(ug%NNEAR(jl,jd))>0) THEN
175  icount = icount+1
176  iindex(icount) = ug%NNEAR(jl,jd)
177  END IF
178  END IF
179  END DO
180  !
181  !IF (ICOUNT>=1) THEN
182  IF (icount>=knpts) THEN
183  iscan = icount
184  !INPTS = MIN(ICOUNT,KNPTS)
185  inpts = knpts
186  ELSEIF (knear_nbr>=u%NDIM_FULL .AND. icount>=1) THEN
187  iscan = icount
188  inpts = icount
189  ELSE
190  kcode(jl) = -4
191  cycle
192  END IF
193  !
194  END IF
195  !
196  DO js=1,iscan
197  !
198  jd = iindex(js)
199  !
200  zdist= ( ( px(jd)-px(jl) ) ** 2 ) + ( ( py(jd)-py(jl) ) ** 2 )
201  !
202  IF ( zdist>zndist(inpts) ) cycle
203  !
204  DO jp = inpts,1,-1
205  !
206  IF ( zdist>zndist(jp-1) ) THEN
207  !
208  IF ( jp<inpts ) THEN
209  DO jpp = inpts,jp+1,-1
210  zndist(jpp) = zndist(jpp-1)
211  znval(jpp,:) = znval(jpp-1,:)
212  ENDDO
213  ENDIF
214  !
215  zndist(jp) = zdist
216  znval(jp,:) = pfield(jd,:)
217  !
218  EXIT
219  !
220  ENDIF
221  !
222  ENDDO
223  !
224  ENDDO
225  !
226  zndist(:) = sqrt(zndist(:))
227  !
228  pfield(jl,:) = 0.
229  zsum(:) = 0.
230  DO jp = 1, inpts
231  pfield(jl,:) = pfield(jl,:) + znval(jp,:)/zndist(jp)
232  zsum(:) = zsum(:) + 1./zndist(jp)
233  ENDDO
234  pfield(jl,:) = pfield(jl,:) / zsum(:)
235  !
236 END DO
237 !
238 IF (lhook) CALL dr_hook('INTERPOL_NPTS',1,zhook_handle)
239 !-------------------------------------------------------------------------------
240 !
241 END SUBROUTINE interpol_npts
integer function sum_on_all_procs(HPROGRAM, HGRID, OIN, HNAME)
subroutine interpol_npts(UG, U, HPROGRAM, KLUOUT, KNPTS, KCODE, PX, PY, PFIELD, KNEAR_NBR)
subroutine get_near_meshes(HGRID, KGRID_PAR, KL, PGRID_PAR, KNEAR_NBR, KNEAR)
subroutine get_interp_halo(HPROGRAM, HGRID, KHALO)