- Timestamp:
- 2019-10-01T18:17:20+02:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2019/ENHANCE-03_closea/src/OCE/SBC/sbcclo.F90
r11295 r11629 2 2 !!====================================================================== 3 3 !! *** MODULE sbcclo *** 4 !! Ocean forcing: closea sea correction4 !! Ocean forcing: redistribution of emp unbalance over closed sea into river mouth or open ocean 5 5 !!===================================================================== 6 !! History : 4.1 ! 2019-09 (P. Mathiot) original 7 !! NEMO 8 !!---------------------------------------------------------------------- 9 ! 10 !!---------------------------------------------------------------------- 6 !! History : 4.0 and earlier ! see closea.F90 history 7 !! NEMO 4.1 ! 2019-09 (P. Mathiot) rewrite sbc_clo module to match new closed sea mask definition (original sbcclo.F90) 8 !! 9 !!---------------------------------------------------------------------- 10 ! 11 !!---------------------------------------------------------------------- 12 !! Public subroutines: 11 13 !! sbc_clo : update emp and qns over target area and source area 12 14 !! sbc_clo_init : initialise all variable needed for closed sea correction 13 15 !! 14 !! alloc_cssurf : allocate closed sea surface array15 !! alloc_cs grp : allocate closed sea grouparray16 !! Private subroutines: 17 !! alloc_csarr : allocate closed sea array 16 18 !! get_cssrcsurf : compute source surface area 17 19 !! get_cstrgsurf : compute target surface area … … 33 35 IMPLICIT NONE 34 36 ! 35 PRIVATE alloc_cssurf 36 PRIVATE alloc_csgrp 37 PRIVATE get_cssrcsurf 38 PRIVATE get_cstrgsurf 39 PRIVATE prt_csctl 40 PRIVATE sbc_csupdate 37 PRIVATE 41 38 ! 42 39 PUBLIC sbc_clo 43 40 PUBLIC sbc_clo_init 44 41 ! 45 REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: rsurfsrcg, rsurftrgg !: closed seatarget glo surface areas46 REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: rsurfsrcr, rsurftrgr !: closed seatarget rnf surface areas47 REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: rsurfsrce, rsurftrge !: closed seatarget emp surface areas48 ! 49 INTEGER, PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: mcsgrpg, mcsgrpr, mcsgrpe !: closed sea group for glo, rnf and emp42 REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: rsurfsrcg, rsurftrgg !: closed sea source/target glo surface areas 43 REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: rsurfsrcr, rsurftrgr !: closed sea source/target rnf surface areas 44 REAL(wp), PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: rsurfsrce, rsurftrge !: closed sea source/target emp surface areas 45 ! 46 INTEGER, PUBLIC, SAVE, ALLOCATABLE, DIMENSION(:) :: mcsgrpg, mcsgrpr, mcsgrpe !: closed sea group for glo, rnf and emp 50 47 ! 51 48 CONTAINS … … 59 56 !! *** ROUTINE sbc_clo_init *** 60 57 !! 61 !! ** Purpose : Initialisation of the net fw closed sea correction58 !! ** Purpose : Initialisation of the variable needed for the net fw closed sea correction 62 59 !! 63 60 !! ** Method : - compute source surface area for each closed sea 64 61 !! - defined the group of each closed sea 65 !! 66 !! - compute target surface area and corresponding group for each closed sea62 !! (needed to manage multiple closed sea and one target area like great lakes / St Laurent outlet) 63 !! - compute target surface area 67 64 !!---------------------------------------------------------------------- 68 65 ! 69 66 ! 0. Allocate cs variables (surf) 70 CALL alloc_cs surf( ncsg, rsurfsrcg, rsurftrgg )71 CALL alloc_cs surf( ncsr, rsurfsrcr, rsurftrgr )72 CALL alloc_cs surf( ncse, rsurfsrce, rsurftrge )67 CALL alloc_csarr( ncsg, rsurfsrcg, rsurftrgg, mcsgrpg ) 68 CALL alloc_csarr( ncsr, rsurfsrcr, rsurftrgr, mcsgrpr ) 69 CALL alloc_csarr( ncse, rsurfsrce, rsurftrge, mcsgrpe ) 73 70 ! 74 71 ! 1. compute source surface area … … 77 74 CALL get_cssrcsurf( ncse, mask_csemp, rsurfsrce ) 78 75 ! 79 ! 2. Allocate cs group variables (mcsgrp) 80 CALL alloc_csgrp( ncsg, mcsgrpg ) 81 CALL alloc_csgrp( ncsr, mcsgrpr ) 82 CALL alloc_csgrp( ncse, mcsgrpe ) 83 ! 84 ! 3. compute target surface area and group number (mcsgrp) for all cs and cases 76 ! 2. compute target surface area and group number (mcsgrp) for all cs and cases 85 77 ! glo could be simpler but for lisibility, all treated the same way 86 78 ! It is only done once, so not a big deal … … 89 81 CALL get_cstrgsurf( ncse, mask_csemp, mask_csgrpemp, rsurftrge, mcsgrpe ) 90 82 ! 91 ! 4. print out in ocean.ouput 83 ! 3. print out in ocean.ouput 84 IF ( lwp ) WRITE(numout,*) 'sbc_clo_init : compute surface area for source (closed sea) and target (river mouth)' 85 IF ( lwp ) WRITE(numout,*) '~~~~~~~~~~~~~~' 92 86 CALL prt_csctl( ncsg, rsurfsrcg, rsurftrgg, mcsgrpg, 'glo' ) 93 87 CALL prt_csctl( ncsr, rsurfsrcr, rsurftrgr, mcsgrpr, 'rnf' ) … … 96 90 END SUBROUTINE sbc_clo_init 97 91 98 SUBROUTINE sbc_clo( kt ) ! to be move in SBC in a file sbcclo ???92 SUBROUTINE sbc_clo( kt ) 99 93 !!--------------------------------------------------------------------- 100 94 !! *** ROUTINE sbc_clo *** … … 144 138 !!---------------------------------------------------------------------- 145 139 ! subroutine parameters 146 INTEGER, INTENT(in ) :: kncs ! closed sea number 147 INTEGER, DIMENSION(:,:), INTENT(in ) :: kmaskcs ! closed sea mask 148 149 REAL(wp), DIMENSION(:) , INTENT(inout) :: psurfsrc ! source surface area 140 INTEGER , INTENT(in ) :: kncs ! closed sea number 141 INTEGER , DIMENSION(:,:), INTENT(in ) :: kmaskcs ! closed sea mask 142 REAL(wp), DIMENSION(:) , INTENT( out) :: psurfsrc ! source surface area 150 143 151 144 ! local variables … … 177 170 !!---------------------------------------------------------------------- 178 171 ! subroutine parameters 172 ! input 179 173 INTEGER, INTENT(in ) :: kncs ! closed sea number 180 INTEGER, DIMENSION(:) , INTENT(inout) :: kcsgrp ! closed sea group number181 174 INTEGER, DIMENSION(:,:), INTENT(in ) :: kmaskcs, kmaskcsgrp ! closed sea and group mask 182 175 183 REAL(wp), DIMENSION(:) , INTENT(inout) :: psurftrg ! target surface area 176 ! output 177 INTEGER , DIMENSION(:) , INTENT( out) :: kcsgrp ! closed sea group number 178 REAL(wp), DIMENSION(:) , INTENT( out) :: psurftrg ! target surface area 184 179 185 180 ! local variables 186 181 INTEGER :: jcs, jtmp ! tmp 187 INTEGER, DIMENSION(jpi,jpj) :: imskgrp, imsksrc, imsktrg ! tmp group, source and targetmask182 INTEGER, DIMENSION(jpi,jpj) :: imskgrp, imsksrc, imsktrg, imsk ! tmp group, source, target and tmp mask 188 183 !!---------------------------------------------------------------------- 189 184 ! … … 194 189 imsksrc = kmaskcs 195 190 ! 196 ! set cs value where cs is 197 imsktrg = HUGE(1) 198 WHERE ( imsksrc == jcs ) imsktrg = jcs 199 ! 200 ! zmsk = HUGE outside the cs number jcs 201 ! ktmp = jcs - group number 202 ! jgrp = group corresponding to the cs jcs 203 imsktrg = imsktrg - imskgrp 204 jtmp = MINVAL(imsktrg) ; CALL mpp_min('closea',jtmp) 191 ! set cs value where cs is defined 192 ! imsk = HUGE outside the cs id jcs 193 imsk = HUGE(1) 194 WHERE ( imsksrc == jcs ) imsk = jcs 195 ! 196 ! jtmp = jcs - group id for this lake 197 imsk = imsk - imskgrp 198 jtmp = MINVAL(imsk) ; CALL mpp_min('closea',jtmp) 199 ! kcsgrp = group id corresponding to the cs id jcs 200 ! kcsgrp(jcs)=(jcs - (jcs - group id))=group id 205 201 kcsgrp(jcs) = jcs - jtmp 206 202 ! 207 !! 1. build river mouth mask for this lake203 !! 1. build the target river mouth mask for this lake 208 204 WHERE ( imskgrp * mask_opnsea == kcsgrp(jcs) ) 209 205 imsktrg = 1 … … 243 239 ! 244 240 DO jcs = 1,kncs 245 WRITE(numout,FMT='(3a,i3,a,i3)') ' ',TRIM(cdcstype),' closed sea id is ',jcs,' and trg id is : ', kcsgrp(jcs)241 WRITE(numout,FMT='(3a,i3,a,i3)') ' ',TRIM(cdcstype),' closed sea id is ',jcs,' and trg group id is : ', kcsgrp(jcs) 246 242 WRITE(numout,FMT='(a,f12.2)' ) ' src surface areas (km2) : ', psurfsrc(jcs) * 1.0e-6 247 243 WRITE(numout,FMT='(a,f12.2)' ) ' trg surface areas (km2) : ', psurftrg(jcs) * 1.0e-6 … … 253 249 END SUBROUTINE 254 250 255 SUBROUTINE sbc_csupdate(kncs, kcsgrp, kmsk_src, kmsk_ trg, psurfsrc, psurftrg, cdcstype, kmsk_opnsea, psurf_opnsea, pwcs, pqcs)251 SUBROUTINE sbc_csupdate(kncs, kcsgrp, kmsk_src, kmsk_grp, psurfsrc, psurftrg, cdcstype, kmsk_opnsea, psurf_opnsea, pwcs, pqcs) 256 252 !!----------------------------------------------------------------------- 257 253 !! *** routine sbc_csupdate *** … … 261 257 !!---------------------------------------------------------------------- 262 258 ! subroutine parameters 263 INTEGER, INTENT(in) :: kncs ! closed sea number264 INTEGER, DIMENSION(: ), INTENT(in) :: kcsgrp ! closed sea group number265 INTEGER, DIMENSION(:,:), INTENT(in) :: kmsk_src, kmsk_ trg, kmsk_opnsea! source, target, open ocean mask259 INTEGER, INTENT(in) :: kncs ! closed sea id 260 INTEGER, DIMENSION(: ), INTENT(in) :: kcsgrp ! closed sea group id 261 INTEGER, DIMENSION(:,:), INTENT(in) :: kmsk_src, kmsk_grp, kmsk_opnsea ! source, target, open ocean mask 266 262 267 263 REAL(wp), DIMENSION(:) , INTENT(in ) :: psurfsrc, psurftrg, psurf_opnsea ! source, target and open ocean surface area … … 271 267 272 268 ! local variables 273 INTEGER :: jcs ! loop index over closed sea269 INTEGER :: jcs ! loop index over closed sea 274 270 INTEGER, DIMENSION(jpi,jpj) :: imsk_src, imsk_trg ! tmp array source and target closed sea masks 275 271 … … 281 277 DO jcs = 1, kncs ! loop over closed seas 282 278 ! 283 !! 0. get mask of eachclosed sea279 !! 0. get mask of the closed sea 284 280 imsk_src(:,:) = 0 285 281 WHERE ( kmsk_src(:,:) == jcs ) imsk_src(:,:) = 1 286 282 ! 287 !! 1. Work out net freshwater fluxes over each closed seas from EMP - RNF. 283 !! 1. Work out net freshwater fluxes over the closed sea from EMP - RNF. 284 !! (PM: should we consider used delayed glob sum ?) 288 285 zcsfwf = glob_sum( 'closea', e1e2t(:,:) * ( emp(:,:)-rnf(:,:) ) * imsk_src(:,:) ) 289 286 ! 290 287 !! 2. Deal with runoff special case (net evaporation spread globally) 288 !! and compute trg mask 291 289 IF (cdcstype == 'rnf' .AND. zcsfwf > 0) THEN 292 zsurftrg = psurf_opnsea(1) 293 imsk_trg = k msk_opnsea * kcsgrp(jcs) ! set imsk_trg value to the corresponding group id290 zsurftrg = psurf_opnsea(1) ! change the target area surface 291 imsk_trg = kcsgrp(jcs) * kmsk_opnsea ! trg mask is now the open sea mask 294 292 ELSE 295 293 zsurftrg = psurftrg(jcs) 296 imsk_trg = kmsk_ trg294 imsk_trg = kmsk_grp * kmsk_opnsea 297 295 END IF 298 imsk_trg = imsk_trg * kmsk_opnsea299 296 ! 300 297 !! 3. Add residuals to target points 301 zcoef 302 zcoef1 298 zcoef = zcsfwf / zsurftrg 299 zcoef1 = rcp * zcoef 303 300 WHERE( imsk_trg(:,:) == kcsgrp(jcs) ) 304 301 pwcs(:,:) = pwcs(:,:) + zcoef … … 313 310 pqcs(:,:) = pqcs(:,:) + zcoef1 * sst_m(:,:) 314 311 ENDWHERE 312 ! WARNING (PM): the correction is done as it was done in the previous version 313 ! this do no conserve heat as there is no reason that 314 ! sum(zcoef1*sst_m) over the source (closed sea) (4) = sum(zcoef1*sst_m) over the target (river mouth) (3) 315 315 ! 316 316 END DO ! jcs … … 318 318 END SUBROUTINE 319 319 320 SUBROUTINE alloc_cs surf( klen, pvarsrc, pvartrg)320 SUBROUTINE alloc_csarr( klen, pvarsrc, pvartrg, kvargrp ) 321 321 !!----------------------------------------------------------------------- 322 322 !! *** routine alloc_cssurf *** 323 323 !! 324 !! ** Purpose : allocate closed sea surface array (source) 325 !!---------------------------------------------------------------------- 326 ! subroutine parameters 327 INTEGER, INTENT(in) :: klen 328 REAL(wp), ALLOCATABLE, DIMENSION(:), INTENT(inout) :: pvarsrc, pvartrg 324 !! ** Purpose : allocate closed sea surface array 325 !!---------------------------------------------------------------------- 326 ! subroutine parameters 327 INTEGER, INTENT(in) :: klen 328 INTEGER, ALLOCATABLE, DIMENSION(:), INTENT( out) :: kvargrp 329 REAL(wp), ALLOCATABLE, DIMENSION(:), INTENT( out) :: pvarsrc, pvartrg 329 330 ! 330 331 ! local variables … … 336 337 IF( ierr /= 0 ) CALL ctl_stop( 'STOP', 'sbc_clo: failed to allocate surf array') 337 338 ! 339 ALLOCATE( kvargrp(MAX(klen,1)) , STAT=ierr ) 340 IF( ierr /= 0 ) CALL ctl_stop( 'STOP', 'sbc_clo: failed to allocate group array') 341 ! 338 342 ! initialise to 0 339 343 pvarsrc(:) = 0.e0_wp 340 344 pvartrg(:) = 0.e0_wp 341 END SUBROUTINE 342 343 SUBROUTINE alloc_csgrp( klen, kvar ) 344 !!----------------------------------------------------------------------- 345 !! *** routine alloc_csgrp *** 346 !! 347 !! ** Purpose : allocate closed sea group surface array 348 !!---------------------------------------------------------------------- 349 ! subroutine parameters 350 INTEGER, INTENT(in) :: klen 351 INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(inout) :: kvar 352 ! 353 ! local variables 354 INTEGER :: ierr 355 !!---------------------------------------------------------------------- 356 ! 357 ! klen (number of lake) can be zero so use MAX(klen,1) to avoid 0 length array 358 ALLOCATE( kvar(MAX(klen,1)) , STAT=ierr ) 359 IF( ierr /= 0 ) CALL ctl_stop( 'STOP', 'sbc_clo: failed to allocate group array') 360 ! initialise to 0 361 kvar(:) = 0 345 kvargrp(:) = 0 362 346 END SUBROUTINE 363 347
Note: See TracChangeset
for help on using the changeset viewer.