30 public :: interp_factor2d
31 public :: interp_factor3d
43 interface interp_factor2d
44 procedure INTERP_factor2d_linear_latlon
45 procedure INTERP_factor2d_linear_xy
46 procedure INTERP_factor2d_weight
47 end interface interp_factor2d
48 interface interp_factor3d
49 procedure INTERP_factor3d_linear_latlon
50 procedure INTERP_factor3d_linear_xy
51 procedure INTERP_factor3d_weight
52 end interface interp_factor3d
62 private :: interp_search_horiz
63 private :: interp_insert
71 real(RP),
private,
parameter :: large_number = 9.999e+15_rp
73 integer,
private :: INTERP_weight_order = 2
74 real(RP),
private :: INTERP_search_limit
75 real(RP),
private :: INTERP_buffer_size_fact = 2.0_rp
76 logical,
private :: INTERP_use_spline_vert = .true.
77 real(RP),
private :: INTERP_threshold_undef = 1.0_rp
79 real(RP),
private :: EPS_bilinear
92 integer,
intent(in) :: weight_order
93 real(rp),
intent(in),
optional :: search_limit
95 namelist /param_interp/ &
96 interp_buffer_size_fact, &
97 interp_use_spline_vert, &
98 interp_threshold_undef
104 log_info(
"INTERP_setup",*)
'Setup'
106 interp_weight_order = weight_order
108 interp_search_limit = large_number
109 if (
present(search_limit) )
then
110 interp_search_limit = search_limit
111 log_info(
"INTERP_setup",*)
'search limit [m] : ', interp_search_limit
118 log_info(
"INTERP_setup",*)
'Not found namelist. Default used.'
119 elseif( ierr > 0 )
then
120 log_error(
"INTERP_setup",*)
'Not appropriate names in namelist PARAM_INTERP. Check!'
123 log_nml(param_interp)
126 eps_bilinear = 1e-6_rp
128 eps_bilinear = 1e-2_rp
152 real(rp),
intent(in) :: lon_org (:,:)
153 real(rp),
intent(in) :: lat_org (:,:)
154 real(rp),
intent(in) :: topc_org(:,:)
155 real(rp),
intent(in) :: lon_loc (:,:)
156 real(rp),
intent(in) :: lat_loc (:,:)
157 real(rp),
intent(in) :: topc_loc(:,:)
158 real(rp),
intent(in) :: topf_loc(:,:)
160 logical,
intent(in),
optional :: skip_z
161 logical,
intent(in),
optional :: skip_x
162 logical,
intent(in),
optional :: skip_y
164 real(rp) :: max_ref, min_ref
165 real(rp) :: max_loc, min_loc
175 if (
present(skip_z) )
then
180 if (
present(skip_x) )
then
185 if (
present(skip_y) )
then
189 if ( .NOT. skip_z_ )
then
190 max_ref = maxval( topc_org(:,:) ) + minval( topf_loc(:,:) - topc_loc(:,:) )
191 max_loc = maxval( topc_loc(:,:) )
193 if ( max_ref < max_loc )
then
194 log_error(
"INTERP_domain_compatibility",*)
'REQUESTED DOMAIN IS TOO MUCH BROAD'
195 log_error_cont(*)
'-- VERTICAL direction over the limit'
196 log_error_cont(*)
'-- reference max: ', max_ref
197 log_error_cont(*)
'-- local max: ', max_loc
202 if ( .NOT. skip_x_ )
then
203 max_ref = maxval( lon_org(:,:) / d2r )
204 min_ref = minval( lon_org(:,:) / d2r )
205 max_loc = maxval( lon_loc(:,:) / d2r )
206 min_loc = minval( lon_loc(:,:) / d2r )
208 if ( (min_ref+360.0_rp-max_ref) < 360.0_rp /
size(lon_org,1) * 2.0_rp )
then
210 elseif( max_ref < max_loc .OR. min_ref > min_loc )
then
211 log_error(
"INTERP_domain_compatibility",*)
'REQUESTED DOMAIN IS TOO MUCH BROAD'
212 log_error_cont(*)
'-- LONGITUDINAL direction over the limit'
213 log_error_cont(*)
'-- reference max: ', max_ref
214 log_error_cont(*)
'-- reference min: ', min_ref
215 log_error_cont(*)
'-- local max: ', max_loc
216 log_error_cont(*)
'-- local min: ', min_loc
221 if ( .NOT. skip_y_ )
then
222 max_ref = maxval( lat_org(:,:) / d2r )
223 min_ref = minval( lat_org(:,:) / d2r )
224 max_loc = maxval( lat_loc(:,:) / d2r )
225 min_loc = minval( lat_loc(:,:) / d2r )
227 if ( max_ref < max_loc .OR. min_ref > min_loc )
then
228 log_error(
"INTERP_domain_compatibility",*)
'REQUESTED DOMAIN IS TOO MUCH BROAD'
229 log_error_cont(*)
'-- LATITUDINAL direction over the limit'
230 log_error_cont(*)
'-- reference max: ', max_ref
231 log_error_cont(*)
'-- reference min: ', min_ref
232 log_error_cont(*)
'-- local max: ', max_loc
233 log_error_cont(*)
'-- local min: ', min_loc
245 KA_ref, KS_ref, KE_ref, &
258 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
259 integer,
intent(in) :: ka, ks, ke
261 real(rp),
intent(in) :: hgt_ref(ka_ref)
262 real(rp),
intent(in) :: hgt (ka)
264 integer,
intent(out) :: idx_k (ka,2)
265 real(rp),
intent(out) :: vfact (ka)
267 logical,
intent(in),
optional :: flag_extrap
269 logical :: flag_extrap_
274 if (
present(flag_extrap) )
then
275 flag_extrap_ = flag_extrap
277 flag_extrap_ = .true.
284 if ( hgt(k) < hgt_ref(ks_ref) - eps )
then
285 if ( flag_extrap_ )
then
294 elseif( hgt(k) < hgt_ref(ks_ref) )
then
298 elseif( hgt(k) > hgt_ref(ke_ref) + eps )
then
299 if ( flag_extrap_ )
then
308 elseif( hgt(k) >= hgt_ref(ke_ref) )
then
313 do kk = ks_ref, ke_ref-1
314 if ( hgt(k) >= hgt_ref(kk ) &
315 .AND. hgt(k) < hgt_ref(kk+1) )
then
318 vfact(k) = ( hgt_ref(kk+1) - hgt(k) ) &
319 / ( hgt_ref(kk+1) - hgt_ref(kk) )
340 idx_i, idx_j, hfact )
344 integer,
intent(in) :: ia_ref, ja_ref
345 integer,
intent(in) :: ia, ja
347 real(rp),
intent(in) :: lon_ref(ia_ref)
348 real(rp),
intent(in) :: lat_ref(ja_ref)
349 real(rp),
intent(in) :: lon(ia,ja)
350 real(rp),
intent(in) :: lat(ia,ja)
351 integer,
intent(out) :: idx_i(ia,ja,4)
352 integer,
intent(out) :: idx_j(ia,ja,4)
353 real(rp),
intent(out) :: hfact(ia,ja,4)
356 integer :: i, j, ii, jj
366 if ( lon(i,j) < lon_ref(1) )
then
368 hfact(i,j,:) = 0.0_rp
369 else if ( lon(i,j) > lon_ref(ia_ref) )
then
370 idx_i(i,j,:) = ia_ref
371 hfact(i,j,:) = 0.0_rp
372 else if ( lon(i,j) == lon_ref(ia_ref) )
then
373 idx_i(i,j,:) = ia_ref
374 hfact(i,j,1) = 0.0_rp
375 hfact(i,j,2) = 1.0_rp
376 hfact(i,j,3) = 0.0_rp
377 hfact(i,j,4) = 1.0_rp
380 if ( lon(i,j) < lon_ref(ii) )
then
381 f1 = ( lon_ref(ii) - lon(i,j) ) / ( lon_ref(ii) - lon_ref(ii-1) )
382 f2 = ( lon(i,j) - lon_ref(ii-1) ) / ( lon_ref(ii) - lon_ref(ii-1) )
397 if ( lat(i,j) < lat_ref(1) )
then
399 hfact(i,j,:) = 0.0_rp
400 else if ( lat(i,j) > lat_ref(ja_ref) )
then
401 idx_j(i,j,:) = ja_ref
402 hfact(i,j,:) = 0.0_rp
403 else if ( lat(i,j) == lat_ref(ja_ref) )
then
404 idx_j(i,j,:) = ja_ref
405 hfact(i,j,1) = 0.0_rp
406 hfact(i,j,2) = 0.0_rp
411 if ( lat(i,j) < lat_ref(jj) )
then
412 f1 = ( lat_ref(jj) - lat(i,j) ) / ( lat_ref(jj) - lat_ref(jj-1) )
413 f2 = ( lat(i,j) - lat_ref(jj-1) ) / ( lat_ref(jj) - lat_ref(jj-1) )
414 hfact(i,j,1) = hfact(i,j,1) * f1
415 hfact(i,j,2) = hfact(i,j,2) * f1
416 hfact(i,j,3) = hfact(i,j,3) * f2
417 hfact(i,j,4) = hfact(i,j,4) * f2
428 hfact(i,j,:), idx_i(i,j,:), idx_j(i,j,:), &
458 integer,
intent(in) :: ia_ref, ja_ref
459 integer,
intent(in) :: ia, ja
461 real(rp),
intent(in) :: x_ref(ia_ref,ja_ref)
462 real(rp),
intent(in) :: y_ref(ia_ref,ja_ref)
463 real(rp),
intent(in) :: x(ia)
464 real(rp),
intent(in) :: y(ja)
466 integer,
intent(out) :: idx_i(ia,ja,4)
467 integer,
intent(out) :: idx_j(ia,ja,4)
468 real(rp),
intent(out) :: hfact(ia,ja,4)
470 logical,
intent(in),
optional :: zonal
471 logical,
intent(in),
optional :: pole
474 integer :: inc_i, inc_j
475 logical :: error, err
476 logical :: zonal_, pole_
480 integer :: i1, i2, i3, i4
481 integer :: j1, j2, j3, j4
483 integer :: ite, ite_max
487 if (
present(zonal) )
then
492 if (
present(pole) )
then
498 ii0 = ia_ref * 0.5_rp
499 jj0 = ja_ref * 0.5_rp
502 ite_max = ia_ref * ja_ref / 4
523 if ( ii == ia_ref )
then
531 if ( i2 > ia_ref ) i2 = i2 - ia_ref
533 if ( i1 > ia_ref ) i1 = i1 - ia_ref
535 if ( jj == ja_ref )
then
539 if ( i3 > ia_ref ) i3 = i3 - ia_ref
541 if ( i4 > ia_ref ) i4 = i4 - ia_ref
543 if ( abs( x_ref(i1,j1) - undef ) < eps .or. &
544 abs( x_ref(i2,j2) - undef ) < eps .or. &
545 abs( x_ref(i3,j3) - undef ) < eps .or. &
546 abs( x_ref(i4,j4) - undef ) < eps )
then
547 if ( ii == ia_ref-1 )
then
549 if ( jj == ja_ref-1 )
then
557 if ( ii == ia_ref )
then
561 if ( jj == ja_ref )
then
564 if ( ii == ia_ref ) ii = 1
567 call interp_check_inside( &
568 x_ref(i1,j1), x_ref(i2,j2), x_ref(i3,j3), x_ref(i4,j4), &
569 y_ref(i1,j1), y_ref(i2,j2), y_ref(i3,j3), y_ref(i4,j4), &
573 if ( err ) error = .true.
575 if ( inc_i == 0 .and. inc_j == 0 )
then
577 x_ref(i1,j1), x_ref(i2,j2), x_ref(i3,j3), x_ref(i4,j4), &
578 y_ref(i1,j1), y_ref(i2,j2), y_ref(i3,j3), y_ref(i4,j4), &
582 if ( err ) error = .true.
592 hfact(i,j,1) = ( 1.0_rp - u ) * ( 1.0_rp - v )
593 hfact(i,j,2) = ( u ) * ( 1.0_rp - v )
594 hfact(i,j,3) = ( u ) * ( v )
595 hfact(i,j,4) = ( 1.0_rp - u ) * ( v )
600 if ( zonal_ .or. pole_ )
then
601 if ( ii == 0 ) ii = ia_ref
602 if ( ii == ia_ref+1 ) ii = 1
605 jj = min( jj, ja_ref )
608 jj = min( jj, ja_ref-1 )
611 if ( ii == 0 .and. jj == 0 )
then
615 if ( ii == 0 .and. jj == ja_ref )
then
619 if ( ii == ia_ref .and. jj == 0 )
then
623 if ( ii == ia_ref .and. jj == ja_ref )
then
627 ii = max( min( ii, ia_ref-1 ), 1 )
628 jj = max( min( jj, ja_ref-1 ), 1 )
632 if ( ite == ite_max+1 )
then
633 log_error(
"INTERP_factor2d_linear_xy",*)
'iteration max has been reached', i, j, x(i), y(j)
634 log_error_cont(*) minval(x_ref), maxval(x_ref), minval(y_ref), maxval(y_ref)
635 log_error_cont(*) x_ref(1,1), x_ref(ia_ref,1),x_ref(1,ja_ref)
636 log_error_cont(*) y_ref(1,1), y_ref(ia_ref,1),y_ref(1,ja_ref)
639 hfact(i,j,:) = 0.0_rp
651 hfact(i,j,:), idx_i(i,j,:), idx_j(i,j,:), &
672 idx_i, idx_j, hfact, &
680 integer,
intent(in) :: npoints
681 integer,
intent(in) :: ia_ref
682 integer,
intent(in) :: ja_ref
683 integer,
intent(in) :: ia
684 integer,
intent(in) :: ja
685 real(rp),
intent(in) :: lon_ref(ia_ref,ja_ref)
686 real(rp),
intent(in) :: lat_ref(ia_ref,ja_ref)
687 real(rp),
intent(in) :: lon (ia,ja)
688 real(rp),
intent(in) :: lat (ia,ja)
689 integer,
intent(out) :: idx_i(ia,ja,npoints)
690 integer,
intent(out) :: idx_j(ia,ja,npoints)
691 real(rp),
intent(out) :: hfact(ia,ja,npoints)
693 real(rp),
intent(in),
optional :: search_limit
694 logical,
intent(in),
optional :: latlon_structure
695 real(rp),
intent(in),
optional :: lon_1d(ia_ref), lat_1d(ja_ref)
696 integer,
intent(in),
optional :: weight_order
698 logical :: ll_struct_
700 real(rp) :: lon_min, lon_max
701 real(rp) :: lat_min, lat_max
702 real(rp) :: dlon, dlat
705 integer :: psizex, psizey
706 real(rp) :: lon0, lat0
707 integer,
allocatable :: i0(:), i1(:), j0(:), j1(:)
710 integer :: nsize, psize, nidx_max
711 integer,
allocatable :: idx_blk(:,:,:), nidx(:,:)
712 integer :: idx_ref(npoints)
715 integer :: i, j, ii, jj, n
720 if (
present(latlon_structure) )
then
721 ll_struct_ = latlon_structure
726 hfact(:,:,:) = 0.0_rp
729 if ( ll_struct_ )
then
731 if ( ia_ref > 10 )
then
732 psizex = int( 2.0_rp*sqrt(real(ia_ref+1,rp)) )
736 if ( ja_ref > 10 )
then
737 psizey = int( 2.0_rp*sqrt(real(ja_ref+1,rp)) )
742 allocate( i0(psizex), i1(psizex) )
743 allocate( j0(psizey), j1(psizey) )
745 dlon = ( lon_max - lon_min ) / psizex
746 dlat = ( lat_max - lat_min ) / psizey
749 lon0 = lon_min + dlon * (ii-1)
751 if ( lon_1d(i) >= lon0 )
then
758 i1(ii) = i0(ii+1) - 1
763 lat0 = lat_min + dlat * (jj-1)
765 if ( lat_1d(j) >= lat0 )
then
772 j1(jj) = j0(jj+1) - 1
783 lon_1d(:), lat_1d(:), &
786 i0(:), i1(:), j0(:), j1(:), &
787 lon(i,j), lat(i,j), &
788 idx_i(i,j,:), idx_j(i,j,:), &
790 search_limit = search_limit, &
791 weight_order = weight_order )
795 deallocate( i0, i1, j0, j1 )
799 nsize = ia_ref * ja_ref
800 if ( nsize > 100 )
then
801 psize = int( sqrt(2.0_rp*sqrt(real(nsize,rp))) )
802 nidx_max = nsize / psize * interp_buffer_size_fact
808 allocate(idx_blk(nidx_max,psize,psize))
809 allocate(nidx( psize,psize))
812 lon_ref(:,:), lat_ref(:,:), &
813 idx_blk(:,:,:), nidx(:,:), &
823 call interp_search_horiz( npoints, &
825 lon_ref(:,:), lat_ref(:,:), &
830 idx_blk(:,:,:), nidx(:,:), &
831 lon(i,j), lat(i,j), &
834 search_limit = search_limit, &
835 weight_order = weight_order )
837 idx_i(i,j,n) = mod(idx_ref(n) - 1, ia_ref) + 1
838 idx_j(i,j,n) = ( idx_ref(n) - 1 ) / ia_ref + 1
843 deallocate(idx_blk, nidx)
856 KA_ref, KS_ref, KE_ref, &
871 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
872 integer,
intent(in) :: ia_ref
873 integer,
intent(in) :: ja_ref
874 integer,
intent(in) :: ka, ks, ke
875 integer,
intent(in) :: ia
876 integer,
intent(in) :: ja
877 real(rp),
intent(in) :: lon_ref(ia_ref)
878 real(rp),
intent(in) :: lat_ref(ja_ref)
879 real(rp),
intent(in) :: hgt_ref(ka_ref,ia_ref,ja_ref)
880 real(rp),
intent(in) :: lon(ia,ja)
881 real(rp),
intent(in) :: lat(ia,ja)
882 real(rp),
intent(in) :: hgt(ka,ia,ja)
884 integer,
intent(out) :: idx_i(ia,ja,4)
885 integer,
intent(out) :: idx_j(ia,ja,4)
886 real(rp),
intent(out) :: hfact(ia,ja,4)
887 integer,
intent(out) :: idx_k(ka,2,ia,ja,4)
888 real(rp),
intent(out) :: vfact(ka, ia,ja,4)
890 logical,
intent(in),
optional :: flag_extrap
892 integer :: i, j, ii, jj, n
897 lon_ref(:), lat_ref(:), &
898 lon(:,:), lat(:,:), &
899 idx_i(:,:,:), idx_j(:,:,:), hfact(:,:,:) )
916 flag_extrap = flag_extrap )
931 KA_ref, KS_ref, KE_ref, &
946 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
947 integer,
intent(in) :: ia_ref
948 integer,
intent(in) :: ja_ref
949 integer,
intent(in) :: ka, ks, ke
950 integer,
intent(in) :: ia
951 integer,
intent(in) :: ja
952 real(rp),
intent(in) :: x_ref(ia_ref,ja_ref)
953 real(rp),
intent(in) :: y_ref(ia_ref,ja_ref)
954 real(rp),
intent(in) :: hgt_ref(ka_ref,ia_ref,ja_ref)
955 real(rp),
intent(in) :: x (ia)
956 real(rp),
intent(in) :: y (ja)
957 real(rp),
intent(in) :: hgt(ka,ia,ja)
959 integer,
intent(out) :: idx_i(ia,ja,4)
960 integer,
intent(out) :: idx_j(ia,ja,4)
961 real(rp),
intent(out) :: hfact(ia,ja,4)
962 integer,
intent(out) :: idx_k(ka,2,ia,ja,4)
963 real(rp),
intent(out) :: vfact(ka, ia,ja,4)
965 logical,
intent(in),
optional :: flag_extrap
966 logical,
intent(in),
optional :: zonal
967 logical,
intent(in),
optional :: pole
969 integer :: i, j, ii, jj, n
974 x_ref(:,:), y_ref(:,:), &
976 idx_i(:,:,:), idx_j(:,:,:), hfact(:,:,:), &
977 zonal = zonal, pole = pole )
994 flag_extrap = flag_extrap )
1009 KA_ref, KS_ref, KE_ref, &
1025 integer,
intent(in) :: npoints
1026 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
1027 integer,
intent(in) :: ia_ref
1028 integer,
intent(in) :: ja_ref
1029 integer,
intent(in) :: ka, ks, ke
1030 integer,
intent(in) :: ia
1031 integer,
intent(in) :: ja
1033 real(rp),
intent(in) :: lon_ref(ia_ref,ja_ref)
1034 real(rp),
intent(in) :: lat_ref(ia_ref,ja_ref)
1035 real(rp),
intent(in) :: hgt_ref(ka_ref,ia_ref,ja_ref)
1036 real(rp),
intent(in) :: lon (ia,ja)
1037 real(rp),
intent(in) :: lat (ia,ja)
1038 real(rp),
intent(in) :: hgt (ka,ia,ja)
1040 integer,
intent(out) :: idx_i(ia,ja,npoints)
1041 integer,
intent(out) :: idx_j(ia,ja,npoints)
1042 real(rp),
intent(out) :: hfact(ia,ja,npoints)
1043 integer,
intent(out) :: idx_k(ka,2,ia,ja,npoints)
1044 real(rp),
intent(out) :: vfact(ka, ia,ja,npoints)
1046 logical,
intent(in),
optional :: flag_extrap
1048 integer :: nsize, psize, nidx_max
1049 integer,
allocatable :: idx_blk(:,:,:), nidx(:,:)
1050 real(rp) :: lon_min, lon_max
1051 real(rp) :: lat_min, lat_max
1052 real(rp) :: dlon, dlat
1053 integer :: idx_ref(npoints)
1055 integer :: i, j, ii, jj, n
1060 nsize = ia_ref * ja_ref
1061 if ( nsize > 100 )
then
1062 psize = int( sqrt(2.0_rp*sqrt(real(nsize,rp))) )
1063 nidx_max = nsize / psize * interp_buffer_size_fact
1069 allocate(idx_blk(nidx_max,psize,psize))
1070 allocate(nidx( psize,psize))
1073 lon_ref(:,:), lat_ref(:,:), &
1074 idx_blk(:,:,:), nidx(:,:), &
1085 call interp_search_horiz( npoints, &
1087 lon_ref(:,:), lat_ref(:,:), &
1092 idx_blk(:,:,:), nidx(:,:), &
1093 lon(i,j), lat(i,j), &
1094 idx_ref(:), hfact(i,j,:) )
1097 ii = mod(idx_ref(n) - 1, ia_ref) + 1
1098 jj = ( idx_ref(n) - 1 ) / ia_ref + 1
1107 flag_extrap = flag_extrap )
1113 deallocate(idx_blk, nidx)
1124 KA_ref, KS_ref, KE_ref, &
1138 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
1139 integer,
intent(in) :: ka, ks, ke
1141 integer,
intent(in) :: idx_k(ka,2)
1142 real(rp),
intent(in) :: vfact(ka )
1143 real(rp),
intent(in) :: hgt_ref(ka_ref)
1144 real(rp),
intent(in) :: hgt (ka)
1145 real(rp),
intent(in),
target :: val_ref(ka_ref)
1147 real(rp),
intent(out) :: val (ka)
1149 logical,
intent(in),
optional :: spline
1150 logical,
intent(in),
optional :: logwgt
1155 real(rp),
pointer :: work(:)
1157 integer :: idx (ka_ref)
1158 integer :: idx_r(ka_ref)
1159 real(rp) :: fdz (ka_ref)
1160 real(rp) :: u (ka_ref)
1168 spline_ = interp_use_spline_vert
1169 if (
present(spline) )
then
1174 if (
present(logwgt) )
then
1179 allocate( work(ka_ref) )
1180 do k = ks_ref, ke_ref
1181 if ( abs( val_ref(k) - undef ) < eps )
then
1184 work(k) = log( val_ref(k) )
1191 call spline_coef( ka_ref, ks_ref, ke_ref, &
1192 hgt_ref(:), work(:), &
1199 idx_k(:,:), vfact(:), &
1200 hgt_ref(:), hgt(:), &
1209 if ( abs( val(k) - undef ) > eps )
then
1210 val(k) = exp( val(k) )
1237 integer,
intent(in) :: npoints
1238 integer,
intent(in) :: ia_ref
1239 integer,
intent(in) :: ja_ref
1240 integer,
intent(in) :: ia
1241 integer,
intent(in) :: ja
1242 integer,
intent(in) :: idx_i (ia,ja,npoints)
1243 integer,
intent(in) :: idx_j (ia,ja,npoints)
1244 real(rp),
intent(in) :: hfact (ia,ja,npoints)
1245 real(rp),
intent(in) :: val_ref(ia_ref,ja_ref)
1247 real(rp),
intent(out) :: val (ia,ja)
1249 real(rp),
intent(in),
optional :: threshold_undef
1250 real(rp),
intent(out),
optional :: wsum(ia,ja)
1251 real(rp),
intent(out),
optional :: val2(ia,ja)
1253 real(rp) :: th_undef
1255 real(rp) :: fact, valn, f, w
1264 if (
present(threshold_undef) )
then
1265 th_undef = threshold_undef
1267 th_undef = interp_threshold_undef
1269 th_undef = min( max( th_undef, eps * 2.0_rp ), 1.0_rp - eps * 2.0_rp )
1271 lval2 =
present(wsum) .and.
present(val2)
1282 w = val_ref(idx_i(i,j,n),idx_j(i,j,n))
1283 if ( f > eps .and. abs( w - undef ) > eps )
then
1288 sw = 0.5_rp - sign( 0.5_rp, fact - th_undef + eps )
1289 val(i,j) = valn / ( fact + sw ) * ( 1.0_rp - sw ) + undef * sw
1292 sw = 0.5_rp - sign( 0.5_rp, fact - eps )
1293 val2(i,j) = valn / ( fact + sw ) * ( 1.0_rp - sw ) + undef * sw
1307 KA_ref, KS_ref, KE_ref, &
1326 integer,
intent(in) :: npoints
1327 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
1328 integer,
intent(in) :: ia_ref
1329 integer,
intent(in) :: ja_ref
1330 integer,
intent(in) :: ka, ks, ke
1331 integer,
intent(in) :: ia
1332 integer,
intent(in) :: ja
1334 integer,
intent(in) :: idx_i (ia,ja,npoints)
1335 integer,
intent(in) :: idx_j (ia,ja,npoints)
1336 real(rp),
intent(in) :: hfact (ia,ja,npoints)
1337 integer,
intent(in) :: idx_k (ka,2,ia,ja,npoints)
1338 real(rp),
intent(in) :: vfact (ka, ia,ja,npoints)
1339 real(rp),
intent(in) :: hgt_ref(ka_ref,ia_ref,ja_ref)
1340 real(rp),
intent(in) :: hgt (ka,ia,ja)
1341 real(rp),
intent(in),
target :: val_ref(ka_ref,ia_ref,ja_ref)
1343 real(rp),
intent(out) :: val (ka,ia,ja)
1345 logical,
intent(in),
optional :: spline
1346 logical,
intent(in),
optional :: logwgt
1347 real(rp),
intent(in),
optional :: threshold_undef
1348 real(rp),
intent(out),
optional :: wsum(ka,ia,ja)
1349 real(rp),
intent(out),
optional :: val2(ka,ia,ja)
1351 real(rp) :: th_undef
1355 real(rp),
pointer :: work(:,:,:)
1357 integer,
allocatable :: kmax(:,:)
1358 integer,
allocatable :: idx(:,:,:), idx_r(:,:,:)
1359 real(rp),
allocatable :: u(:,:,:), fdz(:,:,:)
1365 real(rp) :: w(ka,npoints)
1368 integer :: imin, imax
1369 integer :: jmin, jmax
1371 integer :: k, i, j, n
1376 if (
present(threshold_undef) )
then
1377 th_undef = threshold_undef
1379 th_undef = interp_threshold_undef
1381 th_undef = min( max( th_undef, eps * 2.0_rp ), 1.0_rp - eps * 2.0_rp )
1384 spline_ = interp_use_spline_vert
1385 if (
present(spline) )
then
1390 if (
present(logwgt) )
then
1395 lval2 =
present(wsum) .and.
present(val2)
1408 imin = min(imin, idx_i(i,j,n))
1409 imax = max(imax, idx_i(i,j,n))
1410 jmin = min(jmin, idx_j(i,j,n))
1411 jmax = max(jmax, idx_j(i,j,n))
1416 allocate( kmax(imin:imax,jmin:jmax) )
1417 allocate( idx(ka_ref,imin:imax,jmin:jmax), idx_r(ka_ref,imin:imax,jmin:jmax) )
1418 allocate( u(ka_ref,imin:imax,jmin:jmax), fdz(ka_ref,imin:imax,jmin:jmax) )
1421 allocate( work(ka_ref,imin:imax,jmin:jmax) )
1425 do k = ks_ref, ke_ref
1426 if ( abs( val_ref(k,i,j) - undef ) < eps )
then
1429 work(k,i,j) = log( val_ref(k,i,j) )
1441 call spline_coef( ka_ref, ks_ref, ke_ref, &
1442 hgt_ref(:,i,j), work(:,i,j), &
1445 idx(:,i,j), idx_r(:,i,j), &
1446 u(:,i,j), fdz(:,i,j) )
1456 if ( hfact(i,j,n) < eps )
exit
1459 call spline_exec( ka_ref, kmax(ii,jj), ka, ks, ke, &
1460 idx_k(:,:,i,j,n), vfact(:, i,j,n), &
1461 hgt_ref(:,ii,jj), hgt(:,i,j), &
1463 idx(:,ii,jj), idx_r(:,ii,jj), &
1464 u(:,ii,jj), fdz(:,ii,jj), &
1473 if ( f > eps .and. abs( w(k,n) - undef ) > eps )
then
1475 valn = valn + f * w(k,n)
1478 sw = 0.5_rp - sign( 0.5_rp, fact - th_undef )
1479 val(k,i,j) = valn / ( fact + sw ) * ( 1.0_rp - sw ) + undef * sw
1482 sw = 0.5_rp - sign( 0.5_rp, fact - eps )
1483 val2(k,i,j) = valn / ( fact + sw ) * ( 1.0_rp - sw ) + undef * sw
1490 deallocate( kmax, idx, idx_r )
1491 deallocate( u, fdz )
1499 if ( abs( val(k,i,j) - undef ) > eps )
then
1500 val(k,i,j) = exp( val(k,i,j) )
1519 subroutine interp_search_horiz( &
1538 integer,
intent(in) :: npoints
1539 integer,
intent(in) :: nsize
1540 real(rp),
intent(in) :: lon_ref(nsize)
1541 real(rp),
intent(in) :: lat_ref(nsize)
1542 real(rp),
intent(in) :: lon_min
1543 real(rp),
intent(in) :: lon_max
1544 real(rp),
intent(in) :: lat_min
1545 real(rp),
intent(in) :: lat_max
1546 integer,
intent(in) :: psize
1547 integer,
intent(in) :: nidx_max
1548 real(rp),
intent(in) :: dlon
1549 real(rp),
intent(in) :: dlat
1550 integer,
intent(in) :: idx_blk(nidx_max,psize,psize)
1551 integer,
intent(in) :: nidx (psize,psize)
1552 real(rp),
intent(in) :: lon
1553 real(rp),
intent(in) :: lat
1554 integer,
intent(out) :: idx_ref(npoints)
1555 real(rp),
intent(out) :: hfact(npoints)
1557 real(rp),
intent(in),
optional :: search_limit
1558 integer,
intent(in),
optional :: weight_order
1560 real(rp) :: drad(npoints)
1562 real(rp) :: search_limit_
1563 integer :: weight_order_
1565 real(rp) :: lon0, lon1, lat0, lat1
1566 real(rp) :: dlon_sl, dlat_sl
1568 integer :: ii, jj, ii0, jj0
1571 if (
present(search_limit) )
then
1572 search_limit_ = search_limit
1574 search_limit_ = interp_search_limit
1576 search_limit_ = search_limit_ / radius
1578 if (
present(weight_order) )
then
1579 weight_order_ = weight_order
1581 weight_order_ = interp_weight_order
1586 drad(:) = large_number
1590 ii0 = max( min( int(( lon - lon_min ) / dlon) + 1, psize ), 1 )
1591 jj0 = max( min( int(( lat - lat_min ) / dlat) + 1, psize ), 1 )
1592 do i = 1, nidx(ii0,jj0)
1593 n = idx_blk(i,ii0,jj0)
1594 call interp_insert( npoints, &
1596 lon_ref(n), lat_ref(n), &
1598 drad(:), idx_ref(:) )
1601 if ( abs(drad(1)) < eps )
then
1606 else if ( drad(1) > search_limit_ )
then
1613 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
1614 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
1616 lat0 = lat_min + dlat * (jj-1)
1617 lat1 = lat_min + dlat * jj
1618 if ( lat < lat0 - dlat_sl &
1619 .or. lat >= lat1 + dlat_sl ) cycle
1621 if ( ii==ii0 .and. jj==jj0 ) cycle
1622 lon0 = lon_min + dlon * (ii-1)
1623 lon1 = lon_min + dlon * ii
1624 if ( lon < lon0 - dlon_sl &
1625 .or. lon >= lon1 + dlon_sl ) cycle
1626 do i = 1, nidx(ii,jj)
1627 n = idx_blk(i,ii,jj)
1628 call interp_insert( npoints, &
1630 lon_ref(n), lat_ref(n), &
1632 drad(:), idx_ref(:) )
1634 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
1635 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
1640 if ( weight_order_ < 0 )
then
1642 hfact(n) = 1.0_rp / drad(n)**(-1.0_rp/weight_order_)
1646 hfact(n) = 1.0_rp / drad(n)**weight_order_
1652 if ( drad(n) >= search_limit_ )
then
1660 sum = sum + hfact(n)
1663 if ( sum > 0.0_rp )
then
1665 hfact(n) = hfact(n) / sum
1670 end subroutine interp_search_horiz
1693 integer,
intent(in) :: npoints
1694 integer,
intent(in) :: psizex
1695 integer,
intent(in) :: psizey
1696 integer,
intent(in) :: IA_ref
1697 integer,
intent(in) :: JA_ref
1698 real(RP),
intent(in) :: lon_ref(IA_ref)
1699 real(RP),
intent(in) :: lat_ref(JA_ref)
1700 real(RP),
intent(in) :: lon_min
1701 real(RP),
intent(in) :: lat_min
1702 real(RP),
intent(in) :: dlon
1703 real(RP),
intent(in) :: dlat
1704 integer,
intent(in) :: i0(psizex)
1705 integer,
intent(in) :: i1(psizex)
1706 integer,
intent(in) :: j0(psizey)
1707 integer,
intent(in) :: j1(psizey)
1708 real(RP),
intent(in) :: lon
1709 real(RP),
intent(in) :: lat
1710 integer,
intent(out) :: idx_i(npoints)
1711 integer,
intent(out) :: idx_j(npoints)
1712 real(RP),
intent(out) :: hfact(npoints)
1714 real(RP),
intent(in),
optional :: search_limit
1715 integer,
intent(in),
optional :: weight_order
1717 real(RP) :: drad(npoints)
1719 real(RP) :: search_limit_
1720 integer :: weight_order_
1722 real(RP) :: lon0, lon1, lat0, lat1
1723 real(RP) :: dlon_sl, dlat_sl
1726 integer :: ii, jj, ii0, jj0
1729 if (
present(search_limit) )
then
1730 search_limit_ = search_limit
1732 search_limit_ = interp_search_limit
1734 search_limit_ = search_limit_ / radius
1736 if (
present(weight_order) )
then
1737 weight_order_ = weight_order
1739 weight_order_ = interp_weight_order
1743 drad(:) = large_number
1748 ii0 = max( min( int(( lon - lon_min ) / dlon) + 1, psizex ), 1)
1749 jj0 = max( min( int(( lat - lat_min ) / dlat) + 1, psizey ), 1)
1750 do j = j0(jj0), j1(jj0)
1751 do i = i0(ii0), i1(ii0)
1754 lon_ref(i), lat_ref(j), &
1756 drad(:), idx_i(:), idx_j(:) )
1760 if ( abs(drad(1)) < eps )
then
1765 else if ( drad(1) > search_limit_ )
then
1773 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
1774 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
1776 lat0 = lat_min + dlat * (jj-1)
1777 lat1 = lat_min + dlat * jj
1778 if ( lat < lat0 - dlat_sl &
1779 .or. lat >= lat1 + dlat_sl ) cycle
1781 if ( ii==ii0 .and. jj==jj0 ) cycle
1782 lon0 = lon_min + dlon * (ii-1)
1783 lon1 = lon_min + dlon * ii
1784 if ( lon < lon0 - dlon_sl &
1785 .or. lon >= lon1 + dlon_sl ) cycle
1786 do j = j0(jj0), j1(jj0)
1787 do i = i0(ii0), i1(ii0)
1790 lon_ref(i), lat_ref(j), &
1792 drad(:), idx_i(:), idx_j(:) )
1795 dlon_sl = max(dlon * 0.5_rp, drad(npoints))
1796 dlat_sl = max(dlat * 0.5_rp, drad(npoints))
1802 if ( weight_order_ < 0 )
then
1804 hfact(n) = 1.0_rp / drad(n)**(-1.0_rp/weight_order_)
1808 hfact(n) = 1.0_rp / drad(n)**weight_order_
1814 if ( drad(n) >= search_limit_ )
then
1822 sum = sum + hfact(n)
1825 if ( sum > 0.0_rp )
then
1827 hfact(n) = hfact(n) / sum
1836 subroutine interp_insert( npoints, &
1847 integer,
intent(in) :: npoints
1848 real(RP),
intent(in) :: lon, lat
1849 real(RP),
intent(in) :: lon_ref, lat_ref
1850 integer,
intent(in) :: i
1852 real(RP),
intent(inout) :: drad(npoints)
1853 integer,
intent(inout) :: idx_i(npoints)
1857 if ( abs( lon_ref - undef ) < eps )
return
1859 dradian = haversine( lon, lat, lon_ref, lat_ref )
1861 if ( dradian <= drad(npoints) )
then
1863 drad(npoints) = dradian
1867 call sort_exec( npoints, &
1873 end subroutine interp_insert
1880 drad, idx_i, idx_j )
1887 integer,
intent(in) :: npoints
1888 real(RP),
intent(in) :: lon, lat
1889 real(RP),
intent(in) :: lon_ref, lat_ref
1890 integer,
intent(in) :: i, j
1892 real(RP),
intent(inout) :: drad(npoints)
1893 integer,
intent(inout) :: idx_i(npoints)
1894 integer,
intent(inout) :: idx_j(npoints)
1898 if ( abs( lon_ref - undef ) < eps )
return
1900 dradian = haversine( lon, lat, lon_ref, lat_ref )
1902 if ( dradian <= drad(npoints) )
then
1904 drad(npoints) = dradian
1909 call sort_exec( npoints, &
1930 integer,
intent(in) :: nsize
1931 integer,
intent(in) :: psize
1932 integer,
intent(in) :: nidx_max
1933 real(RP),
intent(in) :: lon_ref(nsize)
1934 real(RP),
intent(in) :: lat_ref(nsize)
1936 integer,
intent(out) :: idx (nidx_max,psize,psize)
1937 integer,
intent(out) :: nidx(psize,psize)
1938 real(RP),
intent(out) :: lon_min, lon_max
1939 real(RP),
intent(out) :: lat_min, lat_max
1940 real(RP),
intent(out) :: dlon, dlat
1942 integer :: i, ii, jj, n
1944 lon_min = minval(lon_ref(:), mask=abs(lon_ref-undef)>eps)
1945 lon_max = maxval(lon_ref(:), mask=abs(lon_ref-undef)>eps)
1946 lat_min = minval(lat_ref(:), mask=abs(lat_ref-undef)>eps)
1947 lat_max = maxval(lat_ref(:), mask=abs(lat_ref-undef)>eps)
1949 dlon = ( lon_max - lon_min ) / psize
1950 dlat = ( lat_max - lat_min ) / psize
1954 if ( abs( lon_ref(i) - undef ) < eps ) cycle
1955 ii = min(int((lon_ref(i) - lon_min) / dlon) + 1, psize)
1956 jj = min(int((lat_ref(i) - lat_min) / dlat) + 1, psize)
1959 if ( n <= nidx_max ) idx(n,ii,jj) = i
1962 if ( maxval(nidx) > nidx_max )
then
1963 log_error(
"INTERP_search_horiz",*)
'Buffer size is not enough'
1964 log_error_cont(*)
' Use larger INTERP_buffer_size_fact: ', interp_buffer_size_fact * maxval(nidx)/nidx_max
1973 x_ref0, x_ref1, x_ref2, x_ref3, &
1974 y_ref0, y_ref1, y_ref2, y_ref3, &
1979 real(RP),
intent(in) :: x_ref0, x_ref1, x_ref2, x_ref3
1980 real(RP),
intent(in) :: y_ref0, y_ref1, y_ref2, y_ref3
1981 real(RP),
intent(in) :: x, y
1983 real(RP),
intent(out) :: u, v
1984 logical,
intent(out) :: error
1986 real(RP) :: e_x, e_y
1987 real(RP) :: f_x, f_y
1988 real(RP) :: g_x, g_y
1989 real(RP) :: h_x, h_y
1990 real(RP) :: k0, k1, k2
1994 e_x = x_ref1 - x_ref0
1995 e_y = y_ref1 - y_ref0
1997 f_x = x_ref3 - x_ref0
1998 f_y = y_ref3 - y_ref0
2000 g_x = x_ref0 - x_ref1 + x_ref2 - x_ref3
2001 g_y = y_ref0 - y_ref1 + y_ref2 - y_ref3
2006 k0 =
cross(h_x, h_y, e_x, e_y)
2007 k1 =
cross(e_x, e_y, f_x, f_y) +
cross(h_x, h_y, g_x, g_y)
2008 k2 =
cross(g_x, g_y, f_x, f_y)
2010 w = k1**2 - 4.0_rp * k0 * k2
2011 if ( w < 0.0_rp )
then
2012 log_error(
"INTERP_bilinear_inv",*)
'Outside of the quadrilateral'
2017 if ( abs(k1) < eps_bilinear )
then
2018 log_error(
"INTERP_bilinear_inv",*)
'Unexpected error occured', k1
2019 log_error_cont(*) x_ref0, x_ref1, x_ref2, x_ref3
2020 log_error_cont(*) y_ref0, y_ref1, y_ref2, y_ref3
2021 log_error_cont(*) x, y
2025 if ( abs(k2) < eps_bilinear * sqrt( (x_ref2-x_ref0)**2+(y_ref2-y_ref0)**2 ) )
then
2028 sig = sign( 1.0_rp,
cross(x_ref1-x_ref0, y_ref1-y_ref0, x_ref3-x_ref0, y_ref3-y_ref0) )
2029 v = ( - k1 + sig * sqrt(w) ) / ( 2.0_rp * k2 )
2031 u = ( h_x - f_x * v ) / ( e_x + g_x * v )
2033 if ( u < -eps_bilinear .or. u > 1.0_rp+eps_bilinear .or. v < -eps_bilinear .or. v > 1.0_rp+eps_bilinear )
then
2034 log_error(
"INTERP_bilinear_inv",*)
'Unexpected error occured', u, v
2035 log_error_cont(*) x_ref0, x_ref1, x_ref2, x_ref3
2036 log_error_cont(*) y_ref0, y_ref1, y_ref2, y_ref3
2037 log_error_cont(*) x, y
2038 log_error_cont(*) k0, k1, k2, sig
2042 u = min( max( u, 0.0_rp ), 1.0_rp )
2043 v = min( max( v, 0.0_rp ), 1.0_rp )
2052 subroutine interp_check_inside( &
2053 x_ref0, x_ref1, x_ref2, x_ref3, &
2054 y_ref0, y_ref1, y_ref2, y_ref3, &
2061 real(RP),
intent(in) :: x_ref0, x_ref1, x_ref2, x_ref3
2062 real(RP),
intent(in) :: y_ref0, y_ref1, y_ref2, y_ref3
2063 real(RP),
intent(in) :: x, y
2065 integer,
intent(out) :: inc_i, inc_j
2066 logical,
intent(out) :: error
2069 real(RP) :: c1, c2, c3, c4
2075 sig = sign( 1.0_rp,
cross(x_ref1-x_ref0, y_ref1-y_ref0, x_ref3-x_ref0, y_ref3-y_ref0) )
2077 c1 = sig *
cross(x_ref1-x_ref0, y_ref1-y_ref0, x-x_ref0, y-y_ref0)
2078 c2 = sig *
cross(x_ref2-x_ref1, y_ref2-y_ref1, x-x_ref1, y-y_ref1)
2079 c3 = sig *
cross(x_ref3-x_ref2, y_ref3-y_ref2, x-x_ref2, y-y_ref2)
2080 c4 = sig *
cross(x_ref0-x_ref3, y_ref0-y_ref3, x-x_ref3, y-y_ref3)
2082 th = - max( abs(c1), abs(c2), abs(c3), abs(c4) ) * eps * 1.e4_rp
2087 if ( c1 < th ) inc_j = -1
2088 if ( c2 < th ) inc_i = 1
2089 if ( c3 < th ) inc_j = 1
2090 if ( c4 < th ) inc_i = -1
2092 fx = c2 < th .and. c4 < th
2093 fy = c1 < th .and. c3 < th
2094 if ( fx .and. fy )
then
2095 log_error(
"INTERP_check_inside",*)
'Unexpected error occured', c1, c2, c3, c4
2096 log_error_cont(*) x_ref0, x_ref1, x_ref2, x_ref3
2097 log_error_cont(*) y_ref0, y_ref1, y_ref2, y_ref3
2098 log_error_cont(*) x, y
2108 end subroutine interp_check_inside
2116 real(rp),
intent(in) :: x0, y0
2117 real(rp),
intent(in) :: x1, y1
2120 cross = x0 * y1 - x1 * y0
2127 function haversine( &
2133 real(rp),
intent(in) :: lon0
2134 real(rp),
intent(in) :: lat0
2135 real(rp),
intent(in) :: lon1
2136 real(rp),
intent(in) :: lat1
2139 real(rp) :: dlonh, dlath
2143 dlonh = 0.5_rp * ( lon0 - lon1 )
2144 dlath = 0.5_rp * ( lat0 - lat1 )
2146 work1 = sin(dlath)**2 + cos(lat0) * cos(lat1) * sin(dlonh)**2
2148 d = 2.0_rp * asin( min(sqrt(work1),1.0_rp) )
2150 end function haversine
2154 subroutine spline_coef( &
2155 KA_ref, KS_ref, KE_ref, &
2165 matrix_solver_tridiagonal
2167 integer,
intent(in) :: ka_ref, ks_ref, ke_ref
2169 real(rp),
intent(in) :: hgt_ref(ka_ref)
2170 real(rp),
intent(in) :: val_ref(ka_ref)
2171 logical,
intent(in) :: spline
2173 integer,
intent(out) :: kmax
2174 integer,
intent(out) :: idx (ka_ref)
2175 integer,
intent(out) :: idx_r(ka_ref)
2176 real(rp),
intent(out) :: u (ka_ref)
2177 real(rp),
intent(out) :: fdz(ka_ref)
2179 real(rp) :: md(ka_ref)
2180 real(rp) :: v (ka_ref)
2188 do k = ks_ref, ke_ref-1
2189 if ( abs( val_ref(k) - undef ) > eps )
then
2195 if ( idx(1) == -999 )
return
2197 do k = idx(1)+1, ke_ref
2198 dz = hgt_ref(k) - hgt_ref(idx(kmax))
2199 if ( abs( val_ref(k) - undef ) > eps .and. dz > eps )
then
2200 do while ( kmax > 1 .and. fdz(kmax) < dz * 0.1_rp )
2205 if ( idx(kmax-1)+1 <= k-1 ) idx_r(idx(kmax-1)+1:k-1) = kmax-1
2207 fdz(kmax) = hgt_ref(k) - hgt_ref(idx(kmax-1))
2211 if ( kmax > 3 )
then
2213 md(2) = 2.0_rp * ( fdz(2) + fdz(3) ) + fdz(2)
2215 md(k) = 2.0_rp * ( fdz(k) + fdz(k+1) )
2217 md(kmax-1) = 2.0_rp * ( fdz(kmax-1) + fdz(kmax) ) + fdz(kmax)
2220 v(k) = ( val_ref(idx(k+1)) - val_ref(idx(k )) ) / fdz(k+1) &
2221 - ( val_ref(idx(k )) - val_ref(idx(k-1)) ) / fdz(k )
2224 call matrix_solver_tridiagonal( kmax, 2, kmax-1, &
2225 fdz(2:), md(:), fdz(:), &
2247 end subroutine spline_coef
2251 KA_ref, kmax, KA, KS, KE, &
2262 integer,
intent(in) :: KA_ref, kmax
2263 integer,
intent(in) :: KA, KS, KE
2264 integer,
intent(in) :: idx_k(KA,2)
2265 real(RP),
intent(in) :: vfact(KA)
2266 real(RP),
intent(in) :: hgt_ref(KA_ref)
2267 real(RP),
intent(in) :: hgt (KA)
2268 real(RP),
intent(in) :: val_ref(KA_ref)
2269 integer,
intent(in) :: idx (KA_ref)
2270 integer,
intent(in) :: idx_r (KA_ref)
2271 real(RP),
intent(in) :: U (KA_ref)
2272 real(RP),
intent(in) :: FDZ (KA_ref)
2274 real(RP),
intent(out) :: val(KA)
2276 real(RP) :: c1, c2, c3, d
2277 integer :: k, kk, kk2
2281 if ( kk == -1 )
then
2283 else if ( idx_k(k,2) == -1 )
then
2284 val(k) = val_ref(kk)
2285 else if ( kk < idx(1) .or. kk >= idx(kmax) )
then
2286 if ( abs( val_ref(kk) - undef ) < eps .or. abs( val_ref(kk+1) - undef ) < eps )
then
2289 val(k) = val_ref(kk) * vfact(k) + val_ref(kk+1) * ( 1.0_rp - vfact(k) )
2294 c3 = ( u(kk2+1) - u(kk2) ) / fdz(kk2+1)
2295 c2 = 3.0_rp * u(kk2)
2296 c1 = ( val_ref(idx(kk2+1)) - val_ref(kk) ) / fdz(kk2+1) - ( 2.0_rp * u(kk2) + u(kk2+1) ) * fdz(kk2+1)
2297 d = hgt(k) - hgt_ref(kk)
2299 val(k) = ( ( c3 * d + c2 ) * d + c1 ) * d + val_ref(kk)