26 num_nbrs, max_dist, src_modulo)
28 type(horiz_interp_type),
intent(inout) :: Interp
32 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: lon_in
33 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: lat_in
34 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: lon_out
35 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: lat_out
36 logical,
intent(in),
optional :: src_modulo
38 integer,
intent(in),
optional :: num_nbrs
45 real(FMS_HI_KIND_),
optional,
intent(in) :: max_dist
50 integer :: map_dst_xsize, map_dst_ysize, map_src_xsize, map_src_ysize
51 integer :: map_src_size, num_neighbors
52 real(FMS_HI_KIND_) :: max_src_dist, tpi, hpi
53 logical :: src_is_modulo
54 real(FMS_HI_KIND_) :: min_theta_dst, max_theta_dst, min_phi_dst, max_phi_dst
55 real(FMS_HI_KIND_) :: min_theta_src, max_theta_src, min_phi_src, max_phi_src
56 integer :: map_src_add(size(lon_out,1),size(lon_out,2),max_neighbors)
57 real(FMS_HI_KIND_) :: map_src_dist(size(lon_out,1),size(lon_out,2),max_neighbors)
58 integer :: num_found(size(lon_out,1),size(lon_out,2))
59 integer :: ilon(max_neighbors), jlat(max_neighbors)
60 real(FMS_HI_KIND_),
dimension(size(lon_out,1),size(lon_out,2)) :: theta_dst, phi_dst
61 real(FMS_HI_KIND_),
dimension(size(lon_in,1)*size(lon_in,2)) :: theta_src, phi_src
62 integer,
parameter :: kindl = fms_hi_kind_
67 root_pe = mpp_root_pe()
69 tpi = 2.0_kindl*real(pi, fms_hi_kind_); hpi = 0.5_kindl*real(pi,fms_hi_kind_)
71 num_neighbors = num_nbrs_default
72 if(
present(num_nbrs)) num_neighbors = num_nbrs
73 if (num_neighbors <= 0)
call mpp_error(fatal,
'horiz_interp_spherical_mod: num_neighbors must be > 0')
75 max_src_dist = real(max_dist_default, fms_hi_kind_)
76 if (
PRESENT(max_dist)) max_src_dist = max_dist
77 interp%HI_KIND_TYPE_%max_src_dist = max_src_dist
79 src_is_modulo = .true.
80 if (
PRESENT(src_modulo)) src_is_modulo = src_modulo
83 map_dst_xsize=
size(lon_out,1);map_dst_ysize=
size(lon_out,2)
84 map_src_xsize=
size(lon_in,1); map_src_ysize=
size(lon_in,2)
85 map_src_size = map_src_xsize*map_src_ysize
87 if (map_dst_xsize /=
size(lat_out,1) .or. map_dst_ysize /=
size(lat_out,2)) &
88 call mpp_error(fatal,
'horiz_interp_spherical_mod: destination grids not conformable')
89 if (map_src_xsize /=
size(lat_in,1) .or. map_src_ysize /=
size(lat_in,2)) &
90 call mpp_error(fatal,
'horiz_interp_spherical_mod: source grids not conformable')
92 theta_src = reshape(lon_in,(/map_src_size/))
93 phi_src = reshape(lat_in,(/map_src_size/))
94 theta_dst(:,:) = lon_out(:,:)
95 phi_dst(:,:) = lat_out(:,:)
97 min_theta_dst=real(tpi, fms_hi_kind_);max_theta_dst=0.0_kindl
98 min_phi_dst=real(pi, fms_hi_kind_);max_phi_dst=real(-pi, fms_hi_kind_)
99 min_theta_src=real(tpi, fms_hi_kind_);max_theta_src=0.0_kindl
100 min_phi_src=real(pi, fms_hi_kind_);max_phi_src=real(-pi, fms_hi_kind_)
102 where(theta_dst<0.0_kindl) theta_dst = theta_dst+real(tpi,fms_hi_kind_)
104 where(theta_dst>real(tpi,fms_hi_kind_)) theta_dst = theta_dst-real(tpi,fms_hi_kind_)
105 where(theta_src<0.0_kindl) theta_src = theta_src+real(tpi,fms_hi_kind_)
106 where(theta_src>real(tpi,fms_hi_kind_)) theta_src = theta_src-real(tpi,fms_hi_kind_)
108 where(phi_dst < -hpi) phi_dst = -hpi
109 where(phi_dst > hpi) phi_dst = hpi
110 where(phi_src < -hpi) phi_src = -hpi
111 where(phi_src > hpi) phi_src = hpi
115 min_theta_dst = min(min_theta_dst,theta_dst(i,j))
116 max_theta_dst = max(max_theta_dst,theta_dst(i,j))
117 min_phi_dst = min(min_phi_dst,phi_dst(i,j))
118 max_phi_dst = max(max_phi_dst,phi_dst(i,j))
123 min_theta_src = min(min_theta_src,theta_src(i))
124 max_theta_src = max(max_theta_src,theta_src(i))
125 min_phi_src = min(min_phi_src,phi_src(i))
126 max_phi_src = max(max_phi_src,phi_src(i))
129 if (min_phi_dst < min_phi_src) print *,
'=> WARNING: latitute of dest grid exceeds src'
130 if (max_phi_dst > max_phi_src) print *,
'=> WARNING: latitute of dest grid exceeds src'
132 if(.not. src_is_modulo)
then
133 if (min_theta_dst < min_theta_src) print *,
'=> WARNING : longitude of dest grid exceeds src'
134 if (max_theta_dst > max_theta_src) print *,
'=> WARNING : longitude of dest grid exceeds src'
138 if(
ALLOCATED(interp%i_lon))
then
139 if(
size(interp%i_lon,1) .NE. map_dst_xsize .OR. &
140 size(interp%i_lon,2) .NE. map_dst_ysize )
call mpp_error(fatal, &
141 .NE..OR.
'horiz_interp_spherical_mod: size(Interp%i_lon(:),1) map_dst_xsize '// &
142 .NE.
'size(Interp%i_lon(:),2) map_dst_ysize')
144 allocate(interp%i_lon(map_dst_xsize,map_dst_ysize,max_neighbors), &
145 interp%j_lat(map_dst_xsize,map_dst_ysize,max_neighbors), &
146 interp%HI_KIND_TYPE_%src_dist(map_dst_xsize,map_dst_ysize,max_neighbors), &
147 interp%num_found(map_dst_xsize,map_dst_ysize) )
151 map_src_dist = real(large, fms_hi_kind_)
156 select case(trim(search_method))
157 case (
"radial_search")
158 call radial_search(theta_src, phi_src, theta_dst, phi_dst, map_src_xsize, map_src_ysize, &
159 map_src_add, map_src_dist, num_found, num_neighbors,max_src_dist,src_is_modulo)
161 call full_search(theta_src, phi_src, theta_dst, phi_dst, map_src_add, map_src_dist, &
162 num_found, num_neighbors,max_src_dist )
164 call mpp_error(fatal,
"HORIZ_INTERP_SPHERICAL_NEW_: nml search_method = "// &
165 trim(search_method)//
" is not a valid namelist option")
170 do n=1,num_found(i,j)
171 if(map_src_add(i,j,n) == 0)
then
172 jlat(n) = 0; ilon(n) = 0
174 jlat(n) = map_src_add(i,j,n)/map_src_xsize + 1
175 ilon(n) = map_src_add(i,j,n) - (jlat(n)-1)*map_src_xsize
176 if(ilon(n) == 0)
then
177 jlat(n) = jlat(n) - 1
178 ilon(n) = map_src_xsize
182 interp%i_lon(i,j,:) = ilon(:)
183 interp%j_lat(i,j,:) = jlat(:)
184 interp%num_found(i,j) = num_found(i,j)
185 interp%HI_KIND_TYPE_%src_dist(i,j,:) = map_src_dist(i,j,:)
189 interp%nlon_src = map_src_xsize; interp%nlat_src = map_src_ysize
190 interp%nlon_dst = map_dst_xsize; interp%nlat_dst = map_dst_ysize
191 interp% HI_KIND_TYPE_ % is_allocated = .true.
192 interp% interp_method = spherical
203 type(horiz_interp_type),
intent(in) :: Interp
206 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: data_in
207 real(FMS_HI_KIND_),
intent(out),
dimension(:,:) :: data_out
208 integer,
intent(in),
optional :: verbose
209 real(FMS_HI_KIND_),
intent(in),
dimension(:,:),
optional :: mask_in
213 real(FMS_HI_KIND_),
intent(out),
dimension(:,:),
optional :: mask_out
215 real(FMS_HI_KIND_),
intent(in),
optional :: missing_value
218 real(FMS_HI_KIND_),
dimension(Interp%nlon_dst, Interp%nlat_dst,size(Interp%HI_KIND_TYPE_%src_dist,3)) :: wt
219 real(FMS_HI_KIND_),
dimension(Interp%nlon_src, Interp%nlat_src) :: mask_src
220 real(FMS_HI_KIND_),
dimension(Interp%nlon_dst, Interp%nlat_dst) :: mask_dst
221 integer :: nlon_in, nlat_in, nlon_out, nlat_out, num_found
222 integer :: m, n, i, j, k, miss_in, miss_out, i1, i2, j1, j2, iverbose
223 real(FMS_HI_KIND_) :: min_in, max_in, avg_in, min_out, max_out, avg_out, sum
224 integer,
parameter :: kindl = fms_hi_kind_
227 iverbose = 0;
if (
present(verbose)) iverbose = verbose
229 nlon_in = interp%nlon_src; nlat_in = interp%nlat_src
230 nlon_out = interp%nlon_dst; nlat_out = interp%nlat_dst
232 if(
size(data_in,1) .ne. nlon_in .or.
size(data_in,2) .ne. nlat_in ) &
233 call mpp_error(fatal,
'horiz_interp_spherical_mod: size of input array incorrect')
235 if(
size(data_out,1) .ne. nlon_out .or.
size(data_out,2) .ne. nlat_out ) &
236 call mpp_error(fatal,
'horiz_interp_spherical_mod: size of output array incorrect')
238 mask_src = 1.0_kindl; mask_dst = 1.0_kindl
239 if(
present(mask_in)) mask_src = mask_in
245 num_found = interp%num_found(m,n)
246 if(num_found == 0 )
then
247 mask_dst(m,n) = 0.0_kindl
249 i1 = interp%i_lon(m,n,1); j1 = interp%j_lat(m,n,1)
250 if (mask_src(i1,j1) .lt. 0.5_kindl )
then
251 mask_dst(m,n) = 0.0_kindl
254 if(num_found .gt. 1 )
then
255 i2 = interp%i_lon(m,n,2); j2 = interp%j_lat(m,n,2)
258 if(abs(interp%HI_KIND_TYPE_%src_dist(m,n,2)-interp%HI_KIND_TYPE_%src_dist(m,n,1)) .lt. &
259 real(epsln,FMS_HI_KIND_)) then
260 if((mask_src(i1,j1) .lt. 0.5_kindl )) mask_dst(m,n) = 0.0_kindl
266 if(mask_src(interp%i_lon(m,n,k),interp%j_lat(m,n,k)) .lt. 0.5_kindl )
then
267 wt(m,n,k) = 0.0_kindl
269 if (interp%HI_KIND_TYPE_%src_dist(m,n,k) <= real(epsln,fms_hi_kind_))
then
270 wt(m,n,k) = real(large, fms_hi_kind_)
271 sum = sum + real(large, fms_hi_kind_)
272 else if(interp%HI_KIND_TYPE_%src_dist(m,n,k) <= interp%HI_KIND_TYPE_%max_src_dist )
then
273 wt(m,n,k) = 1.0_kindl /interp%HI_KIND_TYPE_%src_dist(m,n,k)
276 wt(m,n,k) = 0.0_kindl
280 if (sum > real(epsln,fms_hi_kind_))
then
282 wt(m,n,k) = wt(m,n,k)/sum
285 mask_dst(m,n) = 0.0_kindl
294 if(mask_dst(m,n) .gt. 0.5_kindl )
then
295 do k=1, interp%num_found(m,n)
296 i = interp%i_lon(m,n,k)
297 j = interp%j_lat(m,n,k)
298 data_out(m,n) = data_out(m,n)+data_in(i,j)*wt(m,n,k)
301 if(
present(missing_value))
then
302 data_out(m,n) = missing_value
304 data_out(m,n) = 0.0_kindl
310 if(
present(mask_out)) mask_out = mask_dst
316 if (iverbose > 0)
then
320 call stats (data_in, min_in, max_in, avg_in, miss_in, missing_value, mask=mask_src)
323 call stats (data_out, min_out, max_out, avg_out, miss_out, missing_value, mask=mask_dst)
327 if(pe == root_pe)
then
329 write (*,901) min_in ,max_in, avg_in
330 if (
present(mask_in))
write (*,903) miss_in
331 write (*,902) min_out,max_out,avg_out
332 if (
present(mask_out))
write (*,903) miss_out
334 900
format (/,1x,10(
'-'),
' output from horiz_interp ',10(
'-'))
335 901
format (
' input: min=',f16.9,
' max=',f16.9,
' avg=',f22.15)
336 902
format (
' output: min=',f16.9,
' max=',f16.9,
' avg=',f22.15)
337 903
format (
' number of missing points = ',i6)
348 type (horiz_interp_type),
intent(in) :: Interp
349 real(FMS_HI_KIND_),
intent(out),
dimension(:,:,:) :: wt
350 integer,
intent(in),
optional :: verbose
351 real(FMS_HI_KIND_),
intent(in),
dimension(:,:),
optional :: mask_in
352 real(FMS_HI_KIND_),
intent(inout),
dimension(:,:),
optional :: mask_out
353 real(FMS_HI_KIND_),
intent(in),
optional :: missing_value
356 real(FMS_HI_KIND_),
dimension(Interp%nlon_src, Interp%nlat_src) :: mask_src
357 real(FMS_HI_KIND_),
dimension(Interp%nlon_dst, Interp%nlat_dst) :: mask_dst
358 integer :: nlon_in, nlat_in, nlon_out, nlat_out, num_found
359 integer :: m, n, k, i1, i2, j1, j2, iverbose
360 real(FMS_HI_KIND_) :: sum
361 integer,
parameter :: kindl = fms_hi_kind_
364 iverbose = 0;
if (
present(verbose)) iverbose = verbose
366 nlon_in = interp%nlon_src; nlat_in = interp%nlat_src
367 nlon_out = interp%nlon_dst; nlat_out = interp%nlat_dst
369 mask_src = 1.0_kindl ; mask_dst = 1.0_kindl
370 if(
present(mask_in)) mask_src = mask_in
376 num_found = interp%num_found(m,n)
378 if (num_found > num_nbrs_default)
then
379 if( iverbose .gt. 0) print *,
'pe=',
mpp_pe(),
'num_found=',num_found
380 num_found = num_nbrs_default
383 if(num_found == 0 )
then
384 mask_dst(m,n) = 0.0_kindl
386 i1 = interp%i_lon(m,n,1); j1 = interp%j_lat(m,n,1)
387 if (mask_src(i1,j1) .lt. 0.5_kindl)
then
388 mask_dst(m,n) = 0.0_kindl
391 if(num_found .gt. 1 )
then
392 i2 = interp%i_lon(m,n,2); j2 = interp%j_lat(m,n,2)
395 if(abs(interp%HI_KIND_TYPE_%src_dist(m,n,2)-interp%HI_KIND_TYPE_%src_dist(m,n,1)) .lt. &
396 real(epsln,FMS_HI_KIND_)) then
397 if((mask_src(i1,j1) .lt. 0.5_kindl )) mask_dst(m,n) = 0.0_kindl
403 if(mask_src(interp%i_lon(m,n,k),interp%j_lat(m,n,k)) .lt. 0.5_kindl )
then
404 wt(m,n,k) = 0.0_kindl
406 if (interp%HI_KIND_TYPE_%src_dist(m,n,k) <= real(epsln, fms_hi_kind_))
then
407 wt(m,n,k) = real(large, fms_hi_kind_)
408 sum = sum + real(large, fms_hi_kind_)
409 else if(interp%HI_KIND_TYPE_%src_dist(m,n,k) <= interp%HI_KIND_TYPE_%max_src_dist )
then
410 wt(m,n,k) = 1.0_kindl /interp%HI_KIND_TYPE_%src_dist(m,n,k)
413 wt(m,n,k) = 0.0_kindl
417 if (sum > real(epsln,fms_hi_kind_))
then
419 wt(m,n,k) = wt(m,n,k)/sum
422 mask_dst(m,n) = 0.0_kindl
433 subroutine radial_search_(theta_src,phi_src,theta_dst,phi_dst, map_src_xsize, map_src_ysize, &
434 map_src_add, map_src_dist, num_found, num_neighbors,max_src_dist,src_is_modulo)
435 real(FMS_HI_KIND_),
intent(in),
dimension(:) :: theta_src, phi_src
436 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: theta_dst, phi_dst
437 integer,
intent(in) :: map_src_xsize, map_src_ysize
438 integer,
intent(out),
dimension(:,:,:) :: map_src_add
439 real(FMS_HI_KIND_),
intent(out),
dimension(:,:,:) :: map_src_dist
440 integer,
intent(inout),
dimension(:,:) :: num_found
441 integer,
intent(in) :: num_neighbors
442 real(FMS_HI_KIND_),
intent(in) :: max_src_dist
443 logical,
intent(in) :: src_is_modulo
446 integer,
parameter :: max_nbrs = 50
447 integer :: i, j, jj, i0, j0, n, l,i_left, i_right
448 integer :: map_dst_xsize, map_dst_ysize
449 integer :: i_left1, i_left2, i_right1, i_right2
450 integer :: map_src_size, step, step_size, bound, bound_start, bound_end
451 logical :: continue_search, result, continue_radial_search
452 real(FMS_HI_KIND_) :: d, res
454 map_dst_xsize=
size(theta_dst,1);map_dst_ysize=
size(theta_dst,2)
455 map_src_size = map_src_xsize*map_src_ysize
459 continue_search=.true.
461 step_size = int( sqrt(real(map_src_size, kind=fms_hi_kind_ )))
462 do while (continue_search .and. step_size > 0)
463 do while (step <= map_src_size .and. continue_search)
465 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(step),phi_src(step))
466 if (d <= max_src_dist)
then
467 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
468 step,d, num_found(i,j), num_neighbors )
471 i0 = mod(step,map_src_xsize)
473 if (i0 == 0) i0 = map_src_xsize
474 res = real(step, fms_hi_kind_)/real(map_src_xsize, fms_hi_kind_)
476 continue_radial_search = .true.
477 do while (continue_radial_search)
478 continue_radial_search = .false.
480 if(n > max_nbrs)
exit
483 if (i_left <= 0)
then
484 if (src_is_modulo)
then
485 i_left = map_src_xsize + i_left
494 bound = ( 1 - jj )*map_src_xsize - i_left
495 else if ( jj >= map_src_ysize )
then
496 bound = ( 2*map_src_ysize - jj ) * map_src_xsize - i_left
498 bound = jj * map_src_xsize + i_left
501 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(bound), &
503 if(d<=max_src_dist)
then
504 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
505 bound,d, num_found(i,j), num_neighbors)
506 if (result) continue_radial_search = .true.
512 if (i_right > map_src_xsize)
then
513 if (src_is_modulo)
then
514 i_right = i_right - map_src_xsize
516 i_right = map_src_xsize
523 bound = ( 1 - jj )*map_src_xsize - i_right
524 else if ( jj >= map_src_ysize )
then
525 bound = ( 2*map_src_ysize - jj) * map_src_xsize - i_right
528 bound = jj * map_src_xsize + i_right
531 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(bound), &
533 if(d<=max_src_dist)
then
534 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
535 bound,d, num_found(i,j), num_neighbors)
536 if (result) continue_radial_search = .true.
542 if( i_left > i_right)
then
546 i_right2 = map_src_xsize
554 bound_start = ( 1 - jj)*map_src_xsize - i_right1
555 bound_end = ( 1 - jj)*map_src_xsize - i_left1
557 bound_start = jj * map_src_xsize + i_left1
558 bound_end = jj * map_src_xsize + i_right1
562 do while (bound <= bound_end)
563 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(bound), &
565 if(d<=max_src_dist)
then
566 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
567 bound,d, num_found(i,j), num_neighbors)
568 if (result) continue_radial_search = .true.
574 if(i_left2 > 0 )
then
576 bound_start = ( 1 - jj)*map_src_xsize - i_right2
577 bound_end = ( 1 - jj)*map_src_xsize - i_left2
579 bound_start = jj * map_src_xsize + i_left2
580 bound_end = jj * map_src_xsize + i_right2
584 do while (bound <= bound_end)
585 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(bound), &
587 if(d<=max_src_dist)
then
588 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
589 bound,d, num_found(i,j), num_neighbors)
590 if (result) continue_radial_search = .true.
598 if( jj >= map_src_ysize)
then
599 bound_start = ( 2*map_src_ysize - jj ) * map_src_xsize - i_right1
600 bound_end = ( 2*map_src_ysize - jj ) * map_src_xsize - i_left1
602 bound_start = jj * map_src_xsize + i_left1
603 bound_end = jj * map_src_xsize + i_right1
607 do while (bound <= bound_end)
608 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(bound), &
610 if(d<=max_src_dist)
then
611 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
612 bound,d, num_found(i,j), num_neighbors)
613 if (result) continue_radial_search = .true.
619 if( jj >= map_src_ysize)
then
620 bound_start = ( 2*map_src_ysize - jj ) * map_src_xsize - i_right2
621 bound_end = ( 2*map_src_ysize - jj ) * map_src_xsize - i_left2
623 bound_start = jj * map_src_xsize + i_left2
624 bound_end = jj * map_src_xsize + i_right2
628 do while (bound <= bound_end)
629 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(bound), &
631 if(d<=max_src_dist)
then
632 result = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
633 bound,d, num_found(i,j), num_neighbors)
634 if (result) continue_radial_search = .true.
641 continue_search = .false.
647 step_size = step_size/2
654 end subroutine radial_search_
659 function update_dest_neighbors_(map_src_add, map_src_dist, src_add,d, num_found, min_nbrs)
661 integer,
intent(inout),
dimension(:) :: map_src_add
662 real(FMS_HI_KIND_),
intent(inout),
dimension(:) :: map_src_dist
663 integer,
intent(in) :: src_add
664 real(FMS_HI_KIND_),
intent(in) :: d
665 integer,
intent(inout) :: num_found
666 integer,
intent(in) :: min_nbrs
668 logical :: UPDATE_DEST_NEIGHBORS_, already_exist = .false.
672 update_dest_neighbors_ = .false.
675 nloop :
do while ( n .le. num_found )
677 dist_chk :
if (d .le. map_src_dist(n))
then
679 if (src_add == map_src_add(m))
then
680 already_exist = .true.
684 if(num_found < max_neighbors)
then
685 num_found = num_found + 1
687 call mpp_error(fatal,
'UPDATE_DEST_NEIGHBORS_: '// &
688 'number of neighbor points found is greated than maxium neighbor points' )
690 do m=num_found,n+1,-1
691 map_src_add(m) = map_src_add(m-1)
692 map_src_dist(m) = map_src_dist(m-1)
694 map_src_add(n) = src_add
696 update_dest_neighbors_ = .true.
697 if( num_found > min_nbrs )
then
698 if( map_src_dist(num_found) > map_src_dist(num_found-1) )
then
699 num_found = num_found - 1
701 if( map_src_dist(min_nbrs+1) > map_src_dist(min_nbrs) )
then
708 if(already_exist)
return
710 if( .not. update_dest_neighbors_ )
then
711 if( num_found < min_nbrs )
then
712 num_found = num_found + 1
713 update_dest_neighbors_ = .true.
714 map_src_add(num_found) = src_add
715 map_src_dist(num_found) = d
722 end function update_dest_neighbors_
769 function horiz_interp_spherical_distance_(theta1,phi1,theta2,phi2)
771 real(FMS_HI_KIND_),
intent(in) :: theta1, phi1, theta2, phi2
772 real(FMS_HI_KIND_) :: HORIZ_INTERP_SPHERICAL_DISTANCE_, dot
773 integer,
parameter :: kindl = fms_hi_kind_
775 if(theta1 == theta2 .and. phi1 == phi2)
then
776 horiz_interp_spherical_distance_ = 0.0_kindl
780 dot = cos(phi1)*cos(phi2)*cos(theta1-theta2) + sin(phi1)*sin(phi2)
781 if(dot > 1.0_kindl) dot = 1.0_kindl
782 if(dot < real(-1.0_kindl, fms_hi_kind_)) dot = -1.0_kindl
783 horiz_interp_spherical_distance_ = acos(dot)
787 end function horiz_interp_spherical_distance_
792 subroutine full_search_(theta_src,phi_src,theta_dst,phi_dst,map_src_add, map_src_dist,num_found, &
793 num_neighbors,max_src_dist)
794 real(FMS_HI_KIND_),
intent(in),
dimension(:) :: theta_src, phi_src
795 real(FMS_HI_KIND_),
intent(in),
dimension(:,:) :: theta_dst, phi_dst
796 integer,
intent(out),
dimension(:,:,:) :: map_src_add
797 real(FMS_HI_KIND_),
intent(out),
dimension(:,:,:) :: map_src_dist
798 integer,
intent(out),
dimension(:,:) :: num_found
799 integer,
intent(in) :: num_neighbors
800 real(FMS_HI_KIND_),
intent(in) :: max_src_dist
802 integer :: i,j,map_src_size, step
803 integer :: map_dst_xsize,map_dst_ysize
804 real(FMS_HI_KIND_) :: d
807 map_dst_xsize=
size(theta_dst,1);map_dst_ysize=
size(theta_dst,2)
808 map_src_size =
size(theta_src(:))
812 do step = 1, map_src_size
813 d = spherical_distance(theta_dst(i,j),phi_dst(i,j),theta_src(step),phi_src(step))
814 if( d <= max_src_dist)
then
815 found = update_dest_neighbors_(map_src_add(i,j,:),map_src_dist(i,j,:), &
816 step,d,num_found(i,j), num_neighbors )
822 end subroutine full_search_
subroutine horiz_interp_spherical_(Interp, data_in, data_out, verbose, mask_in, mask_out, missing_value)
Subroutine for performing the horizontal interpolation between two grids. HORIZ_INTERP_SPHERICAL_NEW_...
subroutine horiz_interp_spherical_new_(Interp, lon_in, lat_in, lon_out, lat_out, num_nbrs, max_dist, src_modulo)
subroutine horiz_interp_spherical_wght_(Interp, wt, verbose, mask_in, mask_out, missing_value)
This routine isn't used internally it's similar to the routine above, just gets the weights as an out...
integer function mpp_pe()
Returns processor ID.