Oasis3 4.0.2
vector.F90
Go to the documentation of this file.
00001 MODULE vector
00002 !-----------------------------------------------------------------------
00003 !
00004 !** Description: 
00005 !   ------------
00006 !   This module contains subroutines needed for scriprmp_vector
00007 !
00008 !**  History:
00009 !    --------
00010 !    Created   02/2006   J. Ghattas
00011 !
00012 !
00013   USE kinds_mod 
00014   USE constants 
00015   USE mod_parameter
00016   USE grids
00017   USE mod_unitncdf
00018   
00019   IMPLICIT NONE
00020 
00021 #include <netcdf.inc>
00022 
00023 
00024 CONTAINS
00025 
00026 !
00027 !** -----------------------------------------------------------------------
00028 !** -----------------------------------------------------------------------
00029 ! 
00030 
00031   SUBROUTINE calc_remap_matrix( &
00032        src_mask, dst_mask, &
00033        src_size, dst_size, &
00034        lon_srcA, lat_srcA,  lon_dst,  lat_dst, &
00035        nlon_src, nlat_src, nlon_dst, nlat_dst, &
00036        grd_name_srcA, grd_name_dst, &
00037        map_method,   n_opt, cdgrdtyp, &
00038        id_sper,      cd_sper,      &
00039        id_tper,      cd_tper,      &
00040        rst_type,                   &
00041        n_srch_bins,  crmpfile,     &
00042        cmapping,     lextrapdone,  &
00043        rl_varmul,    id_scripvoi   )
00044     
00045 !
00046 !** Description :
00047 !   -------------
00048 ! Calcutation of remapping matrix for interpolation between qource grid grd_name_src 
00049 ! and target grid grd_name_dst. Remapping matrix written to file crmpfile which must 
00050 ! not exist when the this subroutine is called.
00051 !
00052     IMPLICIT NONE
00053 !
00054 !** Input variables
00055 !   ---------------
00056     INTEGER(KIND=int_kind), INTENT(in) :: src_size, dst_size, 
00057          nlon_src, nlat_src, nlon_dst, nlat_dst, 
00058          id_sper, id_tper, n_srch_bins, id_scripvoi
00059     INTEGER(KIND=int_kind), DIMENSION(src_size), INTENT(in) :: src_mask
00060     INTEGER(KIND=int_kind), DIMENSION(dst_size), INTENT(in) :: dst_mask
00061     REAL(KIND=real_kind), DIMENSION(src_size), INTENT(in) :: lon_srcA,  lat_srcA
00062     REAL(KIND=real_kind), DIMENSION(dst_size), INTENT(in) :: lon_dst,  lat_dst
00063     REAL(KIND=real_kind), INTENT(in) :: rl_varmul
00064     CHARACTER(LEN=8), INTENT(in) :: grd_name_srcA, grd_name_dst, n_opt, rst_type
00065     CHARACTER(LEN=8), INTENT(in) :: map_method, cdgrdtyp, cd_sper, cd_tper
00066     CHARACTER(char_len), INTENT(in) :: crmpfile, cmapping
00067     LOGICAL, INTENT(in) :: lextrapdone
00068  
00069 !
00070 !** Local variables
00071 !   ---------------
00072     INTEGER(KIND=int_kind), DIMENSION(src_size) :: sou_mask
00073     INTEGER(KIND=int_kind), DIMENSION(dst_size) :: tgt_mask
00074     CHARACTER(LEN=8) :: normalize_opt
00075     LOGICAL :: lfracnnei
00076     INTEGER(KIND=int_kind) :: ncrn, src_rank, dst_rank, src_dims(2), dst_dims(2)
00077     REAL (KIND=real_kind), DIMENSION(:,:), ALLOCATABLE :: src_corner_lon, src_corner_lat, 
00078          dst_corner_lon, dst_corner_lat
00079 !
00080     CHARACTER(LEN=8) :: cl_tgt     ! indicates target grid 
00081 !
00082 !** ----------------------------------------------------------------------------
00083 !
00084 !
00085     IF (nlogprt .GE. 2) THEN
00086         WRITE (UNIT = nulou,FMT = *)' '
00087         WRITE (UNIT = nulou,FMT = *)'Entering routine calc_remap_matrix'
00088         CALL FLUSH(nulou)
00089     ENDIF
00090 !
00091 !  
00092 !** -- Setting of the mask for the source and the target grid
00093 !       
00094 
00095     sou_mask(:) = 0
00096     tgt_mask(:) = 0
00097     WHERE (src_mask .eq. 1)
00098        sou_mask = 0
00099     END WHERE
00100     WHERE (src_mask .eq. 0)
00101        sou_mask = 1
00102     END WHERE
00103     
00104     WHERE (dst_mask .eq. 1)
00105        tgt_mask = 0
00106     END WHERE
00107     WHERE (dst_mask .eq. 0)
00108        tgt_mask = 1
00109     END WHERE
00110     
00111 !
00112 !** -- Calculate SCRIP remapping matrix : source to destination grid
00113 !
00114     normalize_opt = n_opt
00115     SELECT CASE (normalize_opt)
00116     CASE ('FRACNNEI')
00117        normalize_opt = 'FRACAREA'
00118        lfracnnei = .true.
00119     END SELECT
00120     
00121     IF (nlogprt .GE. 2) THEN 
00122        WRITE (UNIT = nulou,FMT = *) & 
00123             ' Calculation of SCRIP remapping matrix: method = ', &
00124             map_method
00125        WRITE (UNIT = nulou,FMT = *) ' '
00126        call flush(nulou)
00127     ENDIF
00128 !
00129 !** -- Get grid cell corners for conservative remapping
00130 !
00131     ncrn = 4.
00132     ALLOCATE(src_corner_lon(ncrn,src_size), &
00133        src_corner_lat(ncrn,src_size),&
00134        dst_corner_lon(ncrn,dst_size),&
00135        dst_corner_lat(ncrn,dst_size))
00136     src_corner_lon(:,:)= 0.0
00137     src_corner_lat(:,:)= 0.0
00138     dst_corner_lon(:,:)= 0.0
00139     dst_corner_lat(:,:)= 0.0
00140 
00141     IF (map_method == 'CONSERV') THEN     
00142        CALL corners(nlon_src, nlat_src, ncrn,  &
00143             lon_srcA, lat_srcA,                    &
00144             grd_name_srcA, cdgrdtyp, id_sper, cd_sper, &
00145             src_corner_lon, src_corner_lat)
00146        cl_tgt='TARGETGR' 
00147        CALL corners(nlon_dst, nlat_dst, ncrn,    &
00148             lon_dst, lat_dst,                      &
00149             grd_name_dst, cl_tgt, id_tper, cd_tper,  &
00150             dst_corner_lon, dst_corner_lat)
00151     ENDIF
00152 !
00153 !** -- Initialization of grid arrays for SCRIP
00154 !
00155     src_dims(1) = nlon_src
00156     src_dims(2) = nlat_src
00157     dst_dims(1) = nlon_dst
00158     dst_dims(2) = nlat_dst
00159     src_rank    = 2
00160     dst_rank    = 2
00161 
00162     CALL grid_init(map_method, rst_type, n_srch_bins,&
00163        src_size, dst_size, src_dims(:), dst_dims(:),&
00164        src_rank, dst_rank, ncrn, ncrn,&
00165        sou_mask(:), tgt_mask(:), grd_name_srcA, grd_name_dst,&
00166        lat_srcA(:), lon_srcA(:), lat_dst(:), lon_dst(:),&
00167        src_corner_lat(:,:), src_corner_lon(:,:),&
00168        dst_corner_lat(:,:), dst_corner_lon(:,:))
00169 !        
00170 !** -- Calculation of weights and addresses using SCRIP-library
00171 !
00172     CALL scrip(crmpfile, cmapping, map_method, normalize_opt, &
00173          lextrapdone, rl_varmul, id_scripvoi)
00174     
00175     IF (map_method == 'CONSERV') THEN
00176        DEALLOCATE(src_corner_lon, src_corner_lat,&
00177             dst_corner_lon, dst_corner_lat)
00178     ENDIF
00179         
00180 !
00181     IF (nlogprt .GE. 2) THEN
00182         WRITE (UNIT = nulou,FMT = *)' '
00183         WRITE (UNIT = nulou,FMT = *)'Leaving routine calc_remap_matrix'
00184         CALL FLUSH(nulou)
00185     ENDIF
00186 !
00187   END SUBROUTINE calc_remap_matrix
00188 
00189 !
00190 !** -----------------------------------------------------------------------
00191 !** -----------------------------------------------------------------------
00192 ! 
00193 
00194   SUBROUTINE remap_vector_comps (dst_array, src_array, &
00195        nbr_comp, nc_fileid, &
00196        map_method, cdgrdtyp, order, &
00197        src_mask, &
00198        id_sper, cd_sper, &
00199        nlon_src, nlat_src, src_lon, src_lat, src_size, dst_size)
00200 
00201 !
00202 !** Description :
00203 !   -------------
00204 !   Interpolation of  2 or 3 components in src_array(:,:) on source grid using 
00205 !   remapping matrix allready existing in remappingile. Resulting fields in 
00206 !   dst_array on target grid grd_name_dst. Remapping matrix is read from file 
00207 !   already opend with id nc_fileid.
00208 !
00209     IMPLICIT NONE
00210 !
00211 !** Input variables
00212 !   ---------------
00213     INTEGER (KIND=int_kind), INTENT(in) :: nbr_comp, nc_fileid, id_sper, nlon_src, 
00214          nlat_src, src_size, dst_size
00215     REAL (KIND=real_kind), DIMENSION (src_size, nbr_comp), INTENT(in) :: src_array
00216     REAL (KIND=real_kind), DIMENSION (src_size), INTENT(in) :: src_lon, src_lat
00217     CHARACTER (LEN=8), INTENT(in) :: map_method, cdgrdtyp, order, cd_sper
00218     INTEGER (KIND=int_kind), DIMENSION (src_size), INTENT(in) :: src_mask
00219 !
00220 !** Output variables
00221 !   ----------------
00222     REAL (KIND=real_kind), DIMENSION (dst_size, nbr_comp), INTENT(out) :: dst_array
00223 !
00224 !** Local variables
00225 !   ---------------
00226     INTEGER (KIND=int_kind) :: num_wgts, dimid1, num_links, ib, n, varid
00227     
00228     INTEGER (KIND=int_kind), DIMENSION (:), ALLOCATABLE :: src_addr, dst_addr
00229     INTEGER (KIND=int_kind), DIMENSION (src_size) :: sou_mask
00230     
00231     REAL (KIND=real_kind), DIMENSION (:,:), ALLOCATABLE :: weights
00232     
00233     REAL (KIND=real_kind), DIMENSION (:), ALLOCATABLE :: gradient_lat, gradient_lon, 
00234          gradient_i, gradient_j, gradient_ij
00235     
00236     REAL (KIND=real_kind), DIMENSION (dst_size) :: dst_area, dst_frac
00237     
00238     CHARACTER(LEN=11) :: 
00239          csrcadd,             ! string for source grid addresses
00240          cdstadd               ! string for destination grid addresses
00241     CHARACTER(LEN=13) :: 
00242          cdstare,             ! string for destination grid area
00243          cdstfra               ! string for destination grid frac
00244     CHARACTER(LEN=12) :: 
00245          cweight               ! string for weights
00246     REAL (KIND=real_kind), DIMENSION (dst_size, nbr_comp) :: weightot
00247     LOGICAL  ::   ll_weightot
00248     
00249 !
00250 !** ----------------------------------------------------------------------------
00251 !
00252     IF (nlogprt .GE. 2) THEN
00253         WRITE (UNIT = nulou,FMT = *)' '
00254         WRITE (UNIT = nulou,FMT = *)'Entering routine remap_vector_comps'
00255         CALL FLUSH(nulou)
00256     ENDIF
00257 !  
00258 !* Read weights and addresses
00259 ! 
00260 !** Get number of weights
00261 !
00262     SELECT CASE (map_method)
00263     CASE ('CONSERV')          ! conservative remapping
00264        num_wgts = 3.
00265     CASE ('BILINEAR')         ! bilinear remapping
00266        num_wgts = 1.
00267     CASE ('BICUBIC')          ! bicubic remapping   
00268        IF (cdgrdtyp .eq. 'LR') THEN ! logically rectangular
00269           num_wgts = 4.
00270        ELSE                  ! reduced  
00271           num_wgts=1.
00272        ENDIF
00273     CASE ('DISTWGT')          ! distance weighted averaging
00274        num_wgts = 1.
00275     CASE ('GAUSWGT')          ! distance gaussian weighted averaging
00276        num_wgts = 1.
00277     END SELECT
00278   
00279 !  
00280 !** Setting of the mask for the source grid
00281 !       
00282     sou_mask(:) = 0
00283 
00284     WHERE (src_mask .eq. 1)
00285        sou_mask = 0
00286     END WHERE
00287     WHERE (src_mask .eq. 0)
00288        sou_mask = 1
00289     END WHERE
00290 
00291 !  
00292 !** Character strings of weights and addresses
00293 !
00294     csrcadd = 'src_address'
00295     cdstadd = 'dst_address'
00296     cweight = 'remap_matrix'
00297     cdstare = 'dst_grid_area'
00298     cdstfra = 'dst_grid_frac'
00299 !
00300 !** Get matrix size
00301 ! 
00302     CALL hdlerr(NF_INQ_DIMID &
00303          (nc_fileid, 'num_links', dimid1), 'scriprmp_vector')
00304     CALL hdlerr(NF_INQ_DIMLEN &
00305          (nc_fileid, dimid1, num_links), 'scriprmp_vector')
00306 !
00307 !** Array allocation
00308 !
00309     ALLOCATE (src_addr(num_links), dst_addr(num_links), &
00310          weights(num_wgts,num_links))
00311 !
00312 !** Read source grid addresses and weights
00313 !
00314     CALL hdlerr(NF_INQ_VARID &
00315          (nc_fileid, csrcadd, varid), 'scriprmp_vector')
00316     CALL hdlerr(NF_GET_VAR_INT &
00317          (nc_fileid, varid, src_addr), 'scriprmp_vector')
00318     CALL hdlerr(NF_INQ_VARID &
00319          (nc_fileid, cdstadd, varid), 'scriprmp_vector')
00320     CALL hdlerr(NF_GET_VAR_INT &
00321          (nc_fileid, varid, dst_addr), 'scriprmp_vector')
00322     CALL hdlerr(NF_INQ_VARID &
00323          (nc_fileid, cweight, varid), 'scriprmp_vector')
00324     IF (ll_single) THEN
00325        CALL hdlerr(NF_GET_VAR_REAL &
00326             (nc_fileid, varid, weights), 'scriprmp_vector')
00327     ELSE 
00328        CALL hdlerr(NF_GET_VAR_DOUBLE &
00329             (nc_fileid, varid, weights), 'scriprmp_vector') 
00330     ENDIF
00331     CALL hdlerr(NF_INQ_VARID &
00332          (nc_fileid, cdstare, varid), 'scriprmp_vector')
00333     IF (ll_single) THEN
00334        CALL hdlerr(NF_GET_VAR_REAL &
00335             (nc_fileid, varid, dst_area), 'scriprmp_vector')
00336     ELSE
00337        CALL hdlerr(NF_GET_VAR_DOUBLE &
00338             (nc_fileid, varid, dst_area), 'scriprmp_vector') 
00339     ENDIF
00340     CALL hdlerr(NF_INQ_VARID &
00341          (nc_fileid, cdstfra, varid), 'scriprmp_vector')
00342     IF (ll_single) THEN
00343        CALL hdlerr(NF_GET_VAR_REAL &
00344             (nc_fileid, varid, dst_frac), 'scriprmp_vector') 
00345     ELSE
00346        CALL hdlerr(NF_GET_VAR_DOUBLE &
00347             (nc_fileid, varid, dst_frac), 'scriprmp_vector') 
00348     ENDIF
00349 
00350 !
00351 !** Do the matrix multiplication for the 2 or 3 components
00352 !
00353     ll_weightot  = .false.
00354     weightot(:,:)  = 0.0
00355     dst_array(:,:) = 0.
00356   
00357     SELECT CASE (map_method)
00358      
00359     CASE ('CONSERV')     ! conservative remapping       
00360        SELECT CASE (order)    
00361        CASE ('FIRST')        ! first order remapping 
00362           DO ib=1,nbr_comp
00363              DO n = 1, num_links
00364                IF (src_addr(n) .NE. 0) THEN
00365                 dst_array(dst_addr(n),ib) = dst_array(dst_addr(n),ib)&
00366                      + weights(1,n) * src_array(src_addr(n),ib)
00367                 weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) &
00368                          + weights(1,n)
00369                ENDIF
00370              END DO
00371           END DO
00372        CASE ('SECOND')       ! second order remapping (including gradients)
00373           IF (cdgrdtyp .ne. 'LR') THEN
00374              WRITE (UNIT = nulou,FMT = *) &
00375                   'Field gradient cannot be calculated'
00376              WRITE (UNIT = nulou,FMT = *) &
00377                   'by Oasis as grid is not logically rectangular'
00378              CALL HALTE('STOP in scriprmp (CONSERV)')
00379           ENDIF
00380           ALLOCATE(gradient_lat(src_size), gradient_lon(src_size))
00381           
00382           DO ib=1, nbr_comp
00383              CALL gradient(nlon_src, nlat_src, src_array(:,ib), &
00384                   sou_mask, src_lat, src_lon, id_sper, cd_sper, &
00385                   gradient_lat, gradient_lon)
00386              
00387              DO n = 1, num_links
00388                IF (src_addr(n) .NE. 0) THEN
00389                 dst_array(dst_addr(n),ib) = dst_array(dst_addr(n),ib)&
00390                      + weights(1,n) * src_array(src_addr(n),ib) &
00391                      + weights(2,n) * gradient_lat(src_addr(n)) &
00392                      + weights(3,n) * gradient_lon(src_addr(n))
00393                 weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) & 
00394                      + weights(1,n) + weights(2,n) + weights(3,n)
00395                ENDIF
00396              ENDDO
00397           END DO
00398           DEALLOCATE(gradient_lat, gradient_lon)      
00399        END SELECT! order      
00400     CASE ('BILINEAR')        ! bilinear remapping 
00401        DO ib=1, nbr_comp
00402           DO n = 1, num_links
00403             IF (src_addr(n) .NE. 0) THEN
00404              dst_array(dst_addr(n),ib) = dst_array(dst_addr(n),ib) &
00405                   + weights(1,n) * src_array(src_addr(n),ib)
00406              weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) & 
00407                   + weights(1,n)
00408             ENDIF
00409           ENDDO
00410        END DO
00411     CASE ('BICUBIC')         ! bicubic remapping    
00412        SELECT CASE (cdgrdtyp) !
00413        CASE ('LR')          ! logically rectangular         
00414           ALLOCATE(gradient_i(src_size), gradient_j(src_size), &
00415                gradient_ij(src_size))
00416           
00417           DO ib=1, nbr_comp
00418              CALL gradient_bicubic(nlon_src,nlat_src,src_array(:,ib), &
00419                   sou_mask, src_lat, src_lon, id_sper, cd_sper, &
00420                   gradient_i, gradient_j, gradient_ij)
00421              
00422              DO n = 1, num_links
00423                IF (src_addr(n) .NE. 0) THEN
00424                 dst_array(dst_addr(n),ib) = dst_array(dst_addr(n),ib) &
00425                      + weights(1,n) * src_array(src_addr(n),ib) &
00426                      + weights(2,n) * gradient_i(src_addr(n)) &
00427                      + weights(3,n) * gradient_j(src_addr(n)) &
00428                      + weights(4,n) * gradient_ij(src_addr(n))
00429                 weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) &
00430                      + weights(1,n) + weights(2,n) + weights(3,n) + weights(4,n)
00431                ENDIF
00432              ENDDO
00433           END DO
00434           
00435           DEALLOCATE(gradient_i, gradient_j, gradient_ij)     
00436        CASE ('D')           !reduced      
00437           DO ib=1, nbr_comp 
00438              DO n = 1, num_links
00439                IF (src_addr(n) .NE. 0) THEN
00440                 dst_array(dst_addr(n),ib) =  dst_array(dst_addr(n),ib) &
00441                      + weights(1,n) * src_array(src_addr(n),ib)
00442                 weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) & 
00443                      + weights(1,n)
00444                ENDIF
00445              ENDDO
00446           ENDDO
00447        END SELECT
00448     CASE ('DISTWGT')         ! distance weighted average
00449        DO ib=1, nbr_comp
00450           DO n = 1, num_links
00451             IF (src_addr(n) .NE. 0) THEN
00452              dst_array(dst_addr(n),ib) = dst_array(dst_addr(n),ib) &
00453                   + weights(1,n) * src_array(src_addr(n),ib)
00454              weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) &
00455                   + weights(1,n)
00456             ENDIF
00457           ENDDO
00458        ENDDO
00459     CASE ('GAUSWGT')          ! distance gaussian weighted average
00460        DO ib=1, nbr_comp
00461           DO n = 1, num_links
00462             IF (src_addr(n) .NE. 0) THEN
00463              dst_array(dst_addr(n),ib) = dst_array(dst_addr(n),ib) &
00464                   + weights(1,n) * src_array(src_addr(n),ib)
00465              weightot(dst_addr(n),ib) = weightot(dst_addr(n),ib) &
00466                   + weights(1,n) 
00467             ENDIF
00468           ENDDO
00469        ENDDO
00470     END SELECT  ! remapping method
00471    
00472     IF (ll_weightot) THEN
00473         DO ib=1, nbr_comp
00474           DO n = 1, dst_size
00475             IF (weightot(n,ib) .LT. EPSILON(1.)) dst_array(n,ib) = 1.0E+20
00476           ENDDO
00477         ENDDO
00478     ENDIF
00479     
00480     DEALLOCATE (src_addr, dst_addr, weights)
00481     
00482 !
00483     IF (nlogprt .GE. 2) THEN
00484         WRITE (UNIT = nulou,FMT = *)' '
00485         WRITE (UNIT = nulou,FMT = *)'Leaving routine remap_vector_comps'
00486         CALL FLUSH(nulou)
00487     ENDIF
00488 ! 
00489   END SUBROUTINE remap_vector_comps
00490  
00491 !
00492 !** -----------------------------------------------------------------------
00493 !** -----------------------------------------------------------------------
00494 ! 
00495 
00496   SUBROUTINE check_points_at_poles (arrayA, arrayB, latA, latB, grd_nameA, &
00497        grd_nameB, dst_size)
00498 !
00499 !** Description :
00500 !   -------------
00501 !   Test if there are points on the latitudes 90deg north and 90deg south.
00502 !   If there are points on these latitudes, the averege for these points 
00503 !   in arrayA and arrayB are calculated and distributed. arrayA and arrayB
00504 !   are modified if necessary.
00505 !   
00506     IMPLICIT NONE
00507 !
00508 !** Input variables
00509 !   ----------------
00510     INTEGER(KIND=int_kind), INTENT(in) :: dst_size
00511     REAL (KIND=real_kind), DIMENSION(dst_size), INTENT(in):: latA, latB
00512     CHARACTER(LEN=8), INTENT(in) :: grd_nameA, grd_nameB
00513 !
00514 !** OutInput variables
00515 !   ------------------
00516     REAL (KIND=real_kind), DIMENSION(dst_size), INTENT(inout):: 
00517          arrayA,   ! VECTOR_I field on target grid dstA
00518          arrayB     ! VECTOR_J field on target grid dstB
00519 !
00520 !** Local variables
00521 !   ----------------
00522     INTEGER(KIND=int_kind) :: nbr_N, nbr_S, n
00523     REAL(kind=real_kind) :: ave_N, ave_S, latpolN, latpolS
00524 !
00525 !** ----------------------------------------------------------------------------
00526 !
00527     IF (nlogprt .GE. 2) THEN
00528         WRITE (UNIT = nulou,FMT = *)' '
00529         WRITE (UNIT = nulou,FMT = *)'Entering routine check_points_at_poles'
00530         CALL FLUSH(nulou)
00531     ENDIF
00532 !     
00533     latpolN = pi*half
00534     latpolS = -pi*half
00535     nbr_N = 0
00536     nbr_S = 0
00537     ave_N = 0.0
00538     ave_S = 0.0
00539     
00540     DO n = 1, dst_size
00541        IF (latA(n) == latpolN) THEN
00542           nbr_N = nbr_N + 1
00543           ave_N= ave_N + arrayA(n)
00544        ELSE IF (latA(n) == latpolS) THEN
00545           nbr_S = nbr_S + 1
00546           ave_S= ave_S + arrayA(n)
00547        END IF
00548     END DO
00549     
00550     IF (nbr_N .NE. 0) THEN
00551        ave_N = ave_N/nbr_N
00552        WHERE (latA == latpolN)
00553           arrayA = ave_N
00554        END WHERE
00555     END IF
00556     
00557     IF (nbr_S .NE. 0) THEN
00558        ave_S = ave_S/nbr_S
00559        WHERE (latA .EQ. latpolS)
00560           arrayA = ave_S
00561        END WHERE
00562     END IF
00563 !
00564     IF (nlogprt .GE. 2) THEN    
00565         WRITE (UNIT = nulou,FMT = *) ' '
00566         WRITE (UNIT = nulou,FMT = *) 'For target grid : ', grd_nameA
00567         WRITE (UNIT = nulou,FMT = *) nbr_N,' points at the north pole '
00568         WRITE (UNIT = nulou,FMT = *) nbr_S,' points at the south pole '
00569         WRITE (UNIT = nulou,FMT = *) ' '
00570         IF (nbr_N/=0 .OR. nbr_S/=0) THEN
00571             WRITE (UNIT = nulou,FMT = *) 'Average of field component I at north pole : ', ave_N
00572             WRITE (UNIT = nulou,FMT = *) 'Average of field component I at south pole : ', ave_S
00573         ENDIF
00574         CALL FLUSH (nulou)
00575     ENDIF
00576 !     
00577 !** The same calculation for the second target grid 
00578 !
00579     nbr_N = 0
00580     nbr_S = 0
00581     ave_N = 0.0
00582     ave_S = 0.0
00583   
00584     DO n = 1, dst_size
00585        IF (latB(n) == latpolN) THEN
00586           nbr_N = nbr_N + 1
00587           ave_N= ave_N + arrayB(n)
00588        ELSE IF (latB(n) == latpolS) THEN
00589           nbr_S = nbr_S + 1
00590           ave_S= ave_S + arrayB(n)
00591        END IF
00592     END DO
00593     
00594     IF (nbr_N .NE. 0) THEN
00595        ave_N = ave_N/nbr_N
00596        WHERE (latB == latpolN)
00597           arrayB = ave_N
00598        END WHERE
00599     END IF
00600     
00601     IF (nbr_S .NE. 0) THEN
00602        ave_S = ave_S/nbr_S
00603        WHERE (latB .EQ. latpolS)
00604           arrayB = ave_S
00605        END WHERE
00606     END IF
00607 !
00608     IF (nlogprt .GE. 2) THEN    
00609         IF (grd_nameA .NE. grd_nameB) THEN
00610             WRITE (UNIT = nulou,FMT = *) ' '
00611             WRITE (UNIT = nulou,FMT = *) 'For target grid : ', grd_nameB
00612             WRITE (UNIT = nulou,FMT = *) nbr_N,' points at the north pole '
00613             WRITE (UNIT = nulou,FMT = *) nbr_S,' points at the south pole '
00614             WRITE (UNIT = nulou,FMT = *) ' '
00615         ENDIF
00616         IF (nbr_N/=0 .OR. nbr_S/=0) THEN
00617             WRITE (UNIT = nulou,FMT = *) 'Average of field component J at north pole : ', ave_N
00618             WRITE (UNIT = nulou,FMT = *) 'Average of field component J at south pole : ', ave_S
00619         ENDIF
00620 !
00621         WRITE (UNIT = nulou,FMT = *)' '
00622         WRITE (UNIT = nulou,FMT = *)'Leaving routine check_points_at_poles'
00623         CALL FLUSH(nulou)
00624     ENDIF
00625 !         
00626   END SUBROUTINE check_points_at_poles
00627 
00628 !
00629 !** -----------------------------------------------------------------------
00630 !** -----------------------------------------------------------------------
00631 ! 
00632 
00633   SUBROUTINE write_src_array_spheric(array, array_size, nlon, nlat, &
00634        grd_name_src, grd_name_dst)
00635 !
00636 !** Description
00637 !   -----------
00638 !   This routine will write the 2 spherical components given in 'array' in 
00639 !   netcdf file vector_debug.nc. The file will first be created.
00640 !
00641     IMPLICIT NONE
00642 !
00643 !** Input variables
00644 !  
00645     INTEGER (KIND=int_kind), INTENT(in) :: array_size, nlon, nlat
00646     REAL (KIND=real_kind), DIMENSION(array_size,2), INTENT(in) :: array
00647     CHARACTER(LEN=8), INTENT(in) :: grd_name_src, grd_name_dst
00648 !
00649 !** Local variables
00650 !
00651     INTEGER(KIND=int_kind) :: dim_id(2), nc_fileid, dimI_id, dimJ_id, stat, 
00652          varI_id, varJ_id, icount, kcount
00653     INTEGER(KIND=int_kind) :: ilenstr
00654     CHARACTER(char_len) :: text, filename
00655 !
00656 !** --------------------------------------------------------------------------
00657 !
00658     IF (nlogprt .GE. 2) THEN
00659         WRITE(nulou,*) '   '
00660         WRITE(nulou,*) ' Entering routine write_src_array_spheric'
00661         call flush(nulou)
00662     ENDIF
00663 !  
00664 !
00665 !** Create the file vector_debug.nc and define the dimensions
00666 !
00667 
00668     icount = ilenstr(grd_name_src,jpeight)
00669     kcount = ilenstr(grd_name_dst, jpeight)
00670     filename='vector_debug_'//grd_name_src(1:icount)//'_to_'//grd_name_dst(1:kcount)//'.nc'
00671     CALL hdlerr(NF_CREATE(filename, 0, nc_fileid), 'write_src_array_spheric')
00672 !
00673     IF (nlogprt .GE. 2) THEN
00674         WRITE (UNIT = nulou,FMT = *) ' '
00675         WRITE (UNIT = nulou,FMT = *) filename,' is created containg fields in spheric and'
00676         WRITE (UNIT = nulou,FMT = *) ' eventually cartesian referentials'
00677         WRITE (UNIT = nulou,FMT = *) ' '
00678         CALL FLUSH(nulou)
00679     ENDIF
00680 !    
00681     CALL hdlerr(NF_DEF_DIM &
00682          (nc_fileid,'src_grid_dim_I',nlon,dimI_id), 'write_src_array_spheric')
00683     
00684     CALL hdlerr(NF_DEF_DIM &
00685          (nc_fileid,'src_grid_dim_J',nlat,dimJ_id), 'write_src_array_spheric')
00686     
00687     dim_id(1) = dimI_id
00688     dim_id(2) = dimJ_id
00689 !    
00690 !** Define variable for component I    
00691 !
00692     CALL hdlerr(NF_DEF_VAR &
00693      (nc_fileid,'Comp_I_src_spheric',NF_DOUBLE,2,dim_id,varI_id), &
00694          'write_src_array_spheric')     
00695 
00696     text = 'Component I in spherical referential on source grid '//grd_name_src
00697 
00698     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varI_id, 'array',&
00699      LEN(text),text),'write_src_array_spheric')
00700 !
00701 !** Define variable for component J   
00702 !
00703     CALL hdlerr(NF_DEF_VAR &
00704      (nc_fileid,'Comp_J_src_spheric',NF_DOUBLE,2,dim_id,varJ_id), &
00705          'write_src_array_spheric')     
00706 
00707     text = 'Component J in spherical referential on source grid '//grd_name_src
00708 
00709     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varJ_id, 'array',&
00710      LEN(text),text),'write_src_array_spheric')
00711     
00712     CALL hdlerr(NF_ENDDEF(nc_fileid), 'write_src_array_spheric')
00713     
00714 !
00715 !** Put the component I and J into file
00716 !
00717     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00718      (nc_fileid,varI_id,array(:,1)),'write_src_array_spheric')
00719 
00720     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00721      (nc_fileid,varJ_id,array(:,2)),'write_src_array_spheric')
00722 
00723     CALL hdlerr(NF_CLOSE(nc_fileid),'write_src_array_spheric')
00724 !
00725     IF (nlogprt .GE. 2) THEN
00726         WRITE(nulou,*) '   '
00727         WRITE(nulou,*) ' Entering routine write_src_array_spheric'
00728         call flush(nulou)
00729     ENDIF
00730 !    
00731   END SUBROUTINE write_src_array_spheric
00732 
00733 !
00734 !** -----------------------------------------------------------------------
00735 !** -----------------------------------------------------------------------
00736 ! 
00737 
00738   SUBROUTINE write_dst_array_spheric(array, array_size, nlon, nlat, &
00739        grd_name_src, grd_name_dst)
00740 !
00741 !** Description
00742 !   -----------
00743 !   This routine will write the 3 spherical components given in 'array' in 
00744 !   netcdf file vector_debug_XXX_to_YYY.nc. The file has to existe(it is created by 
00745 !   call to write_src_array_spheric).
00746 ! 
00747     IMPLICIT NONE
00748 !  
00749 !** Input variables
00750 !   ---------------
00751     INTEGER (KIND=int_kind), INTENT(in) :: array_size, nlon, nlat
00752     REAL (KIND=real_kind), DIMENSION(array_size,3), INTENT(in) :: array
00753     CHARACTER(LEN=8), INTENT(in) :: grd_name_src, grd_name_dst
00754 !
00755 !** Local variables
00756 !   ---------------
00757     INTEGER(KIND=int_kind) :: dim_id(2), nc_fileid, dimI_id, dimJ_id, 
00758          stat, varI_id, varJ_id, varK_id, icount, kcount
00759     INTEGER(KIND=int_kind) :: ilenstr
00760     CHARACTER(char_len) :: text, filename
00761 !
00762 !** -----------------------------------------------------------------------
00763 !
00764     IF (nlogprt .GE. 2) THEN
00765         WRITE(nulou,*) '   '
00766         WRITE(nulou,*) ' Entering routine write_dst_array_spheric'
00767         call flush(nulou)
00768     ENDIF
00769 !
00770 !** Open the file vector_debug_XXX_to_YYY.nc and define the dimensions
00771 !  
00772     icount = ilenstr(grd_name_src,jpeight)
00773     kcount = ilenstr(grd_name_dst, jpeight)
00774     filename='vector_debug_'//grd_name_src(1:icount)//'_to_'//grd_name_dst(1:kcount)//'.nc'
00775     CALL hdlerr(NF_OPEN(filename, NF_WRITE, nc_fileid), 'write_dst_array_spheric')
00776     
00777     CALL hdlerr(NF_REDEF(nc_fileid), 'write_dst_array_spheric')
00778 
00779     stat=NF_INQ_DIMID(nc_fileid,'dst_grid_dim_I',dimI_id)
00780     IF (stat .NE. NF_NOERR) CALL hdlerr(NF_DEF_DIM &
00781          (nc_fileid,'dst_grid_dim_I',nlon,dimI_id), 'write_dst_array_spheric')
00782 
00783     stat=NF_INQ_DIMID(nc_fileid,'dst_grid_dim_J',dimJ_id)
00784     IF (stat .NE. NF_NOERR) CALL hdlerr(NF_DEF_DIM &
00785          (nc_fileid,'dst_grid_dim_J',nlat,dimJ_id), 'write_dst_array_spheric')
00786     
00787     dim_id(1) = dimI_id
00788     dim_id(2) = dimJ_id
00789 !    
00790 !** Define variable for component I 
00791 !
00792     CALL hdlerr(NF_DEF_VAR &
00793      (nc_fileid,'Comp_I_dst_spheric',NF_DOUBLE,2,dim_id,varI_id), &
00794          'write_dst_array_spheric')     
00795 
00796     text = 'Component I in spherical referential on target grid '//grd_name_dst
00797 
00798     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varI_id, 'array',&
00799      LEN(text),text),'write_dst_array_spheric')
00800 !
00801 !* Defining variable for component J   
00802 !
00803     CALL hdlerr(NF_DEF_VAR &
00804      (nc_fileid,'Comp_J_dst_spheric',NF_DOUBLE,2,dim_id,varJ_id), &
00805          'write_dst_array_spheric')     
00806 
00807     text = 'Component J in spherical referential on target grid '//grd_name_dst
00808     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varJ_id, 'array',&
00809      LEN(text),text),'write_dst_array_spheric')
00810 !    
00811 !* Defining variable for component K
00812 !
00813     CALL hdlerr(NF_DEF_VAR &
00814      (nc_fileid,'Comp_K_dst_spheric',NF_DOUBLE,2,dim_id,varK_id), &
00815          'write_dst_array_spheric')     
00816 
00817     text = 'Component K in spherical referential on target grid '//grd_name_dst
00818     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varK_id, 'array',&
00819      LEN(text),text),'write_dst_array_spheric')
00820     
00821     CALL hdlerr(NF_ENDDEF(nc_fileid), 'write_src_array_spheric')
00822 !
00823 !* Putting the fields into the file
00824 !
00825     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00826      (nc_fileid,varI_id,array(:,1)),'write_dst_array_spheric')
00827 
00828     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00829      (nc_fileid,varJ_id,array(:,2)),'write_dst_array_spheric')
00830 
00831     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00832      (nc_fileid,varK_id,array(:,3)),'write_dst_array_spheric')
00833 
00834     CALL hdlerr(NF_CLOSE(nc_fileid),'write_src_array_spheric')
00835 !
00836     IF (nlogprt .GE. 2) THEN
00837         WRITE(nulou,*) '   '
00838         WRITE(nulou,*) ' Leaving routine write_dst_array_spheric'
00839         call flush(nulou)
00840     ENDIF
00841 !    
00842   END SUBROUTINE write_dst_array_spheric
00843 
00844 !
00845 !** -----------------------------------------------------------------------
00846 !** -----------------------------------------------------------------------
00847 ! 
00848 
00849   SUBROUTINE  write_cartesian_components(src_array, dst_array, src_size, dst_size, &
00850        nlon_src, nlat_src, nlon_dst, nlat_dst, grd_name_src, grd_name_dst)
00851 !
00852 !** Description
00853 !   -----------
00854 ! This routine will write the 3 cartesian components on soure and target grid in 
00855 ! netcdf file vector_debug_XXX_to_YYY.nc. The file has to existe(it is created by 
00856 ! call to write_src_array_spheric).
00857 !
00858     IMPLICIT NONE
00859 !  
00860 !** Input variables
00861 !   ---------------    
00862     INTEGER (KIND=int_kind), INTENT(in) :: src_size, dst_size, 
00863          nlon_src, nlat_src, nlon_dst, nlat_dst
00864     REAL (KIND=real_kind), DIMENSION(src_size,3), INTENT(in) :: src_array
00865     REAL (KIND=real_kind), DIMENSION(dst_size,3), INTENT(in) :: dst_array
00866     CHARACTER(LEN=8), INTENT(in) :: grd_name_src, grd_name_dst
00867 !
00868 !** Local variables
00869 !   ---------------
00870 !
00871     INTEGER(KIND=int_kind) :: dimsrc_id(2), dimdst_id(2), nc_fileid, 
00872          dimI_id, dimJ_id, stat, 
00873          varXsrc_id, varXdst_id, varYsrc_id, varYdst_id, varZsrc_id, varZdst_id, 
00874          icount, kcount
00875     INTEGER(KIND=int_kind) :: ilenstr
00876     CHARACTER(char_len) :: text, filename
00877 !
00878 !** ----------------------------------------------------------------------------
00879 !
00880     IF (nlogprt .GE. 2) THEN
00881         WRITE(nulou,*) '   '
00882         WRITE(nulou,*) ' Entering routine write_cartesian_components'
00883         call flush(nulou)
00884     ENDIF
00885 !
00886 !** Open the file vector_debug_XXX_to_YYY.nc and define the dimensions
00887 !
00888     
00889     icount = ilenstr(grd_name_src,jpeight)
00890     kcount = ilenstr(grd_name_dst, jpeight)
00891     filename='vector_debug_'//grd_name_src(1:icount)//'_to_'//grd_name_dst(1:kcount)//'.nc'
00892     CALL hdlerr(NF_OPEN(filename, NF_WRITE, nc_fileid), 'write_cartesian_components')
00893     
00894     CALL hdlerr(NF_REDEF(nc_fileid), 'write_cartesian_components')
00895 !
00896 !** Define dimension for src grid
00897 !
00898     stat=NF_INQ_DIMID(nc_fileid,'src_grid_dim_I',dimI_id)
00899     IF (stat .NE. NF_NOERR) CALL hdlerr(NF_DEF_DIM &
00900          (nc_fileid,'src_grid_dim_I',nlon_src,dimI_id), 'write_cartesian_components')
00901 
00902     stat=NF_INQ_DIMID(nc_fileid,'src_grid_dim_J',dimJ_id)
00903     IF (stat .NE. NF_NOERR) CALL hdlerr(NF_DEF_DIM &
00904          (nc_fileid,'src_grid_dim_J',nlat_src,dimJ_id), 'write_cartesian_components')
00905     
00906     dimsrc_id(1) = dimI_id
00907     dimsrc_id(2) = dimJ_id
00908 !
00909 !** Define dimension for dst grid
00910 !
00911     stat=NF_INQ_DIMID(nc_fileid,'dst_grid_dim_I',dimI_id)
00912     IF (stat .NE. NF_NOERR) CALL hdlerr(NF_DEF_DIM &
00913          (nc_fileid,'dst_grid_dim_I',nlon_dst,dimI_id), 'write_cartesian_components')
00914 
00915     stat=NF_INQ_DIMID(nc_fileid,'dst_grid_dim_J',dimJ_id)
00916     IF (stat .NE. NF_NOERR) CALL hdlerr(NF_DEF_DIM &
00917          (nc_fileid,'dst_grid_dim_J',nlat_dst,dimJ_id), 'write_cartesian_components')
00918     
00919     dimdst_id(1) = dimI_id
00920     dimdst_id(2) = dimJ_id
00921 
00922 !    
00923 !* Define src and dst variables for component X
00924 !
00925     CALL hdlerr(NF_DEF_VAR &
00926      (nc_fileid,'Comp_X_cart_src',NF_DOUBLE,2,dimsrc_id, varXsrc_id), &
00927          'write_cartesian_components')     
00928     text = 'Component X in cartesian referential on source grid '//grd_name_src
00929     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varXsrc_id, 'array',&
00930      LEN(text),text),'write_cartesian_components')
00931 
00932     CALL hdlerr(NF_DEF_VAR &
00933      (nc_fileid,'Comp_X_cart_dst',NF_DOUBLE,2,dimdst_id, varXdst_id), &
00934          'write_cartesian_components')     
00935     text = 'Component X in cartesian referential on target grid '//grd_name_dst
00936     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varXdst_id, 'array',&
00937      LEN(text),text),'write_cartesian_components')
00938 
00939 
00940 !    
00941 !* Define src and dst variables for component Y
00942 !
00943     CALL hdlerr(NF_DEF_VAR &
00944      (nc_fileid,'Comp_Y_cart_src',NF_DOUBLE,2,dimsrc_id, varYsrc_id), &
00945          'write_cartesian_components')     
00946     text = 'Component Y in cartesian referential on source grid '//grd_name_src
00947     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varYsrc_id, 'array',&
00948      LEN(text),text),'write_cartesian_components')
00949 
00950     CALL hdlerr(NF_DEF_VAR &
00951      (nc_fileid,'Comp_Y_cart_dst',NF_DOUBLE,2,dimdst_id, varYdst_id), &
00952          'write_cartesian_components')     
00953     text = 'Component Y in cartesian referential on target grid '//grd_name_dst
00954     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varYdst_id, 'array',&
00955      LEN(text),text),'write_cartesian_components')
00956 
00957 
00958 !    
00959 !* Define src and dst variables for component Z
00960 !
00961     CALL hdlerr(NF_DEF_VAR &
00962      (nc_fileid,'Comp_Z_cart_src',NF_DOUBLE,2,dimsrc_id, varZsrc_id), &
00963          'write_cartesian_components')     
00964     text = 'Component Z in cartesian referential on source grid '//grd_name_src
00965     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varZsrc_id, 'array',&
00966      LEN(text),text),'write_cartesian_components')
00967 
00968     CALL hdlerr(NF_DEF_VAR &
00969      (nc_fileid,'Comp_Z_cart_dst',NF_DOUBLE,2,dimdst_id, varZdst_id), &
00970          'write_cartesian_components')     
00971     text = 'Component Z in cartesian referential on target grid '//grd_name_dst
00972     CALL hdlerr(NF_PUT_ATT_TEXT(nc_fileid,varZdst_id, 'array',&
00973      LEN(text),text),'write_cartesian_components')
00974 
00975     
00976     CALL hdlerr(NF_ENDDEF(nc_fileid), 'write_src_array_spheric')
00977     
00978 !
00979 !* Putting the fields into the file
00980 !
00981     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00982      (nc_fileid,varXsrc_id,src_array(:,1)),'write_cartesian_components')
00983     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00984      (nc_fileid,varXdst_id,dst_array(:,1)),'write_cartesian_components')
00985 
00986     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00987      (nc_fileid,varYsrc_id,src_array(:,2)),'write_cartesian_components')
00988     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00989      (nc_fileid,varYdst_id,dst_array(:,2)),'write_cartesian_components')
00990 
00991     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00992      (nc_fileid,varZsrc_id,src_array(:,3)),'write_cartesian_components')
00993     CALL hdlerr(NF_PUT_VAR_DOUBLE &
00994      (nc_fileid,varZdst_id,dst_array(:,3)),'write_cartesian_components')
00995 
00996 
00997     CALL hdlerr(NF_CLOSE(nc_fileid),'write_src_array_spheric')
00998 !
00999     IF (nlogprt .GE. 2) THEN
01000         WRITE(nulou,*) '   '
01001         WRITE(nulou,*) ' Leaving routine write_cartesian_components'
01002         call flush(nulou)
01003     ENDIF
01004 !
01005   END SUBROUTINE write_cartesian_components
01006 
01007 !
01008 !** -----------------------------------------------------------------------
01009 !** -----------------------------------------------------------------------
01010 ! 
01011     
01012 END MODULE vector
 All Data Structures Namespaces Files Functions Variables Defines