Oasis3 4.0.2
|
00001 MODULE remap_bicubic_reduced 00002 00003 !----------------------------------------------------------------------- 00004 ! BOP 00005 ! 00006 ! !MODULE: remap_bicubic_reduced 00007 ! 00008 ! !USES: 00009 USE mod_kinds_oasis ! defines common data types 00010 USE constants ! defines common constants 00011 USE grids ! module containing grid info 00012 USE remap_vars ! module containing remap info 00013 00014 ! !PUBLIC TYPES: 00015 USE mod_unit 00016 IMPLICIT NONE 00017 ! !PUBLIC MEMBER FUNCTIONS: 00018 ! 00019 ! !PUBLIC DATA MEMBERS: 00020 00021 ! !DESCRIPTION: 00022 ! This routine computes the weights for a bicubic interpolation 00023 ! with a reduced grid. Computes mappings from grid1 to grid2. 00024 ! 00025 ! !REVISION HISTORY: 00026 ! 2002.10.21 J.Ghattas created 00027 ! 00028 ! EOP 00029 !----------------------------------------------------------------------- 00030 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 00031 ! $Author: coquart $ 00032 !----------------------------------------------------------------------- 00033 00034 00035 00036 CONTAINS 00037 00038 !*********************************************************************** 00039 00040 00041 !----------------------------------------------------------------------- 00042 ! BOP 00043 ! 00044 ! !IROUTINE: remap_bicub_reduced 00045 ! 00046 ! !INTERFACE: 00047 00048 SUBROUTINE remap_bicub_reduced(ld_extrapdone) 00049 00050 ! !USES: 00051 00052 ! !RETURN VALUE: 00053 00054 ! !PARAMETERS: 00055 00056 LOGICAL, INTENT(in) :: 00057 ld_extrapdone ! logical, true if EXTRAP done on field 00058 LOGICAL :: 00059 ll_nnei ! true if extra search is done 00060 00061 INTEGER (KIND=ip_intwp_p), DIMENSION(4,4) :: 00062 ila_src_add ! address for source points non-masked 00063 00064 INTEGER (KIND=ip_intwp_p), DIMENSION(4) :: 00065 ila_nbr_found ! nrb of points found on each latitude 00066 00067 INTEGER (KIND=ip_intwp_p) :: 00068 ib_i, ! iter index 00069 ib_dst_add, ! destination address, target point 00070 il_count, ! nbr of latitudes with found points 00071 il_min, il_max, bin ! begin and end for distances calculation 00072 00073 REAL (KIND=ip_realwp_p), DIMENSION(4,4) :: 00074 rla_src_lons, ! longitudes for the points 'ila_src_add' 00075 rla_weight, ! bicubic weights for the points 'ila_src_add' 00076 rla_wght_lon ! temp. weights 00077 00078 REAL (KIND=ip_realwp_p), DIMENSION(4) :: 00079 rla_src_lats, ! latitudes for the points 'ila_src_add' 00080 rla_lats_temp, ! temp. latitudes 00081 rla_wght_lat, rla_wght_temp! temp. weights 00082 00083 REAL (KIND=ip_realwp_p) :: 00084 rl_plat, rl_plon ! latitude and longitude for destination address 00085 00086 REAL (KIND=ip_realwp_p) :: ! variables for distances calculation 00087 rl_coslat_dst, rl_sinlat_dst, 00088 rl_coslon_dst, rl_sinlon_dst, 00089 rl_distance, arg 00090 00091 REAL (KIND=ip_realwp_p), DIMENSION(2) :: 00092 rla_dist ! lat distances to point cible 00093 00094 INTEGER (KIND=ip_intwp_p), DIMENSION(4) :: 00095 ila_add_dist ! temporary addr. for distances 00096 00097 LOGICAL :: ll_linear ! flag 00098 00099 00100 ! !DESCRIPTION: 00101 ! This routine computes the weights for a bicubic interpolation 00102 ! with a reduced grid. Computes mappings from grid1 to grid2. 00103 ! 00104 ! !REVISION HISTORY: 00105 ! 2002.10.21 J.Ghattas created 00106 ! 00107 ! EOP 00108 !----------------------------------------------------------------------- 00109 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 00110 ! $Author: coquart $ 00111 !----------------------------------------------------------------------- 00112 ! 00113 IF (nlogprt .GE. 2) THEN 00114 WRITE (UNIT = nulou,FMT = *)' ' 00115 WRITE (UNIT = nulou,FMT = *) 'Entering routine remap_bicub_reduced' 00116 CALL FLUSH(nulou) 00117 ENDIF 00118 ! 00119 ll_nnei = .true. 00120 ! 00121 ! Loop over destination grid 00122 ! 00123 00124 DO ib_dst_add = 1, grid2_size ! for each target point 00125 ll_linear=.false. 00126 IF (.NOT. grid2_mask(ib_dst_add)) THEN 00127 CYCLE ! target point is masked 00128 END IF 00129 00130 rl_plat = grid2_center_lat(ib_dst_add) 00131 rl_plon = grid2_center_lon(ib_dst_add) 00132 00133 00134 ! 00135 ! Search for non-masked points among the closest 16 points 00136 ! on source grid (grid1) 00137 ! 00138 00139 CALL grid_search_16_points(ila_src_add, rla_src_lats, rla_src_lons,& 00140 ila_nbr_found, bin, rl_plat, & 00141 rl_plon, ld_extrapdone) 00142 00143 00144 ! 00145 ! If there is no point found, search the neaerst 00146 ! non-masked point 00147 ! 00148 00149 IF (SUM(ila_nbr_found)==0) THEN 00150 IF (ll_nnei .eqv. .TRUE. ) THEN 00151 IF (nlogprt .GE. 2) THEN 00152 WRITE(nulou,*) ' ' 00153 WRITE(nulou,*) & 00154 'All 16 surrounding source grid points are masked' 00155 WRITE(nulou,*) 'for target point ',ib_dst_add 00156 WRITE(nulou,*) 'with longitude and latitude', rl_plon, rl_plat 00157 WRITE(nulou,*) 'Using the nearest non-masked neighbour.' 00158 WRITE(nulou,*) ' ' 00159 CALL FLUSH(nulou) 00160 ENDIF 00161 00162 ! Search the nearest point in bin [il_min:il_max] 00163 IF (bin==0 .or. bin==1) THEN 00164 il_min=1 00165 il_max=bin_addr1_r(2,3) 00166 ELSE IF (bin==num_srch_red .or. bin==num_srch_red-1) THEN 00167 il_min=bin_addr1_r(1,num_srch_red-2) 00168 il_max=bin_addr1_r(2,num_srch_red) 00169 ELSE 00170 il_min=bin_addr1_r(1,bin-1)+1 00171 il_max=bin_addr1_r(2,bin+2) 00172 END IF 00173 00174 rl_coslat_dst = COS(rl_plat) 00175 rl_sinlat_dst = SIN(rl_plat) 00176 rl_coslon_dst = COS(rl_plon) 00177 rl_sinlon_dst = SIN(rl_plon) 00178 00179 rla_weight(1,1) = bignum 00180 ila_src_add(1,1) = 0 00181 !cdir novector 00182 DO ib_i=il_min, il_max 00183 IF (grid1_mask(ib_i) .or. ld_extrapdone) THEN 00184 arg = rl_coslat_dst*COS(grid1_center_lat(ib_i))* & 00185 (rl_coslon_dst*COS(grid1_center_lon(ib_i)) + & 00186 rl_sinlon_dst*SIN(grid1_center_lon(ib_i)))+& 00187 rl_sinlat_dst*SIN(grid1_center_lat(ib_i)) 00188 IF (arg < -1.0d0) THEN 00189 arg = -1.0d0 00190 ELSE IF (arg > 1.0d0) THEN 00191 arg = 1.0d0 00192 END IF 00193 rl_distance = ACOS(arg) 00194 IF (rl_distance < rla_weight(1,1)) THEN 00195 rla_weight(1,1) = rl_distance 00196 ila_src_add(1,1) = ib_i 00197 END IF 00198 END IF 00199 END DO 00200 rla_weight(:,:) = 0 00201 rla_weight(1,1) = 1 00202 00203 CALL store_link_bicub(ib_dst_add, ila_src_add, rla_weight) 00204 IF (nlogprt .GE. 2) THEN 00205 WRITE(nulou,*) & 00206 'Nearest non masked neighbour is source point ', & 00207 ila_src_add(1,1) 00208 WRITE(nulou,*) 'with longitude and latitude', & 00209 grid1_center_lon(ila_src_add(1,1)), & 00210 grid1_center_lat(ila_src_add(1,1)) 00211 WRITE(nulou,*) ' ' 00212 ENDIF 00213 CYCLE 00214 END IF 00215 ENDIF 00216 00217 rla_weight(:,:) = 0 00218 ! if there is only one point found, save it 00219 IF (SUM(ila_nbr_found)==1) THEN 00220 DO ib_i=1,4 00221 IF (ila_nbr_found(ib_i)==1) THEN 00222 rla_weight(ib_i,1)=1 00223 EXIT 00224 END IF 00225 END DO 00226 CALL store_link_bicub(ib_dst_add, ila_src_add, rla_weight) 00227 CYCLE 00228 END IF 00229 00230 ! if there are only 2 points found, distance weighted average 00231 IF (SUM(ila_nbr_found)==2) THEN 00232 rl_coslat_dst = COS(rl_plat) 00233 rl_sinlat_dst = SIN(rl_plat) 00234 rl_coslon_dst = COS(rl_plon) 00235 rl_sinlon_dst = SIN(rl_plon) 00236 00237 rl_distance=0 ! count of total distance 00238 DO ib_i=1,4 00239 IF (ila_nbr_found(ib_i) > 0) THEN 00240 arg = rl_coslat_dst*COS(rla_src_lats(ib_i))* & 00241 (rl_coslon_dst*COS(rla_src_lons(ib_i,1)) + & 00242 rl_sinlon_dst*SIN(rla_src_lons(ib_i,1)))+& 00243 rl_sinlat_dst*SIN(rla_src_lats(ib_i)) 00244 IF (arg < -1.0d0) THEN 00245 arg = -1.0d0 00246 ELSE IF (arg > 1.0d0) THEN 00247 arg = 1.0d0 00248 END IF 00249 rla_weight(ib_i,1) = ACOS(arg) 00250 rl_distance = rl_distance+rla_weight(ib_i,1) 00251 IF (ila_nbr_found(ib_i)==2) THEN 00252 arg = rl_coslat_dst*COS(rla_src_lats(ib_i))* & 00253 (rl_coslon_dst*COS(rla_src_lons(ib_i,2)) + & 00254 rl_sinlon_dst*SIN(rla_src_lons(ib_i,2)))+& 00255 rl_sinlat_dst*SIN(rla_src_lats(ib_i)) 00256 IF (arg < -1.0d0) THEN 00257 arg = -1.0d0 00258 ELSE IF (arg > 1.0d0) THEN 00259 arg = 1.0d0 00260 END IF 00261 rla_weight(ib_i,2) = ACOS(arg) 00262 rl_distance = rl_distance+rla_weight(ib_i,2) 00263 END IF 00264 END IF 00265 END DO 00266 rla_weight=rla_weight/rl_distance 00267 00268 CALL store_link_bicub(ib_dst_add, ila_src_add, rla_weight) 00269 CYCLE 00270 END IF 00271 00272 ! Some case exceptional when just one point per line found 00273 00274 IF (ila_nbr_found(1)==1) THEN ! elimination of point 00275 ila_nbr_found(1)=0 00276 ila_src_add(1,1)=0 00277 END IF 00278 IF (ila_nbr_found(4)==1) THEN 00279 ila_nbr_found(4)=0 00280 ila_src_add(4,1)=0 00281 END IF 00282 00283 00284 00285 IF (ila_nbr_found(2)==1 .OR. ila_nbr_found(3)==1) THEN 00286 ila_add_dist(:)=4 00287 rla_dist(:)=bignum 00288 00289 ! search for the 2 nearest points or line of points 00290 DO ib_i=1,4 00291 IF (ila_nbr_found(ib_i) > 1) THEN 00292 rl_distance=ABS(rla_src_lats(ib_i)-rl_plat) 00293 ELSE IF (ila_nbr_found(ib_i)==1) THEN 00294 rl_coslat_dst = COS(rl_plat) 00295 rl_sinlat_dst = SIN(rl_plat) 00296 rl_coslon_dst = COS(rl_plon) 00297 rl_sinlon_dst = SIN(rl_plon) 00298 arg = rl_coslat_dst*COS(rla_src_lats(ib_i))* & 00299 (rl_coslon_dst*COS(rla_src_lons(ib_i,1)) + & 00300 rl_sinlon_dst*SIN(rla_src_lons(ib_i,1)))+& 00301 rl_sinlat_dst*SIN(rla_src_lats(ib_i)) 00302 IF (arg < -1.0d0) THEN 00303 arg = -1.0d0 00304 ELSE IF (arg > 1.0d0) THEN 00305 arg = 1.0d0 00306 END IF 00307 rl_distance= ACOS(arg) 00308 ELSE 00309 rl_distance=bignum 00310 END IF 00311 00312 IF (rl_distance < rla_dist(1)) THEN 00313 ila_add_dist(2)=ila_add_dist(1) 00314 ila_add_dist(1)=ib_i 00315 rla_dist(2)=rla_dist(1) 00316 rla_dist(1)=rl_distance 00317 ELSE IF (rl_distance < rla_dist(2)) THEN 00318 ila_add_dist(2)=ib_i 00319 rla_dist(2)=rl_distance 00320 END IF 00321 END DO 00322 00323 IF (ila_nbr_found(ila_add_dist(1))>1 .AND. & 00324 ila_nbr_found(ila_add_dist(2))>1) THEN 00325 ! linearie 00326 ll_linear=.true. 00327 ELSE 00328 ! do distance weighted averege 00329 rla_wght_lon(:,:)=0 00330 DO ib_i=1,2 00331 SELECT CASE (ila_nbr_found(ila_add_dist(ib_i))) 00332 CASE (4) 00333 CALL calcul_wght_irreg(rla_src_lons(ila_add_dist(ib_i),:),& 00334 rl_plon, rla_wght_lon(ila_add_dist(ib_i),:)) 00335 rla_wght_lon(ila_add_dist(ib_i),:)=& 00336 rla_wght_lon(ila_add_dist(ib_i),:)/& 00337 rla_dist(ib_i) 00338 CASE (3) 00339 CALL calcul_wght_3(rla_src_lons(ila_add_dist(ib_i),1:3),& 00340 rl_plon, rla_wght_lon(ila_add_dist(ib_i),1:3)) 00341 rla_wght_lon(ila_add_dist(ib_i),1:3)=& 00342 rla_wght_lon(ila_add_dist(ib_i),1:3)/& 00343 rla_dist(ib_i) 00344 CASE (2) 00345 CALL calcul_wght_2(rla_src_lons(ila_add_dist(ib_i),1:2),& 00346 rl_plon, rla_wght_lon(ila_add_dist(ib_i),1:2)) 00347 rla_wght_lon(ila_add_dist(ib_i),1:2)=& 00348 rla_wght_lon(ila_add_dist(ib_i),1:2)/& 00349 rla_dist(ib_i) 00350 CASE (1) 00351 rla_wght_lon(ila_add_dist(ib_i),1)=1/rla_dist(ib_i) 00352 END SELECT 00353 END DO 00354 rl_distance=0 00355 DO ib_i=1,4 00356 rl_distance=rl_distance + sum(rla_wght_lon(ib_i,:)) 00357 END DO 00358 rla_weight(:,:)=rla_wght_lon(:,:)/rl_distance 00359 00360 CALL store_link_bicub(ib_dst_add, ila_src_add , rla_weight) 00361 CYCLE 00362 END IF 00363 END IF 00364 00365 ! 00366 ! Calculation of weights for longitudes 00367 ! 00368 00369 rla_wght_lon(:,:)=0 00370 DO ib_i=1,4 00371 SELECT CASE (ila_nbr_found(ib_i)) 00372 CASE (4) 00373 CALL calcul_wght_irreg(rla_src_lons(ib_i,:), rl_plon, & 00374 rla_wght_lon(ib_i,:)) 00375 CASE (3) 00376 CALL calcul_wght_3(rla_src_lons(ib_i,1:3), rl_plon, & 00377 rla_wght_lon(ib_i,1:3)) 00378 CASE (2) 00379 CALL calcul_wght_2(rla_src_lons(ib_i,1:2), rl_plon, & 00380 rla_wght_lon(ib_i,1:2)) 00381 END SELECT 00382 END DO 00383 00384 00385 IF (ll_linear) THEN 00386 rla_wght_lat(:)=0 00387 CALL calcul_wght_2(rla_src_lats(ila_add_dist(:)), rl_plat, & 00388 rla_wght_temp(1:2)) 00389 rla_wght_lat(ila_add_dist(1))=rla_wght_temp(1) 00390 rla_wght_lat(ila_add_dist(2))=rla_wght_temp(2) 00391 DO ib_i=1,4 00392 rla_weight(ib_i,:)=rla_wght_lat(ib_i)*rla_wght_lon(ib_i,:) 00393 END DO 00394 00395 CALL store_link_bicub(ib_dst_add, ila_src_add , rla_weight) 00396 CYCLE 00397 END IF 00398 00399 00400 ! 00401 ! Calculation of weights for latitudes 00402 ! 00403 00404 il_count=0 00405 DO ib_i=1,4 00406 IF (ila_nbr_found(ib_i)/=0) THEN 00407 il_count=il_count+1 00408 rla_lats_temp(il_count)=rla_src_lats(ib_i) 00409 END IF 00410 END DO 00411 00412 SELECT CASE (il_count) 00413 CASE (4) 00414 CALL calcul_wght_irreg(rla_lats_temp, rl_plat, rla_wght_temp(:)) 00415 CASE (3) 00416 CALL calcul_wght_3(rla_lats_temp(1:3), rl_plat, rla_wght_temp(1:3)) 00417 CASE (2) 00418 CALL calcul_wght_2(rla_lats_temp(1:2), rl_plat, rla_wght_temp(1:2)) 00419 CASE (1) 00420 rla_wght_temp(1)=1 00421 END SELECT 00422 00423 il_count=0 00424 DO ib_i=1,4 00425 IF (ila_nbr_found(ib_i)/=0) THEN 00426 il_count=il_count+1 00427 rla_wght_lat(ib_i)=rla_wght_temp(il_count) 00428 ELSE 00429 rla_wght_lat(ib_i)=0 00430 END IF 00431 END DO 00432 00433 ! 00434 ! Calculation of total weight, elementwise multiplication 00435 ! 00436 00437 DO ib_i=1,4 00438 rla_weight(ib_i,:)=rla_wght_lat(ib_i)*rla_wght_lon(ib_i,:) 00439 END DO 00440 00441 CALL store_link_bicub(ib_dst_add, ila_src_add , rla_weight) 00442 00443 END DO 00444 ! 00445 IF (nlogprt .GE. 2) THEN 00446 WRITE (UNIT = nulou,FMT = *)' ' 00447 WRITE (UNIT = nulou,FMT = *) 'Leaving routine remap_bicub_reduced' 00448 CALL FLUSH(nulou) 00449 ENDIF 00450 ! 00451 END SUBROUTINE remap_bicub_reduced 00452 00453 00454 !----------------------------------------------------------------------- 00455 ! BOP 00456 ! 00457 ! !IROUTINE: grid_search_16_points 00458 ! 00459 ! !INTERFACE: 00460 ! 00461 SUBROUTINE grid_search_16_points(ida_src_add, rda_src_lats, rda_src_lons,& 00462 ida_nbr_found, bin, rd_plat, & 00463 rd_plon, ld_extrapdone) 00464 ! 00465 ! !USES: 00466 ! 00467 ! !RETURN VALUE: 00468 ! 00469 INTEGER (KIND=ip_intwp_p), DIMENSION(4,4), INTENT(out) :: 00470 ida_src_add ! searched addresses of the unmasked points enclosing 00471 ! target point 00472 00473 REAL (KIND=ip_realwp_p), DIMENSION(4,4), INTENT(out) :: 00474 rda_src_lons ! longitudes of the searched points 00475 00476 REAL (KIND=ip_realwp_p), DIMENSION(4), INTENT(out) :: 00477 rda_src_lats ! latitudes of the searched points 00478 00479 INTEGER (KIND=ip_intwp_p), DIMENSION(4), INTENT(out) :: 00480 ida_nbr_found ! indicates for each line how many points found 00481 00482 INTEGER (KIND=ip_intwp_p), INTENT(out) :: 00483 bin ! actual bin for target point 00484 ! 00485 ! !PARAMETERS: 00486 ! 00487 REAL (KIND=ip_realwp_p), INTENT(in) :: 00488 rd_plat, ! latitude of the target point 00489 rd_plon ! longitude of the target point 00490 00491 LOGICAL, INTENT(in) :: ld_extrapdone ! true if extrapolation done 00492 00493 INTEGER (KIND=ip_intwp_p) :: 00494 ib_k, ib_j, ib_i, ! iteration indices 00495 il_min, il_max, il_inter ! begin and end for actual bin 00496 00497 INTEGER (KIND=ip_intwp_p), DIMENSION(4,2) :: 00498 ila_corners ! temp addresses for bins 00499 00500 ! 00501 ! !DESCRIPTION: 00502 ! This routine finds the location of the target point in the source 00503 ! grid and returns those of the 16 nearest points that are unmasked. 00504 ! The source grid is a reduced grid. 00505 ! 00506 ! !REVISION HISTORY: 00507 ! 2002.10.21 J.Ghattas created 00508 ! 00509 ! EOP 00510 !----------------------------------------------------------------------- 00511 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 00512 ! $Author: coquart $ 00513 !----------------------------------------------------------------------- 00514 00515 00516 ! 00517 ! serch of actual bin 00518 ! 00519 00520 00521 IF (rd_plat > bin_lats_r(1,1)) THEN ! norther of the first bin 00522 bin=0 00523 ila_corners(1:2,1:2)= 0 00524 ila_corners(3,1)= bin_addr1_r(1,1)+1 00525 ila_corners(3,2)= bin_addr1_r(2,1) 00526 ila_corners(4,1)= bin_addr1_r(1,2) 00527 ila_corners(4,2)= bin_addr1_r(2,2) 00528 00529 ELSE IF (rd_plat > bin_lats_r(1,2)) THEN ! in the first bin 00530 bin=1 00531 ila_corners(1,1:2)= 0 00532 ila_corners(2,1)= bin_addr1_r(1,1)+1 00533 ila_corners(2,2)= bin_addr1_r(2,1) 00534 ila_corners(3,1)= bin_addr1_r(1,2) 00535 ila_corners(3,2)= bin_addr1_r(2,2) 00536 ila_corners(4,1)= bin_addr1_r(1,3) 00537 ila_corners(4,2)= bin_addr1_r(2,3) 00538 00539 ELSE IF (rd_plat < bin_lats_r(1,num_srch_red)) THEN 00540 ! South of the last complet bin 00541 bin=num_srch_red 00542 ila_corners(1,1) = bin_addr1_r(1,num_srch_red-1) 00543 ila_corners(1,2) = bin_addr1_r(2,num_srch_red-1) 00544 ila_corners(2,1) = bin_addr1_r(1,num_srch_red) 00545 ila_corners(2,2) = bin_addr1_r(2,num_srch_red) 00546 ila_corners(3:4,1:2) = 0 00547 00548 ELSE IF (rd_plat < bin_lats_r(1,num_srch_red-1)) THEN 00549 ! in the last bin which is complet 00550 ! the bin (num_srch_red-1) is the last bin which is complet 00551 bin=num_srch_red-1 00552 ila_corners(1,1) = bin_addr1_r(1,num_srch_red-2) 00553 ila_corners(1,2) = bin_addr1_r(2,num_srch_red-2) 00554 ila_corners(2,1) = bin_addr1_r(1,num_srch_red-1) 00555 ila_corners(2,2) = bin_addr1_r(2,num_srch_red-1) 00556 ila_corners(3,1) = bin_addr1_r(1,num_srch_red) 00557 ila_corners(3,2) = bin_addr1_r(2,num_srch_red) 00558 ila_corners(4,1:2) = 0 00559 ELSE 00560 il_min=2 00561 il_max=num_srch_red-1 00562 DO WHILE (il_min /= il_max-1) 00563 il_inter=(il_max-il_min)/2 + il_min 00564 IF (rd_plat <= bin_lats_r(1,il_min) .and. & 00565 rd_plat > bin_lats_r(1,il_inter)) THEN 00566 il_max=il_inter 00567 ELSE 00568 il_min=il_inter 00569 END IF 00570 END DO 00571 bin=il_min 00572 ila_corners(1,1) = bin_addr1_r(1,bin-1) 00573 ila_corners(1,2) = bin_addr1_r(2,bin-1) 00574 ila_corners(2,1) = bin_addr1_r(1,bin) 00575 ila_corners(2,2) = bin_addr1_r(2,bin) 00576 ila_corners(3,1) = bin_addr1_r(1,bin+1) 00577 ila_corners(3,2) = bin_addr1_r(2,bin+1) 00578 ila_corners(4,1) = bin_addr1_r(1,bin+2) 00579 ila_corners(4,2) = bin_addr1_r(2,bin+2) 00580 00581 IF (ila_corners(1,1)==0) THEN 00582 ila_corners(1,1)=1 00583 END IF 00584 END IF 00585 00586 DO ib_k=1,4 00587 IF (ila_corners(ib_k,1) .NE. 0) & 00588 rda_src_lats(ib_k)= grid1_center_lat(ila_corners(ib_k,1)) 00589 ENDDO 00590 00591 ! 00592 ! now perform a more detailed search for each line 00593 ! 00594 00595 ida_src_add(:,:)=0 00596 ida_nbr_found(:)=0 00597 rda_src_lons(:,:)=0 00598 00599 DO ib_k=1,4 ! for each line of found points 00600 IF (ila_corners(ib_k,1)==0) THEN 00601 CYCLE 00602 END IF 00603 00604 il_min=ila_corners(ib_k,1) 00605 il_max=ila_corners(ib_k,2) 00606 00607 IF (rd_plon < grid1_center_lon(il_min)) THEN 00608 DO ib_j=il_max-1, il_max 00609 IF (grid1_mask(ib_j) .or. ld_extrapdone) THEN 00610 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00611 ida_src_add(ib_k,ida_nbr_found(ib_k)) = ib_j 00612 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00613 grid1_center_lon(ib_j)-pi2 00614 END IF 00615 END DO 00616 DO ib_j=il_min, il_min+1 00617 IF (grid1_mask(ib_j) .or. ld_extrapdone) THEN 00618 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00619 ida_src_add(ib_k,ida_nbr_found(ib_k)) = ib_j 00620 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00621 grid1_center_lon(ib_j) 00622 END IF 00623 END DO 00624 00625 ELSE IF (rd_plon < grid1_center_lon(il_min+1)) THEN 00626 IF (grid1_mask(il_max) .or. ld_extrapdone) THEN 00627 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00628 ida_src_add(ib_k,ida_nbr_found(ib_k)) = il_max 00629 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00630 grid1_center_lon(il_max)-pi2 00631 END IF 00632 DO ib_j=il_min, il_min+2 00633 IF (grid1_mask(ib_j) .or. ld_extrapdone) THEN 00634 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00635 ida_src_add(ib_k,ida_nbr_found(ib_k)) = ib_j 00636 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00637 grid1_center_lon(ib_j) 00638 END IF 00639 END DO 00640 00641 ELSE IF (rd_plon > grid1_center_lon(il_max)) THEN 00642 DO ib_j=il_max-1, il_max 00643 IF (grid1_mask(ib_j) .or. ld_extrapdone) THEN 00644 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00645 ida_src_add(ib_k,ida_nbr_found(ib_k)) = ib_j 00646 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00647 grid1_center_lon(ib_j) 00648 END IF 00649 END DO 00650 DO ib_j=il_min, il_min+1 00651 IF (grid1_mask(ib_j) .or. ld_extrapdone) THEN 00652 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00653 ida_src_add(ib_k,ida_nbr_found(ib_k)) = ib_j 00654 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00655 grid1_center_lon(ib_j)+pi2 00656 END IF 00657 END DO 00658 00659 ELSE IF (rd_plon > grid1_center_lon(il_max-1)) THEN 00660 DO ib_j=il_max-2, il_max 00661 IF (grid1_mask(ib_j) .or. ld_extrapdone) THEN 00662 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00663 ida_src_add(ib_k,ida_nbr_found(ib_k)) = ib_j 00664 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00665 grid1_center_lon(ib_j) 00666 END IF 00667 END DO 00668 IF (grid1_mask(il_min) .or. ld_extrapdone) THEN 00669 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00670 ida_src_add(ib_k,ida_nbr_found(ib_k)) = il_min 00671 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00672 grid1_center_lon(il_min)+pi2 00673 END IF 00674 00675 ELSE 00676 00677 DO WHILE (il_min/=il_max-1) 00678 il_inter=(il_max-il_min)/2 + il_min 00679 IF (rd_plon >= grid1_center_lon(il_min) .and. & 00680 rd_plon < grid1_center_lon(il_inter)) THEN 00681 il_max=il_inter 00682 ELSE 00683 il_min=il_inter 00684 END IF 00685 END DO 00686 DO ib_i= il_min-1, il_min+2 00687 IF (grid1_mask(ib_i) .or. ld_extrapdone) THEN 00688 ida_nbr_found(ib_k)=ida_nbr_found(ib_k)+1 00689 ida_src_add(ib_k,ida_nbr_found(ib_k))=ib_i 00690 rda_src_lons(ib_k,ida_nbr_found(ib_k))= & 00691 grid1_center_lon(ib_i) 00692 END IF 00693 END DO 00694 00695 END IF 00696 00697 END DO 00698 00699 00700 END SUBROUTINE grid_search_16_points 00701 00702 00703 00704 !----------------------------------------------------------------------- 00705 ! BOP 00706 ! 00707 ! !IROUTINE: calcul_wght_irreg 00708 ! 00709 ! !INTERFACE: 00710 ! 00711 SUBROUTINE calcul_wght_irreg(rda_x, rd_pt, rda_wght) 00712 ! 00713 ! !USES: 00714 ! 00715 ! !RETURN VALUE: 00716 ! 00717 REAL (KIND=ip_realwp_p), DIMENSION(4), INTENT(out) :: 00718 rda_wght ! array of weights for the points x 00719 ! 00720 ! !PARAMETERS: 00721 ! 00722 REAL (KIND=ip_realwp_p), DIMENSION(4), INTENT(in) :: 00723 rda_x ! array of positions on source grid, lat or lon 00724 00725 REAL (KIND=ip_realwp_p),INTENT(in) :: 00726 rd_pt ! position of target point to interpolate 00727 00728 REAL (KIND=ip_realwp_p) :: 00729 rl_t1, rl_t2, rl_t3, rl_t4, rl_t5, rl_t6, rl_t7, rl_t8, rl_t9, 00730 rl_u1, rl_u2, rl_u3, rl_u4, 00731 rl_k1, rl_k2, rl_k3, 00732 rl_d1, rl_d2, rl_d3, rl_d4, 00733 rl_c1, rl_c2, rl_c3, rl_c4, 00734 rl_b1, rl_b2, rl_b3, rl_b4, 00735 rl_a1, rl_a2, rl_a3, rl_a4, 00736 rl_y1, rl_y2, rl_y3, 00737 rl_a1_y, rl_a2_y, rl_a3_y, rl_a4_y, 00738 rl_b1_y, rl_b2_y, rl_b3_y, rl_b4_y, 00739 rl_c1_y, rl_c2_y, rl_c3_y, rl_c4_y 00740 ! 00741 ! !DESCRIPTION: 00742 ! Calculates a the weights of four points for a bicubic interpolation. 00743 ! The distances between the points can be irregulier. 00744 ! 00745 ! !REVISION HISTORY: 00746 ! 2002.10.21 J.Ghattas created 00747 ! 00748 ! EOP 00749 !----------------------------------------------------------------------- 00750 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 00751 ! $Author: coquart $ 00752 !----------------------------------------------------------------------- 00753 00754 00755 IF (rda_x(1)/=0.and. rda_x(2)/=0 .and. rda_x(3)/=0 .and. rda_x(4)/=0) THEN 00756 00757 rl_t1 = 1/rda_x(1) - 1/rda_x(2) 00758 rl_t2 = 1/rda_x(1)**2 - 1/rda_x(2)**2 00759 rl_t3 = 1/rda_x(1)**3 - 1/rda_x(2)**3 00760 rl_t4 = 1/rda_x(1) - 1/rda_x(3) 00761 rl_t5 = 1/rda_x(1)**2 - 1/rda_x(3)**2 00762 rl_t6 = 1/rda_x(1)**3 - 1/rda_x(3)**3 00763 rl_t7 = 1/rda_x(1) - 1/rda_x(4) 00764 rl_t8 = 1/rda_x(1)**2 - 1/rda_x(4)**2 00765 rl_t9 = 1/rda_x(1)**3 - 1/rda_x(4)**3 00766 00767 rl_u1 = rl_t2/rl_t1 - rl_t5/rl_t4 00768 rl_u2 = rl_t3/rl_t1 - rl_t6/rl_t4 00769 rl_u3 = rl_t2/rl_t1 - rl_t8/rl_t7 00770 rl_u4 = rl_t3/rl_t1 - rl_t9/rl_t7 00771 00772 rl_k1 = (1/(rl_t1*rl_u1)-1/(rl_t1*rl_u3)) / (rl_u2/rl_u1-rl_u4/rl_u3) 00773 rl_k2 = -1/(rl_t4*rl_u1) / (rl_u2/rl_u1-rl_u4/rl_u3) 00774 rl_k3 = 1/(rl_t7*rl_u3) / (rl_u2/rl_u1-rl_u4/rl_u3) 00775 00776 00777 rl_d1=(rl_k1+rl_k2+rl_k3)/rda_x(1)**3 00778 rl_d2 = -rl_k1/rda_x(2)**3 00779 rl_d3 = -rl_k2/rda_x(3)**3 00780 rl_d4 = -rl_k3/rda_x(4)**3 00781 00782 rl_c1 = 1/rl_u1*(1/(rl_t1*rda_x(1)**3)-1/(rl_t4*rda_x(1)**3)- & 00783 rl_u2*rl_d1) 00784 rl_c2 = 1/rl_u1*(1/(-rl_t1*rda_x(2)**3)-rl_u2*rl_d2) 00785 rl_c3 = 1/rl_u1*(1/(rl_t4*rda_x(3)**3)-rl_u2*rl_d3) 00786 rl_c4 = 1/rl_u1*(-rl_u2*rl_d4) 00787 00788 rl_b1 = 1/rl_t1/rda_x(1)**3-rl_t2/rl_t1*rl_c1-rl_t3/rl_t1*rl_d1 00789 rl_b2 = -1/rl_t1/rda_x(2)**3-rl_t2/rl_t1*rl_c2-rl_t3/rl_t1*rl_d2 00790 rl_b3 = -rl_t2/rl_t1*rl_c3-rl_t3/rl_t1*rl_d3 00791 rl_b4 = -rl_t2/rl_t1*rl_c4-rl_t3/rl_t1*rl_d4 00792 00793 rl_a1 = 1/rda_x(1)**3-1/rda_x(1)*rl_b1-1/rda_x(1)**2*rl_c1- & 00794 1/rda_x(1)**3*rl_d1 00795 rl_a2 = -1/rda_x(1)*rl_b2-1/rda_x(1)**2*rl_c2-1/rda_x(1)**3*rl_d2 00796 rl_a3 = -1/rda_x(1)*rl_b3-1/rda_x(1)**2*rl_c3-1/rda_x(1)**3*rl_d3 00797 rl_a4 = -1/rda_x(1)*rl_b4-1/rda_x(1)**2*rl_c4-1/rda_x(1)**3*rl_d4 00798 00799 ! Weights 00800 rda_wght(1) = rl_a1*rd_pt**3 + rl_b1*rd_pt**2 + rl_c1*rd_pt + rl_d1 00801 rda_wght(2) = rl_a2*rd_pt**3 + rl_b2*rd_pt**2 + rl_c2*rd_pt + rl_d2 00802 rda_wght(3) = rl_a3*rd_pt**3 + rl_b3*rd_pt**2 + rl_c3*rd_pt + rl_d3 00803 rda_wght(4) = rl_a4*rd_pt**3 + rl_b4*rd_pt**2 + rl_c4*rd_pt + rl_d4 00804 00805 ELSE ! there is one point = 0 00806 00807 rl_d1=0; rl_d2=0; rl_d3=0; rl_d4=0 00808 00809 ! Transformation for each case 00810 IF (rda_x(1)==0) THEN 00811 rl_y1=rda_x(2); rl_y2=rda_x(3); rl_y3=rda_x(4) 00812 rl_d1=1 00813 ELSE IF (rda_x(2)==0) THEN 00814 rl_y1=rda_x(1); rl_y2=rda_x(3); rl_y3=rda_x(4) 00815 rl_d2=1 00816 ELSE IF (rda_x(3)==0) THEN 00817 rl_y1=rda_x(1); rl_y2=rda_x(2); rl_y3=rda_x(4) 00818 rl_d3=1 00819 ELSE 00820 rl_y1=rda_x(1); rl_y2=rda_x(2); rl_y3=rda_x(3) 00821 rl_d4=1 00822 END IF 00823 00824 ! Solving the system 00825 rl_t1 = 1/rl_y1-1/rl_y2 00826 rl_t2 = 1/rl_y1**2-1/rl_y2**2 00827 rl_t3 = 1/rl_y1-1/rl_y3 00828 rl_t4 = 1/rl_y1**2-1/rl_y3**2 00829 00830 rl_c1_y =(1/rl_y1**3/rl_t1-1/rl_y1**3/rl_t3)/(rl_t2/rl_t1-rl_t4/rl_t3) 00831 rl_c2_y = -1/rl_y2**3/rl_t1/(rl_t2/rl_t1-rl_t4/rl_t3) 00832 rl_c3_y = 1/rl_y3**3/rl_t3/(rl_t2/rl_t1-rl_t4/rl_t3) 00833 rl_c4_y=(-1/rl_y1**3/rl_t1+1/rl_y2**3/rl_t1+ & 00834 1/rl_y1**3/rl_t3-1/rl_y3**3/rl_t3)/(rl_t2/rl_t1-rl_t4/rl_t3) 00835 00836 rl_b1_y = 1/rl_y1**3/rl_t1 - rl_c1_y*rl_t2/rl_t1 00837 rl_b2_y = -1/rl_y2**3/rl_t1 - rl_c2_y*rl_t2/rl_t1 00838 rl_b3_y = -rl_c3_y*rl_t2/rl_t1 00839 rl_b4_y = -1/rl_y1**3/rl_t1 + 1/rl_y2**3/rl_t1 - rl_c4_y*rl_t2/rl_t1 00840 00841 rl_a1_y = 1/rl_y1**3 - rl_b1_y/rl_y1 - rl_c1_y/rl_y1**2 00842 rl_a2_y = -rl_b2_y/rl_y1 - rl_c2_y/rl_y1**2 00843 rl_a3_y = -rl_b3_y/rl_y1 - rl_c3_y/rl_y1**2 00844 rl_a4_y = -1/rl_y1**3 - rl_b4_y/rl_y1 - rl_c4_y/rl_y1**2 00845 00846 ! Retransformation 00847 IF (rda_x(1)==0) THEN 00848 rl_a1=rl_a4_y; rl_a2=rl_a1_y; rl_a3=rl_a2_y; rl_a4=rl_a3_y 00849 rl_b1=rl_b4_y; rl_b2=rl_b1_y; rl_b3=rl_b2_y; rl_b4=rl_b3_y 00850 rl_c1=rl_c4_y; rl_c2=rl_c1_y; rl_c3=rl_c2_y; rl_c4=rl_c3_y 00851 ELSE IF (rda_x(2)==0) THEN 00852 rl_a1=rl_a1_y; rl_a2=rl_a4_y; rl_a3=rl_a2_y; rl_a4=rl_a3_y 00853 rl_b1=rl_b1_y; rl_b2=rl_b4_y; rl_b3=rl_b2_y; rl_b4=rl_b3_y 00854 rl_c1=rl_c1_y; rl_c2=rl_c4_y; rl_c3=rl_c2_y; rl_c4=rl_c3_y 00855 ELSE IF (rda_x(3)==0) THEN 00856 rl_a1=rl_a1_y; rl_a2=rl_a2_y; rl_a3=rl_a4_y; rl_a4=rl_a3_y 00857 rl_b1=rl_b1_y; rl_b2=rl_b2_y; rl_b3=rl_b4_y; rl_b4=rl_b3_y 00858 rl_c1=rl_c1_y; rl_c2=rl_c2_y; rl_c3=rl_c4_y; rl_c4=rl_c3_y 00859 ELSE 00860 rl_a1=rl_a1_y; rl_a2=rl_a2_y; rl_a3=rl_a3_y; rl_a4=rl_a4_y 00861 rl_b1=rl_b1_y; rl_b2=rl_b2_y; rl_b3=rl_b3_y; rl_b4=rl_b4_y 00862 rl_c1=rl_c1_y; rl_c2=rl_c2_y; rl_c3=rl_c3_y; rl_c4=rl_c4_y 00863 END IF 00864 00865 ! Weights 00866 rda_wght(1) = rl_a1*rd_pt**3 + rl_b1*rd_pt**2 + rl_c1*rd_pt +rl_d1 00867 rda_wght(2) = rl_a2*rd_pt**3 + rl_b2*rd_pt**2 + rl_c2*rd_pt +rl_d2 00868 rda_wght(3) = rl_a3*rd_pt**3 + rl_b3*rd_pt**2 + rl_c3*rd_pt +rl_d3 00869 rda_wght(4) = rl_a4*rd_pt**3 + rl_b4*rd_pt**2 + rl_c4*rd_pt +rl_d4 00870 00871 END IF 00872 00873 00874 END SUBROUTINE calcul_wght_irreg 00875 00876 !----------------------------------------------------------------------- 00877 ! BOP 00878 ! 00879 ! !IROUTINE: calcul_wght_3 00880 ! 00881 ! !INTERFACE: 00882 00883 SUBROUTINE calcul_wght_3(rda_x, rd_pt, rda_wght) 00884 00885 ! !USES: 00886 00887 ! !RETURN VALUE: 00888 00889 REAL (KIND=ip_realwp_p), DIMENSION(3), INTENT(out) :: 00890 rda_wght ! array of weights for the points x 00891 00892 ! !PARAMETERS: 00893 00894 REAL (KIND=ip_realwp_p), DIMENSION(3), INTENT(in) :: 00895 rda_x ! array of positions on source grid, lat or lon 00896 00897 REAL (KIND=ip_realwp_p), INTENT(in) :: 00898 rd_pt ! position of target point to interpolate 00899 00900 REAL (KIND=ip_realwp_p) :: 00901 rl_c1, rl_c2, rl_c3, 00902 rl_a1, rl_a2, rl_a3, 00903 rl_b1, rl_b2, rl_b3, 00904 rl_t1, rl_t2, rl_t3, rl_t4 00905 00906 ! !DESCRIPTION: 00907 ! Calculates a the weights of 3 points for a parabolic interpolation. 00908 ! 00909 ! !REVISION HISTORY: 00910 ! 2002.10.21 J.Ghattas created 00911 ! 00912 ! EOP 00913 !----------------------------------------------------------------------- 00914 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 00915 ! $Author: coquart $ 00916 !----------------------------------------------------------------------- 00917 00918 00919 IF (rda_x(1)/=0 .and. rda_x(2)/=0 .and. rda_x(3)/=0) THEN 00920 rl_t1 = 1/rda_x(1)-1/rda_x(2) 00921 rl_t2 = 1/rda_x(1)**2-1/rda_x(2)**2 00922 rl_t3 = 1/rda_x(1)-1/rda_x(3) 00923 rl_t4 = 1/rda_x(1)**2-1/rda_x(3)**2 00924 00925 rl_c1 = (1/rda_x(1)**2/rl_t1-1/rda_x(1)**2/rl_t3) / & 00926 (rl_t2/rl_t1-rl_t4/rl_t3) 00927 rl_c2 = -1/rda_x(2)**2/rl_t1 / (rl_t2/rl_t1-rl_t4/rl_t3) 00928 rl_c3 = 1/rda_x(3)**2/rl_t3 / (rl_t2/rl_t1-rl_t4/rl_t3) 00929 00930 rl_b1 = 1/rda_x(1)**2/rl_t1 - rl_c1*rl_t2/rl_t1 00931 rl_b2 = -1/rda_x(2)**2/rl_t1 - rl_c2*rl_t2/rl_t1 00932 rl_b3 = - rl_c3*rl_t2/rl_t1 00933 00934 rl_a1 = 1/rda_x(1)**2 - rl_b1/rda_x(1) - rl_c1/rda_x(1)**2 00935 rl_a2 = - rl_b2/rda_x(1) - rl_c2/rda_x(1)**2 00936 rl_a3 = - rl_b3/rda_x(1) - rl_c3/rda_x(1)**2 00937 00938 00939 ELSE IF (rda_x(1)==0) THEN 00940 rl_c1 = 1; rl_c2 = 0; rl_c3 = 0 00941 rl_b1 = (-1/rda_x(2)**2+1/rda_x(3)**2) / (1/rda_x(2)-1/rda_x(3)) 00942 rl_b2 = 1/rda_x(2)**2 / (1/rda_x(2)-1/rda_x(3)) 00943 rl_b3 = -1/rda_x(3)**2 / (1/rda_x(2)-1/rda_x(3)) 00944 00945 rl_a1 = -1/rda_x(2)**2 - rl_b1/rda_x(2) 00946 rl_a2 = 1/rda_x(2)**2 - rl_b2/rda_x(2) 00947 rl_a3 = - rl_b3/rda_x(2) 00948 00949 ELSE IF (rda_x(2)==0) THEN 00950 00951 rl_c1 = 0; rl_c2 = 1; rl_c3 = 0 00952 rl_b1 = 1/rda_x(1)**2 / (1/rda_x(1)-1/rda_x(3)) 00953 rl_b2 = (-1/rda_x(1)**2+1/rda_x(3)**2) / (1/rda_x(1)-1/rda_x(3)) 00954 rl_b3 = -1/rda_x(3)**2 / (1/rda_x(1)-1/rda_x(3)) 00955 00956 rl_a1 = 1/rda_x(1)**2 - rl_b1/rda_x(1) 00957 rl_a2 = -1/rda_x(1)**2 - rl_b2/rda_x(1) 00958 rl_a3 = - rl_b3/rda_x(1) 00959 00960 ELSE !rda_x(3)==0 00961 rl_c1 = 0; rl_c2 = 0; rl_c3 = 1 00962 rl_b1 = 1/rda_x(1)**2 / (1/rda_x(1)-1/rda_x(2)) 00963 rl_b2 = -1/rda_x(2)**2 / (1/rda_x(1)-1/rda_x(2)) 00964 rl_b3 = (-1/rda_x(1)**2+1/rda_x(2)**2) / (1/rda_x(1)-1/rda_x(2)) 00965 00966 rl_a1 = 1/rda_x(1)**2 - rl_b1/rda_x(1) 00967 rl_a2 = - rl_b2/rda_x(1) 00968 rl_a3 = -1/rda_x(1)**2 - rl_b3/rda_x(1) 00969 00970 00971 END IF 00972 00973 ! Weights 00974 rda_wght(1) = rl_a1*rd_pt**2 + rl_b1*rd_pt + rl_c1 00975 rda_wght(2) = rl_a2*rd_pt**2 + rl_b2*rd_pt + rl_c2 00976 rda_wght(3) = rl_a3*rd_pt**2 + rl_b3*rd_pt + rl_c3 00977 00978 00979 END SUBROUTINE calcul_wght_3 00980 00981 00982 !----------------------------------------------------------------------- 00983 ! BOP 00984 ! 00985 ! !IROUTINE: calcul_wght_2 00986 ! 00987 ! !INTERFACE: 00988 00989 SUBROUTINE calcul_wght_2(rda_x, rd_pt, rda_wght) 00990 00991 ! !USES: 00992 00993 ! !RETURN VALUE: 00994 00995 REAL (KIND=ip_realwp_p), DIMENSION(2), INTENT(out) :: 00996 rda_wght ! array of weights for the points x 00997 00998 ! !PARAMETERS: 00999 01000 REAL (KIND=ip_realwp_p), DIMENSION(2), INTENT(in) :: 01001 rda_x ! array of positions on source grid, lat or lon 01002 01003 REAL (KIND=ip_realwp_p), INTENT(in) :: 01004 rd_pt ! position of target point to interpolate 01005 01006 REAL (KIND=ip_realwp_p) :: rl_b1, rl_b2, rl_a1, rl_a2 01007 01008 ! !DESCRIPTION: 01009 ! Calculates a the weights of 2 points for a linair interpolation. 01010 ! 01011 ! !REVISION HISTORY: 01012 ! 2002.10.21 J.Ghattas created 01013 ! 01014 ! EOP 01015 !----------------------------------------------------------------------- 01016 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 01017 ! $Author: coquart $ 01018 !----------------------------------------------------------------------- 01019 01020 01021 IF (rda_x(1)/=0 .and. rda_x(2)/=0) THEN 01022 rl_b1 = 1/(1-rda_x(1)/rda_x(2)) 01023 rl_b2 = -1/(rda_x(2)/rda_x(1)-1) 01024 rl_a1 = 1/rda_x(1) - rl_b1/rda_x(1) 01025 rl_a2 = - rl_b2/rda_x(1) 01026 01027 ELSE IF (rda_x(1)==0) THEN 01028 rl_b1=1; rl_b2=0 01029 rl_a1=-1/rda_x(2) 01030 rl_a2=1/rda_x(2) 01031 ELSE 01032 rl_b1=0; rl_b2=1 01033 rl_a1=1/rda_x(1) 01034 rl_a2=-1/rda_x(1) 01035 END IF 01036 01037 rda_wght(1) = rl_a1*rd_pt + rl_b1 01038 rda_wght(2) = rl_a2*rd_pt + rl_b2 01039 01040 END SUBROUTINE calcul_wght_2 01041 01042 01043 !----------------------------------------------------------------------- 01044 ! BOP 01045 ! 01046 ! !IROUTINE: store_link_bicub 01047 ! 01048 ! !INTERFACE: 01049 01050 SUBROUTINE store_link_bicub(id_dst_add, ida_src_add, rda_wght) 01051 01052 ! !USES: 01053 01054 ! !RETURN VALUE: 01055 01056 ! !PARAMETERS: 01057 01058 INTEGER (KIND=ip_intwp_p), INTENT(in) :: 01059 id_dst_add ! address on destination grid 01060 01061 INTEGER (KIND=ip_intwp_p), DIMENSION(4,4), INTENT(in) :: 01062 ida_src_add ! addresses for links on source grid 01063 01064 REAL (KIND=ip_realwp_p), DIMENSION(4,4), INTENT(in) :: 01065 rda_wght ! array of remapping weights for these links 01066 01067 INTEGER (KIND=ip_intwp_p) :: ib_i, 01068 il_num_links_old ! placeholder for old link number 01069 01070 INTEGER (KIND=ip_intwp_p), DIMENSION(16) :: 01071 ila_src_add ! reshaped addresses 01072 01073 REAL (KIND=ip_realwp_p), DIMENSION(16) :: 01074 rla_wght ! reshaped weights 01075 01076 ! !DESCRIPTION: 01077 ! This routine stores the addresses and weights for 16 links associated 01078 ! with one destination point in the appropriate address. 01079 ! 01080 ! !REVISION HISTORY: 01081 ! 2002.10.21 J.Ghattas created 01082 ! 01083 ! EOP 01084 !----------------------------------------------------------------------- 01085 ! $Id: remap_bicubic_reduced.F90 3500 2012-03-22 14:58:30Z coquart $ 01086 ! $Author: coquart $ 01087 !----------------------------------------------------------------------- 01088 01089 01090 ! 01091 ! Increment number of links and check if remap arrays need 01092 ! to be increased to accomodate the new link. then store the link. 01093 ! 01094 01095 il_num_links_old = num_links_map1 01096 num_links_map1 = il_num_links_old + 16 01097 01098 IF (num_links_map1 > max_links_map1) THEN 01099 CALL resize_remap_vars(1,MAX(resize_increment,16)) 01100 END IF 01101 01102 ila_src_add=RESHAPE(ida_src_add,(/16/)) 01103 rla_wght=RESHAPE(rda_wght,(/16/)) 01104 01105 DO ib_i=1,16 01106 grid1_add_map1(il_num_links_old+ib_i) = ila_src_add(ib_i) 01107 grid2_add_map1(il_num_links_old+ib_i) = id_dst_add 01108 wts_map1(1,il_num_links_old+ib_i) = rla_wght(ib_i) 01109 END DO 01110 01111 END SUBROUTINE store_link_bicub 01112 01113 01114 END MODULE remap_bicubic_reduced 01115 01116 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01117