46 private :: interp_search_horiz
47 private :: interp_search_vert
48 private :: interp_insert
56 real(RP),
private,
parameter :: large_number = 9.999e+15_rp
58 integer,
private :: interp_weight_order = 2
59 real(RP),
private :: interp_search_limit
60 real(RP),
private :: interp_buffer_size_fact = 2.0_rp
73 integer,
intent(in) :: weight_order
74 real(RP),
intent(in),
optional :: search_limit
76 namelist /param_interp/ &
77 interp_buffer_size_fact
83 log_info(
"INTERP_setup",*)
'Setup' 85 interp_weight_order = weight_order
87 interp_search_limit = large_number
88 if (
present(search_limit) )
then 89 interp_search_limit = search_limit
90 log_info(
"INTERP_setup",*)
'search limit [m] : ', interp_search_limit
97 log_info(
"INTERP_setup",*)
'Not found namelist. Default used.' 98 elseif( ierr > 0 )
then 99 log_error(
"INTERP_setup",*)
'Not appropriate names in namelist PARAM_INTERP. Check!' 102 log_nml(param_interp)
125 real(RP),
intent(in) :: lon_org (:,:)
126 real(RP),
intent(in) :: lat_org (:,:)
127 real(RP),
intent(in) :: topc_org(:,:)
128 real(RP),
intent(in) :: lon_loc (:,:)
129 real(RP),
intent(in) :: lat_loc (:,:)
130 real(RP),
intent(in) :: topc_loc(:,:)
131 real(RP),
intent(in) :: topf_loc(:,:)
133 logical,
intent(in),
optional :: skip_z
134 logical,
intent(in),
optional :: skip_x
135 logical,
intent(in),
optional :: skip_y
137 real(RP) :: max_ref, min_ref
138 real(RP) :: max_loc, min_loc
148 if (
present(skip_z) )
then 153 if (
present(skip_x) )
then 158 if (
present(skip_y) )
then 162 if ( .NOT. skip_z_ )
then 163 max_ref = maxval( topc_org(:,:) ) + minval( topf_loc(:,:) - topc_loc(:,:) )
164 max_loc = maxval( topc_loc(:,:) )
166 if ( max_ref < max_loc )
then 167 log_error(
"INTERP_domain_compatibility",*)
'REQUESTED DOMAIN IS TOO MUCH BROAD' 168 log_error_cont(*)
'-- VERTICAL direction over the limit' 169 log_error_cont(*)
'-- reference max: ', max_ref
170 log_error_cont(*)
'-- local max: ', max_loc
175 if ( .NOT. skip_x_ )
then 176 max_ref = maxval( lon_org(:,:) / d2r )
177 min_ref = minval( lon_org(:,:) / d2r )
178 max_loc = maxval( lon_loc(:,:) / d2r )
179 min_loc = minval( lon_loc(:,:) / d2r )
181 if ( (min_ref+360.0_rp-max_ref) < 360.0_rp /
size(lon_org,1) * 2.0_rp )
then 183 elseif( max_ref < max_loc .OR. min_ref > min_loc )
then 184 log_error(
"INTERP_domain_compatibility",*)
'REQUESTED DOMAIN IS TOO MUCH BROAD' 185 log_error_cont(*)
'-- LONGITUDINAL direction over the limit' 186 log_error_cont(*)
'-- reference max: ', max_ref
187 log_error_cont(*)
'-- reference min: ', min_ref
188 log_error_cont(*)
'-- local max: ', max_loc
189 log_error_cont(*)
'-- local min: ', min_loc
194 if ( .NOT. skip_y_ )
then 195 max_ref = maxval( lat_org(:,:) / d2r )
196 min_ref = minval( lat_org(:,:) / d2r )
197 max_loc = maxval( lat_loc(:,:) / d2r )
198 min_loc = minval( lat_loc(:,:) / d2r )
200 if ( max_ref < max_loc .OR. min_ref > min_loc )
then 201 log_error(
"INTERP_domain_compatibility",*)
'REQUESTED DOMAIN IS TOO MUCH BROAD' 202 log_error_cont(*)
'-- LATITUDINAL direction over the limit' 203 log_error_cont(*)
'-- reference max: ', max_ref
204 log_error_cont(*)
'-- reference min: ', min_ref
205 log_error_cont(*)
'-- local max: ', max_loc
206 log_error_cont(*)
'-- local min: ', min_loc
222 idx_i, idx_j, hfact, &
232 integer,
intent(in) :: npoints
233 integer,
intent(in) :: IA_ref
234 integer,
intent(in) :: JA_ref
235 real(RP),
intent(in) :: lon_ref(ia_ref,ja_ref)
236 real(RP),
intent(in) :: lat_ref(ia_ref,ja_ref)
237 integer,
intent(in) :: IA
238 integer,
intent(in) :: JA
239 real(RP),
intent(in) :: lon (ia,ja)
240 real(RP),
intent(in) :: lat (ia,ja)
241 integer,
intent(out) :: idx_i(ia,ja,npoints)
242 integer,
intent(out) :: idx_j(ia,ja,npoints)
243 real(RP),
intent(out) :: hfact(ia,ja,npoints)
245 real(RP),
intent(in),
optional :: search_limit
246 logical,
intent(in),
optional :: latlon_structure
247 integer,
intent(in),
optional :: weight_order
249 logical :: ll_struct_
251 real(RP) :: lon_min, lon_max
252 real(RP) :: lat_min, lat_max
253 real(RP) :: dlon, dlat
256 integer :: is, ie, js, je
257 integer :: psizex, psizey
258 real(RP) :: lon1d(ia_ref), lat1d(ja_ref)
259 real(RP) :: lon0, lat0
260 integer,
allocatable :: i0(:), i1(:), j0(:), j1(:)
263 integer :: nsize, psize, nidx_max
264 integer,
allocatable :: idx_blk(:,:,:), nidx(:,:)
265 integer :: idx_ref(npoints)
268 integer :: i, j, ii, jj, n
273 if (
present(latlon_structure) )
then 274 ll_struct_ = latlon_structure
279 hfact(:,:,:) = 0.0_rp
282 if ( ll_struct_ )
then 288 if ( lon_ref(i,j) .ne. undef )
then 289 lon1d(i) = lon_ref(i,j)
293 if ( lon_min == undef .and. lon1d(i) .ne. undef )
then 297 if ( lon_min .ne. undef )
then 298 if ( lon1d(i) .ne. undef )
then 309 if ( lat_ref(i,j) .ne. undef )
then 310 lat1d(j) = lat_ref(i,j)
314 if ( lat_min == undef .and. lat1d(j) .ne. undef )
then 318 if ( lat_min .ne. undef )
then 319 if ( lat1d(j) .ne. undef )
then 327 dlon = ( lon_max - lon_min ) / ( ie - is )
329 if ( lon1d(i) == undef ) lon1d(i) = lon_min + dlon * ( i - is )
331 dlat = ( lat_max - lat_min ) / ( je - js )
333 if ( lat1d(j) == undef ) lat1d(j) = lat_min + dlat * ( j - js )
338 if ( ie-is > 10 )
then 339 psizex = int( 2.0_rp*sqrt(
real(ie-is+1,
rp)) )
343 if ( je-js > 10 )
then 344 psizey = int( 2.0_rp*sqrt(
real(je-js+1,
rp)) )
349 allocate( i0(psizex), i1(psizex) )
350 allocate( j0(psizey), j1(psizey) )
352 dlon = ( lon_max - lon_min ) / psizex
353 dlat = ( lat_max - lat_min ) / psizey
356 lon0 = lon_min + dlon * (ii-1)
358 if ( lon1d(i) >= lon0 )
then 365 i1(ii) = i0(ii+1) - 1
370 lat0 = lat_min + dlat * (jj-1)
372 if ( lat1d(j) >= lat0 )
then 379 j1(jj) = j0(jj+1) - 1
390 lon1d(:), lat1d(:), &
393 i0(:), i1(:), j0(:), j1(:), &
394 lon(i,j), lat(i,j), &
395 idx_i(i,j,:), idx_j(i,j,:), &
397 search_limit = search_limit, &
398 weight_order = weight_order )
402 deallocate( i0, i1, j0, j1 )
406 nsize = ia_ref * ja_ref
407 if ( nsize > 100 )
then 408 psize = int( sqrt(2.0_rp*sqrt(
real(nsize,
rp))) )
409 nidx_max = nsize / psize * interp_buffer_size_fact
415 allocate(idx_blk(nidx_max,psize,psize))
416 allocate(nidx( psize,psize))
419 lon_ref(:,:), lat_ref(:,:), &
420 idx_blk(:,:,:), nidx(:,:), &
430 call interp_search_horiz( npoints, &
432 lon_ref(:,:), lat_ref(:,:), &
437 idx_blk(:,:,:), nidx(:,:), &
438 lon(i,j), lat(i,j), &
441 search_limit = search_limit, &
442 weight_order = weight_order )
444 idx_i(i,j,n) = mod(idx_ref(n) - 1, ia_ref) + 1
445 idx_j(i,j,n) = ( idx_ref(n) - 1 ) / ia_ref + 1
450 deallocate(idx_blk, nidx)
488 integer,
intent(in) :: npoints
489 integer,
intent(in) :: KA_ref, KS_ref, KE_ref
490 integer,
intent(in) :: IA_ref
491 integer,
intent(in) :: JA_ref
492 real(RP),
intent(in) :: lon_ref(ia_ref,ja_ref)
493 real(RP),
intent(in) :: lat_ref(ia_ref,ja_ref)
494 real(RP),
intent(in) :: hgt_ref(ka_ref,ia_ref,ja_ref)
495 integer,
intent(in) :: KA, KS, KE
496 integer,
intent(in) :: IA
497 integer,
intent(in) :: JA
498 real(RP),
intent(in) :: lon (ia,ja)
499 real(RP),
intent(in) :: lat (ia,ja)
500 real(RP),
intent(in) :: hgt (ka,ia,ja)
501 integer,
intent(out) :: idx_i(ia,ja,npoints)
502 integer,
intent(out) :: idx_j(ia,ja,npoints)
503 real(RP),
intent(out) :: hfact(ia,ja,npoints)
504 integer,
intent(out) :: idx_k(ka,2,ia,ja,npoints)
505 real(RP),
intent(out) :: vfact(ka,2,ia,ja,npoints)
507 integer :: nsize, psize, nidx_max
508 integer,
allocatable :: idx_blk(:,:,:), nidx(:,:)
509 real(RP) :: lon_min, lon_max
510 real(RP) :: lat_min, lat_max
511 real(RP) :: dlon, dlat
512 integer :: idx_ref(npoints)
514 integer :: i, j, ii, jj, n
519 nsize = ia_ref * ja_ref
520 if ( nsize > 100 )
then 521 psize = int( sqrt(2.0_rp*sqrt(
real(nsize,
rp))) )
522 nidx_max = nsize / psize * interp_buffer_size_fact
528 allocate(idx_blk(nidx_max,psize,psize))
529 allocate(nidx( psize,psize))
532 lon_ref(:,:), lat_ref(:,:), &
533 idx_blk(:,:,:), nidx(:,:), &
538 hfact(:,:,:) = 0.0_rp
539 vfact(:,:,:,:,:) = 0.0_rp
547 call interp_search_horiz( npoints, &
549 lon_ref(:,:), lat_ref(:,:), &
554 idx_blk(:,:,:), nidx(:,:), &
555 lon(i,j), lat(i,j), &
556 idx_ref(:), hfact(i,j,:) )
559 ii = mod(idx_ref(n) - 1, ia_ref) + 1
560 jj = ( idx_ref(n) - 1 ) / ia_ref + 1
564 call interp_search_vert( ka_ref, ks_ref, ke_ref, &
574 deallocate(idx_blk, nidx)
599 integer,
intent(in) :: npoints
600 integer,
intent(in) :: IA_ref
601 integer,
intent(in) :: JA_ref
602 integer,
intent(in) :: IA
603 integer,
intent(in) :: JA
604 integer,
intent(in) :: idx_i (ia,ja,npoints)
605 integer,
intent(in) :: idx_j (ia,ja,npoints)
606 real(RP),
intent(in) :: hfact (ia,ja,npoints)
607 real(RP),
intent(in) :: val_ref(ia_ref,ja_ref)
608 real(RP),
intent(out) :: val (ia,ja)
619 if ( hfact(i,j,1) < eps .or. val_ref(idx_i(i,j,1),idx_j(i,j,1)) == undef )
then 622 val(i,j) = hfact(i,j,1) * val_ref(idx_i(i,j,1),idx_j(i,j,1))
624 if ( val_ref(idx_i(i,j,n),idx_j(i,j,n)) == undef )
then 625 val(i,j) = val(i,j) / sum( hfact(i,j,1:n-1) )
628 val(i,j) = val(i,j) &
629 + hfact(i,j,n) * val_ref(idx_i(i,j,n),idx_j(i,j,n))
660 integer,
intent(in) :: npoints
661 integer,
intent(in) :: KA_ref
662 integer,
intent(in) :: IA_ref
663 integer,
intent(in) :: JA_ref
664 integer,
intent(in) :: KA, KS, KE
665 integer,
intent(in) :: IA
666 integer,
intent(in) :: JA
667 integer,
intent(in) :: idx_i (ia,ja,npoints)
668 integer,
intent(in) :: idx_j (ia,ja,npoints)
669 real(RP),
intent(in) :: hfact (ia,ja,npoints)
670 integer,
intent(in) :: idx_k (ka,2,ia,ja,npoints)
671 real(RP),
intent(in) :: vfact (ka,2,ia,ja,npoints)
673 real(RP),
intent(in),
target :: val_ref(ka_ref,ia_ref,ja_ref)
675 real(RP),
intent(out) :: val (ka,ia,ja)
677 logical,
intent(in),
optional:: logwgt
681 real(RP),
pointer :: work(:,:,:)
683 integer :: k, i, j, n
689 if (
present(logwgt) )
then 694 allocate( work(ka_ref,ia_ref,ja_ref) )
699 work(k,i,j) = log( val_ref(k,i,j) )
711 val(k,i,j) = hfact(i,j,1) * vfact(k,1,i,j,1) * work(idx_k(k,1,i,j,1),idx_i(i,j,1),idx_j(i,j,1)) &
712 + hfact(i,j,1) * vfact(k,2,i,j,1) * work(idx_k(k,2,i,j,1),idx_i(i,j,1),idx_j(i,j,1))
724 val(k,i,j) = val(k,i,j) &
725 + hfact(i,j,n) * vfact(k,1,i,j,n) * work(idx_k(k,1,i,j,n),idx_i(i,j,n),idx_j(i,j,n)) &
726 + hfact(i,j,n) * vfact(k,2,i,j,n) * work(idx_k(k,2,i,j,n),idx_i(i,j,n),idx_j(i,j,n))
738 val(k,i,j) = exp( val(k,i,j) )
752 subroutine interp_search_horiz( &
771 integer,
intent(in) :: npoints
772 integer,
intent(in) :: nsize
773 real(RP),
intent(in) :: lon_ref(nsize)
774 real(RP),
intent(in) :: lat_ref(nsize)
775 real(RP),
intent(in) :: lon_min
776 real(RP),
intent(in) :: lon_max
777 real(RP),
intent(in) :: lat_min
778 real(RP),
intent(in) :: lat_max
779 integer,
intent(in) :: psize
780 integer,
intent(in) :: nidx_max
781 real(RP),
intent(in) :: dlon
782 real(RP),
intent(in) :: dlat
783 integer,
intent(in) :: idx_blk(nidx_max,psize,psize)
784 integer,
intent(in) :: nidx (psize,psize)
785 real(RP),
intent(in) :: lon
786 real(RP),
intent(in) :: lat
787 integer,
intent(out) :: idx_ref(npoints)
788 real(RP),
intent(out) :: hfact(npoints)
790 real(RP),
intent(in),
optional :: search_limit
791 integer,
intent(in),
optional :: weight_order
793 real(RP) :: drad(npoints)
795 real(RP) :: search_limit_
796 integer :: weight_order_
798 real(RP) :: lon0, lon1, lat0, lat1
799 real(RP) :: dlon_sl, dlat_sl
801 integer :: ii, jj, ii0, jj0
804 if (
present(search_limit) )
then 805 search_limit_ = search_limit
807 search_limit_ = interp_search_limit
809 search_limit_ = search_limit_ / radius
811 if (
present(weight_order) )
then 812 weight_order_ = weight_order
814 weight_order_ = interp_weight_order
819 drad(:) = large_number
823 ii0 = max( min( int(( lon - lon_min ) / dlon) + 1, psize ), 1 )
824 jj0 = max( min( int(( lat - lat_min ) / dlat) + 1, psize ), 1 )
825 do i = 1, nidx(ii0,jj0)
826 n = idx_blk(i,ii0,jj0)
827 call interp_insert( npoints, &
829 lon_ref(n), lat_ref(n), &
831 drad(:), idx_ref(:) )
834 if ( abs(drad(1)) < eps )
then 839 else if ( drad(1) > search_limit_ )
then 846 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
847 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
849 lat0 = lat_min + dlat * (jj-1)
850 lat1 = lat_min + dlat * jj
851 if ( lat < lat0 - dlat_sl &
852 .or. lat >= lat1 + dlat_sl ) cycle
854 if ( ii==ii0 .and. jj==jj0 ) cycle
855 lon0 = lon_min + dlon * (ii-1)
856 lon1 = lon_min + dlon * ii
857 if ( lon < lon0 - dlon_sl &
858 .or. lon >= lon1 + dlon_sl ) cycle
859 do i = 1, nidx(ii,jj)
861 call interp_insert( npoints, &
863 lon_ref(n), lat_ref(n), &
865 drad(:), idx_ref(:) )
867 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
868 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
873 if ( weight_order_ < 0 )
then 875 hfact(n) = 1.0_rp / drad(n)**(-1.0_rp/weight_order_)
879 hfact(n) = 1.0_rp / drad(n)**weight_order_
885 if ( drad(n) >= search_limit_ )
then 896 if ( sum > 0.0_rp )
then 898 hfact(n) = hfact(n) / sum
903 end subroutine interp_search_horiz
926 integer,
intent(in) :: npoints
927 integer,
intent(in) :: psizex
928 integer,
intent(in) :: psizey
929 integer,
intent(in) :: IA_ref
930 integer,
intent(in) :: JA_ref
931 real(RP),
intent(in) :: lon_ref(ia_ref)
932 real(RP),
intent(in) :: lat_ref(ja_ref)
933 real(RP),
intent(in) :: lon_min
934 real(RP),
intent(in) :: lat_min
935 real(RP),
intent(in) :: dlon
936 real(RP),
intent(in) :: dlat
937 integer,
intent(in) :: i0(psizex)
938 integer,
intent(in) :: i1(psizex)
939 integer,
intent(in) :: j0(psizey)
940 integer,
intent(in) :: j1(psizey)
941 real(RP),
intent(in) :: lon
942 real(RP),
intent(in) :: lat
943 integer,
intent(out) :: idx_i(npoints)
944 integer,
intent(out) :: idx_j(npoints)
945 real(RP),
intent(out) :: hfact(npoints)
947 real(RP),
intent(in),
optional :: search_limit
948 integer,
intent(in),
optional :: weight_order
950 real(RP) :: drad(npoints)
952 real(RP) :: search_limit_
953 integer :: weight_order_
955 real(RP) :: lon0, lon1, lat0, lat1
956 real(RP) :: dlon_sl, dlat_sl
959 integer :: ii, jj, ii0, jj0
962 if (
present(search_limit) )
then 963 search_limit_ = search_limit
965 search_limit_ = interp_search_limit
967 search_limit_ = search_limit_ / radius
969 if (
present(weight_order) )
then 970 weight_order_ = weight_order
972 weight_order_ = interp_weight_order
976 drad(:) = large_number
981 ii0 = max( min( int(( lon - lon_min ) / dlon) + 1, psizex ), 1)
982 jj0 = max( min( int(( lat - lat_min ) / dlat) + 1, psizey ), 1)
983 do j = j0(jj0), j1(jj0)
984 do i = i0(ii0), i1(ii0)
987 lon_ref(i), lat_ref(j), &
989 drad(:), idx_i(:), idx_j(:) )
993 if ( abs(drad(1)) < eps )
then 998 else if ( drad(1) > search_limit_ )
then 1006 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
1007 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
1009 lat0 = lat_min + dlat * (jj-1)
1010 lat1 = lat_min + dlat * jj
1011 if ( lat < lat0 - dlat_sl &
1012 .or. lat >= lat1 + dlat_sl ) cycle
1014 if ( ii==ii0 .and. jj==jj0 ) cycle
1015 lon0 = lon_min + dlon * (ii-1)
1016 lon1 = lon_min + dlon * ii
1017 if ( lon < lon0 - dlon_sl &
1018 .or. lon >= lon1 + dlon_sl ) cycle
1019 do j = j0(jj0), j1(jj0)
1020 do i = i0(ii0), i1(ii0)
1023 lon_ref(i), lat_ref(j), &
1025 drad(:), idx_i(:), idx_j(:) )
1028 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
1029 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
1035 if ( weight_order_ < 0 )
then 1037 hfact(n) = 1.0_rp / drad(n)**(-1.0_rp/weight_order_)
1041 hfact(n) = 1.0_rp / drad(n)**weight_order_
1047 if ( drad(n) >= search_limit_ )
then 1055 sum = sum + hfact(n)
1058 if ( sum > 0.0_rp )
then 1060 hfact(n) = hfact(n) / sum
1070 subroutine interp_search_vert( &
1071 KA_ref, KS_ref, KE_ref, &
1081 integer,
intent(in) :: KA_ref, KS_ref, KE_ref
1082 integer,
intent(in) :: KA, KS, KE
1083 real(RP),
intent(in) :: hgt_ref(ka_ref)
1084 real(RP),
intent(in) :: hgt (ka)
1085 integer,
intent(inout) :: idx_k (ka,2)
1086 real(RP),
intent(inout) :: vfact (ka,2)
1096 if ( hgt(k) < hgt_ref(ks_ref) )
then 1101 elseif( hgt(k) >= hgt_ref(ke_ref) )
then 1107 do kk = ks_ref, ke_ref-1
1108 if ( hgt(k) >= hgt_ref(kk ) &
1109 .AND. hgt(k) < hgt_ref(kk+1) )
then 1111 weight = ( hgt(k) - hgt_ref(kk) ) &
1112 / ( hgt_ref(kk+1) - hgt_ref(kk) )
1116 vfact(k,1) = 1.0_rp - weight
1123 if ( idx_k(k,1) < 0 )
then 1124 log_error(
"INTERP_search_vert",*)
'data for interpolation was not found.' 1125 log_error_cont(*)
'k=', k,
', hgt(k)=', hgt(k),
', hgt_ref(:)=', hgt_ref(:)
1132 end subroutine interp_search_vert
1137 subroutine interp_insert( npoints, &
1147 integer,
intent(in) :: npoints
1148 real(RP),
intent(in) :: lon, lat
1149 real(RP),
intent(in) :: lon_ref, lat_ref
1150 integer,
intent(in) :: i
1152 real(RP),
intent(inout) :: drad(npoints)
1153 integer,
intent(inout) :: idx_i(npoints)
1157 if ( lon_ref == undef )
return 1159 dradian = haversine( lon, lat, lon_ref, lat_ref )
1161 if ( dradian <= drad(npoints) )
then 1163 drad(npoints) = dradian
1167 call sort_exec( npoints, &
1173 end subroutine interp_insert
1180 drad, idx_i, idx_j )
1186 integer,
intent(in) :: npoints
1187 real(RP),
intent(in) :: lon, lat
1188 real(RP),
intent(in) :: lon_ref, lat_ref
1189 integer,
intent(in) :: i, j
1191 real(RP),
intent(inout) :: drad(npoints)
1192 integer,
intent(inout) :: idx_i(npoints)
1193 integer,
intent(inout) :: idx_j(npoints)
1197 if ( lon_ref == undef )
return 1199 dradian = haversine( lon, lat, lon_ref, lat_ref )
1201 if ( dradian <= drad(npoints) )
then 1203 drad(npoints) = dradian
1208 call sort_exec( npoints, &
1227 integer,
intent(in) :: nsize
1228 integer,
intent(in) :: psize
1229 integer,
intent(in) :: nidx_max
1230 real(RP),
intent(in) :: lon_ref(nsize)
1231 real(RP),
intent(in) :: lat_ref(nsize)
1233 integer,
intent(out) :: idx (nidx_max,psize,psize)
1234 integer,
intent(out) :: nidx(psize,psize)
1235 real(RP),
intent(out) :: lon_min, lon_max
1236 real(RP),
intent(out) :: lat_min, lat_max
1237 real(RP),
intent(out) :: dlon, dlat
1239 integer :: i, ii, jj, n
1241 lon_min = minval(lon_ref(:), mask=lon_ref.ne.undef)
1242 lon_max = maxval(lon_ref(:), mask=lon_ref.ne.undef)
1243 lat_min = minval(lat_ref(:), mask=lat_ref.ne.undef)
1244 lat_max = maxval(lat_ref(:), mask=lat_ref.ne.undef)
1246 dlon = ( lon_max - lon_min ) / psize
1247 dlat = ( lat_max - lat_min ) / psize
1251 if ( lon_ref(i) == undef ) cycle
1252 ii = min(int((lon_ref(i) - lon_min) / dlon) + 1, psize)
1253 jj = min(int((lat_ref(i) - lat_min) / dlat) + 1, psize)
1256 if ( n <= nidx_max ) idx(n,ii,jj) = i
1259 if ( maxval(nidx) > nidx_max )
then 1260 log_error(
"INTERP_search_horiz",*)
'Buffer size is not enough' 1261 log_error_cont(*)
' Use larger INTERP_buffer_size_fact: ', interp_buffer_size_fact * maxval(nidx)/nidx_max
1271 function haversine( &
1277 real(RP),
intent(in) :: lon0
1278 real(RP),
intent(in) :: lat0
1279 real(RP),
intent(in) :: lon1
1280 real(RP),
intent(in) :: lat1
1283 real(RP) :: dlonh, dlath
1287 dlonh = 0.5_rp * ( lon0 - lon1 )
1288 dlath = 0.5_rp * ( lat0 - lat1 )
1290 work1 = sin(dlath)**2 + cos(lat0) * cos(lat1) * sin(dlonh)**2
1292 d = 2.0_rp * asin( min(sqrt(work1),1.0_rp) )
1294 end function haversine
subroutine interp_div_block(nsize, psize, nidx_max, lon_ref, lat_ref, idx, nidx, lon_min, lon_max, lat_min, lat_max, dlon, dlat)
real(rp), public const_radius
radius of the planet [m]
subroutine, public interp_factor3d(npoints, KA_ref, KS_ref, KE_ref, IA_ref, JA_ref, lon_ref, lat_ref, hgt_ref, KA, KS, KE, IA, JA, lon, lat, hgt, idx_i, idx_j, hfact, idx_k, vfact)
integer, public io_fid_conf
Config file ID.
real(rp), public const_d2r
degree to radian
subroutine, public interp_interp3d(npoints, KA_ref, IA_ref, JA_ref, KA, KS, KE, IA, JA, idx_i, idx_j, hfact, idx_k, vfact, val_ref, val, logwgt)
real(rp), public const_undef
module atmosphere / grid / cartesC index
subroutine, public interp_domain_compatibility(lon_org, lat_org, topc_org, lon_loc, lat_loc, topc_loc, topf_loc, skip_x, skip_y, skip_z)
subroutine interp_insert_2d(npoints, lon, lat, lon_ref, lat_ref, i, j, drad, idx_i, idx_j)
subroutine, public interp_interp2d(npoints, IA_ref, JA_ref, IA, JA, idx_i, idx_j, hfact, val_ref, val)
subroutine, public prc_abort
Abort Process.
subroutine, public interp_setup(weight_order, search_limit)
Setup.
subroutine interp_search_horiz_struct(npoints, psizex, psizey, IA_ref, JA_ref, lon_ref, lat_ref, lon_min, lat_min, dlon, dlat, i0, i1, j0, j1, lon, lat, idx_i, idx_j, hfact, search_limit, weight_order)
subroutine, public prof_rapstart(rapname_base, level)
Start raptime.
real(rp), public const_eps
small number
subroutine, public interp_factor2d(npoints, IA_ref, JA_ref, lon_ref, lat_ref, IA, JA, lon, lat, idx_i, idx_j, hfact, search_limit, latlon_structure, weight_order)
subroutine, public prof_rapend(rapname_base, level)
Save raptime.
integer, parameter, public rp