Oasis3 4.0.2
|
00001 SUBROUTINE scriprmp_vector( & 00002 dst_arrayI_dstA, dst_arrayJ_dstB, & 00003 src_arrayI_srcA, src_arrayJ_srcB, & 00004 grd_name_srcA, grd_name_srcB, & 00005 grd_name_dstA, grd_name_dstB, & 00006 src_size, dst_size, & 00007 msk_srcA, msk_srcB, & 00008 msk_dstA, msk_dstB, & 00009 lon_srcA, lat_srcA, & 00010 lon_srcB, lat_srcB, & 00011 lon_dstA, lat_dstA, & 00012 lon_dstB, lat_dstB, & 00013 nlon_src, nlat_src, & 00014 nlon_dst, nlat_dst, & 00015 map_method, cdgrdtyp, & 00016 id_sper, id_tper, & 00017 cd_sper, cd_tper, & 00018 normalize_opt, order, & 00019 rst_type, n_srch_bins, & 00020 lextrapdone, lprojcart, & 00021 rl_varmul, id_scripvoi ) 00022 00023 !C Input: 00024 !C ----- 00025 !C src_arrayI_srcA : field on source grid defined as VECTOR_I 00026 !C src_arrayJ_srcB : field on source grid defined as VECTOR_J 00027 !C grd_name_srcA : name for the source grid where VECTOR_I is defined 00028 !C grd_name_srcB : name for the source grid where VECTOR_J is defined 00029 !C grd_name_dstA : name for the target grid where VECTOR_I is defined 00030 !C grd_name_dstB : name for the target grid where VECTOR_J is defined 00031 !C src_size : source grid size 00032 !C dst_size : target grid size 00033 !C msk_srcA : grid mask for srcA 00034 !C msk_srcB : grid mask for srcB 00035 !C msk_dstA : grid mask for dstA 00036 !C msk_dstB : grid mask for dstB 00037 !C lon_srcA : longitudes for grid srcA 00038 !C lon_srcB : longitudes for grid srcB 00039 !C lon_dstA : longitudes for grid dstA 00040 !C lon_dstB : longitudes for grid dstB 00041 !C lat_srcA : latitudes for grid srcA 00042 !C lat_srcB : latitudes for grid srcB 00043 !C lat_dstA : latitudes for grid dstA 00044 !C lat_dstB : latitudes for grid dstB 00045 !C nlon_src : number of longitudes for source grid 00046 !C nlat_src : number of latitudes for source grid 00047 !C nlon_dst : number of longitudes for target grid 00048 !C nlat_dst : number of latitudes for target grid 00049 !C map_method : remapping method 00050 !C cdgrdtyp : grid type for source grid 00051 !C id_sper : number of overlapping for source grid 00052 !C id_tper : number of overlapping for target grid 00053 !C cd_sper : source grid periodicity type 00054 !C cd_tper : target grid periodicity type 00055 !C normalize_opt : option for normalization 00056 !C order : order of conservative remapping 00057 !C rst_type : type of scrip search restriction 00058 !C n_srch_bins : number of seach bins 00059 !C lextrapdone : logical, true if EXTRAP done on field 00060 !C lprojcart : logical, true for rotation to cartesian refernetial 00061 !C rl_varmul : Gaussian variance (for GAUSWGT) 00062 !C id_scripvoi : number of neighbour for DISTWGT and GAUSWGT 00063 !C 00064 !C Output: 00065 !C ------ 00066 !C dst_arrayI_dstA : VECTOR_I field on target grid as defined in namcouple 00067 !C dst_arrayJ_dstB : VECTOR_J field on target grid as defined in namcouple 00068 !C 00069 !C Externals: 00070 !C --------- 00071 !C corners, scrip, gradient, gradient_bicubic, 00072 !C from module rotations : loc2spher, sher2car, car2spher, spher2loc 00073 !C from module vector : remap_vector_comps, write_src_array_spheric, 00074 !C write_dst_array_spheric, write_cartesian_components, 00075 !C check_points_at_poles 00076 !C 00077 !C History: 00078 !C -------- 00079 !C E. Rapaport 2004/03 Created 00080 !C J. Ghattas 2006/02 Rewritten 00081 ! 00082 ! 00083 ! Description : 00084 ! ------------- 00085 ! This routine interpolates a vector field, described as 2 scalar components I and J. 00086 ! The 2 components are described on different source grids and the resulting 2 00087 ! components can be calculated on 2 differents target grids. The source grids 00088 ! are named grd_srcA which is the original grid for the component I, and grd_srcB 00089 ! which is the original grid for component J. The target grid defined for the component 00090 ! I are dstA and for for the component J dstB. The two source grids have to be identical 00091 ! in number of cells and their mask must be the same; for different target grids the same 00092 ! criteria are imposed. 00093 ! 00094 ! Steps: 00095 ! ------ 00096 ! -> If the source grid differs a first interpolation will be done from grd_srcB 00097 ! towards grd_srcA scalarly for the 2 components 00098 ! -> Rotation towards spherical referentials on source grid srcA 00099 ! -> If desired rotation towards cartesian referentials 00100 ! -> Interpolation of the components scalarly from srcA towards target grid dstA 00101 ! -> Rotation towards local referentials. 00102 ! -> If target grids differ, the same procedure will be done from grd_srcA towards grd_dstB. 00103 ! 00104 !C %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00105 !C* ---------------------------- Modules used ---------------------------- 00106 USE grids 00107 USE rotations 00108 USE remap_vars 00109 USE vector 00110 ! 00111 !* ---------------------------- Implicit -------------------------------- 00112 ! 00113 IMPLICIT NONE 00114 ! 00115 !* ---------------------------- Include files --------------------------- 00116 ! 00117 !* ---------------------------- Intent In ------------------------------- 00118 ! 00119 INTEGER(KIND=int_kind), INTENT(in) :: 00120 nlon_src, nlat_src, ! number of longitudes and latitudes on source grid 00121 nlon_dst, nlat_dst, ! number of longitudes and latitudes on target grid 00122 src_size, dst_size, ! number of source/target grid cells 00123 n_srch_bins, ! number of search bins for SCRIP 00124 msk_srcA(src_size), ! grid mask for srcA 00125 msk_srcB(src_size), ! grid mask for srcB 00126 msk_dstA(dst_size), ! grid mask for dstA 00127 msk_dstB(dst_size), ! grid mask for dstB 00128 id_sper, ! number of overlapping points for source grid 00129 id_tper, ! number of overlapping points for target grid 00130 id_scripvoi ! number of neighbour for DISTWGT and GAUSWGT 00131 00132 REAL (KIND=real_kind), INTENT(in) :: 00133 src_arrayI_srcA(src_size), ! field component I on original source grid srcA 00134 src_arrayJ_srcB(src_size), ! field component J on original source grid srcB 00135 lon_srcA(src_size), lat_srcA(src_size), ! lon-/latitudes for source grid srcA 00136 lon_srcB(src_size), lat_srcB(src_size), ! lon-/latitudes for source grid srcB 00137 lon_dstA(dst_size), lat_dstA(dst_size), ! lon-/latitudes for target grid dstA 00138 lon_dstB(dst_size), lat_dstB(dst_size), ! lon-/latitudes for target grid dstB 00139 rl_varmul ! Gaussian variance (for GAUSWGT) 00140 00141 CHARACTER(LEN=8), INTENT(in) :: 00142 grd_name_srcA, grd_name_srcB, ! grid name for the 2 sources grids 00143 grd_name_dstA, grd_name_dstB, ! grid name for the 2 target grids 00144 map_method, ! remapping method 00145 cdgrdtyp, ! source grid type 00146 normalize_opt, ! option for normalization 00147 order, ! order of conservative remapping 00148 rst_type, ! type of scrip search restriction 00149 cd_sper, ! source grid periodicity type 00150 cd_tper ! target grid periodicity type 00151 00152 LOGICAL, INTENT(in) :: 00153 lextrapdone, ! logical, true if EXTRAP done on field 00154 lprojcart ! logical, ture if projection to cartesian should be done 00155 00156 ! 00157 !* ---------------------------- Intent Out ------------------------------- 00158 ! 00159 REAL (KIND=real_kind), INTENT(out):: 00160 dst_arrayI_dstA(dst_size), ! VECTOR_I field on target grid dstA 00161 dst_arrayJ_dstB(dst_size) ! VECTOR_J field on target grid dstB 00162 00163 ! 00164 !* ---------------------------- Local declarations ---------------------- 00165 ! 00166 INTEGER(KIND=int_kind) :: nbr_dst, nbr_comp, ii, jj, icount, kcount, stat, 00167 nc_gridsid, angid, nc_fileid, var_id 00168 INTEGER(KIND=int_kind) :: ilenstr 00169 INTEGER (KIND=int_kind), DIMENSION(dst_size) :: msk_dst 00170 REAL (KIND=real_kind), DIMENSION(src_size) :: src_arrayJ_srcA 00171 REAL (KIND=real_kind), DIMENSION(src_size,3) :: src_array, src_array_buf 00172 REAL (KIND=real_kind), DIMENSION(dst_size) :: lon_dst, lat_dst 00173 REAL (KIND=real_kind), DIMENSION(src_size,2,2) :: mat_loc2sph 00174 REAL (KIND=real_kind), DIMENSION(src_size,3,2) :: mat_sph2car 00175 REAL (KIND=real_kind), DIMENSION(dst_size,3,3) :: mat_car2sph 00176 REAL (KIND=real_kind), DIMENSION(dst_size,2,2) :: mat_sph2loc 00177 REAL (KIND=real_kind), DIMENSION(dst_size,3) :: dst_array, dst_array_buf 00178 00179 CHARACTER(LEN=8) :: grd_name_dst 00180 CHARACTER (char_len) :: cmapping, crmpfile 00181 CHARACTER(LEN=12) :: ang_name 00182 #if defined use_oasis_para || defined use_oasis_cmcc_para 00183 CHARACTER*3 :: cl_indexoa 00184 #endif 00185 00186 LOGICAL :: ll_loc2spher_srcA, ll_spher2loc_dst 00187 00188 ! 00189 !* ---------------------------- Poema verses ---------------------------- 00190 ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00191 ! 00192 !*** O. Initialization 00193 ! -------------- 00194 ! -------------- 00195 IF (nlogprt .GE. 2) THEN 00196 WRITE (UNIT = nulou,FMT = *) ' ' 00197 WRITE (UNIT = nulou,FMT = *) & 00198 ' Entering ROUTINE scriprmp_vector - Level 3' 00199 WRITE (UNIT = nulou,FMT = *) & 00200 ' *********************** *******' 00201 WRITE (UNIT = nulou,FMT = *) ' ' 00202 WRITE (UNIT = nulou,FMT = *) 'SCRIP remapping for vector' 00203 WRITE (UNIT = nulou,FMT = *) ' ' 00204 call flush(nulou) 00205 ENDIF 00206 00207 ! 00208 !*** 1. Interpolation towards the same source grid 00209 ! ------------------------------------------ 00210 ! ------------------------------------------ 00211 ! 00212 !* If the source grids of the two vector components are different 00213 !* -> interpolation of field J on grd_srcB towards the same grid as for 00214 !* the field I grd_srcA. 00215 ! 00216 ! 00217 !* After this step the two components are on the same source grid: 00218 !* -> src_arrayI_srcA, src_arrayJ_srcA 00219 ! 00220 00221 IF (grd_name_srcA .NE. grd_name_srcB) THEN 00222 ! Interpolate the field src_arrayJ_srcB from grid srcB towards 00223 ! grid srcA. Resulting field on srcA is src_arrayJ_srcA 00224 CALL scriprmp( & 00225 src_arrayJ_srcA,src_arrayJ_srcB, src_size, src_size, & 00226 msk_srcB, msk_srcA, & 00227 lon_srcB, lat_srcB, nlon_src, nlat_src, & 00228 lon_srcA, lat_srcA, nlon_src, nlat_src, & 00229 map_method, cdgrdtyp, & 00230 id_sper, id_sper, cd_sper, cd_sper, & 00231 grd_name_srcB, grd_name_srcA, & 00232 normalize_opt, order, rst_type, n_srch_bins, & 00233 lextrapdone, rl_varmul, id_scripvoi) 00234 ELSE 00235 ! grid srcA equal grid srcB, no interpolation necessary 00236 src_arrayJ_srcA = src_arrayJ_srcB 00237 ENDIF 00238 00239 ! 00240 !*** 2. Check if the target grids are different 00241 ! If different the interpolation will be done twice 00242 ! ------------------------------------------------- 00243 ! ------------------------------------------------- 00244 00245 IF (grd_name_dstA .EQ. grd_name_dstB) THEN 00246 nbr_dst=1 00247 ELSE 00248 nbr_dst=2 00249 ENDIF 00250 00251 00252 DO ii=1, nbr_dst 00253 00254 IF (ii == 1) THEN 00255 grd_name_dst = grd_name_dstA 00256 lon_dst(:) = lon_dstA(:) 00257 lat_dst(:) = lat_dstA(:) 00258 msk_dst(:) = msk_dstA(:) 00259 ELSE 00260 grd_name_dst = grd_name_dstB 00261 lon_dst(:) = lon_dstB(:) 00262 lat_dst(:) = lat_dstB(:) 00263 msk_dst(:) = msk_dstB(:) 00264 ENDIF 00265 00266 IF (nlogprt .GE. 2) THEN 00267 WRITE (UNIT = nulou,FMT = *) '' 00268 WRITE (UNIT = nulou,FMT = *) & 00269 ' Now making interpolation towards target grid : ', grd_name_dst 00270 CALL FLUSH(nulou) 00271 ENDIF 00272 00273 ! 00274 !*** 3. Calculate and/or read weights, remapping and rotation matrix 00275 ! ------------------------------------------------------------ 00276 ! ------------------------------------------------------------ 00277 ! 00278 !* -- Get the name of the file containing the remapping matrix. 00279 ! 00280 #if defined use_oasis_para || defined use_oasis_cmcc_para 00281 IF (ig_indexoa .le. 9) THEN 00282 WRITE(cl_indexoa,FMT='(I1)') ig_indexoa 00283 ELSE IF (ig_indexoa .le. 99) THEN 00284 WRITE(cl_indexoa,FMT='(I2)') ig_indexoa 00285 ELSE IF (ig_indexoa .le. 999) THEN 00286 WRITE(cl_indexoa,FMT='(I3)') ig_indexoa 00287 ENDIF 00288 #endif 00289 ! 00290 icount = ilenstr(grd_name_srcA,jpeight) 00291 kcount = ilenstr(grd_name_dst, jpeight) 00292 00293 SELECT CASE (map_method) 00294 CASE ('CONSERV') ! conservative remapping 00295 cmapping = & 00296 grd_name_srcA(1:icount)//' to '//grd_name_dst(1:kcount)//' '& 00297 //map_method//' '//normalize_opt(1:4)//' remapping' 00298 #if defined use_oasis_para || defined use_oasis_cmcc_para 00299 IF (ig_indexoa .LE. 9) THEN 00300 crmpfile = & 00301 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00302 //'_'//map_method(1:7)//'_'//normalize_opt(1:4)// & 00303 '_'//cl_indexoa(1:1)//'.nc' 00304 ELSE IF (ig_indexoa .LE. 99) THEN 00305 crmpfile = & 00306 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00307 //'_'//map_method(1:7)//'_'//normalize_opt(1:4)// & 00308 '_'//cl_indexoa(1:2)//'.nc' 00309 ELSE IF (ig_indexoa .LE. 999) THEN 00310 crmpfile = & 00311 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00312 //'_'//map_method(1:7)//'_'//normalize_opt(1:4)// & 00313 '_'//cl_indexoa(1:3)//'.nc' 00314 ENDIF 00315 #else 00316 crmpfile = & 00317 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00318 //'_'//map_method(1:7)//'_'//normalize_opt(1:4)//'.nc' 00319 #endif 00320 ! 00321 CASE DEFAULT 00322 cmapping = & 00323 grd_name_srcA(1:icount)//' to '//grd_name_dst(1:kcount)//' '& 00324 //map_method//' remapping' 00325 #if defined use_oasis_para || defined use_oasis_cmcc_para 00326 IF (ig_indexoa .LE. 9) THEN 00327 crmpfile = & 00328 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00329 //'_'//map_method(1:7)//'_'//cl_indexoa(1:1)//'.nc' 00330 ELSE IF (ig_indexoa .le. 99) THEN 00331 crmpfile = & 00332 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00333 //'_'//map_method(1:7)//'_'//cl_indexoa(1:2)//'.nc' 00334 ELSE IF (ig_indexoa .le. 999) THEN 00335 crmpfile = & 00336 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00337 //'_'//map_method(1:7)//'_'//cl_indexoa(1:3)//'.nc' 00338 ENDIF 00339 #else 00340 crmpfile = & 00341 'rmp_'//grd_name_srcA(1:icount)//'_to_'//grd_name_dst(1:kcount)& 00342 //'_'//map_method(1:7)//'.nc' 00343 #endif 00344 END SELECT 00345 00346 IF (nlogprt .GE. 2) THEN 00347 WRITE (UNIT = nulou,FMT = *) & 00348 ' SCRIP filename : ', crmpfile 00349 CALL FLUSH(nulou) 00350 ENDIF 00351 00352 ! 00353 !*** 3.1 Create and/or open the file with remapping matrix 00354 ! ------------------------------------------------- 00355 ! 00356 stat = NF_OPEN(crmpfile, NF_WRITE, nc_fileid) 00357 IF (stat .NE. NF_NOERR) THEN 00358 ! 00359 !* -- The file does not exist. The remapping matrix has to be created 00360 ! for remapping from source grd_name_srcA to target grd_name_dst 00361 ! 00362 CALL calc_remap_matrix( & 00363 msk_srcA(:), msk_dst(:), & 00364 src_size, dst_size, & 00365 lon_srcA(:), lat_srcA(:), lon_dst(:), lat_dst(:), & 00366 nlon_src, nlat_src, nlon_dst, nlat_dst, & 00367 grd_name_srcA, grd_name_dst, & 00368 map_method, normalize_opt, cdgrdtyp, & 00369 id_sper, cd_sper, & 00370 id_tper, cd_tper, & 00371 rst_type, & 00372 n_srch_bins, crmpfile, & 00373 cmapping, lextrapdone, & 00374 rl_varmul, id_scripvoi ) 00375 00376 stat = NF_OPEN(crmpfile, NF_WRITE, nc_fileid) 00377 00378 ELSE 00379 00380 !* -- The file with remapping matrix existe already 00381 ! 00382 IF (nlogprt .GE. 2) THEN 00383 WRITE (UNIT = nulou,FMT = *) & 00384 'SCRIP file exists with remapping matrix src to dst grid' 00385 WRITE (UNIT = nulou,FMT = *) ' ' 00386 CALL FLUSH(nulou) 00387 ENDIF 00388 00389 END IF !IF (stat .NE. NF_NOERR) 00390 00391 00392 !*** 3.2. If necessary calculate matrix for rotation on srcA grid local to sperical 00393 ! -------------------------------------------------------------------------- 00394 ! 00395 !* Get angles from file grids.nc. 00396 ! If they exist a rotation from local to spherical referntial will be done, 00397 ! if no angles the grid is considered as a spheric referential 00398 ! 00399 CALL hdlerr(NF_OPEN & 00400 ('grids.nc',NF_NOWRITE, nc_gridsid), 'scriprmp_vector') 00401 ang_name = grd_name_srcA(1:icount)//'.ang' 00402 stat = NF_INQ_VARID(nc_gridsid, ang_name, var_id) 00403 00404 CALL hdlerr(NF_CLOSE(nc_gridsid), 'scriprmp_vector') 00405 00406 IF(stat == NF_NOERR) THEN 00407 ll_loc2spher_srcA = .true. 00408 ! 00409 !* Rotaion from local to spherical referential on grd_srcA is needed 00410 !* Check if the rotation matrix Mat_src_loc2spher exists in the remapping file 00411 ! 00412 stat = NF_INQ_VARID(nc_fileid, 'Mat_src_loc2sph', var_id) 00413 00414 IF (stat == NF_NOERR) THEN 00415 !* Read the matrix already existing 00416 IF (ll_single) THEN 00417 CALL hdlerr(NF_GET_VAR_REAL & 00418 (nc_fileid, var_id, mat_loc2sph(:,:,:)), 'scriprmp_vector') 00419 ELSE 00420 CALL hdlerr(NF_GET_VAR_DOUBLE & 00421 (nc_fileid, var_id, mat_loc2sph(:,:,:)), 'scriprmp_vector') 00422 ENDIF 00423 ELSE 00424 !* The matrix has to be calculated and written to the file 00425 !* CALL loc2spher() writes the matrix to netcdf file nc_fileid 00426 ! and returns the matrix mat_loc2sph 00427 CALL loc2spher(grd_name_srcA, src_size, mat_loc2sph(:,:,:), nc_fileid) 00428 ENDIF 00429 00430 ELSE ! The angles does not exist in grids.nc 00431 ll_loc2spher_srcA = .false. 00432 WRITE (UNIT = nulou,FMT = *) & 00433 ' WARNING' 00434 WRITE (UNIT = nulou,FMT = *) & 00435 '***************' 00436 WRITE (UNIT = nulou,FMT = *) & 00437 'file grids.nc contains no angle information' 00438 WRITE (UNIT = nulou,FMT = *) & 00439 'source grid '// grd_name_srcA// & 00440 ' will be considered as a spheric referential' 00441 CALL FLUSH(nulou) 00442 END IF 00443 ! 00444 !*** 3.3 Calculate matrix for projection to cartesian if demanded by user option PROJCART 00445 ! 00446 ! -> calculate matrix from spherical to cartesian referntials on source grid srcA 00447 ! -> calculate matrix from cartesian to spherical referntials on target grid dst 00448 ! 00449 IF ( lprojcart ) THEN 00450 00451 !* On source grid 00452 00453 stat = NF_INQ_VARID(nc_fileid, 'Mat_src_sph2car', var_id) 00454 IF (stat == NF_NOERR) THEN 00455 !* Read the matrix already existing 00456 IF (ll_single) THEN 00457 CALL hdlerr(NF_GET_VAR_REAL & 00458 (nc_fileid, var_id, mat_sph2car(:,:,:)), 'scriprmp_vector') 00459 ELSE 00460 CALL hdlerr(NF_GET_VAR_DOUBLE & 00461 (nc_fileid, var_id, mat_sph2car(:,:,:)), 'scriprmp_vector') 00462 ENDIF 00463 ELSE 00464 !* Calculate the matrix mat_sph2car and write to file nc_fileid 00465 ! 00466 CALL spher2car(lon_srcA(:), lat_srcA(:), src_size, mat_sph2car(:,:,:), nc_fileid) 00467 00468 ENDIF 00469 00470 !* On target grid 00471 00472 stat = NF_INQ_VARID(nc_fileid, 'Mat_dst_car2sph', var_id) 00473 IF (stat == NF_NOERR) THEN 00474 !* Read the matrix already existing 00475 IF (ll_single) THEN 00476 CALL hdlerr(NF_GET_VAR_REAL & 00477 (nc_fileid, var_id, mat_car2sph(:,:,:)), 'scriprmp_vector') 00478 ELSE 00479 CALL hdlerr(NF_GET_VAR_DOUBLE & 00480 (nc_fileid, var_id, mat_car2sph(:,:,:)), 'scriprmp_vector') 00481 ENDIF 00482 ELSE 00483 !* Calculate the matrix mat_car2sph and write to file nc_fileid 00484 ! 00485 CALL car2spher(lon_dst(:), lat_dst(:), dst_size, mat_car2sph(:,:,:), nc_fileid) 00486 00487 ENDIF 00488 00489 ENDIF !IF ( lprojcart ) 00490 00491 ! 00492 !*** 3.4 If necessary calculate matrix for rotation on target grid sperical to local 00493 ! --------------------------------------------------------------------------- 00494 ! 00495 !* Get angles from file grids.nc. 00496 ! If they exist a rotation from spherical to local referntial will be done, 00497 ! if no angles the grid is considered as a spheric referential 00498 ! 00499 CALL hdlerr(NF_OPEN & 00500 ('grids.nc',NF_NOWRITE, nc_gridsid), 'scriprmp_vector') 00501 ang_name = grd_name_dst(1:kcount)//'.ang' 00502 stat = NF_INQ_VARID(nc_gridsid, ang_name, angid) 00503 00504 CALL hdlerr(NF_CLOSE(nc_gridsid), 'scriprmp_vector') 00505 00506 IF (stat == NF_NOERR) THEN 00507 ll_spher2loc_dst = .true. 00508 ! 00509 !* Rotaion from spherical to local referential on grd_dst is needed 00510 ! Check if the rotation matrix Mat_dst_sph2loc exists in the remapping file 00511 ! 00512 stat = NF_INQ_VARID(nc_fileid, 'Mat_dst_sph2loc', var_id) 00513 00514 IF (stat == NF_NOERR) THEN 00515 !* Read the matrix already existing 00516 IF (ll_single) THEN 00517 CALL hdlerr(NF_GET_VAR_REAL & 00518 (nc_fileid, var_id, mat_sph2loc(:,:,:)), 'scriprmp_vector') 00519 ELSE 00520 CALL hdlerr(NF_GET_VAR_DOUBLE & 00521 (nc_fileid, var_id, mat_sph2loc(:,:,:)), 'scriprmp_vector') 00522 ENDIF 00523 ELSE 00524 !* The matrix has to be calculated and written to the file 00525 !* CALL spher2loc() writes the matrix to netcdf file nc_fileid 00526 ! and returns the matrix mat_sph2loc 00527 CALL spher2loc(grd_name_dst, dst_size, mat_sph2loc(:,:,:), nc_fileid) 00528 00529 ENDIF 00530 00531 ELSE ! The angles does not exist in grids.nc 00532 ll_spher2loc_dst = .false. 00533 WRITE (UNIT = nulou,FMT = *) & 00534 ' WARNING' 00535 WRITE (UNIT = nulou,FMT = *) & 00536 '***************' 00537 WRITE (UNIT = nulou,FMT = *) & 00538 'file grids.nc contains no angle information' 00539 WRITE (UNIT = nulou,FMT = *) & 00540 'target grid '// grd_name_dst// & 00541 ' will be considered as a spheric referential' 00542 CALL FLUSH(nulou) 00543 00544 END IF ! IF (stat == NF_NOERR) 00545 00546 ! 00547 !* End of calculation of weight and transformation matrix 00548 !* All matrix do now exist 00549 ! 00550 00551 ! 00552 !*** 4. Rotation and interpolation of the two components on grd_srcA towards 00553 ! the target grid grd_dst 00554 ! ------------------------------------------------------------------- 00555 ! ------------------------------------------------------------------- 00556 ! 00557 !* save the both source components in src_array(:,:) 00558 src_array(:,1) = src_arrayI_srcA(:) 00559 src_array(:,2) = src_arrayJ_srcA(:) 00560 src_array(:,3) = 0 00561 nbr_comp=2 00562 ! 00563 !*** 4.1 Rotate the the vector field components on srcA to spherical referential 00564 ! 00565 IF ( ll_loc2spher_srcA ) THEN 00566 00567 src_array(:,1) = mat_loc2sph(:,1,1) * src_arrayI_srcA(:) + & 00568 mat_loc2sph(:,1,2) * src_arrayJ_srcA(:) 00569 00570 src_array(:,2) = mat_loc2sph(:,2,1) * src_arrayI_srcA(:) + & 00571 mat_loc2sph(:,2,2) * src_arrayJ_srcA(:) 00572 00573 ENDIF 00574 #ifdef __DEBUG 00575 ! The components in spherical referential are saved to vector_debugXXXXXX.nc file. 00576 CALL write_src_array_spheric(src_array(:,1:2), src_size, nlon_src, nlat_src, & 00577 grd_name_srcA, grd_name_dst) 00578 #endif 00579 00580 ! 00581 !*** 4.2 If PROJCART, rotate the the vector field components to cartesian referential 00582 ! 00583 IF (lprojcart) THEN 00584 00585 nbr_comp=3 00586 00587 src_array_buf(:,1) = & 00588 mat_sph2car(:,1,1) * src_array(:,1) + & 00589 mat_sph2car(:,1,2) * src_array(:,2) 00590 00591 src_array_buf(:,2) = & 00592 mat_sph2car(:,2,1) * src_array(:,1) + & 00593 mat_sph2car(:,2,2) * src_array(:,2) 00594 00595 src_array_buf(:,3) = & 00596 mat_sph2car(:,3,1) * src_array(:,1) + & 00597 mat_sph2car(:,3,2) * src_array(:,2) 00598 00599 src_array(:,1)= src_array_buf(:,1) 00600 src_array(:,2)= src_array_buf(:,2) 00601 src_array(:,3)= src_array_buf(:,3) 00602 00603 ENDIF 00604 ! 00605 !*** 4.3 Interpolate scalar the 2 or 3 compontents src_array(:,:) 00606 ! from the source grd_srcA to target grd_dst, result in dst_array(:,:) 00607 ! -------------------------------------------------------------------- 00608 00609 CALL remap_vector_comps (dst_array(:,1:nbr_comp), src_array(:,1:nbr_comp), & 00610 nbr_comp, nc_fileid, & 00611 map_method, cdgrdtyp, order, & 00612 msk_srcA(:), & 00613 id_sper, cd_sper, & 00614 nlon_src, nlat_src, lon_srcA(:), lat_srcA(:), src_size, dst_size) 00615 00616 ! 00617 !** Close remapping file 00618 ! 00619 CALL hdlerr(NF_CLOSE(nc_fileid), 'scriprmp') 00620 00621 ! 00622 !*** 4.4 If PROJCART, rotate dst_array from cartesian to spherical referential 00623 ! --------------------------------------------------------------------- 00624 00625 IF (lprojcart) THEN 00626 00627 #ifdef __DEBUG 00628 ! The components in cartesian referential are saved to vector_debugXXXXXX.nc file 00629 CALL write_cartesian_components(src_array(:,1:3), dst_array(:,1:3), src_size, & 00630 dst_size, nlon_src, nlat_src, nlon_dst, nlat_dst, grd_name_srcA, & 00631 grd_name_dst) 00632 #endif 00633 00634 dst_array_buf(:,1) = & 00635 mat_car2sph(:,1,1) * dst_array(:,1) + & 00636 mat_car2sph(:,1,2) * dst_array(:,2) + & 00637 mat_car2sph(:,1,3) * dst_array(:,3) 00638 00639 dst_array_buf(:,2) = & 00640 mat_car2sph(:,2,1) * dst_array(:,1) + & 00641 mat_car2sph(:,2,2) * dst_array(:,2) + & 00642 mat_car2sph(:,2,3) * dst_array(:,3) 00643 00644 dst_array_buf(:,3) = & 00645 mat_car2sph(:,3,1) * dst_array(:,1) + & 00646 mat_car2sph(:,3,2) * dst_array(:,2) + & 00647 mat_car2sph(:,3,3) * dst_array(:,3) 00648 00649 dst_array(:,1) = dst_array_buf(:,1) 00650 dst_array(:,2) = dst_array_buf(:,2) 00651 dst_array(:,3) = dst_array_buf(:,3) 00652 00653 ENDIF 00654 00655 ! 00656 !*** 4.5 If the target grid is not in a spherical referential 00657 ! then rotate the spherical components towords locals 00658 ! ---------------------------------------------------- 00659 00660 IF (ll_spher2loc_dst) THEN 00661 00662 #ifdef __DEBUG 00663 ! The components in spherical referential are saved to vector_debugXXXXXX.nc file 00664 ! The field K dst_array(:,3) should be close to zero 00665 CALL write_dst_array_spheric(dst_array(:,1:2), dst_size, nlon_dst, nlat_dst, & 00666 grd_name_srcA, grd_name_dst) 00667 #endif 00668 00669 dst_array_buf(:,1) = & 00670 mat_sph2loc(:,1,1) * dst_array(:,1) + & 00671 mat_sph2loc(:,1,2) * dst_array(:,2) 00672 00673 dst_array_buf(:,2) = & 00674 mat_sph2loc(:,2,1) * dst_array(:,1) + & 00675 mat_sph2loc(:,2,2) * dst_array(:,2) 00676 00677 dst_array(:,1) = dst_array_buf(:,1) 00678 dst_array(:,2) = dst_array_buf(:,2) 00679 00680 ENDIF 00681 00682 !* The dst_array is now the I and J components in the local referential 00683 !* on target grid grd_dst 00684 ! 00685 00686 00687 ! 00688 !*** 5. Save the the components that correspond to VECTOR_I and VECTOR_J grid 00689 ! --------------------------------------------------------------------- 00690 ! --------------------------------------------------------------------- 00691 00692 IF (ii == 1 .AND. nbr_dst == 1) THEN 00693 ! There is only one target grid. Save both components calculated above. 00694 dst_arrayI_dstA(:) = dst_array(:,1) 00695 dst_arrayJ_dstB(:) = dst_array(:,2) 00696 ELSEIF (ii == 1) THEN 00697 ! There are 2 target grid and the one just calculated is the grid for VECTOR_I 00698 dst_arrayI_dstA(:) = dst_array(:,1) 00699 ELSE 00700 ! There are 2 target grids and the one just calculated is the grid for VECTOR_J 00701 dst_arrayJ_dstB(:) = dst_array(:,2) 00702 ENDIF 00703 00704 IF (nlogprt .GE. 2) THEN 00705 write(nulou,*)' src_size = ',src_size,'dst_size = ',dst_size 00706 write(nulou,*)' Now finish interpolation towards target grid : ', grd_name_dst 00707 call flush(nulou) 00708 ENDIF 00709 00710 END DO 00711 00712 ! 00713 !*** 6. Test if there are points on the latitudes 90deg north and 90deg south. 00714 ! If there are points on these latitudes, the averege for these points 00715 ! are calculated and distributed. 00716 ! ----------------------------------------------------------------------- 00717 ! ----------------------------------------------------------------------- 00718 00719 CALL check_points_at_poles (dst_arrayI_dstA(:), dst_arrayJ_dstB(:), lat_dstA(:), & 00720 lat_dstB(:), grd_name_dstA, grd_name_dstB, dst_size) 00721 00722 ! 00723 !* End of routine 00724 ! 00725 IF (nlogprt .GE. 2) THEN 00726 WRITE (UNIT = nulou,FMT = *) ' ' 00727 WRITE (UNIT = nulou,FMT = *) & 00728 ' --------- End of routine scriprmp_vector ---------' 00729 CALL FLUSH (nulou) 00730 ENDIF 00731 00732 END SUBROUTINE scriprmp_vector