prismtrs_remap_conserv.F90

Go to the documentation of this file.
00001 !------------------------------------------------------------------------
00002 ! Copyright 2006-2010, CERFACS, Toulouse, France.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PRISMTrs_remap_conserv
00008 !
00009 ! !INTERFACE
00010 subroutine prismtrs_remap_conserv (     &
00011    grid1_size, grid2_size,              &
00012    grid1_corners, grid2_corners,        &
00013    id_src_lonlatz_size,                 &
00014    id_index_size1,                      &
00015    grid1_corner_lat, grid1_corner_lon,  &
00016    grid2_corner_lat, grid2_corner_lon,  &
00017    ida_nbsrccells_pertgtpt,             &
00018    ida_index_array,                     &
00019    ida_srcepio_add,                     &
00020    id_epio_id,                          &
00021    id_interp_id,                        &
00022    id_idim,                             &
00023    num_wts,                             &
00024    id_err)
00025 
00026 !
00027 ! !USES:
00028   USE PRISMDrv, dummy_INTERFACE => PRISMTrs_remap_conserv
00029   IMPLICIT NONE
00030 !
00031 ! !PARAMETERS:
00032 !
00033   INTEGER :: grid1_size, grid2_size ! Source and target epio size
00034   !
00035   INTEGER :: grid1_corners, grid2_corners
00036   INTEGER :: id_src_lonlatz_size ! Size of array containing source corner info
00037   INTEGER :: id_index_size1 ! Size of array containing info of all source cells
00038   ! contributing to all epio target cells (sum of ida_nbsrccells_pertgtpt(:))
00039   DOUBLE PRECISION, DIMENSION (id_src_lonlatz_size)       :: grid1_corner_lat
00040   DOUBLE PRECISION, DIMENSION (id_src_lonlatz_size)       :: grid1_corner_lon
00041   DOUBLE PRECISION, DIMENSION (grid2_size, grid2_corners) :: grid2_corner_lat
00042   DOUBLE PRECISION, DIMENSION (grid2_size, grid2_corners) :: grid2_corner_lon
00043   ! Number of source cells contributing to the rremapping of each target cell
00044   INTEGER, DIMENSION(grid2_size)                          :: ida_nbsrccells_pertgtpt
00045   ! Index in id_src_lonlatz_size of each contributing source cell corner
00046   INTEGER, DIMENSION(id_index_size1,grid1_corners)        :: ida_index_array
00047   ! Index in grid1_size of each contributing source cell
00048   INTEGER, DIMENSION(id_index_size1)                      :: ida_srcepio_add
00049   INTEGER :: id_epio_id   ! EPIO Id
00050   INTEGER :: id_interp_id ! Interpolation Id
00051   INTEGER :: id_idim      ! Dimension concerned with the current interpolation
00052   INTEGER :: num_wts      ! Number of weights for 2D conservative remapping
00053   INTEGER :: id_err, il_add
00054 !
00055 ! !RETURN VALUE
00056 !
00057 ! !DESCRIPTION
00058 !
00059 ! SUBROUTINE "PRISMTrs_remap_conserv" computes for weights with a
00060 ! 2d conservative remapping method, derived from the SCRIP 1.4
00061 ! library available from Los Alamos National Laboratory.
00062 !
00063 ! !REVISED HISTORY
00064 !   Date      Programmer   Description
00065 ! ----------  ----------   -----------
00066 ! 14/12/2006  S. Valcke    Created (based on SCRIP library)
00067 !
00068 ! EOP
00069 !----------------------------------------------------------------------
00070 ! $Id: prismtrs_remap_conserv.F90 2082 2009-10-21 13:31:19Z hanke $
00071 ! $Author: hanke $
00072 !----------------------------------------------------------------------
00073 !
00074 ! Local declarations
00075 ! 
00076   CHARACTER(LEN=len_cvs_string), SAVE  :: mycvs = 
00077      '$Id: prismtrs_remap_conserv.F90 2082 2009-10-21 13:31:19Z hanke $'
00078 ! ---------------------------------------------------------------------
00079 !
00080 ! max number of subsegments per segment to prevent infinite loop
00081   INTEGER, PARAMETER ::  max_subseg = 10000
00082 !
00083   INTEGER  ::   
00084      grid2_add,  ! current linear address for grid2 cell in tgt epio
00085      grid1_add,  ! current linear address for grid1 cell in src epio
00086      n, nwgt,    ! generic counters
00087      npart,      ! generic counters
00088      corner,     ! corner of cell that segment starts from
00089      next_corn,  ! corner of cell that segment ends on
00090      num_subseg, ! number of subsegments
00091      il_loop, il_count, il_bou, i, il_grid1,  ! loop counter
00092      num_srch_cells,  ! Number of search cell for each source and target cell
00093      il_nbrsrc_cells, ! Number of source cells treated in grid1 sweep
00094      il_cumul,   ! index in ida_index_array 
00095      il_action,  ! defines action in prismtrs_store_link_cnsrv: 
00096                   ! 0 if first call, 2 if last call, 1 otherwise
00097      il_stride, & ! stride in lat/lon corner array for Gaussian Red src grid
00098      nb_corner_grid1cell, &  ! real number of corners for source grid
00099      il_grid1_new   ! new index of neighbour cells when cells ovelarp to
00100                     ! keep only non masked cells
00101                     ! (for example when orca is source) 
00102 
00103 #ifdef DEBUGX
00104   INTEGER, PARAMETER :: nbr_src_cells = 10
00105   INTEGER, DIMENSION(nbr_src_cells) :: grid_src ! number of source cells linked to grid_tgt
00106   INTEGER  :: grid_tgt  ! EPIO target number of the target cell under investigation
00107   INTEGER :: ii
00108   DOUBLE PRECISION, PARAMETER :: dbl_rad2deg = 360.0/6.2831853
00109 #endif
00110 
00111   LOGICAL  :: 
00112      lcoinc,     ! flag for coincident segments
00113      lrevers,    ! flag for reversing direction of segment
00114      lbegin       ! flag for first integration of a segment
00115 
00116   LOGICAL ::  ll_gaussred ! flag true if source grid is Gaussian Reduced
00117   LOGICAL ::  ll_debug    ! for debug outputs
00118 
00119   LOGICAL, DIMENSION(:), ALLOCATABLE :: 
00120      srch_mask   ! mask for restricting searches
00121 
00122   DOUBLE PRECISION ::                     
00123      intrsct_lat, intrsct_lon,        ! lat/lon of next intersect
00124      beglat, endlat, beglon, endlon,  ! endpoints of current seg.
00125      norm_factor                       ! factor for normalizing wts
00126 
00127   DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: 
00128      grid1cell_corner_lat, grid1cell_corner_lon ! corner of a given source cell
00129  
00130   DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE ::    
00131      grid2_centroid_lat, grid2_centroid_lon ,      ! centroid coords on each grid
00132      grid1_centroid_lat, grid1_centroid_lon
00133 
00134   DOUBLE PRECISION, DIMENSION(grid1_size) ::   
00135      grid1_center_lat, grid1_center_lon,       ! center coords on each grid
00136      grid1_frac,                               ! intersected part of the cell
00137      grid1_larea                                ! cell area as estimated here
00138 
00139   DOUBLE PRECISION, DIMENSION(grid2_size) ::   
00140      grid2_center_lat, grid2_center_lon,       ! center coords on each grid
00141      grid2_frac,                               ! intersected part of the cell
00142      grid2_larea                                ! cell area as estimated here
00143 
00144   DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE ::    
00145      srch_corner_lat,   ! lat of each corner of srch cells
00146      srch_corner_lon     ! lon of each corner of srch cells
00147 
00148   DOUBLE PRECISION, DIMENSION(2) :: begseg ! begin lat/lon for full segment
00149 
00150   DOUBLE PRECISION, DIMENSION(6) :: lcl_weights ! local wgt array
00151 
00152   INTEGER, DIMENSION(id_index_size1) :: ila_grid2_assoc
00153   LOGICAL, DIMENSION(grid1_size)     :: ll_grid1done ! .true. if associated source grid has been treated
00154   INTEGER, DIMENSION(:), ALLOCATABLE :: srch_add,search_add_temp
00155 
00156   !
00157   ! ---------------------------------------------------------------------
00158   !
00159 #ifdef VERBOSE
00160   PRINT *, '| | | | | | | Enter PRISMTrs_remap_conserv'
00161   call psmile_flushstd
00162 #endif
00163   !
00164   nb_corner_grid1cell = grid1_corners
00165   !
00166 #ifdef DEBUGX
00167   grid_tgt = 4382
00168   grid_src(1) = 18300
00169   grid_src(2) = 18381
00170   grid_src(3) = 18382
00171   grid_src(4) = 10583
00172   grid_src(5) = 10579
00173   grid_src(6) = 18379
00174   grid_src(7) = 18380
00175   grid_src(8) = 18383
00176   grid_src(9) = 18310
00177   grid_src(10) = 18305
00178 !!$  grid_src(11) = 10610
00179 !!$  grid_src(12) = 10554
00180 !!$  grid_src(13) = 10558
00181 !!$  grid_src(14) = 10548
00182 #endif
00183   !
00184   ! Check if the source grid is Gaussian Reduced
00185   !
00186   ll_gaussred = .false.
00187   il_stride = 0
00188 
00189   IF (Drv_Epios(id_epio_id)%src_grid_type == PRISM_Gaussreduced_regvrt .OR. &
00190      Drv_Epios(id_epio_id)%src_grid_type == PRISM_Gaussreduced_sigmavrt) THEN
00191       ll_gaussred = .TRUE.
00192       il_stride = Drv_Epios(id_epio_id)%gaussred_stride
00193       nb_corner_grid1cell = 4
00194 
00195 #ifdef DEBUG
00196       IF (il_stride == 0) THEN
00197           PRINT *, '| | | | | | Pb in prismtrs_remap_conserv: Stride in '
00198           PRINT *, '| | | | | | lat/lon corner array for Gaussian Red = 0'
00199           call psmile_abort
00200       ENDIF
00201 #endif
00202   ENDIF
00203   !
00204   ! Allocate array that will contain the corner of a given source cell
00205   !
00206   ALLOCATE (grid1cell_corner_lat(nb_corner_grid1cell))
00207   ALLOCATE (grid1cell_corner_lon(nb_corner_grid1cell))
00208   !
00209   !  initialize centroid arrays
00210   !
00211       allocate( grid1_centroid_lat(grid1_size), &
00212                 grid1_centroid_lon(grid1_size), &
00213                 grid2_centroid_lat(grid2_size), &
00214                 grid2_centroid_lon(grid2_size))
00215 
00216       grid1_centroid_lat = zero
00217       grid1_centroid_lon = zero
00218       grid2_centroid_lat = zero
00219       grid2_centroid_lon = zero
00220   !
00221       ! Initialize cell areas and fraction for local calculation
00222       grid1_larea = zero
00223       grid2_larea = zero
00224       grid1_frac  = zero
00225       grid2_frac  = zero
00226       !
00227       ! For now the center of the grid cells will be calculated
00228       grid1_center_lat = zero
00229       grid1_center_lon = zero
00230       grid2_center_lat = zero
00231       grid2_center_lon = zero
00232       !
00233       lcl_weights = zero
00234   ! integrate around each cell on grid1
00235   !
00236 #ifdef VERBOSE
00237   PRINT *,'grid1 sweep '
00238   call psmile_flushstd
00239 #endif
00240 
00241 !  DO grid1_add = 1,grid1_size
00242         !***
00243         !*** create search arrays for each source mesh
00244         !***
00245 !
00246       allocate(srch_mask(grid2_size))
00247 !
00248   srch_mask (:) = .FALSE.
00249   ila_grid2_assoc(:) = 0
00250   il_count = 1
00251   !
00252   ! Define grid2_add associated to each source cell of ida_index_array
00253   ! and calculate center lat and lon
00254   !
00255   DO grid2_add = 1,grid2_size
00256     ila_grid2_assoc(il_count : il_count+ida_nbsrccells_pertgtpt(grid2_add)-1) = grid2_add
00257     il_count = il_count + ida_nbsrccells_pertgtpt(grid2_add)
00258     grid2_center_lat(grid2_add) = SUM(grid2_corner_lat(grid2_add,:))/grid2_corners
00259     grid2_center_lon(grid2_add) = SUM(grid2_corner_lon(grid2_add,:))/grid2_corners
00260   ENDDO
00261   !
00262   ll_grid1done(:) = .FALSE.
00263   il_nbrsrc_cells = 0
00264   il_action = 0
00265 
00266   PRINT *,'grid1 sweep '
00267 
00268   DO il_loop = 1, id_index_size1
00269     grid1_add = ida_srcepio_add(il_loop)
00270     !
00271     ! Define all target cells associated to each source cell of ida_index_array
00272     ! Each source cell may appear more than once in ida_index_array
00273     ! ll_grid1done indicates if this source cell was already treated or not
00274     !
00275     IF (.NOT. ll_grid1done(grid1_add)) THEN
00276         ll_grid1done(grid1_add) = .TRUE.
00277         ! Number of source cells treated
00278         il_nbrsrc_cells = il_nbrsrc_cells + 1
00279         !
00280 #ifdef DEBUGX
00281         DO ii=1,nbr_src_cells
00282           IF (grid1_add == grid_src(ii)) THEN
00283               WRITE(88,*) 'grid1_add=', grid1_add
00284           ENDIF
00285         ENDDO
00286 #endif
00287 
00288         ! Define the corners of the source cell
00289         !
00290         IF (ll_gaussred) THEN 
00291             grid1cell_corner_lon(1) = &
00292                grid1_corner_lon(ida_index_array(il_loop,1))
00293             grid1cell_corner_lon(2) = &
00294                grid1_corner_lon(ida_index_array(il_loop,1)+il_stride)
00295             grid1cell_corner_lon(3) = &
00296                grid1_corner_lon(ida_index_array(il_loop,1)+il_stride)
00297             grid1cell_corner_lon(4) = &
00298                grid1_corner_lon(ida_index_array(il_loop,1))
00299             grid1cell_corner_lat(1) = &
00300                grid1_corner_lat(ida_index_array(il_loop,1))
00301             grid1cell_corner_lat(2) = &
00302                grid1_corner_lat(ida_index_array(il_loop,1))
00303             grid1cell_corner_lat(3) = &
00304                grid1_corner_lat(ida_index_array(il_loop,1)+il_stride)
00305             grid1cell_corner_lat(4) = &
00306                grid1_corner_lat(ida_index_array(il_loop,1)+il_stride)
00307         ELSE
00308             grid1cell_corner_lat(:) = grid1_corner_lat(ida_index_array(il_loop,:))
00309             grid1cell_corner_lon(:) = grid1_corner_lon(ida_index_array(il_loop,:))
00310         ENDIF
00311         !
00312         ! Calculate lat and lon for centers of source grid cells 
00313         ! Hypothesis: it is an average of the corner lats and lons
00314         !
00315         DO il_bou = 1, nb_corner_grid1cell
00316           grid1_center_lat(grid1_add) = grid1_center_lat(grid1_add) + &
00317              grid1cell_corner_lat(il_bou)
00318           grid1_center_lon(grid1_add) = grid1_center_lon(grid1_add) + &
00319              grid1cell_corner_lon(il_bou)
00320         ENDDO
00321         grid1_center_lat(grid1_add) = grid1_center_lat(grid1_add)/nb_corner_grid1cell
00322         grid1_center_lon(grid1_add) = grid1_center_lon(grid1_add)/nb_corner_grid1cell
00323         !
00324         num_srch_cells = 0
00325         srch_mask(:) = .FALSE.
00326         DO il_bou = 1, id_index_size1
00327           !
00328           ! Identify all target cells for grid1_add source cell 
00329           IF (ida_srcepio_add(il_bou) == grid1_add) THEN
00330               num_srch_cells = num_srch_cells + 1
00331               srch_mask(ila_grid2_assoc(il_bou)) = .TRUE.
00332           ENDIF
00333         ENDDO
00334         !
00335         IF (num_srch_cells .GT. grid2_size) THEN
00336             PRINT *, '| | | | | | Number of search cell on target grid'
00337             PRINT *, '| | | | | | greater than epio target size ' 
00338             PRINT *, '| | | | | | Calling psmile_abort in prismtrs_remap_conserv'
00339             call psmile_abort 
00340         ENDIF
00341         !
00342         ALLOCATE(srch_add(num_srch_cells), &
00343            srch_corner_lat(grid2_corners,num_srch_cells), &
00344            srch_corner_lon(grid2_corners,num_srch_cells))
00345         srch_add(:) = 0
00346         srch_corner_lat(:,:) = zero
00347         srch_corner_lon(:,:) = zero
00348         !
00349         n = 0
00350         !
00351         ! Store lon and lat of target cells associated to grid1_add source cell
00352         !
00353         gather1: DO grid2_add = 1, grid2_size 
00354           if (srch_mask(grid2_add)) then
00355             n = n+1
00356             srch_add(n) = grid2_add
00357             srch_corner_lat(:,n) = grid2_corner_lat(grid2_add,:)
00358             srch_corner_lon(:,n) = grid2_corner_lon(grid2_add,:)
00359           endif
00360         end do gather1
00361         !
00362 #ifdef DEBUGX
00363         DO ii=1,nbr_src_cells
00364           IF (grid1_add == grid_src(ii)) THEN
00365               WRITE(88,*)'    '
00366               WRITE(88,*)'  ** Grid1 cell and associated search cells **'
00367               WRITE(88,*) 'grid1_add=', grid1_add
00368               DO corner = 1, nb_corner_grid1cell
00369                 WRITE(88,1111) corner, &
00370                    dbl_rad2deg*grid1cell_corner_lon(corner), &
00371                    dbl_rad2deg*grid1cell_corner_lat(corner)
00372               ENDDO
00373               WRITE(88,*) '  num_srch_cells=', num_srch_cells
00374               WRITE(88,*) '    '
00375               IF (num_srch_cells .NE. 0) & 
00376                  WRITE(88,*) '  srch_add(:)=', srch_add(:)
00377               DO n=1, num_srch_cells
00378                 DO corner = 1,grid2_corners
00379                   WRITE(88,1112) n, dbl_rad2deg*srch_corner_lon(corner,n), &
00380                                dbl_rad2deg*srch_corner_lat(corner,n)
00381                 END DO
00382               END DO
00383               WRITE(88,*)'    ***************************************'
00384               WRITE(88,*)'    '
00385           ENDIF
00386         ENDDO
00387 
00388  1111 format ('   grid1 corner, lon, lat = ', I2, 2X, F12.4, 2X, F12.4)
00389  1112 format ('     srch cell, lon, lat = ', I2, 2X, F12.4, 2X, F12.4) 
00390 #endif
00391         !
00392         DO corner = 1,nb_corner_grid1cell
00393           next_corn = mod(corner,nb_corner_grid1cell) + 1
00394 
00395           !***
00396           !*** define endpoints of the current segment
00397           !***
00398           beglat = grid1cell_corner_lat(corner)
00399           beglon = grid1cell_corner_lon(corner)
00400           endlat = grid1cell_corner_lat(next_corn)
00401           endlon = grid1cell_corner_lon(next_corn)
00402 
00403           lrevers = .false.
00404 
00405           !***
00406           !*** to ensure exact path taken during both
00407           !*** sweeps, always integrate segments in the same 
00408           !*** direction (SW to NE).
00409           !***
00410 
00411           if ((endlat < beglat) .or.  &
00412             (endlat == beglat .and. endlon < beglon)) then 
00413               beglat = grid1cell_corner_lat(next_corn)
00414               beglon = grid1cell_corner_lon(next_corn)
00415               endlat = grid1cell_corner_lat(corner)
00416               endlon = grid1cell_corner_lon(corner)
00417               lrevers = .true.
00418 #ifdef DEBUGX
00419         DO ii=1,nbr_src_cells
00420           IF (grid1_add == grid_src(ii)) THEN
00421               WRITE(88, *) ' sweep1 LREVERS TRUE'
00422               WRITE(88,*) 'grid1_add=', grid1_add
00423           ENDIF
00424         ENDDO
00425 #endif
00426           endif
00427           begseg(1) = beglat
00428           begseg(2) = beglon
00429           lbegin = .true.
00430           num_subseg = 0
00431 
00432           !***
00433           !*** if this is a constant-longitude segment, skip the rest 
00434           !*** since the line integral contribution will be zero.
00435           !***
00436 #ifdef DEBUGX
00437         DO ii=1,nbr_src_cells
00438           IF (grid1_add == grid_src(ii)) THEN
00439               IF (endlon .EQ. beglon) THEN
00440                   WRITE(88,1110) grid1_add,corner,next_corn
00441                   WRITE(88,1113) dbl_rad2deg*beglon, dbl_rad2deg*beglat 
00442                   WRITE(88,1114) dbl_rad2deg*endlon, dbl_rad2deg*endlat
00443                   WRITE(88, *)'  sweep1 endlon == beglon; skip segment'
00444                   WRITE(88,*) '             '
00445               ENDIF
00446           ENDIF
00447         ENDDO
00448  1110 FORMAT ('    grid1_add, corners = ', 2X, I6, 2X, I2, 2X, I2)
00449  1113 format ('   endlon == beglon;  beglon, beglat = ', &
00450               2X, F12.4, 2X, F12.4)
00451  1114 format ('   endlon == beglon;  endlon, endlat = ', &
00452               2X, F12.4, 2X, F12.4)
00453 #endif
00454 
00455           if (endlon /= beglon) then
00456           !***
00457           !*** integrate along this segment, detecting intersections 
00458           !*** and computing the line integral for each sub-segment
00459           !***
00460 
00461               DO WHILE (beglat /= endlat .OR. beglon /= endlon)
00462               !***
00463               !*** prevent infinite loops if integration gets stuck
00464               !*** near cell or threshold boundary
00465               !***
00466                 num_subseg = num_subseg + 1
00467                 if (num_subseg > max_subseg) THEN
00468                     print*, 'ERROR=>integration stalled:' 
00469                     print*, 'num_subseg exceeded limit'
00470                     print*, '=>Verify corners in grids.nc, especially'
00471                     print*, 'if calculated by OASIS routine corners'           
00472                     PRINT *, 'integration stalled: num_subseg exceeded limit'
00473                     call psmile_abort
00474                 endif
00475 
00476                 !***
00477                 !*** find next intersection of this segment with a grid
00478                 !*** line on grid 2.
00479                 !***
00480 
00481 !                call timer_start(2)
00482 
00483 #ifdef DEBUGX
00484         DO ii=1,nbr_src_cells
00485           IF (grid1_add == grid_src(ii)) THEN
00486               WRITE(88,1110) grid1_add,corner,next_corn
00487               WRITE(88,*) '             '
00488               WRITE(88,1115) dbl_rad2deg*beglon, dbl_rad2deg*beglat 
00489               WRITE(88,1116) dbl_rad2deg*endlon, dbl_rad2deg*endlat
00490               WRITE(88,*) '             '
00491           ENDIF
00492         ENDDO
00493 
00494  1115 format ('   avant intersection;  beglon, beglat = ', &
00495               2X, F12.4, 2X, F12.4)
00496  1116 format ('   avant intersection;  endlon, endlat = ', &
00497               2X, F12.4, 2X, F12.4)
00498 #endif
00499 
00500                 call prismtrs_intersection(grid2_add,intrsct_lat,intrsct_lon, &
00501                     lcoinc, beglat, beglon, endlat, endlon, begseg, &
00502                     lbegin, lrevers, &
00503                     num_srch_cells, grid2_corners, &
00504                     srch_corner_lat, srch_corner_lon, srch_add)
00505 
00506 #ifdef DEBUGX
00507         DO ii=1,nbr_src_cells
00508 !          IF (grid1_add == grid_src(ii) .AND. grid2_add==grid_tgt) THEN
00509           IF (grid1_add == grid_src(ii) ) THEN
00510               WRITE(88,*) 'grid1_add=', grid1_add
00511               WRITE(88,*) ' After call intersection, grid2_add', &
00512                                 grid2_add
00513               WRITE(88,1117) dbl_rad2deg*beglon, dbl_rad2deg*beglat 
00514               WRITE(88,1118) dbl_rad2deg*endlon, dbl_rad2deg*endlat
00515               WRITE(88,1119) dbl_rad2deg*intrsct_lon, dbl_rad2deg*intrsct_lat
00516               WRITE(88,*) '   '
00517           ENDIF
00518         ENDDO
00519 
00520  1117 format('   après intersection;  beglon, beglat =           ', &
00521               2X, F12.4, 2X, F12.4)
00522  1118 format ('   après intersection;  endlon, endlat =          ', &
00523               2X, F12.4, 2X, F12.4)
00524  1119 format ('   après intersection; intrsct_lon, intrsct_lat = ', &
00525                     2X, F12.4, 2X, F12.4)
00526 #endif
00527 
00528 !                call timer_stop(2)
00529                 lbegin = .false.
00530 
00531                 !***
00532                 !*** compute line integral for this subsegment.
00533                 !***
00534 
00535                 ! call timer_start(3)
00536                 if (grid2_add /= 0) THEN
00537                     !
00538                     call prismtrs_line_integral(lcl_weights, &
00539                                beglon, intrsct_lon, beglat, intrsct_lat, &
00540                                grid1_center_lon(grid1_add), &
00541                                grid2_center_lon(grid2_add), &
00542                                num_wts)
00543 
00544 #ifdef DEBUGX
00545         DO ii=1,nbr_src_cells
00546 !          IF (grid1_add == grid_src(ii) .AND. grid2_add==grid_tgt) THEN
00547           IF (grid1_add == grid_src(ii)) THEN
00548               WRITE(88,*) 'grid1_add=', grid1_add
00549               WRITE(88,*) '  A1) WEIGHTS for this subsegment =', &
00550                                    lcl_weights(1)
00551               WRITE(88,*) '     '
00552           ENDIF
00553         ENDDO
00554 #endif
00555 
00556                 else
00557                     call prismtrs_line_integral(lcl_weights, &
00558                                beglon, intrsct_lon, beglat, intrsct_lat, &
00559                                grid1_center_lon(grid1_add), &
00560                                grid1_center_lon(grid1_add), &
00561                                num_wts)
00562 
00563 #ifdef DEBUGX
00564         DO ii=1,nbr_src_cells
00565           IF (grid1_add == grid_src(ii)) THEN
00566               WRITE(88,*) 'grid1_add=', grid1_add
00567               WRITE(88,*) '  B1) WEIGHTS for this subsegment =', &
00568                                    lcl_weights(1)
00569               WRITE(88,*) '     ' 
00570           ENDIF
00571         ENDDO
00572 #endif
00573 
00574                 endif
00575                 ! call timer_stop(3)
00576                 !***
00577                 !*** if integrating in reverse order, change
00578                 !*** sign of lcl_weights
00579                 !***
00580 
00581                 if (lrevers) then
00582                     lcl_weights = -lcl_weights
00583 #ifdef DEBUGX
00584         DO ii=1,nbr_src_cells
00585 !          IF (grid1_add == grid_src(ii) .AND. grid2_add==grid_tgt) THEN
00586           IF (grid1_add == grid_src(ii)) THEN
00587               WRITE(88,*) 'grid1_add=', grid1_add
00588               WRITE(88,*) '  LREVERS; WEIGHTS for this subsegment =', &
00589                               lcl_weights(1)
00590               WRITE(88,*) '     '
00591           ENDIF
00592         ENDDO
00593 #endif
00594                 endif
00595                 !***
00596                 !*** store the appropriate addresses and lcl_weights. 
00597                 !*** also add contributions to cell areas and centroids.
00598                 !***
00599 
00600 
00601                 if (grid2_add /= 0) then
00602                     if (Drv_Epios(id_epio_id)%src_mask_pointer(grid1_add) == 1) then
00603                         ! call timer_start(4)
00604                         call prismtrs_store_link_cnsrv(grid1_add, grid2_add, & 
00605                             lcl_weights, il_action, id_epio_id, num_wts)
00606 
00607 #ifdef DEBUGX
00608         DO ii=1,nbr_src_cells
00609 !          IF (grid1_add == grid_src(ii) .AND. grid2_add==grid_tgt) THEN
00610           IF (grid1_add == grid_src(ii)) THEN
00611               WRITE(88,*) '      after store_link_cnsrv'
00612               WRITE(88,1120) grid1_add, grid2_add,dbl_rad2deg*beglon, dbl_rad2deg*beglat, &
00613                              dbl_rad2deg*intrsct_lon,dbl_rad2deg*intrsct_lat,lcl_weights(1)
00614           ENDIF
00615         ENDDO
00616 
00617  1120 format ('      STORE add1,add2,blon,blat,ilon,ilat,WEIGHTS=', &
00618                1X,I6,1X,I6,1X,F12.8,1X,F12.8,1X,F12.8,1X,F12.8,1X,E15.8)
00619 #endif
00620 
00621                         il_action = 1
00622                         ! call timer_stop(4)
00623                         grid1_frac(grid1_add) = &
00624                            grid1_frac(grid1_add)+lcl_weights(1)
00625                         grid2_frac(grid2_add) = &
00626                            grid2_frac(grid2_add)+lcl_weights(num_wts+1)
00627                     endif
00628                 endif
00629 
00630                 grid1_larea(grid1_add) = &
00631                    grid1_larea(grid1_add) + lcl_weights(1)
00632                  
00633                 grid1_centroid_lat(grid1_add) = &
00634                    grid1_centroid_lat(grid1_add) + lcl_weights(2)
00635                 grid1_centroid_lon(grid1_add) = &
00636                    grid1_centroid_lon(grid1_add) + lcl_weights(3)
00637 
00638                 !***
00639                 !*** reset beglat and beglon for next subsegment.
00640                 !***
00641 
00642                 beglat = intrsct_lat
00643                 beglon = intrsct_lon
00644 
00645               END DO
00646 
00647           endif
00648 
00649           !***
00650           !*** end of segment
00651           !***
00652 
00653         END DO
00654 
00655         !***
00656         !*** finished with this cell: deallocate search array and
00657         !*** start on next cell
00658         deallocate(srch_add, srch_corner_lat, srch_corner_lon)
00659     ENDIF                        
00660   END DO
00661 #ifdef VERBOSE
00662   PRINT *, 'Number of source cells in epio = ', grid1_size
00663   PRINT *, 'Number of source cells in grid1 sweep = ', il_nbrsrc_cells
00664 #endif
00665   IF (il_nbrsrc_cells /= grid1_size) THEN 
00666       PRINT *, '| | |WARNING: Number of source cells in grid1 sweep '
00667       PRINT *, '| | |not equal to number of source cells in epio '
00668   ENDIF
00669 
00670       deallocate(srch_mask)
00671  
00672       print *,'grid1 end sweep '
00673 !-----------------------------------------------------------------------
00674 !
00675 !     integrate around each cell on grid2
00676 !
00677 !-----------------------------------------------------------------------
00678 
00679       print *,'grid2 sweep '
00680       il_cumul = 0
00681       DO grid2_add = 1,grid2_size
00682 
00683         il_grid1_new = 0
00684 
00685 #ifdef DEBUGX
00686         IF (grid2_add == grid_tgt) THEN 
00687             WRITE(88,*) 'grid2_add=', grid2_add
00688         ENDIF
00689 #endif
00690 
00691         num_srch_cells = ida_nbsrccells_pertgtpt (grid2_add)
00692 
00693         ALLOCATE(srch_add(num_srch_cells),search_add_temp(num_srch_cells),&
00694                  srch_corner_lat(nb_corner_grid1cell,num_srch_cells), &
00695                  srch_corner_lon(nb_corner_grid1cell,num_srch_cells))
00696 
00697         gather2: DO il_grid1 = 1, num_srch_cells
00698             il_cumul = il_cumul + 1
00699             srch_add(il_grid1) = ida_srcepio_add (il_cumul)
00700 #ifdef DEBUGX
00701             IF (grid2_add == grid_tgt) THEN
00702                 WRITE(88,*), 'srch_add(il_grid1) :', grid2_add,il_grid1,srch_add(il_grid1)
00703             ENDIF
00704 #endif
00705             IF (Drv_Epios(id_epio_id)%src_mask_pointer(srch_add(il_grid1)) == 1) THEN
00706             il_grid1_new = il_grid1_new + 1
00707             search_add_temp(il_grid1_new) = srch_add(il_grid1)
00708             IF (ll_gaussred) THEN
00709                 srch_corner_lon(1,il_grid1_new) = &
00710                    grid1_corner_lon(ida_index_array(il_cumul,1))
00711                 srch_corner_lon(2,il_grid1_new) = &
00712                    grid1_corner_lon(ida_index_array(il_cumul,1)+il_stride)
00713                 srch_corner_lon(3,il_grid1_new) = &
00714                    grid1_corner_lon(ida_index_array(il_cumul,1)+il_stride)
00715                 srch_corner_lon(4,il_grid1_new) = &
00716                    grid1_corner_lon(ida_index_array(il_cumul,1))
00717                 srch_corner_lat(1,il_grid1_new) = &
00718                    grid1_corner_lat(ida_index_array(il_cumul,1))
00719                 srch_corner_lat(2,il_grid1_new) = &
00720                    grid1_corner_lat(ida_index_array(il_cumul,1))
00721                 srch_corner_lat(3,il_grid1_new) = &
00722                    grid1_corner_lat(ida_index_array(il_cumul,1)+il_stride)
00723                 srch_corner_lat(4,il_grid1_new) = &
00724                    grid1_corner_lat(ida_index_array(il_cumul,1)+il_stride)  
00725             ELSE
00726                 srch_corner_lat(:,il_grid1_new) = grid1_corner_lat(ida_index_array(il_cumul,:))
00727                 srch_corner_lon(:,il_grid1_new) = grid1_corner_lon(ida_index_array(il_cumul,:))
00728             ENDIF
00729         ENDIF
00730         end do gather2
00731 
00732         num_srch_cells = il_grid1_new
00733         srch_add(1:num_srch_cells)=search_add_temp(1:il_grid1_new)
00734 
00735 #ifdef DEBUGX
00736         IF (grid2_add == grid_tgt) THEN 
00737             WRITE(88,*)'    '
00738             WRITE(88,*)'  ** Grid2 cell and associated search cells **'
00739             DO corner = 1,grid2_corners 
00740               WRITE(88,1131) corner, &
00741                  dbl_rad2deg*grid2_corner_lon(grid2_add,corner), &
00742                  dbl_rad2deg*grid2_corner_lat(grid2_add,corner)
00743             ENDDO
00744             WRITE(88,*) '  num_srch_cells=', num_srch_cells
00745             WRITE(88,*) '    '
00746             WRITE(88,*) '  srch_add(:)=', srch_add(:)
00747             DO n=1, num_srch_cells
00748               DO corner = 1,nb_corner_grid1cell
00749                 WRITE(88,1132) n, dbl_rad2deg*srch_corner_lon(corner,n), &
00750                               dbl_rad2deg*srch_corner_lat(corner,n)
00751               END DO
00752             END DO
00753             WRITE(88,*)'    ***************************************'
00754             WRITE(88,*)'    '
00755         ENDIF
00756  1131 format ('   grid2 corner, lon, lat = ', I2, 2X, F12.4, 2X, F12.4)
00757  1132 format ('     srch cell, lon, lat = ', I2, 2X, F12.4, 2X, F12.4) 
00758 #endif
00759 
00760         DO corner = 1,grid2_corners
00761           next_corn = mod(corner,grid2_corners) + 1
00762 
00763           beglat = grid2_corner_lat(grid2_add,corner)
00764           beglon = grid2_corner_lon(grid2_add,corner)
00765           endlat = grid2_corner_lat(grid2_add,next_corn)
00766           endlon = grid2_corner_lon(grid2_add,next_corn)
00767           lrevers = .false.
00768 
00769           !***
00770           !*** to ensure exact path taken during both
00771           !*** sweeps, always integrate in the same direction
00772           !***
00773 
00774           if ((endlat < beglat) .or. &
00775               (endlat == beglat .and. endlon < beglon)) then 
00776             beglat = grid2_corner_lat(grid2_add,next_corn)
00777             beglon = grid2_corner_lon(grid2_add,next_corn)
00778             endlat = grid2_corner_lat(grid2_add,corner)
00779             endlon = grid2_corner_lon(grid2_add,corner)
00780             lrevers = .true.
00781 #ifdef DEBUGX
00782             IF (grid2_add == grid_tgt) WRITE(88, *) ' sweep2 LREVERS TRUE'
00783 #endif
00784           endif
00785           begseg(1) = beglat
00786           begseg(2) = beglon
00787           lbegin = .true.
00788 
00789           !***
00790           !*** if this is a constant-longitude segment, skip the rest 
00791           !*** since the line integral contribution will be zero.
00792           !***
00793 
00794 #ifdef DEBUGX
00795           IF (grid2_add == grid_tgt) THEN
00796               IF (endlon .EQ. beglon) THEN
00797                   WRITE(88,1113) dbl_rad2deg*beglon, dbl_rad2deg*beglat 
00798                   WRITE(88,1114) dbl_rad2deg*endlon, dbl_rad2deg*endlat
00799                   WRITE(88, *)'  sweep2 endlon == beglon; skip segment'
00800                   WRITE(88,*) '             '
00801               ENDIF
00802           ENDIF
00803 #endif
00804 
00805           if (endlon /= beglon) then
00806           num_subseg = 0
00807 
00808           !***
00809           !*** integrate along this segment, detecting intersections 
00810           !*** and computing the line integral for each sub-segment
00811           !***
00812 
00813           do while (beglat /= endlat .or. beglon /= endlon)
00814 
00815             !***
00816             !*** prevent infinite loops if integration gets stuck
00817             !*** near cell or threshold boundary
00818             !***
00819 
00820             num_subseg = num_subseg + 1
00821             if (num_subseg > max_subseg) THEN
00822                 print*, 'ERROR=>integration stalled:' 
00823                 print*, 'num_subseg exceeded limit'
00824                 print*, '=>Verify corners in grids.nc, especially'
00825                 print*, 'if calculated by OASIS routine corners' 
00826                 PRINT *, 'integration stalled: num_subseg exceeded limit'
00827                 call psmile_abort
00828             endif
00829 
00830             !***
00831             !*** find next intersection of this segment with a line 
00832             !*** on grid 2.
00833             !***
00834 
00835             !call timer_start(6)
00836 
00837 #ifdef DEBUGX
00838             IF (grid2_add == grid_tgt) THEN
00839                 WRITE(88,*) '             '
00840                 WRITE(88,1115) dbl_rad2deg*beglon, dbl_rad2deg*beglat 
00841                 WRITE(88,1116) dbl_rad2deg*endlon, dbl_rad2deg*endlat
00842                 WRITE(88,*) '             '
00843             ENDIF
00844 #endif
00845             call prismtrs_intersection(grid1_add,intrsct_lat,intrsct_lon,lcoinc, &
00846                               beglat, beglon, endlat, endlon, begseg, &
00847                               lbegin, lrevers, &
00848                               num_srch_cells, nb_corner_grid1cell, &
00849                               srch_corner_lat, srch_corner_lon, srch_add)
00850 
00851 #ifdef DEBUGX
00852             IF (grid2_add == grid_tgt) THEN
00853                 WRITE(88,*) ' After call intersection, grid1_add', &
00854                    grid1_add
00855                 WRITE(88,1117) dbl_rad2deg*beglon, dbl_rad2deg*beglat 
00856                 WRITE(88,1118) dbl_rad2deg*endlon, dbl_rad2deg*endlat
00857                 WRITE(88,1119) dbl_rad2deg*intrsct_lon, dbl_rad2deg*intrsct_lat
00858                 WRITE(88,*) '   '
00859             ENDIF
00860 #endif
00861 
00862             !call timer_stop(6)
00863             lbegin = .false.
00864 
00865             !***
00866             !*** compute line integral for this subsegment.
00867             !***
00868 
00869             ! call timer_start(7)
00870             if (grid1_add /= 0) then
00871 
00872                 ! Check if grid1 center was calculated 
00873                 IF (.NOT. ll_grid1done(grid1_add)) THEN
00874                     PRINT *, &
00875                        '| | | | Center of grid1 mesh not known - cannot call prismtrs_line_integral'
00876                     call psmile_abort
00877                 ENDIF
00878 
00879               call prismtrs_line_integral(lcl_weights, &
00880                               beglon, intrsct_lon, beglat, intrsct_lat, &
00881                               grid1_center_lon(grid1_add), &
00882                               grid2_center_lon(grid2_add), &
00883                               num_wts)
00884 
00885 #ifdef DEBUGX
00886               IF (grid2_add == grid_tgt) THEN
00887                   WRITE(88,*) '  A2) WEIGHTS for this subsegment =', &
00888                                   lcl_weights(1)
00889                   WRITE(88,*) '     ' 
00890               ENDIF
00891 #endif
00892 
00893             else
00894               call prismtrs_line_integral(lcl_weights, &
00895                              beglon, intrsct_lon, beglat, intrsct_lat, &
00896                              grid2_center_lon(grid2_add), &
00897                              grid2_center_lon(grid2_add), &
00898                              num_wts)
00899 
00900 #ifdef DEBUGX
00901              IF (grid2_add == grid_tgt) THEN
00902                  WRITE(88,*) '  B2) WEIGHTS for this subsegment =', &
00903                      lcl_weights(1)
00904                   WRITE(88,*) '     ' 
00905               ENDIF
00906 #endif
00907 
00908             endif
00909             ! call timer_stop(7)
00910 
00911             if (lrevers) then
00912               lcl_weights = -lcl_weights
00913 #ifdef DEBUGX
00914               IF (grid2_add == grid_tgt) THEN
00915                 WRITE(88,*) '  LREVERS; WEIGHTS for this subsegment =', &
00916                    lcl_weights(1)
00917                 WRITE(88,*) '     '
00918               ENDIF
00919 #endif
00920             endif
00921             !***
00922             !*** store the appropriate addresses and weights. 
00923             !*** also add contributions to cell areas and centroids.
00924             !*** if there is a coincidence, do not store weights
00925             !*** because they have been captured in the previous loop.
00926             !*** the grid1 mask is the master mask
00927             !***
00928 
00929 #ifdef DEBUGX
00930             IF (lcoinc .AND. grid2_add == grid_tgt) &
00931                WRITE(88,*) '  LCOINC is TRUE; weight not stored'
00932 #endif
00933 
00934             if (.not. lcoinc .and. grid1_add /= 0) then
00935               if (Drv_Epios(id_epio_id)%src_mask_pointer(grid1_add) == 1) then
00936                   ! call timer_start(8)
00937                   call prismtrs_store_link_cnsrv(grid1_add, grid2_add, & 
00938                      lcl_weights, il_action, id_epio_id, num_wts)
00939 
00940 #ifdef DEBUGX
00941                   IF (grid2_add == grid_tgt) THEN
00942                       WRITE(88,*) '      after store_link_cnsrv'
00943                       WRITE(88,1120) grid1_add, grid2_add,dbl_rad2deg*beglon, dbl_rad2deg*beglat, &
00944                                      dbl_rad2deg*intrsct_lon,dbl_rad2deg*intrsct_lat,lcl_weights(1)
00945                   ENDIF
00946 #endif
00947 
00948                   il_action = 1
00949                   ! call timer_stop(8)
00950                   grid1_frac(grid1_add) = &
00951                      grid1_frac(grid1_add) + lcl_weights(1)
00952                   grid2_frac(grid2_add) = &
00953                      grid2_frac(grid2_add) + lcl_weights(num_wts+1)
00954               endif
00955 
00956             endif
00957 
00958             grid2_larea(grid2_add) = &
00959                grid2_larea(grid2_add) + lcl_weights(num_wts+1)
00960             grid2_centroid_lat(grid2_add) = &
00961                grid2_centroid_lat(grid2_add) + lcl_weights(num_wts+2)
00962             grid2_centroid_lon(grid2_add) = &
00963                grid2_centroid_lon(grid2_add) + lcl_weights(num_wts+3)
00964 
00965             !***
00966             !*** reset beglat and beglon for next subsegment.
00967             !***
00968 
00969             beglat = intrsct_lat
00970             beglon = intrsct_lon
00971 
00972           end DO
00973 
00974           END if
00975 
00976           !***
00977           !*** end of segment
00978           !***
00979 
00980         END DO
00981 
00982         !***
00983         !*** finished with this cell: deallocate search array and
00984         !*** start on next cell
00985 
00986         DEALLOCATE(srch_add, srch_corner_lat, srch_corner_lon, search_add_temp)
00987 
00988 #ifdef DEBUGX
00989         IF (grid2_add == grid_tgt) THEN
00990         DO n=1,Drv_Epios(id_epio_id)%num_links_map1
00991           IF (Drv_Epios(id_epio_id)%grid2_add_map1(n) == grid_tgt) THEN
00992               WRITE(88,*) 'grid1, grid2, weight= ', &
00993                  Drv_Epios(id_epio_id)%grid1_add_map1(n), Drv_Epios(id_epio_id)%grid2_add_map1(n), &
00994                  Drv_Epios(id_epio_id)%wts_map1(1,n)
00995           ENDIF
00996         END DO
00997     ENDIF
00998 #endif
00999 
01000     END DO
01001 
01002       print *,'grid2 end sweep '
01003 
01004 !-----------------------------------------------------------------------
01005 !
01006 !     correct for situations where N/S pole not explicitly included in
01007 !     grid (i.e. as a grid corner point). if pole is missing from only
01008 !     one grid, need to correct only the area and centroid of that 
01009 !     grid.  if missing from both, do complete weight calculation.
01010 !
01011 !-----------------------------------------------------------------------
01012       !*** North Pole
01013       lcl_weights(1) =  dble_pi2
01014       lcl_weights(2) =  dble_pi*dble_pi
01015       lcl_weights(3) =  zero
01016       lcl_weights(4) =  dble_pi2
01017       lcl_weights(5) =  dble_pi*dble_pi
01018       lcl_weights(6) =  zero
01019 
01020       grid1_add = 0
01021       pole_loop1: do n=1,grid1_size
01022         if (grid1_larea(n) < -three*dble_pih .and. &
01023             grid1_center_lat(n) > zero) then
01024           grid1_add = n
01025           exit pole_loop1
01026         endif
01027       end do pole_loop1
01028 
01029       grid2_add = 0
01030       pole_loop2: do n=1,grid2_size
01031         if (grid2_larea(n) < -three*dble_pih .and. &
01032             grid2_center_lat(n) > zero) then
01033           grid2_add = n
01034           exit pole_loop2
01035         endif
01036       end do pole_loop2
01037 
01038       if (grid1_add /=0) then
01039         grid1_larea(grid1_add) = grid1_larea(grid1_add) + lcl_weights(1)
01040         grid1_centroid_lat(grid1_add) = &
01041         grid1_centroid_lat(grid1_add) + lcl_weights(2)
01042         grid1_centroid_lon(grid1_add) = &
01043         grid1_centroid_lon(grid1_add) + lcl_weights(3)
01044       endif
01045 
01046       if (grid2_add /=0) then
01047         grid2_larea(grid2_add) = grid2_larea(grid2_add) + &
01048                                         lcl_weights(num_wts+1)
01049         grid2_centroid_lat(grid2_add) = &
01050         grid2_centroid_lat(grid2_add) + lcl_weights(num_wts+2)
01051         grid2_centroid_lon(grid2_add) = &
01052         grid2_centroid_lon(grid2_add) + lcl_weights(num_wts+3)
01053       endif
01054 
01055       if (grid1_add /= 0 .and. grid2_add /=0) then
01056           call prismtrs_store_link_cnsrv(grid1_add, grid2_add, & 
01057              lcl_weights, il_action, id_epio_id, num_wts)
01058           il_action = 1
01059         grid1_frac(grid1_add) = &
01060            grid1_frac(grid1_add) + lcl_weights(1)
01061         grid2_frac(grid2_add) = &
01062            grid2_frac(grid2_add) + lcl_weights(num_wts+1)
01063       endif
01064 
01065       !*** South Pole
01066       lcl_weights(1) =  dble_pi2
01067       lcl_weights(2) = -dble_pi*dble_pi
01068       lcl_weights(3) =  zero
01069       lcl_weights(4) =  dble_pi2
01070       lcl_weights(5) = -dble_pi*dble_pi
01071       lcl_weights(6) =  zero
01072 
01073       grid1_add = 0
01074       pole_loop3: do n=1,grid1_size
01075         if (grid1_larea(n) < -three*dble_pih .and. &
01076             grid1_center_lat(n) < zero) then
01077           grid1_add = n
01078           exit pole_loop3
01079         endif
01080       end do pole_loop3
01081 
01082       grid2_add = 0
01083       pole_loop4: do n=1,grid2_size
01084         if (grid2_larea(n) < -three*dble_pih .and. &
01085             grid2_center_lat(n) < zero) then
01086           grid2_add = n
01087           exit pole_loop4
01088         endif
01089       end do pole_loop4
01090 
01091       if (grid1_add /=0) then
01092         grid1_larea(grid1_add) = grid1_larea(grid1_add) + lcl_weights(1)
01093         grid1_centroid_lat(grid1_add) = &
01094         grid1_centroid_lat(grid1_add) + lcl_weights(2)
01095         grid1_centroid_lon(grid1_add) = &
01096         grid1_centroid_lon(grid1_add) + lcl_weights(3)
01097       endif
01098 
01099       if (grid2_add /=0) then
01100         grid2_larea(grid2_add) = grid2_larea(grid2_add) + &
01101                                         lcl_weights(num_wts+1)
01102         grid2_centroid_lat(grid2_add) = &
01103         grid2_centroid_lat(grid2_add) + lcl_weights(num_wts+2)
01104         grid2_centroid_lon(grid2_add) = &
01105         grid2_centroid_lon(grid2_add) + lcl_weights(num_wts+3)
01106       endif
01107 
01108       if (grid1_add /= 0 .and. grid2_add /=0) then
01109         call prismtrs_store_link_cnsrv(grid1_add, grid2_add, lcl_weights, 1, &
01110            id_epio_id, num_wts)
01111         grid1_frac(grid1_add) = grid1_frac(grid1_add) + & 
01112                                 lcl_weights(1)
01113         grid2_frac(grid2_add) = grid2_frac(grid2_add) + &
01114                                 lcl_weights(num_wts+1)
01115       endif
01116 
01117 !-----------------------------------------------------------------------
01118 !
01119 !     finish centroid computation
01120 !
01121 !-----------------------------------------------------------------------
01122 
01123       where (grid1_larea /= zero)
01124         grid1_centroid_lat = grid1_centroid_lat/grid1_larea
01125         grid1_centroid_lon = grid1_centroid_lon/grid1_larea
01126       end where
01127 
01128       where (grid2_larea /= zero)
01129         grid2_centroid_lat = grid2_centroid_lat/grid2_larea
01130         grid2_centroid_lon = grid2_centroid_lon/grid2_larea
01131       end where
01132 !
01133 !-----------------------------------------------------------------------
01134 !
01135 !     include centroids in weights and normalize using destination
01136 !     area if requested
01137 !
01138 !-----------------------------------------------------------------------
01139 
01140       do n=1,Drv_Epios(id_epio_id)%num_links_map1
01141 
01142         grid1_add = Drv_Epios(id_epio_id)%grid1_add_map1(n)
01143         grid2_add = Drv_Epios(id_epio_id)%grid2_add_map1(n)
01144         do nwgt=1,num_wts
01145           lcl_weights(nwgt) = Drv_Epios(id_epio_id)%wts_map1(nwgt,n)
01146         end do
01147 #ifdef DEBUGX
01148         IF (grid2_add == grid_tgt) THEN
01149             WRITE(88,*), 'Source and weight before normalisation for target point ', grid_tgt
01150             WRITE(88,*), grid1_add, lcl_weights(1)
01151         ENDIF
01152 #endif
01153 
01154         select case(Drv_Interps(id_interp_id)%arg4(id_idim))
01155         case (PSMILe_destarea)
01156           if (grid2_larea(grid2_add) /= zero) then
01157             !if (luse_grid2_area) then
01158             !  norm_factor = one/grid2_area_in(grid2_add)
01159             !else
01160               norm_factor = one/grid2_larea(grid2_add)
01161             !endif
01162           else
01163             norm_factor = zero
01164           endif
01165         case (PSMILe_fracarea)
01166           if (grid2_frac(grid2_add) /= zero) then
01167             !if (luse_grid2_area) then
01168             !  norm_factor = grid2_larea(grid2_add)/
01169      !&                     (grid2_frac(grid2_add)*
01170      !&                      grid2_larea_in(grid2_add))
01171             !else
01172               norm_factor = one/grid2_frac(grid2_add)
01173             !endif
01174           else
01175             norm_factor = zero
01176           endif
01177         case (PSMILe_none)
01178           norm_factor = one
01179         end select
01180 
01181 #ifdef DEBUGX
01182         IF (grid2_add == grid_tgt) THEN
01183             WRITE(88,*), 'Normalisation coef', grid_tgt,norm_factor
01184         ENDIF
01185 #endif
01186 
01187         Drv_Epios(id_epio_id)%wts_map1(1,n)= lcl_weights(1)*norm_factor
01188         Drv_Epios(id_epio_id)%wts_map1(2,n)=(lcl_weights(2) - lcl_weights(1)* &
01189            grid1_centroid_lat(grid1_add))* norm_factor
01190         Drv_Epios(id_epio_id)%wts_map1(3,n)=(lcl_weights(3) - lcl_weights(1)* &
01191            grid1_centroid_lon(grid1_add))* norm_factor
01192 
01193 #ifdef DEBUGX
01194         IF (grid2_add == grid_tgt) THEN
01195             WRITE(88,*), 'Source and weight after normalisation for target point ', grid_tgt
01196             WRITE(88,*), grid1_add, Drv_Epios(id_epio_id)%wts_map1(1,n)
01197             WRITE(88,*), ''
01198         ENDIF
01199 #endif
01200       end do
01201       print *, 'Total number of links = ',Drv_Epios(id_epio_id)%num_links_map1
01202 
01203       where (grid1_larea /= zero) &
01204          grid1_frac = &
01205          grid1_frac/grid1_larea
01206       where (grid2_larea /= zero) &
01207          grid2_frac = &
01208          grid2_frac/grid2_larea
01209 
01210 !
01211 !-----------------------------------------------------------------------
01212 !
01213 !     perform some error checking on final weights
01214 !
01215 !-----------------------------------------------------------------------
01216 
01217       !grid2_centroid_lat = zero
01218       !grid2_centroid_lon = zero
01219 #ifdef DEBUG
01220       do n=1,grid1_size
01221         if (grid1_larea(n) < -.01) then
01222           print *,'Grid 1 area error: n, area, mask =' &
01223                 ,n,grid1_larea(n), &
01224                 Drv_Epios(id_epio_id)%src_mask_pointer(n)
01225         endif
01226         if (grid1_centroid_lat(n) < -dble_pih-.01 .or. &
01227             grid1_centroid_lat(n) >  dble_pih+.01) then
01228             print *,'Grid 1 centroid lat error: n, centroid_lat, mask=' &
01229                 ,n,grid1_centroid_lat(n), &
01230                 Drv_Epios(id_epio_id)%src_mask_pointer(n)
01231         endif
01232         grid1_centroid_lat(n) = zero
01233         grid1_centroid_lon(n) = zero
01234       end do
01235 
01236       do n=1,grid2_size
01237         if (grid2_larea(n) < -.01) then
01238             PRINT *,'Grid 2 area error:  n, area, mask =' &
01239             ,n,grid2_larea(n), &
01240             Drv_Epios(id_epio_id)%tgt_mask_pointer(n)
01241         endif
01242         if (grid2_centroid_lat(n) < -dble_pih-.01 .or. &
01243             grid2_centroid_lat(n) >  dble_pih+.01) then
01244           PRINT *,'Grid 2 centroid lat error: n, centroid_lat, mask =' &
01245                 ,n,grid2_centroid_lat(n), &
01246                 Drv_Epios(id_epio_id)%tgt_mask_pointer(n)
01247         endif
01248         grid2_centroid_lat(n) = zero
01249         grid2_centroid_lon(n) = zero
01250       end do
01251 
01252 ! Rene: print statements prohibit vectorisation, better put this in a VERBOSE statement
01253 !   to spped up producton runs. Stripmining of loop to avoid problems on the SX.
01254 
01255       do npart = 1, Drv_Epios(id_epio_id)%num_links_map1, 5000
01256       do n = npart, min(Drv_Epios(id_epio_id)%num_links_map1,npart+5000-1)
01257 
01258         grid1_add = Drv_Epios(id_epio_id)%grid1_add_map1(n)
01259         grid2_add = Drv_Epios(id_epio_id)%grid2_add_map1(n)
01260         
01261         if (Drv_Epios(id_epio_id)%wts_map1(1,n) < -.01) then
01262           print *,'Map 1 weight < 0 '
01263           PRINT *, &
01264               'grid1_add, grid2_add, wts_map1, grid1_mask, grid2_mask', &
01265               grid1_add, grid2_add, Drv_Epios(id_epio_id)%wts_map1(1,n), & 
01266               Drv_Epios(id_epio_id)%src_mask_pointer(grid1_add), &
01267               Drv_Epios(id_epio_id)%tgt_mask_pointer(grid2_add) 
01268         endif
01269         if (Drv_Interps(id_interp_id)%arg4(id_idim) /= PSMILe_none .and. Drv_Epios(id_epio_id)%wts_map1(1,n) > 1.01) then
01270           print *,'Map 1 weight > 1 '
01271           PRINT *, &
01272               'grid1_add, grid2_add, wts_map1, grid1_mask, grid2_mask', &
01273               grid1_add, grid2_add, Drv_Epios(id_epio_id)%wts_map1(1,n), & 
01274               Drv_Epios(id_epio_id)%src_mask_pointer(grid1_add), &
01275               Drv_Epios(id_epio_id)%tgt_mask_pointer(grid2_add) 
01276         endif
01277         grid2_centroid_lat(grid2_add) = &
01278         grid2_centroid_lat(grid2_add) + Drv_Epios(id_epio_id)%wts_map1(1,n)
01279 
01280       end do
01281       end do
01282 
01283       do n=1,grid2_size
01284         select case(Drv_Interps(id_interp_id)%arg4(id_idim))
01285         case (PSMILe_destarea)
01286           norm_factor = grid2_frac(n)
01287         case (PSMILe_fracarea)
01288           norm_factor = one
01289         case (PSMILe_none)
01290           ! if (luse_grid2_area) then
01291           !  norm_factor = grid2_area_in(grid2_add)
01292           ! else
01293             norm_factor = grid2_larea(n)
01294           ! endif
01295         end select
01296         if (abs(grid2_centroid_lat(n)-norm_factor) > .01) then
01297           print *, &
01298       'Error sum wts map1:grid2_add,grid2_centroid_lat,norm_factor, mask=' &
01299       ,n,grid2_centroid_lat(n), &
01300       norm_factor,Drv_Epios(id_epio_id)%tgt_mask_pointer(n)  
01301         endif
01302       end do
01303 #endif
01304       ! Call prismtrs_store_link_cnsrv juste to deallocate local save arrays
01305       !
01306       il_action = il_action + 1
01307       IF (il_action == 2) THEN
01308           call prismtrs_store_link_cnsrv(grid1_add, grid2_add, lcl_weights, &
01309              il_action, id_epio_id, num_wts)
01310       ENDIF
01311       !
01312 !-----------------------------------------------------------------------
01313 !
01314 !     deallocate allocated arrays
01315 !
01316 !----------------------------------------------------------------------- 
01317 
01318       deallocate (grid1_centroid_lat, grid1_centroid_lon, &
01319                   grid2_centroid_lat, grid2_centroid_lon)
01320       DEALLOCATE (grid1cell_corner_lat, grid1cell_corner_lon)
01321 
01322 !-----------------------------------------------------------------------
01323 !
01324 #ifdef VERBOSE
01325   PRINT *, '| | | | | | | Quit PRISMTrs_remap_conserv'
01326   call psmile_flushstd
01327 #endif
01328 END SUBROUTINE PRISMTrs_remap_conserv
01329 

Generated on 1 Dec 2011 for Oasis4 by  doxygen 1.6.1