Changeset 2528 for trunk/NEMOGCM/NEMO/OPA_SRC/SBC
- Timestamp:
- 2010-12-27T18:33:53+01:00 (14 years ago)
- Location:
- trunk/NEMOGCM/NEMO/OPA_SRC/SBC
- Files:
-
- 21 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/albedo.F90
- Property svn:eol-style deleted
r1601 r2528 45 45 46 46 !!---------------------------------------------------------------------- 47 !! NEMO/OPA 9.0 , LOCEAN-IPSL (2009)47 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 48 48 !! $Id$ 49 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)49 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 50 50 !!---------------------------------------------------------------------- 51 51 -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/cpl_oasis3.F90
- Property svn:eol-style deleted
r2090 r2528 29 29 USE mod_prism_put_proto ! OASIS3 prism module for snding 30 30 USE mod_prism_get_proto ! OASIS3 prism module for receiving 31 USE mod_comprism_proto ! OASIS3 prism module to get coupling frequency 31 32 USE par_oce ! ocean parameters 32 33 USE dom_oce ! ocean space and time domain … … 61 62 PUBLIC cpl_prism_snd 62 63 PUBLIC cpl_prism_rcv 64 PUBLIC cpl_prism_freq 63 65 PUBLIC cpl_prism_finalize 64 66 65 67 !!---------------------------------------------------------------------- 66 !! OPA 9.0 , LOCEAN-IPSL (2006)67 !! $ Header$68 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)68 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 69 !! $Id$ 70 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 69 71 !!---------------------------------------------------------------------- 70 72 … … 210 212 !! * Arguments 211 213 !! 212 INTEGER, INTENT( IN ) :: kid ! variable in tex in the array214 INTEGER, INTENT( IN ) :: kid ! variable index in the array 213 215 INTEGER, INTENT( OUT ) :: kinfo ! OASIS3 info argument 214 216 INTEGER, INTENT( IN ) :: kstep ! ocean time-step in seconds … … 247 249 !! like stresses and fluxes from the coupler or remote application. 248 250 !!---------------------------------------------------------------------- 249 INTEGER, INTENT( IN ) :: kid ! variable in tex in the array251 INTEGER, INTENT( IN ) :: kid ! variable index in the array 250 252 INTEGER, INTENT( IN ) :: kstep ! ocean time-step in seconds 251 253 REAL(wp), DIMENSION(jpi,jpj), INTENT( INOUT ) :: pdata ! IN to keep the value if nothing is done … … 293 295 294 296 297 FUNCTION cpl_prism_freq( kid ) 298 299 !!--------------------------------------------------------------------- 300 !! *** ROUTINE cpl_prism_freq *** 301 !! 302 !! ** Purpose : - send back the coupling frequency for a particular field 303 !!---------------------------------------------------------------------- 304 INTEGER,INTENT( IN ) :: kid ! variable index 305 INTEGER :: cpl_prism_freq ! coupling frequency 306 cpl_prism_freq = ig_def_freq( kid ) 307 308 END FUNCTION cpl_prism_freq 309 310 295 311 SUBROUTINE cpl_prism_finalize 296 312 -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/cpl_oasis4.F90
- Property svn:eol-style deleted
r1715 r2528 1 1 MODULE cpl_oasis4 2 2 !!====================================================================== 3 !! *** MODULE cpl_oasis 4***3 !! *** MODULE cpl_oasis *** 4 4 !! Coupled O/A : coupled ocean-atmosphere case using OASIS4 5 !! special case: OPA/LIM coupled to ECHAM56 5 !!===================================================================== 7 6 !! History : … … 11 10 !! " " ! 05-08 (R. Redler, W. Park) frld initialization, paral(2) revision 12 11 !! " " ! 05-09 (R. Redler) extended to allow for communication over root only 13 !! " " ! 05-09 (R. Redler) extended to allow for communication over root only 14 !! " " ! 05-12 (R. Hill, Met. Office) Tweaks and hacks to get NEMO/O4 working 15 !! " " ! 06-02 (R. Redler, W. Park) Bug fixes and updates according to the OASIS3 interface 16 !! " " ! 06-02 (R. Redler) app/grid/grid_name from namelist 12 !! " " ! 06-01 (W. Park) modification of physical part 13 !! " " ! 06-02 (R. Redler, W. Park) buffer array fix for root exchange 14 !! " " ! 2010 (E. Maisonnave and S. Masson) complete rewrite 17 15 !!---------------------------------------------------------------------- 18 16 #if defined key_oasis4 19 17 !!---------------------------------------------------------------------- 20 18 !! 'key_oasis4' coupled Ocean/Atmosphere via OASIS4 19 !!---------------------------------------------------------------------- 21 20 !!---------------------------------------------------------------------- 22 21 !! cpl_prism_init : initialization of coupled mode communication 23 22 !! cpl_prism_define : definition of grid and fields 24 !! cpl_prism_send : send out fields in coupled mode 25 !! cpl_prism_recv : receive fields in coupled mode 23 !! cpl_prism_snd : snd out fields in coupled mode 24 !! cpl_prism_rcv : receive fields in coupled mode 25 !! cpl_prism_update_time : update date sent to Oasis 26 26 !! cpl_prism_finalize : finalize the coupled mode communication 27 27 !!---------------------------------------------------------------------- 28 !! * Modules used 29 !##################### WARNING coupled mode ############################### 30 !##################### WARNING coupled mode ############################### 31 ! Following line must be enabled if coupling with OASIS 32 ! USE prism ! prism module 33 !##################### WARNING coupled mode ############################### 34 !##################### WARNING coupled mode ############################### 35 #if defined key_mpp_mpi 36 USE lib_mpp, only : mppsize, mpprank ! message passing 37 USE lib_mpp, only : mppsend ! message passing 38 USE lib_mpp, only : mpprecv ! message passing 39 #endif 28 USE prism ! OASIS4 prism module 29 USE par_oce ! ocean parameters 40 30 USE dom_oce ! ocean space and time domain 31 USE domwri ! ocean space and time domain 41 32 USE in_out_manager ! I/O manager 42 USE par_oce ! 43 USE phycst, only : rt0 ! freezing point of sea water 44 USE oasis4_date ! OASIS4 date declarations in 45 ! PRISM compatible format 33 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 34 46 35 IMPLICIT NONE 36 PRIVATE 47 37 ! 48 ! Exchange parameters for coupling ORCA-LIM with ECHAM5 49 ! 50 #if defined key_cpl_ocevel 51 INTEGER, PARAMETER :: nsend = 6 52 #else 53 INTEGER, PARAMETER :: nsend = 4 54 #endif 55 56 #if defined key_cpl_discharge 57 INTEGER, PARAMETER :: nrecv = 20 58 #else 59 INTEGER, PARAMETER :: nrecv = 17 60 #endif 61 62 INTEGER, DIMENSION(nsend) :: send_id 63 INTEGER, DIMENSION(nrecv) :: recv_id 64 65 CHARACTER(len=32) :: cpl_send (nsend) 66 CHARACTER(len=32) :: cpl_recv (nrecv) 67 68 CHARACTER(len=16) :: app_name ! application name for OASIS use 69 CHARACTER(len=16) :: comp_name ! name of this PRISM component 70 CHARACTER(len=16) :: grid_name ! name of the grid 71 CHARACTER(len=1) :: c_mpi_send 72 73 ! The following now come in via new module oasis4_date 74 ! TYPE(PRISM_Time_struct), PUBLIC :: dates ! date info for send operation 75 ! TYPE(PRISM_Time_struct), PUBLIC :: dates_bound(2) ! date info for send operation 76 ! TYPE(PRISM_Time_struct), PUBLIC :: dater ! date info for receive operation 77 ! TYPE(PRISM_Time_struct), PUBLIC :: dater_bound(2) ! date info for receive operation 78 ! TYPE(PRISM_Time_struct), PUBLIC :: tmpdate 79 80 PRIVATE 81 82 INTEGER, PARAMETER :: localRoot = 0 83 84 INTEGER :: localRank ! local MPI rank 85 INTEGER :: localSize ! local MPI size 86 INTEGER :: localComm ! local MPI size 87 LOGICAL :: commRank ! true for ranks doing OASIS communication 88 INTEGER :: comp_id ! id returned by prism_init_comp 89 90 INTEGER :: range(5) 91 92 LOGICAL, SAVE :: prism_was_initialized 93 LOGICAL, SAVE :: prism_was_terminated 94 INTEGER, SAVE :: write_grid 95 96 INTEGER :: ierror ! return error code 97 98 #ifdef key_cpl_rootexchg 99 LOGICAL :: rootexchg =.true. ! logical switch 100 #else 101 LOGICAL :: rootexchg =.false. ! logical switch 102 #endif 103 104 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: exfld ! Temporary buffer for exchange 105 REAL(wp), DIMENSION(:), ALLOCATABLE :: buffer ! Temporary buffer for exchange 106 INTEGER, DIMENSION(:,:), ALLOCATABLE :: ranges ! Temporary buffer for exchange 107 108 DOUBLE PRECISION :: date_incr 38 ! LOGICAL, PUBLIC, PARAMETER :: lk_cpl = .TRUE. ! coupled flag 39 INTEGER :: ncomp_id ! id returned by prism_init_comp 40 INTEGER :: nerror ! return error code 41 INTEGER, PUBLIC :: OASIS_Rcv = 1 ! return code if received field 42 INTEGER, PUBLIC :: OASIS_idle = 0 ! return code if nothing done by oasis 43 44 INTEGER, PARAMETER :: nmaxfld=40 ! Maximum number of coupling fields 45 46 TYPE, PUBLIC :: FLD_CPL ! Type for coupling field information 47 LOGICAL :: laction ! To be coupled or not 48 CHARACTER(len = 8) :: clname ! Name of the coupling field 49 CHARACTER(len = 1) :: clgrid ! Grid type 50 REAL(wp) :: nsgn ! Control of the sign change 51 INTEGER :: nid ! Id of the field 52 END TYPE FLD_CPL 53 54 TYPE(FLD_CPL), DIMENSION(nmaxfld), PUBLIC :: srcv, ssnd ! Coupling fields 55 56 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: exfld ! Temporary buffer for receiving 57 58 TYPE(PRISM_Time_struct), PUBLIC :: date ! date info for send operation 59 TYPE(PRISM_Time_struct), PUBLIC :: date_bound(2) ! date info for send operation 60 109 61 110 62 !! Routine accessibility 111 63 PUBLIC cpl_prism_init 112 64 PUBLIC cpl_prism_define 113 PUBLIC cpl_prism_send 114 PUBLIC cpl_prism_recv 65 PUBLIC cpl_prism_snd 66 PUBLIC cpl_prism_rcv 67 PUBLIC cpl_prism_update_time 115 68 PUBLIC cpl_prism_finalize 116 69 117 PUBLIC send_id, recv_id118 119 70 !!---------------------------------------------------------------------- 120 71 !! OPA 9.0 , LOCEAN-IPSL (2006) 121 !! $ Id$72 !! $Header$ 122 73 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) 123 74 !!---------------------------------------------------------------------- … … 125 76 CONTAINS 126 77 127 SUBROUTINE cpl_prism_init( localCommunicator ) 128 129 IMPLICIT NONE 78 SUBROUTINE cpl_prism_init (kl_comm) 130 79 131 80 !!------------------------------------------------------------------- … … 137 86 !! ** Method : OASIS4 MPI communication 138 87 !!-------------------------------------------------------------------- 139 !! * Arguments 140 !! 141 INTEGER, INTENT(OUT) :: localCommunicator 142 !! 143 !! * Local declarations 144 !! 145 146 NAMELIST/nam_mpp/ app_name, comp_name, c_mpi_send, grid_name 147 148 !! 149 !!-------------------------------------------------------------------- 150 !! 151 IF(lwp) WRITE(numout,*) 152 IF(lwp) WRITE(numout,*) 'cpl_prism_init : initialization in coupled ocean/atmosphere case' 153 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~~' 154 IF(lwp) WRITE(numout,*) 155 156 #if defined key_flx_bulk_monthly || defined key_flx_bulk_daily || defined key_flx_forced_daily 157 158 #if !defined key_oasis4 159 ! The following is not necessarily a valid peice of checking 160 161 IF(lwp) WRITE(numout,cform_err) 162 IF(lwp) WRITE(numout,*) ' key_coupled and key_flx_bulk_* key_flx_forced_daily are incompatible' 163 nstop = nstop + 1 164 165 #endif 166 167 #endif 168 169 REWIND( numnam ) 170 READ ( numnam, nam_mpp ) 171 REWIND( numnam ) 172 173 !------------------------------------------------------------------ 174 ! 1st Initialize the PRISM system for the application 175 !------------------------------------------------------------------ 176 177 CALL prism_initialized (prism_was_initialized, ierror) 178 IF ( ierror /= PRISM_Success ) & 179 CALL prism_abort( comp_id, 'OPA9.0', 'cpl_prism_init: Failure in prism_initialized' ) 180 181 IF ( .NOT. prism_was_initialized ) THEN 182 CALL prism_init( app_name, ierror ) 183 IF ( ierror /= PRISM_Success ) & 184 CALL prism_abort(comp_id, 'OPA9.0', 'cpl_prism_init: Failure in prism_init') 185 prism_was_initialized = .true. 186 ELSE 187 call prism_abort(comp_id, 'OPA9.0', 'cpl_prism_init: Do not initialize prism twice!') 188 ENDIF 189 ! 190 ! Obtain the actual dates and date bounds 191 ! 192 ! date is determined by adding days since beginning of 193 ! the run to the corresponding initial date. Note that 194 ! OPA internal info about the start date of the experiment 195 ! is bypassed. Instead we rely sololy on the info provided 196 ! by the SCC.xml file. 197 ! 198 dates = PRISM_Jobstart_date 199 200 WRITE(6,*) "PRISM JOB START DATE IS", dates 201 202 ! 203 ! upper bound is determined by adding half a time step 204 ! 205 tmpdate = dates 206 date_incr = rdttra(1)/2.0 207 CALL PRISM_calc_newdate ( tmpdate, date_incr, ierror ) 208 dates_bound(2) = tmpdate 209 ! 210 ! lower bound is determined by half distance to date from previous run 211 ! 212 tmpdate = dates 213 date_incr = ( adatrj - adatrj0 ) * 43200.0 214 CALL PRISM_calc_newdate ( tmpdate, date_incr, ierror ) 215 dates_bound(1) = tmpdate 216 217 dater = dates 218 dater_bound(1) = dates_bound(1) 219 dater_bound(2) = dates_bound(2) 220 221 WRITE(6,*) "DATE send and rec BOUNDS",dater_bound 222 WRITE(6,*) "OTHER BITS FOR DATE",rdttra(1) 223 WRITE(6,*) "adatrj/0",adatrj,adatrj0,date_incr 88 INTEGER, INTENT( OUT ) :: kl_comm ! local communicator of the model 89 ! 90 91 CALL prism_init( 'nemo', nerror ) 224 92 225 93 !------------------------------------------------------------------ 226 94 ! 2nd Initialize the PRISM system for the component 227 95 !------------------------------------------------------------------ 228 229 CALL prism_init_comp ( comp_id, comp_name, ierror ) 230 IF ( ierror /= PRISM_Success ) & 231 CALL prism_abort (comp_id, 'OPA9.0', 'cpl_prism_init: Failure in prism_init_comp') 232 233 WRITE(6,*) "COMPLETED INIT_COMP",comp_name,comp_id 234 235 !------------------------------------------------------------------ 236 ! 3rd Get an MPI communicator for OPA local communication 237 !------------------------------------------------------------------ 238 239 CALL prism_get_localcomm ( comp_id, localComm, ierror ) 240 IF ( ierror /= PRISM_Success ) & 241 CALL prism_abort (comp_id, 'OPA9.0', 'cpl_prism_init: Failure in prism_get_localcomm' ) 242 243 localCommunicator = localComm 244 245 WRITE(6,*) "COMPLETED GET_LOCALCOMM",comp_name,comp_id 96 CALL prism_init_comp( ncomp_id, 'oceanx', nerror ) 97 IF( nerror /= PRISM_Success ) CALL prism_abort( ncomp_id, 'cpl_prism_init', 'Failure in prism_init_comp' ) 98 99 !------------------------------------------------------------------ 100 ! 3rd Get an MPI communicator fr OPA local communication 101 !------------------------------------------------------------------ 102 CALL prism_get_localcomm( ncomp_id, kl_comm, nerror ) 103 IF( nerror /= PRISM_Success ) CALL prism_abort( ncomp_id, 'cpl_prism_init', 'Failure in prism_get_localcomm' ) 246 104 247 105 … … 249 107 250 108 251 SUBROUTINE cpl_prism_define () 252 253 IMPLICIT NONE 109 SUBROUTINE cpl_prism_define (krcv, ksnd) 254 110 255 111 !!------------------------------------------------------------------- … … 261 117 !! ** Method : OASIS4 MPI communication 262 118 !!-------------------------------------------------------------------- 263 !! * Arguments 264 !! 265 !! * Local declarations 266 267 INTEGER :: grid_id(2) ! id returned by prism_def_grid 268 269 INTEGER :: upoint_id(2), & 270 vpoint_id(2), & 271 tpoint_id(2), & 272 fpoint_id(2) ! ids returned by prism_set_points 273 274 INTEGER :: umask_id(2), & 275 vmask_id(2), & 276 tmask_id(2), & 277 fmask_id(2) ! ids returned by prism_set_mask 278 279 INTEGER :: grid_type ! PRISM grid type 280 281 INTEGER :: shape(2,3) ! shape of arrays passed to PSMILe 282 INTEGER :: nodim(2) 119 INTEGER, INTENT( IN ) :: krcv, ksnd ! Number of received and sent coupling fields 120 ! 121 INTEGER, DIMENSION(4) :: igrid ! ids returned by prism_def_grid 122 INTEGER, DIMENSION(4) :: iptid ! ids returned by prism_set_points 123 124 INTEGER, DIMENSION(4) :: imskid ! ids returned by prism_set_mask 125 INTEGER, DIMENSION(4) :: iishift ! 126 INTEGER, DIMENSION(4) :: ijshift ! 127 INTEGER, DIMENSION(4) :: iioff ! 128 INTEGER, DIMENSION(4) :: ijoff ! 129 INTEGER, DIMENSION(4) :: itmp ! 130 INTEGER, DIMENSION(1,3) :: iextent ! 131 INTEGER, DIMENSION(1,3) :: ioffset ! 132 133 134 INTEGER :: ishape(2,3) ! shape of arrays passed to PSMILe 283 135 INTEGER :: data_type ! data type of transients 284 136 285 INTEGER :: nbr_corners286 137 287 138 LOGICAL :: new_points 288 139 LOGICAL :: new_mask 289 LOGICAL :: mask(jpi,jpj,jpk) 290 291 INTEGER :: ji, jj, jk ! local loop indicees 292 293 CHARACTER(len=32) :: cpl_send (nsend) 294 CHARACTER(len=32) :: cpl_recv (nrecv) 295 296 CHARACTER(len=32) :: grid_name ! name of the grid 297 CHARACTER(len=32) :: point_name ! name of the grid points 298 299 REAL(kind=wp), ALLOCATABLE :: rclon(:,:,:) 300 REAL(kind=wp), ALLOCATABLE :: rclat(:,:,:) 301 REAL(kind=wp), ALLOCATABLE :: rcz (:,:) 302 140 LOGICAL :: llmask(jpi,jpj,1) 141 142 INTEGER :: ji, jj, jg, jc ! local loop indicees 143 INTEGER :: ii,ij ! index 144 INTEGER, DIMENSION(1) :: ind ! index 145 146 CHARACTER(len=32) :: clpt_name ! name of the grid points 147 CHARACTER(len=7) :: cltxt 148 CHARACTER(len=1), DIMENSION(4) :: clgrd = (/ 'T','U','V','F' /) ! name of the grid points 149 150 REAL(kind=wp), DIMENSION(jpi,jpj,4) :: zclo, zcla 151 REAL(kind=wp), DIMENSION(jpi,jpj ) :: zlon, zlat 152 153 TYPE(PRISM_Time_struct) :: tmpdate 154 INTEGER :: idate_incr ! date increment 155 !! 303 156 !!-------------------------------------------------------------------- 304 157 305 158 IF(lwp) WRITE(numout,*) 306 159 IF(lwp) WRITE(numout,*) 'cpl_prism_define : initialization in coupled ocean/atmosphere case' 307 160 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~~~~' 308 161 IF(lwp) WRITE(numout,*) 309 310 #if defined key_flx_bulk_monthly || defined key_flx_bulk_daily || defined key_flx_forced_daily 311 312 #if !defined key_oasis4 313 ! The problem with the following is that it ASSUMES we're only ever coupling to an atmosphere 314 ! which is not necessarily the case. Prevent this test temporarily for NEMOGAM development. 315 316 IF(lwp) WRITE(numout,cform_err) 317 IF(lwp) WRITE(numout,*) ' key_coupled and key_flx_bulk_... are incompatible' 318 nstop = nstop + 1 319 320 #endif 321 322 #endif 323 324 ! ----------------------------------------------------------------- 325 ! ... Some initialisation 326 ! ----------------------------------------------------------------- 327 328 send_id = 0 329 recv_id = 0 330 331 #if defined key_mpp_mpi 332 333 ! ----------------------------------------------------------------- 334 ! ... Some MPI stuff relevant for optional exchange via root only 335 ! ----------------------------------------------------------------- 336 337 commRank = .false. 338 339 localRank = mpprank ! from lib_mpp 340 localSize = mppsize ! from lib_mpp 341 342 IF(lwp) WRITE(numout,*) "CALLING DEFINE" 343 344 IF ( rootexchg ) THEN 345 IF ( localRank == localRoot ) commRank = .true. 346 ELSE 347 commRank = .true. 348 ENDIF 349 350 #else 351 ! 352 ! For non-parallel configurations the one and only process ("localRoot") 353 ! takes part in the communication 354 ! 355 localRank = localRoot 356 commRank = .true. 357 358 #endif 359 360 ! ----------------------------------------------------------------- 162 163 ! 361 164 ! ... Allocate memory for data exchange 362 ! ----------------------------------------------------------------- 363 364 365 IF(lwp) WRITE(numout,*) "Abbout to allocate exfld",jpi,jpj 366 367 ALLOCATE(exfld(1:jpi,1:jpj), stat = ierror) 368 IF (ierror > 0) THEN 369 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in allocating Reals') 165 ! 166 ALLOCATE( exfld(nlei-nldi+1, nlej-nldj+1, 1), stat = nerror ) 167 IF ( nerror > 0 ) THEN 168 CALL prism_abort( ncomp_id, 'cpl_prism_define', 'Failure in allocating exfld' ) 370 169 RETURN 371 170 ENDIF 372 171 373 IF ( rootexchg .and. localRank == localRoot ) THEN 374 ALLOCATE(ranges(5,0:localSize-1), stat = ierror) 375 IF (ierror > 0) THEN 376 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in allocating Integer') 377 RETURN 378 ENDIF 379 ENDIF 380 381 !------------------------------------------------------------------ 382 ! 1st Declare the local grid (ORCA tripolar) characteristics for 383 ! surface coupling. The halo regions must be excluded. For 384 ! surface coupling it is sufficient to specify only one 385 ! vertical z-level. 386 !------------------------------------------------------------------ 387 388 grid_type = PRISM_irrlonlat_regvrt 389 390 IF(lwp) WRITE(numout,*) "Set grid type" 391 392 393 ! ----------------------------------------------------------------- 394 ! ... Define the shape of the valid region without the halo. 172 173 ! ----------------------------------------------------------------- 174 ! ... Define the shape of the valid region without the halo and overlaps between cpus 395 175 ! For serial configuration (key_mpp_mpi not being active) 396 176 ! nl* is set to the global values 1 and jp*glo. 397 177 ! ----------------------------------------------------------------- 398 178 399 IF ( rootexchg ) THEN 400 shape(1,1) = 1+jpreci 401 shape(2,1) = jpiglo-jpreci 402 shape(1,2) = 1+jpreci 403 shape(2,2) = jpjglo-jpreci 404 shape(1,3) = 1 405 shape(2,3) = 1 406 ELSE 407 shape(1,1) = 1+jpreci 408 shape(2,1) = jpi-jpreci 409 shape(1,2) = 1+jpreci 410 shape(2,2) = jpj-jpreci 411 shape(1,3) = 1 412 shape(2,3) = 1 413 ENDIF 414 415 IF(lwp) WRITE(numout,*) "commrank is", commRank 416 417 IF ( commRank ) THEN 418 419 IF(lwp) WRITE(numout,*) "CALLING DEF_GRID" 420 421 IF(lwp) WRITE(numout,*) "grid name",grid_name 422 IF(lwp) WRITE(numout,*) " shape",shape 423 IF(lwp) WRITE(numout,*) "grid type",grid_type 424 425 CALL prism_def_grid ( grid_id(1), grid_name, comp_id, shape, & 426 grid_type, ierror ) 427 IF ( ierror /= PRISM_Success ) THEN 428 PRINT *, 'OPA cpl_prism_define: Failure in prism_def_grid' 429 CALL prism_abort (comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_def_grid') 179 ishape(:,1) = (/ 1, nlei-nldi+1 /) 180 ishape(:,2) = (/ 1, nlej-nldj+1 /) 181 ishape(:,3) = (/ 1, 1 /) 182 183 DO ji = 1, 4 184 CALL prism_def_grid( igrid(ji), 'orca'//clgrd(ji), ncomp_id, ishape, PRISM_irrlonlat_regvrt, nerror ) 185 IF( nerror /= PRISM_Success ) CALL prism_abort (ncomp_id, 'cpl_prism_define', & 186 & 'Failure in prism_def_grid of '//clgrd(jg)//'-point' ) 187 END DO 188 189 ! ----------------------------------------------------------------- 190 ! ... Define the partition 191 ! ----------------------------------------------------------------- 192 193 iextent(1,:) = (/ nlei-nldi+1, nlej-nldj+1, 1 /) 194 ioffset(1,:) = (/ nldi-1+nimpp-1, nldj-1+njmpp-1, 0 /) 195 196 DO ji = 1, 4 197 CALL prism_def_partition( igrid(ji), 1, ioffset, iextent, nerror ) 198 IF( nerror /= PRISM_Success ) CALL prism_abort (ncomp_id, 'cpl_prism_define', & 199 & 'Failure in prism_def_partition of '//clgrd(jg)//'-point' ) 200 END DO 201 202 ! ----------------------------------------------------------------- 203 ! ... Define the elements, i.e. specify the corner points for each 204 ! volume element. In case OPA runs on level coordinates (regular 205 ! in the vertical) we only need to give the 4 horizontal corners 206 ! for a volume element plus the vertical position of the upper 207 ! and lower face. Nevertheless the volume element has 8 corners. 208 ! ----------------------------------------------------------------- 209 210 iioff(:) = (/0,1,0,1/) 211 ijoff(:) = (/0,0,1,1/) 212 iishift(:) = (/0,1,1,0/) 213 ijshift(:) = (/0,0,1,1/) 214 215 DO jg = 1, 4 ! ... the t,u,v,f-points 216 217 cltxt = clgrd(jg)//'-point' 218 219 ! ----------------------------------------------------------------- 220 ! ... Convert OPA masks to logicals and define the masks 221 ! ----------------------------------------------------------------- 222 SELECT CASE( jg ) 223 CASE(1) ; llmask(:,:,1) = ( tmask(:,:,1) ) == 1. 224 CASE(2) ; llmask(:,:,1) = ( umask(:,:,1) ) == 1. 225 CASE(3) ; llmask(:,:,1) = ( vmask(:,:,1) ) == 1. 226 CASE(4) ; llmask(:,:,1) = ( fmask(:,:,1) ) == 1. 227 ! CASE(1) ; llmask(:,:,1) = ( tmask(:,:,1) * dom_uniq('T') ) == 1. 228 ! CASE(2) ; llmask(:,:,1) = ( umask(:,:,1) * dom_uniq('U') ) == 1. 229 ! CASE(3) ; llmask(:,:,1) = ( vmask(:,:,1) * dom_uniq('V') ) == 1. 230 ! CASE(4) ; llmask(:,:,1) = ( fmask(:,:,1) * dom_uniq('F') ) == 1. 231 END SELECT 232 CALL prism_set_mask( imskid(jg), igrid(jg), ishape, llmask(nldi:nlei, nldj:nlej, 1), .TRUE., nerror ) 233 IF( nerror /= PRISM_Success ) CALL prism_abort( ncomp_id, 'cpl_prism_define', 'Failure in prism_set_mask for '//cltxt ) 234 235 ! ----------------------------------------------------------------- 236 ! ... Define the corners 237 ! ----------------------------------------------------------------- 238 SELECT CASE( jg ) 239 CASE(1) ; zlon(:,:) = glamf(:,:) ; zlat(:,:) = gphif(:,:) 240 CASE(2) ; zlon(:,:) = glamv(:,:) ; zlat(:,:) = gphiv(:,:) 241 CASE(3) ; zlon(:,:) = glamu(:,:) ; zlat(:,:) = gphiu(:,:) 242 CASE(4) ; zlon(:,:) = glamt(:,:) ; zlat(:,:) = gphit(:,:) 243 END SELECT 244 245 DO jc = 1, 4 ! corner number (anti-clockwise, starting from the bottom left corner) 246 DO jj = 2, jpjm1 247 DO ji = 2, jpim1 ! NO vector opt. 248 ii = ji-1 + iioff(jg) + iishift(jc) 249 ij = jj-1 + ijoff(jg) + ijshift(jc) 250 zclo(ji,jj,jc) = zlon(ii,ij) 251 zcla(ji,jj,jc) = zlat(ii,ij) 252 END DO 253 END DO 254 CALL lbc_lnk( zclo(:,:,jc), clgrd(jg), 1. ) ; CALL lbc_lnk( zcla(:,:,jc), clgrd(jg), 1. ) 255 END DO 256 257 CALL prism_set_corners( igrid(jg), 8, ishape, zclo(nldi:nlei, nldj:nlej,:), & 258 & zcla(nldi:nlei, nldj:nlej,:), RESHAPE( (/-1.,1./), (/1,2/) ), nerror ) 259 IF( nerror /= PRISM_Success ) CALL prism_abort( ncomp_id, 'cpl_prism_define', 'Failure in prism_set_corners of '//cltxt ) 260 261 ! ----------------------------------------------------------------- 262 ! ... Define the center points 263 ! ----------------------------------------------------------------- 264 SELECT CASE( jg ) 265 CASE(1) ; zlon(:,:) = glamt(:,:) ; zlat(:,:) = gphit(:,:) 266 CASE(2) ; zlon(:,:) = glamu(:,:) ; zlat(:,:) = gphiu(:,:) 267 CASE(3) ; zlon(:,:) = glamv(:,:) ; zlat(:,:) = gphiv(:,:) 268 CASE(4) ; zlon(:,:) = glamf(:,:) ; zlat(:,:) = gphif(:,:) 269 END SELECT 270 271 CALL prism_set_points ( iptid(jg), cltxt, igrid(jg), ishape, zlon(nldi:nlei, nldj:nlej), & 272 & zlat(nldi:nlei, nldj:nlej), (/0./), .TRUE., nerror ) 273 IF( nerror /= PRISM_Success ) CALL prism_abort ( ncomp_id, 'cpl_prism_define', 'Failure in prism_set_points '//cltxt ) 274 275 END DO 276 277 ! ... Announce send variables. 278 ! 279 DO ji = 1, ksnd 280 IF ( ssnd(ji)%laction ) THEN 281 282 itmp(:) = 0 283 WHERE( clgrd == ssnd(ji)%clgrid ) itmp = 1 284 ind(:) = maxloc( itmp ) 285 WRITE(6,*) ' grid for field ', ind(1), ssnd(ji)%clname 286 ind(1) = 1 287 288 CALL prism_def_var( ssnd(ji)%nid, ssnd(ji)%clname, igrid(ind(1)), iptid(ind(1)), imskid(ind(1)), (/ 3, 0/), & 289 & ishape, PRISM_Double_Precision, nerror ) 290 IF ( nerror /= PRISM_Success ) CALL prism_abort( ssnd(ji)%nid, 'cpl_prism_define', & 291 & 'Failure in prism_def_var for '//TRIM(ssnd(ji)%clname)) 292 430 293 ENDIF 431 432 !------------------------------------------------------------------ 433 ! 2nd Declare the geometic information for this grid. 434 !------------------------------------------------------------------ 435 436 ! ----------------------------------------------------------------- 437 ! ... Redefine shape which may now include the halo region as well. 438 ! ----------------------------------------------------------------- 439 440 shape(1,1) = 1 441 shape(2,1) = jpi 442 shape(1,2) = 1 443 shape(2,2) = jpj 444 shape(1,3) = 1 445 shape(2,3) = 1 446 447 IF(lwp) WRITE(numout,*) "redefined shape",shape 448 449 ! ----------------------------------------------------------------- 450 ! ... Define the elements, i.e. specify the corner points for each 451 ! volume element. In case OPA runs on level coordinates (regular 452 ! in the vertical) we only need to give the 4 horizontal corners 453 ! for a volume element plus the vertical position of the upper 454 ! and lower face. Nevertheless the volume element has 8 corners. 455 ! ----------------------------------------------------------------- 456 457 ! 458 ! ... Treat corners in the horizontal plane 459 ! 460 ALLOCATE(rclon(shape(1,1):shape(2,1),shape(1,2):shape(2,2),4), & 461 STAT=ierror) 462 IF ( ierror /= 0 ) & 463 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: error in allocate for rclon') 464 465 ALLOCATE(rclat(shape(1,1):shape(2,1),shape(1,2):shape(2,2),4), & 466 STAT=ierror) 467 IF ( ierror /= 0 ) & 468 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: error in allocate for rclon') 469 470 nbr_corners = 8 471 ! 472 ! ... Set right longitudes and upper latitudes 473 ! 474 DO jj = shape(1,2), shape(2,2) 475 DO ji = shape(1,1), shape(2,1) 476 rclon(ji,jj,1) = glamu(ji,jj) 477 rclon(ji,jj,2) = glamu(ji,jj) 478 rclat(ji,jj,2) = gphiv(ji,jj) 479 rclat(ji,jj,3) = gphiv(ji,jj) 480 ENDDO 481 ENDDO 482 ! 483 ! ... Set the lower latitudes 484 ! 485 DO jj = shape(1,2)+1, shape(2,2) 486 DO ji = shape(1,1), shape(2,1) 487 rclat(ji,jj-1,1) = rclat(ji,jj,2) 488 rclat(ji,jj-1,4) = rclat(ji,jj,3) 489 ENDDO 490 ENDDO 491 ! 492 ! ... Set the left longitudes 493 ! 494 DO jj = shape(1,2), shape(2,2) 495 DO ji = shape(1,1)+1, shape(2,1) 496 rclon(ji-1,jj,3) = rclon(ji,jj,2) 497 rclon(ji-1,jj,4) = rclon(ji,jj,1) 498 ENDDO 499 ENDDO 500 ! 501 ! ... Set the lowermost latitudes 502 ! 503 DO jj = shape(1,2), shape(1,2) 504 DO ji = shape(1,1), shape(2,1) 505 rclat(ji,jj,1) = 2.0*gphit(ji,jj)-rclat(ji,jj,2) 506 rclat(ji,jj,4) = 2.0*gphit(ji,jj)-rclat(ji,jj,4) 507 ENDDO 508 ENDDO 509 ! 510 ! ... Set the rightmost latitudes 511 ! 512 DO jj = shape(1,2), shape(2,2) 513 DO ji = shape(1,2), shape(1,2) 514 rclon(ji,jj,3) = 2.0*glamt(ji,jj)-rclon(ji,jj,2) 515 rclon(ji,jj,4) = 2.0*glamt(ji,jj)-rclon(ji,jj,1) 516 517 WRITE(76,*) "rclon", ji, jj, rclon(ji,jj,1), & 518 rclon(ji,jj,2), & 519 rclon(ji,jj,3), & 520 rclon(ji,jj,4) 521 522 WRITE(76,*) "rclat", ji, jj, rclat(ji,jj,1), & 523 rclat(ji,jj,2), & 524 rclat(ji,jj,3), & 525 rclat(ji,jj,4) 526 527 ENDDO 528 ENDDO 529 530 ! 531 ! ... Treat corners along the vertical axis 532 ! 533 ALLOCATE(rcz(shape(1,3):shape(2,3),2), STAT=ierror) 534 IF ( ierror /= 0 ) & 535 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: error in allocate for rcz') 536 537 DO jk = shape(1,3), shape(2,3) 538 rcz(jk,1) = gdepw(jk) 539 rcz(jk,2) = gdepw(jk+1) 540 ENDDO 541 542 IF(lwp) WRITE(numout,*) "ABOUT TO CALL SET CORNERS",shape 543 544 CALL prism_set_corners ( grid_id(1), nbr_corners, shape, rclon, rclat, & 545 rcz, ierror) 546 IF ( ierror /= PRISM_Success ) & 547 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_corners') 548 549 DEALLOCATE(rclon, rclat, rcz) 550 551 ! ----------------------------------------------------------------- 552 ! ... Define the gridpoints 553 ! ----------------------------------------------------------------- 554 555 new_points = .TRUE. 556 557 IF(lwp) WRITE(numout,*) "CALLING SET_POINTS" 558 559 ! 560 ! ... the u-points 561 ! 562 point_name = 'u-points' 563 CALL prism_set_points ( upoint_id(1), point_name, grid_id(1), shape, & 564 glamu, gphiu, gdept(shape(1,3):shape(2,3)), new_points, ierror ) 565 IF ( ierror /= PRISM_Success ) & 566 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_points upoint_id') 567 ! 568 ! ... the v-points 569 ! 570 571 IF(lwp) WRITE(numout,*) "CALLING SET_POINTS done u doing v" 572 573 point_name = 'v-points' 574 CALL prism_set_points ( vpoint_id(1), point_name, grid_id(1), shape, & 575 glamv, gphiv, gdept(shape(1,3):shape(2,3)), new_points, ierror ) 576 IF ( ierror /= PRISM_Success ) & 577 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_points vpoint_id') 578 ! 579 ! ... the t-points 580 ! 581 ! WRITE(76,*) 'CALLING T POINTS', shape 582 ! WRITE(77,*) 'glamt', glamt 583 ! WRITE(78,*) 'gphit', gphit 584 ! 585 point_name = 't-points' 586 CALL prism_set_points ( tpoint_id(1), point_name, grid_id(1), shape, & 587 glamt, gphit, gdept(shape(1,3):shape(2,3)), new_points, ierror ) 588 IF ( ierror /= PRISM_Success ) & 589 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_points tpoint_id') 590 ! 591 ! ... the f-points 592 ! 593 point_name = 'f-points' 594 CALL prism_set_points ( fpoint_id(1), point_name, grid_id(1), shape, & 595 glamf, gphif, gdept(shape(1,3):shape(2,3)), new_points, ierror ) 596 IF ( ierror /= PRISM_Success ) & 597 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_points fpoint_id') 598 599 600 IF(lwp) WRITE(numout,*) "CALLING SET_POINTS done f" 601 602 ! ----------------------------------------------------------------- 603 ! ... Convert OPA masks to logicals and define the masks 604 ! ----------------------------------------------------------------- 605 606 new_mask = .true. 607 608 mask = (umask == 1) 609 CALL prism_set_mask (umask_id(1), grid_id(1), shape, & 610 mask(shape(1,1):shape(2,1), & 611 shape(1,2):shape(2,2), & 612 shape(1,3):shape(2,3)), & 613 new_mask, ierror ) 614 IF ( ierror /= PRISM_Success ) & 615 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_mask umask_id') 616 617 mask = (vmask == 1) 618 CALL prism_set_mask (vmask_id(1), grid_id(1), shape, & 619 mask(shape(1,1):shape(2,1), & 620 shape(1,2):shape(2,2), & 621 shape(1,3):shape(2,3)), & 622 new_mask, ierror ) 623 IF ( ierror /= PRISM_Success ) & 624 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_mask umask_id') 625 626 mask = (tmask == 1) 627 CALL prism_set_mask (tmask_id(1), grid_id(1), shape, & 628 mask(shape(1,1):shape(2,1), & 629 shape(1,2):shape(2,2), & 630 shape(1,3):shape(2,3)), & 631 new_mask, ierror ) 632 IF ( ierror /= PRISM_Success ) & 633 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_mask umask_id') 634 635 mask = (fmask == 1) 636 CALL prism_set_mask (fmask_id(1), grid_id(1), shape, & 637 mask(shape(1,1):shape(2,1), & 638 shape(1,2):shape(2,2), & 639 shape(1,3):shape(2,3)), & 640 new_mask, ierror ) 641 IF ( ierror /= PRISM_Success ) & 642 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_set_mask umask_id') 643 644 IF(lwp) WRITE(numout,*) "DONE ALL THE SET MASKS" 645 646 ! ----------------------------------------------------------------- 647 ! ... Define the angles 648 ! This is needed if zonal tau is not oriented E-W and meridional 649 ! tau is not oriented along N-S but rather along local coordinate 650 ! axis. Please check!!!! 651 ! ----------------------------------------------------------------- 652 653 !rr cal prism_set_angles ( ..., ierror ) ! not yet supported by OASIS4 654 655 ! ----------------------------------------------------------------- 656 ! ... Define the partition 657 ! ----------------------------------------------------------------- 658 659 IF ( rootexchg ) THEN 660 661 range(1) = nimpp-1+nldi ! global start in i 662 range(2) = nlei-nldi+1 ! local size in i of valid region 663 range(3) = njmpp-1+nldj ! global start in j 664 range(4) = nlej-nldj+1 ! local size in j of valid region 665 range(5) = range(2) & 666 * range(4) ! local horizontal size 667 ! 668 ! Collect ranges from all NEMO procs on the local root process 669 ! 670 CALL mpi_gather(range, 5, MPI_INTEGER, & 671 ranges, 5, MPI_INTEGER, localRoot, localComm, ierror) 672 673 IF ( localRank == localRoot ) THEN 674 675 maxlen = maxval(ranges(5,:)) 676 677 ALLOCATE(buffer(1:maxlen), stat = ierror) 678 IF (ierror > 0) THEN 679 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in allocating buffer') 680 RETURN 681 ENDIF 682 683 ENDIF 294 END DO 295 ! 296 ! ... Announce received variables. 297 ! 298 DO ji = 1, krcv 299 IF ( srcv(ji)%laction ) THEN 300 301 itmp(:) = 0 302 WHERE( clgrd == srcv(ji)%clgrid ) itmp = 1 303 ind(:) = maxloc( itmp ) 304 WRITE(6,*) ' grid for field ', ind(1), srcv(ji)%clname 305 ind(1) = 1 306 307 CALL prism_def_var( srcv(ji)%nid, srcv(ji)%clname, igrid(ind(1)), iptid(ind(1)), imskid(ind(1)), (/ 3, 0/), & 308 & ishape, PRISM_Double_Precision, nerror ) 309 IF ( nerror /= PRISM_Success ) CALL prism_abort( srcv(ji)%nid, 'cpl_prism_define', & 310 & 'Failure in prism_def_var for '//TRIM(srcv(ji)%clname)) 684 311 685 312 ENDIF 686 687 ! ----------------------------------------------------------------- 688 ! ... Define the scalefactors 689 ! ----------------------------------------------------------------- 690 691 !rr WRITE(numout,*) "CALLING SCALEFACTOR" 692 !rr call prism_set_scalefactor ( grid_id(1), shape, e1t, e2t, e3t, ierror ) ! not yet supported by OASIS4 693 !rr WRITE(numout,*) "ABOUT TO DEFINE THE TRANSIENTS" 694 695 !------------------------------------------------------------------ 696 ! 3rd Declare the transient variables 697 !------------------------------------------------------------------ 698 ! 699 ! ... Define symbolic names for the transient fields send by the ocean 700 ! These must be identical to the names specified in the SMIOC file. 701 ! 702 cpl_send( 1)='SOSSTSST' ! sea surface temperature -> sst_io 703 cpl_send( 2)='SITOCEAN' ! sea ice thickness -> hicif (only 1 layer available!) 704 #if defined key_cpl_albedo 705 cpl_send( 3)='STIOCEAN' ! surface temperature over sea ice -> tn_ice 706 cpl_send( 4)='SAIOCEAN' ! albedo over sea ice -> alb_ice 707 #else 708 cpl_send( 3)='SITOCEAN' ! sea ice thickness -> hicif (only 1 layer available!) 709 cpl_send( 4)='SNTOCEAN' ! surface snow thickness over sea ice -> hsnif 710 #endif 711 #if defined key_cpl_ocevel 712 cpl_send( 5)='SUNOCEAN' ! U-velocity -> un 713 cpl_send( 6)='SVNOCEAN' ! V-velocity -> vn 714 #endif 715 ! 716 ! ... Define symbolic names for transient fields received by the ocean. 717 ! These must be identical to the names specified in the SMIOC file. 718 ! 719 ! ... a) U-Grid fields 720 ! 721 cpl_recv( 1)='TXWOCEWU' ! weighted surface downward eastward stress 722 cpl_recv( 2)='TYWOCEWU' ! weighted surface downward northward stress 723 cpl_recv( 3)='TXIOCEWU' ! weighted surface downward eastward stress over ice 724 cpl_recv( 4)='TYIOCEWU' ! weighted surface downward northward stress over ice 725 ! 726 ! ... a) V-Grid fields 727 ! 728 cpl_recv( 5)='TXWOCEWV' ! weighted surface downward eastward stress 729 cpl_recv( 6)='TYWOCEWV' ! weighted surface downward northward stress 730 cpl_recv( 7)='TXIOCEWV' ! weighted surface downward eastward stress over ice 731 cpl_recv( 8)='TYIOCEWV' ! weighted surface downward northward stress over ice 732 ! 733 ! ... a) T-Grid fields 734 ! 735 cpl_recv( 9)='FRWOCEPE' ! P-E over water -> zpew 736 cpl_recv(10)='FRIOCEPE' ! P-E over ice -> zpei 737 cpl_recv(11)='FRROCESN' ! surface downward snow fall -> zpsol 738 cpl_recv(12)='FRIOCEEV' ! surface upward snow flux where sea ice -> zevice 739 740 cpl_recv(13)='QSWOCESR' ! surface net downward shortwave flux -> qsr_oce 741 cpl_recv(14)='QSWOCENS' ! surface downward non-solar heat flux in air -> qnsr_oce 742 cpl_recv(15)='QSIOCESR' ! solar heat flux on sea ice -> qsr_ice 743 cpl_recv(16)='QSIOCENS' ! non-solar heat flux on sea ice -> qnsr_ice 744 cpl_recv(17)='QSIOCEDQ' ! non-solar heat flux derivative -> dqns_ice 745 746 #ifdef key_cpl_discharge 747 cpl_recv(18)='FRWOCEIS' ! ice discharge into ocean -> calving 748 cpl_recv(19)='FRWOCERD' ! river discharge into ocean -> zrunriv 749 cpl_recv(20)='FRWOCECD' ! continental discharge into ocean -> zruncot 750 #endif 751 IF ( wp == 4 ) data_type = PRISM_REAL 752 IF ( wp == 8 ) data_type = PRISM_DOUBLE_PRECISION 753 754 nodim(1) = 3 ! check 755 nodim(2) = 0 756 ! 757 ! ... Announce send variables, all on T points. 758 ! 759 DO ji = 1, nsend 760 ! if ( ji == 2 ) ; then ; nodim(2) = 2 ; else ; nodim(2) = 0 ; endif 761 CALL prism_def_var (send_id(ji), cpl_send(ji), grid_id(1), & 762 tpoint_id(1), tmask_id(1), nodim, shape, data_type, ierror) 763 IF ( ierror /= PRISM_Success ) THEN 764 PRINT *, 'Failed to define transient ', ji, TRIM(cpl_send(ji)) 765 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_def_var') 766 ENDIF 767 ENDDO 768 ! 769 nodim(1) = 3 ! check 770 nodim(2) = 0 771 ! 772 ! ... Announce recv variables. 773 ! 774 ! ... a) on U points 775 ! 776 DO ji = 1, 4 777 CALL prism_def_var (recv_id(ji), cpl_recv(ji), grid_id(1), & 778 upoint_id(1), umask_id(1), nodim, shape, data_type, ierror) 779 IF ( ierror /= PRISM_Success ) THEN 780 PRINT *, 'Failed to define transient ', ji, TRIM(cpl_recv(ji)) 781 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_def_var') 782 ENDIF 783 ENDDO 784 ! 785 ! ... b) on V points 786 ! 787 DO ji = 5, 8 788 CALL prism_def_var (recv_id(ji), cpl_recv(ji), grid_id(1), & 789 vpoint_id(1), vmask_id(1), nodim, shape, data_type, ierror) 790 IF ( ierror /= PRISM_Success ) THEN 791 PRINT *, 'Failed to define transient ', TRIM(cpl_recv(ji)) 792 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_def_var') 793 ENDIF 794 ENDDO 795 ! 796 ! ... c) on T points 797 ! 798 DO ji = 9, nrecv 799 CALL prism_def_var (recv_id(ji), "SORUNOFF", grid_id(1), & 800 tpoint_id(1), tmask_id(1), nodim, shape, data_type, ierror) 801 IF ( ierror /= PRISM_Success ) THEN 802 PRINT *, 'Failed to define transient ', TRIM(cpl_recv(ji)) 803 CALL prism_abort ( comp_id, 'OPA9.0', 'OPA cpl_prism_define: Failure in prism_def_var') 804 ENDIF 805 ENDDO 806 807 ENDIF ! commRank 808 809 !------------------------------------------------------------------ 810 ! 4th End of definition phase 811 !------------------------------------------------------------------ 812 813 IF(lwp) WRITE(numout,*) "ABOUT TO CALL PRISM_ENDDEF" 814 815 CALL prism_enddef(ierror) 816 817 IF(lwp) WRITE(numout,*) "DONE ENDDEF",ierror 818 819 IF ( ierror /= PRISM_Success ) & 820 CALL prism_abort ( comp_id, 'OPA9.0', 'cpl_prism_define: Failure in prism_enddef') 821 822 IF(lwp) WRITE(numout,*) "ALL DONE, EXITING PRISM SET UP PHASE" 823 313 END DO 314 315 !------------------------------------------------------------------ 316 ! End of definition phase 317 !------------------------------------------------------------------ 318 319 CALL prism_enddef( nerror ) 320 IF ( nerror /= PRISM_Success ) CALL prism_abort ( ncomp_id, 'cpl_prism_define', 'Failure in prism_enddef') 321 824 322 END SUBROUTINE cpl_prism_define 825 826 827 828 SUBROUTINE cpl_prism_send( var_id, date, data_array, info ) 829 830 IMPLICIT NONE 323 324 325 SUBROUTINE cpl_prism_snd( kid, kstep, pdata, kinfo ) 831 326 832 327 !!--------------------------------------------------------------------- 833 !! *** ROUTINE cpl_prism_s end ***328 !! *** ROUTINE cpl_prism_snd *** 834 329 !! 835 330 !! ** Purpose : - At each coupling time-step,this routine sends fields 836 331 !! like sst or ice cover to the coupler or remote application. 837 !!838 !! ** Method : OASIS4839 332 !!---------------------------------------------------------------------- 840 333 !! * Arguments 841 334 !! 842 INTEGER, INTENT( IN ) :: var_id ! variable Id 843 INTEGER, INTENT( OUT ) :: info ! variable Id 844 INTEGER, INTENT( IN ) :: date ! ocean time-step in seconds 845 REAL(wp) :: data_array(:,:) 846 !! 847 !! * Local declarations 848 !! 849 #if defined key_mpp_mpi 850 REAL(wp) :: global_array(jpiglo,jpjglo) 851 ! 852 !mpi INTEGER :: status(MPI_STATUS_SIZE) 853 !mpi INTEGER :: type ! MPI data type 854 INTEGER :: request ! MPI isend request 855 INTEGER :: ji, jj, jn ! local loop indicees 856 #else 857 INTEGER :: ji 858 #endif 859 !! 860 INTEGER, SAVE :: ncount = 0 335 INTEGER, INTENT( IN ) :: kid ! variable intex in the array 336 INTEGER, INTENT( OUT ) :: kinfo ! OASIS4 info argument 337 INTEGER, INTENT( IN ) :: kstep ! ocean time-step in seconds 338 REAL(wp), DIMENSION(jpi,jpj), INTENT( IN ) :: pdata 339 !! 861 340 !! 862 341 !!-------------------------------------------------------------------- 863 !! 864 ncount = ncount + 1 865 866 #if defined key_mpp_mpi 867 868 request = 0 869 870 IF ( rootexchg ) THEN 871 ! 872 !mpi IF ( wp == 4 ) type = MPI_REAL 873 !mpi IF ( wp == 8 ) type = MPI_DOUBLE_PRECISION 874 ! 875 ! collect data on the local root process 876 ! 877 IF ( localRank /= localRoot ) THEN 878 879 DO jj = nldj, nlej 880 DO ji = nldi, nlei 881 exfld(ji-nldi+1,jj-nldj+1)=data_array(ji,jj) 882 ENDDO 883 ENDDO 884 885 !mpi CALL mpi_send(exfld, range(5), type, localRoot, localRank, localComm, ierror) 886 CALL mppsend (localRank, exfld, range(5), localRoot, request) 887 ENDIF 888 889 IF ( localRank == localRoot ) THEN 890 891 DO jj = ranges(3,localRoot), ranges(3,localRoot)+ranges(4,localRoot)-1 892 DO ji = ranges(1,localRoot), ranges(1,localRoot)+ranges(2,localRoot)-1 893 global_array(ji,jj) = data_array(ji,jj) ! workaround 894 ENDDO 895 ENDDO 896 897 DO jn = 1, localSize-1 898 899 !mpi CALL mpi_recv(buffer, ranges(5,jn), type, localRoot, jn, localComm, status, ierror) 900 CALL mpprecv(jn, buffer, ranges(5,jn)) 901 902 DO jj = ranges(3,jn), ranges(3,jn)+ranges(4,jn)-1 903 DO ji = ranges(1,jn), ranges(1,jn)+ranges(2,jn)-1 904 global_array(ji,jj) = buffer( (jj-ranges(3,jn))*ranges(2,jn) + ji-ranges(1,jn)+1 ) 905 ENDDO 906 ENDDO 907 908 ENDDO 909 910 ENDIF 911 ! 912 ! send data from local root to OASIS4 913 ! 914 CALL prism_put ( var_id, dates, dates_bound, global_array, info, ierror ) 915 916 ELSE 917 ! 918 ! send local data from every process to OASIS4 919 ! 920 CALL prism_put ( var_id, dates, dates_bound, data_array, info, ierror ) 921 922 ENDIF !rootexchg 923 924 #else 925 926 ! 927 ! send local data from every process to OASIS4 928 ! 929 IF ( commRank ) & 930 CALL prism_put ( var_id, dates, dates_bound, data_array, info, ierror ) 931 932 #endif 933 934 IF ( commRank ) THEN 935 936 IF (l_ctl) THEN 937 938 IF ( info==PRISM_Cpl ) THEN 939 WRITE(numout,*) '****************' 940 DO ji = 1, nsend 941 IF (var_id == send_id(ji) ) THEN 942 WRITE(numout,*) 'prism_put_proto: Outgoing ', cpl_send(ji) 943 EXIT 944 ENDIF 945 ENDDO 946 WRITE(numout,*) 'prism_put: var_id ', var_id 947 WRITE(numout,*) 'prism_put: date ', date 948 WRITE(numout,*) 'prism_put: info ', info 949 WRITE(numout,*) ' - Minimum value is ', MINVAL(data_array) 950 WRITE(numout,*) ' - Maximum value is ', MAXVAL(data_array) 951 WRITE(numout,*) ' - Sum value is ', SUM(data_array) 952 WRITE(numout,*) '****************' 953 ENDIF 954 955 ENDIF 956 957 IF ( ncount == nrecv ) THEN 958 ! 959 ! 3. Update dates and dates_bound for next step. We assume that cpl_prism_send 960 ! is called for all send fields at each time step. Therefore we update 961 ! the date argument to prism_put only every nsend call to cpl_prism_send. 962 ! 963 dates_bound(1) = dates_bound(2) 964 965 tmpdate = dates_bound(2) 966 date_incr = rdCplttra(1)/2.0 967 968 CALL PRISM_calc_newdate ( tmpdate, date_incr, ierror ) 969 dates = tmpdate 970 CALL PRISM_calc_newdate ( tmpdate, date_incr, ierror ) 971 dates_bound(2) = tmpdate 972 973 ncount = 0 974 975 ENDIF 976 977 ENDIF ! commRank 978 979 END SUBROUTINE cpl_prism_send 980 981 982 983 SUBROUTINE cpl_prism_recv( var_id, date, data_array, info ) 984 985 IMPLICIT NONE 342 ! 343 ! snd data to OASIS4 344 ! 345 exfld(:,:,1) = pdata(nldi:nlei, nldj:nlej) 346 CALL prism_put( ssnd(kid)%nid, date, date_bound, exfld, kinfo, nerror ) 347 IF ( nerror /= PRISM_Success ) CALL prism_abort( ssnd(kid)%nid, 'cpl_prism_snd', & 348 & 'Failure in prism_put for '//TRIM(ssnd(kid)%clname) ) 349 350 IF ( ln_ctl ) THEN 351 IF ( kinfo >= PRISM_Cpl .OR. kinfo == PRISM_Rst .OR. & 352 & kinfo == PRISM_RstTimeop ) THEN 353 WRITE(numout,*) '****************' 354 WRITE(numout,*) 'prism_put: Outgoing ', ssnd(kid)%clname 355 WRITE(numout,*) 'prism_put: ivarid ', ssnd(kid)%nid 356 WRITE(numout,*) 'prism_put: kstep ', kstep 357 WRITE(numout,*) 'prism_put: info ', kinfo 358 WRITE(numout,*) ' - Minimum value is ', MINVAL(pdata) 359 WRITE(numout,*) ' - Maximum value is ', MAXVAL(pdata) 360 WRITE(numout,*) ' - Sum value is ', SUM(pdata) 361 WRITE(numout,*) '****************' 362 ENDIF 363 ENDIF 364 END SUBROUTINE cpl_prism_snd 365 366 367 SUBROUTINE cpl_prism_rcv( kid, kstep, pdata, kinfo ) 986 368 987 369 !!--------------------------------------------------------------------- 988 !! *** ROUTINE cpl_prism_r ecv ***370 !! *** ROUTINE cpl_prism_rcv *** 989 371 !! 990 372 !! ** Purpose : - At each coupling time-step,this routine receives fields 991 373 !! like stresses and fluxes from the coupler or remote application. 992 !!993 !! ** Method : OASIS4994 374 !!---------------------------------------------------------------------- 995 !! * Arguments 996 !! 997 INTEGER, INTENT( IN ) :: var_id ! variable Id 998 INTEGER, INTENT( OUT ) :: info ! variable Id 999 INTEGER, INTENT( IN ) :: date ! ocean time-step in seconds 1000 REAL(wp),INTENT( OUT ) :: data_array(:,:) 1001 !! 1002 !! * Local declarations 1003 !! 1004 #if defined key_mpp_mpi 1005 REAL(wp) :: global_array(jpiglo,jpjglo) 1006 ! 1007 LOGICAL :: action = .false. 1008 !mpi INTEGER :: status(MPI_STATUS_SIZE) 1009 !mpi INTEGER :: type ! MPI data type 1010 INTEGER :: request ! MPI isend request 1011 INTEGER :: ji, jj, jn ! local loop indicees 1012 #else 1013 INTEGER :: ji 1014 #endif 1015 1016 INTEGER, SAVE :: ncount = 0 1017 !! 375 INTEGER, INTENT( IN ) :: kid ! variable intex in the array 376 INTEGER, INTENT( IN ) :: kstep ! ocean time-step in seconds 377 REAL(wp), DIMENSION(jpi,jpj), INTENT( INOUT ) :: pdata ! IN to keep the value if nothing is done 378 INTEGER, INTENT( OUT ) :: kinfo ! OASIS4 info argument 379 !! 380 LOGICAL :: llaction 1018 381 !!-------------------------------------------------------------------- 1019 !! 1020 ncount = ncount + 1 1021 1022 #ifdef key_mpp_mpi 1023 1024 request = 0 1025 1026 IF ( rootexchg ) THEN 1027 ! 1028 ! receive data from OASIS4 on local root 1029 ! 1030 IF ( commRank ) & 1031 CALL prism_get (var_id, dater, dater_bound, global_array, info, ierror) 1032 CALL MPI_BCAST ( info, 1, MPI_INTEGER, localRoot, localComm, ierror ) 1033 1034 ELSE 1035 ! 1036 ! receive local data from OASIS4 on every process 1037 ! 1038 CALL prism_get (var_id, dater, dater_bound, exfld, info, ierror) 1039 1040 ENDIF 1041 1042 action = (info==PRISM_CplIO) 1043 1044 IF ( rootexchg .and. action ) THEN 1045 ! 1046 !mpi IF ( wp == 4 ) type = MPI_REAL 1047 !mpi IF ( wp == 8 ) type = MPI_DOUBLE_PRECISION 1048 ! 1049 ! distribute data to processes 1050 ! 1051 IF ( localRank == localRoot ) THEN 1052 1053 DO jj = ranges(3,localRoot), ranges(3,localRoot)+ranges(4,localRoot)-1 1054 DO ji = ranges(1,localRoot), ranges(1,localRoot)+ranges(2,localRoot)-1 1055 exfld(ji,jj) = global_array(ji,jj) 1056 ENDDO 1057 ENDDO 1058 1059 DO jn = 1, localSize-1 1060 1061 DO jj = ranges(3,jn), ranges(3,jn)+ranges(4,jn)-1 1062 DO ji = ranges(1,jn), ranges(1,jn)+ranges(2,jn)-1 1063 buffer( (jj-ranges(3,jn))*ranges(2,jn) + ji-ranges(1,jn)+1 ) = global_array(ji,jj) 1064 ENDDO 1065 ENDDO 1066 1067 !mpi CALL mpi_send(buffer, ranges(5,jn), type, jn, jn, localComm, ierror) 1068 CALL mppsend (jn, buffer, ranges(5,jn), jn, request) 1069 1070 ENDDO 1071 1072 ENDIF 1073 1074 IF ( localRank /= localRoot ) & 1075 !mpi CALL mpi_recv(exfld, range(5), type, localRoot, localRank, localComm, status, ierror) 1076 CALL mpprecv(localRank, exfld, range(5)) 1077 ENDIF 1078 1079 IF ( action ) THEN 1080 1081 data_array = 0.0 1082 1083 DO jj = nldj, nlej 1084 DO ji = nldi, nlei 1085 data_array(ji,jj)=exfld(ji-nldi+1,jj-nldj+1) 1086 ENDDO 1087 ENDDO 1088 1089 IF (l_ctl) THEN 382 ! 383 ! receive local data from OASIS4 on every process 384 ! 385 CALL prism_get( srcv(kid)%nid, date, date_bound, exfld, kinfo, nerror ) 386 IF ( nerror /= PRISM_Success ) CALL prism_abort( srcv(kid)%nid, 'cpl_prism_rcv', & 387 & 'Failure in prism_get for '//TRIM(srcv(kid)%clname) ) 388 389 WRITE(numout,*) 'prism_get: Incoming ', srcv(kid)%clname 390 call flush(numout) 391 llaction = .false. 392 IF( kinfo == PRISM_Cpl ) llaction = .TRUE. 393 394 IF ( ln_ctl ) WRITE(numout,*) "llaction, kinfo, kstep, ivarid: " , llaction, kinfo, kstep, srcv(kid)%nid 395 396 IF ( llaction ) THEN 397 398 kinfo = OASIS_Rcv 399 pdata(nldi:nlei, nldj:nlej) = exfld(:,:,1) 400 401 !--- Fill the overlap areas and extra hallows (mpp) 402 !--- check periodicity conditions (all cases) 403 CALL lbc_lnk( pdata, srcv(kid)%clgrid, srcv(kid)%nsgn ) 404 405 IF ( ln_ctl ) THEN 1090 406 WRITE(numout,*) '****************' 1091 DO ji = 1, nrecv 1092 IF (var_id == recv_id(ji) ) THEN 1093 WRITE(numout,*) 'prism_get: Incoming ', cpl_recv(ji) 1094 EXIT 1095 ENDIF 1096 ENDDO 1097 WRITE(numout,*) 'prism_get: var_id ', var_id 1098 WRITE(numout,*) 'prism_get: date ', date 1099 WRITE(numout,*) 'prism_get: info ', info 1100 WRITE(numout,*) ' - Minimum value is ', MINVAL(data_array) 1101 WRITE(numout,*) ' - Maximum value is ', MAXVAL(data_array) 1102 WRITE(numout,*) ' - Sum value is ', SUM(data_array) 407 WRITE(numout,*) 'prism_get: Incoming ', srcv(kid)%clname 408 WRITE(numout,*) 'prism_get: ivarid ' , srcv(kid)%nid 409 WRITE(numout,*) 'prism_get: kstep', kstep 410 WRITE(numout,*) 'prism_get: info ', kinfo 411 WRITE(numout,*) ' - Minimum value is ', MINVAL(pdata) 412 WRITE(numout,*) ' - Maximum value is ', MAXVAL(pdata) 413 WRITE(numout,*) ' - Sum value is ', SUM(pdata) 1103 414 WRITE(numout,*) '****************' 1104 415 ENDIF 1105 416 417 ELSE 418 kinfo = OASIS_idle 1106 419 ENDIF 1107 #else 1108 1109 CALL prism_get (var_id, dater, dater_bound, exfld, info, ierror) 1110 1111 IF ( info==PRISM_CplIO ) THEN 1112 data_array=exfld 1113 1114 IF (l_ctl) THEN 1115 WRITE(numout,*) '****************' 1116 DO ji = 1, nrecv 1117 IF (var_id == recv_id(ji) ) THEN 1118 WRITE(numout,*) 'prism_get: Incoming ', cpl_recv(ji) 1119 EXIT 1120 ENDIF 1121 ENDDO 1122 WRITE(numout,*) 'prism_get: var_id ', var_id 1123 WRITE(numout,*) 'prism_get: date ', date 1124 WRITE(numout,*) 'prism_get: info ', info 1125 WRITE(numout,*) ' - Minimum value is ', MINVAL(data_array) 1126 WRITE(numout,*) ' - Maximum value is ', MAXVAL(data_array) 1127 WRITE(numout,*) ' - Sum value is ', SUM(data_array) 1128 WRITE(numout,*) '****************' 1129 ENDIF 1130 1131 ENDIF 1132 1133 #endif 1134 1135 IF ( ncount == nrecv ) THEN 1136 ! 1137 ! 3. Update dater and dater_bound for next step. We assume that cpl_prism_recv 1138 ! is called for all recv fields at each time step. Therefore we update 1139 ! the date argument to prism_get only every nrecv call to cpl_prism_recv. 1140 ! 1141 dater_bound(1) = dater_bound(2) 1142 1143 tmpdate = dater_bound(2) 1144 date_incr = rdttra(1)/2.0 1145 1146 CALL PRISM_calc_newdate ( tmpdate, date_incr, ierror ) 1147 dater = tmpdate 1148 CALL PRISM_calc_newdate ( tmpdate, date_incr, ierror ) 1149 dater_bound(2) = tmpdate 1150 1151 ncount = 0 1152 1153 ENDIF 1154 1155 END SUBROUTINE cpl_prism_recv 1156 420 421 422 END SUBROUTINE cpl_prism_rcv 1157 423 1158 424 1159 425 SUBROUTINE cpl_prism_finalize 1160 1161 IMPLICIT NONE1162 426 1163 427 !!--------------------------------------------------------------------- … … 1167 431 !! called explicitly before cpl_prism_init it will also close 1168 432 !! MPI communication. 1169 !!1170 !! ** Method : OASIS41171 433 !!---------------------------------------------------------------------- 1172 434 1173 435 DEALLOCATE(exfld) 1174 1175 if ( prism_was_initialized ) then 1176 1177 call prism_terminated ( prism_was_terminated, ierror ) 1178 1179 if ( prism_was_terminated ) then 1180 print *, 'prism has already been terminated.' 1181 else 1182 call prism_terminate ( ierror ) 1183 prism_was_terminated = .true. 1184 endif 1185 1186 else 1187 1188 print *, 'Initialize prism before terminating it.' 1189 1190 endif 1191 436 CALL prism_terminate ( nerror ) 1192 437 1193 438 END SUBROUTINE cpl_prism_finalize 1194 439 1195 #else 1196 1197 !!---------------------------------------------------------------------- 1198 !! Default case Dummy module forced Ocean/Atmosphere 1199 !!---------------------------------------------------------------------- 1200 CONTAINS 1201 SUBROUTINE cpl_prism_init ! Dummy routine 1202 END SUBROUTINE cpl_prism_init 1203 SUBROUTINE cpl_prism_define ! Dummy routine 1204 END SUBROUTINE cpl_prism_define 1205 SUBROUTINE cpl_prism_send ! Dummy routine 1206 END SUBROUTINE cpl_prism_send 1207 SUBROUTINE cpl_prism_recv ! Dummy routine 1208 END SUBROUTINE cpl_prism_recv 1209 SUBROUTINE cpl_prism_finalize ! Dummy routine 1210 END SUBROUTINE cpl_prism_finalize 440 SUBROUTINE cpl_prism_update_time(kt) 441 442 !!--------------------------------------------------------------------- 443 !! *** ROUTINE cpl_prism_update_time *** 444 !! 445 !! ** Purpose : - Increment date with model timestep 446 !! called explicitly at the end of each timestep 447 !!---------------------------------------------------------------------- 448 449 INTEGER, INTENT(in) :: kt ! ocean model time step index 450 451 TYPE(PRISM_Time_struct) :: tmpdate 452 INTEGER :: idate_incr ! date increment 453 454 455 IF( kt == nit000 ) THEN 456 ! 457 ! Define the actual date 458 ! 459 ! date is determined by adding days since beginning of the run to the corresponding initial date. 460 ! Note that OPA internal info about the start date of the experiment is bypassed. 461 ! Instead we rely sololy on the info provided by the SCC.xml file. 462 ! 463 date = PRISM_Jobstart_date 464 ! 465 ! 466 ! lower/upper bound is determined by adding half a time step 467 ! 468 idate_incr = 0.5 * NINT ( rdttra(1) ) 469 tmpdate = date ; CALL PRISM_calc_newdate ( tmpdate, -idate_incr, nerror ) ; date_bound(1) = tmpdate 470 tmpdate = date ; CALL PRISM_calc_newdate ( tmpdate, idate_incr, nerror ) ; date_bound(2) = tmpdate 471 472 ELSE 473 ! 474 ! Date update 475 ! 476 idate_incr = rdttra(1) 477 CALL PRISM_calc_newdate( date, idate_incr, nerror ) 478 date_bound(1) = date_bound(2) 479 tmpdate = date_bound(2) 480 CALL PRISM_calc_newdate( tmpdate, idate_incr, nerror ) 481 date_bound(2) = tmpdate 482 483 END IF 484 485 END SUBROUTINE cpl_prism_update_time 1211 486 1212 487 #endif -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90
r2323 r2528 15 15 USE oce ! ocean dynamics and tracers 16 16 USE dom_oce ! ocean space and time domain 17 USE ioipsl, ONLY : ymds2ju, ju2ymds ! for calendar 17 18 USE phycst ! ??? 18 19 USE in_out_manager ! I/O manager … … 29 30 LOGICAL :: ln_tint ! time interpolation or not (T/F) 30 31 LOGICAL :: ln_clim ! climatology or not (T/F) 31 CHARACTER(len = 7) :: cltype ! type of data file 'daily', 'monthly' or yearly'32 CHARACTER(len = 8) :: cltype ! type of data file 'daily', 'monthly' or yearly' 32 33 CHARACTER(len = 34) :: wname ! generic name of a NetCDF weights file to be used, blank if not 33 34 CHARACTER(len = 34) :: vcomp ! symbolic component name if a vector that needs rotation 34 ! a string starting with "U" or "V" for each component35 ! chars 2 onwards identify which components go together35 ! a string starting with "U" or "V" for each component 36 ! chars 2 onwards identify which components go together 36 37 END TYPE FLD_N 37 38 … … 43 44 LOGICAL :: ln_tint ! time interpolation or not (T/F) 44 45 LOGICAL :: ln_clim ! climatology or not (T/F) 45 CHARACTER(len = 7) :: cltype ! type of data file 'daily', 'monthly' or yearly'46 CHARACTER(len = 8) :: cltype ! type of data file 'daily', 'monthly' or yearly' 46 47 INTEGER :: num ! iom id of the jpfld files to be read 47 INTEGER :: nswap_sec ! swapping time in second since Jan. 1st 00h of nit000 year48 48 INTEGER , DIMENSION(2) :: nrec_b ! before record (1: index, 2: second since Jan. 1st 00h of nit000 year) 49 49 INTEGER , DIMENSION(2) :: nrec_a ! after record (1: index, 2: second since Jan. 1st 00h of nit000 year) 50 REAL(wp) , ALLOCATABLE, DIMENSION(:,: ) :: fnow! input fields interpolated to now time step51 REAL(wp) , ALLOCATABLE, DIMENSION(:,:,: ) :: fdta! 2 consecutive record of input fields50 REAL(wp) , ALLOCATABLE, DIMENSION(:,:,: ) :: fnow ! input fields interpolated to now time step 51 REAL(wp) , ALLOCATABLE, DIMENSION(:,:,:,:) :: fdta ! 2 consecutive record of input fields 52 52 CHARACTER(len = 256) :: wgtname ! current name of the NetCDF weight file acting as a key 53 53 ! into the WGTLIST structure 54 54 CHARACTER(len = 34) :: vcomp ! symbolic name for a vector component that needs rotation 55 LOGICAL , DIMENSION(2):: rotn ! flag to indicate whether field has been rotated55 LOGICAL :: rotn ! flag to indicate whether field has been rotated 56 56 END TYPE FLD 57 57 … … 71 71 INTEGER :: numwgt ! number of weights (4=bilinear, 16=bicubic) 72 72 INTEGER :: nestid ! for agrif, keep track of nest we're in 73 INTEGER :: o ffset ! =0 when cyclic grid has coincident first/last columns,74 ! = 1 when they assumed to be one grid spacing apart75 ! =-1 otherwise73 INTEGER :: overlap ! =0 when cyclic grid has no overlapping EW columns 74 ! =>1 when they have one or more overlapping columns 75 ! =-1 not cyclic 76 76 LOGICAL :: cyclic ! east-west cyclic or not 77 INTEGER, DIMENSION(:,:,:), POINTER:: data_jpi ! array of source integers78 INTEGER, DIMENSION(:,:,:), POINTER:: data_jpj ! array of source integers77 INTEGER, DIMENSION(:,:,:), POINTER :: data_jpi ! array of source integers 78 INTEGER, DIMENSION(:,:,:), POINTER :: data_jpj ! array of source integers 79 79 REAL(wp), DIMENSION(:,:,:), POINTER :: data_wgt ! array of weights on model grid 80 REAL(wp), DIMENSION(:,: ), POINTER:: fly_dta ! array of values on input grid81 REAL(wp), DIMENSION(:,: ), POINTER :: col2! temporary array for reading in columns80 REAL(wp), DIMENSION(:,:,:), POINTER :: fly_dta ! array of values on input grid 81 REAL(wp), DIMENSION(:,:,:), POINTER :: col ! temporary array for reading in columns 82 82 END TYPE WGT 83 83 … … 91 91 92 92 !!---------------------------------------------------------------------- 93 !! OPA 9.0 , LOCEAN-IPSL (2006)93 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 94 94 !! $Id$ 95 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)95 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 96 96 !!---------------------------------------------------------------------- 97 97 … … 114 114 TYPE(FLD), INTENT(inout), DIMENSION(:) :: sd ! input field related variables 115 115 !! 116 CHARACTER (LEN=34) :: acomp ! dummy weight name 117 INTEGER :: kf, nf ! dummy indices 118 INTEGER :: imf ! size of the structure sd 119 REAL(wp), DIMENSION(jpi,jpj) :: utmp, vtmp! temporary arrays for vector rotation 120 116 INTEGER :: imf ! size of the structure sd 121 117 INTEGER :: jf ! dummy indices 122 INTEGER :: kw ! index into wgts array123 118 INTEGER :: ireclast ! last record to be read in the current year file 124 119 INTEGER :: isecend ! number of second since Jan. 1st 00h of nit000 year at nitend … … 131 126 CHARACTER(LEN=1000) :: clfmt ! write format 132 127 !!--------------------------------------------------------------------- 133 ! 128 ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 129 isecsbc = nsec_year + nsec1jan000 + NINT(0.5 * REAL(kn_fsbc - 1,wp) * rdttra(1)) ! middle of sbc time step 134 130 imf = SIZE( sd ) 135 isecsbc = nsec_year + nsec1jan000 + NINT(0.5 * REAL(kn_fsbc - 1,wp) * rdttra(1)) ! centrered in the middle of sbc time step 136 ! 137 ! ! ===================== ! 138 DO jf = 1, imf ! LOOP OVER FIELD ! 139 ! ! ===================== ! 140 ! 141 IF( kt == nit000 ) CALL fld_init( kn_fsbc, sd(jf) ) 142 ! 143 ! read/update the after data? 144 IF( isecsbc > sd(jf)%nswap_sec ) THEN 145 146 IF( sd(jf)%ln_tint ) THEN ! time interpolation: swap before record field 131 ! 132 IF( kt == nit000 ) THEN ! initialization 133 DO jf = 1, imf 134 CALL fld_init( kn_fsbc, sd(jf) ) ! read each before field (put them in after as they will be swapped) 135 END DO 136 IF( lwp ) CALL wgt_print() ! control print 137 CALL fld_rot( kt, sd ) ! rotate vector fiels if needed 138 ENDIF 139 ! ! ====================================== ! 140 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN ! update field at each kn_fsbc time-step ! 141 ! ! ====================================== ! 142 ! 143 DO jf = 1, imf ! --- loop over field --- ! 144 145 IF( isecsbc > sd(jf)%nrec_a(2) .OR. kt == nit000 ) THEN ! read/update the after data? 146 147 IF( sd(jf)%ln_tint ) THEN ! swap before record field and informations 148 sd(jf)%nrec_b(:) = sd(jf)%nrec_a(:) 147 149 !CDIR COLLAPSE 148 sd(jf)%fdta(:,:,1) = sd(jf)%fdta(:,:,2) 149 sd(jf)%rotn(1) = sd(jf)%rotn(2) 150 sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2) 151 ENDIF 152 153 CALL fld_rec( kn_fsbc, sd(jf) ) ! update record informations 154 155 ! do we have to change the year/month/week/day of the forcing field?? 156 IF( sd(jf)%ln_tint ) THEN 157 ! if we do time interpolation we will need to open next year/month/week/day file before the end of the current 158 ! one. If so, we are still before the end of the year/month/week/day when calling fld_rec so sd(jf)%nrec_a(1) 159 ! will be larger than the record number that should be read for current year/month/week/day 160 161 ! last record to be read in the current file 162 IF ( sd(jf)%nfreqh == -12 ) THEN ; ireclast = 1 ! yearly mean 163 ELSEIF( sd(jf)%nfreqh == -1 ) THEN ! monthly mean 164 IF( sd(jf)%cltype == 'monthly' ) THEN ; ireclast = 1 165 ELSE ; ireclast = 12 166 ENDIF 167 ELSE ! higher frequency mean (in hours) 168 IF( sd(jf)%cltype == 'monthly' ) THEN ; ireclast = 24 * nmonth_len(nmonth) / sd(jf)%nfreqh 169 ELSEIF( sd(jf)%cltype(1:4) == 'week' ) THEN ; ireclast = 24 * 7 / sd(jf)%nfreqh 170 ELSEIF( sd(jf)%cltype == 'daily' ) THEN ; ireclast = 24 / sd(jf)%nfreqh 171 ELSE ; ireclast = 24 * nyear_len( 1 ) / sd(jf)%nfreqh 172 ENDIF 173 ENDIF 174 175 ! do we need next file data? 176 IF( sd(jf)%nrec_a(1) > ireclast ) THEN 177 178 sd(jf)%nrec_a(1) = 1 ! force to read the first record of the next file 179 180 IF( .NOT. sd(jf)%ln_clim ) THEN ! close the current file and open a new one. 181 182 llnxtmth = sd(jf)%cltype == 'monthly' .OR. nday == nmonth_len(nmonth) ! open next month file? 183 llnxtyr = sd(jf)%cltype == 'yearly' .OR. (nmonth == 12 .AND. llnxtmth) ! open next year file? 184 185 ! if the run finishes at the end of the current year/month/week/day, we will allow next 186 ! year/month/week/day file to be not present. If the run continue further than the current 187 ! year/month/week/day, next year/month/week/day file must exist 188 isecend = nsec_year + nsec1jan000 + (nitend - kt) * NINT(rdttra(1)) ! second at the end of the run 189 llstop = isecend > sd(jf)%nrec_a(2) ! read more than 1 record of next year 190 191 CALL fld_clopn( sd(jf), nyear + COUNT((/llnxtyr /)) , & 192 & nmonth + COUNT((/llnxtmth/)) - 12 * COUNT((/llnxtyr /)), & 193 & nday + 1 - nmonth_len(nmonth) * COUNT((/llnxtmth/)), llstop ) 194 195 IF( sd(jf)%num <= 0 .AND. .NOT. llstop ) THEN ! next year file does not exist 196 CALL ctl_warn('next year/month/week/day file: '//TRIM(sd(jf)%clname)// & 197 & ' not present -> back to current year/month/day') 198 CALL fld_clopn( sd(jf), nyear, nmonth, nday ) ! back to the current year/month/day 199 sd(jf)%nrec_a(1) = ireclast ! force to read the last record to be read in the current year file 200 ENDIF 201 202 ENDIF 203 ENDIF 204 205 ELSE 206 ! if we are not doing time interpolation, we must change the year/month/week/day of the file just after 207 ! switching to the NEW year/month/week/day. If it is the case, we are at the beginning of the 208 ! year/month/week/day when calling fld_rec so sd(jf)%nrec_a(1) = 1 209 IF( sd(jf)%nrec_a(1) == 1 .AND. .NOT. ( sd(jf)%ln_clim .AND. sd(jf)%cltype == 'yearly' ) ) & 210 & CALL fld_clopn( sd(jf), nyear, nmonth, nday ) 211 ENDIF 212 213 ! read after data 214 CALL fld_get( sd(jf) ) 215 150 216 ENDIF 151 152 ! update record informations 153 CALL fld_rec( kn_fsbc, sd(jf) ) 154 155 ! do we have to change the year/month/day of the forcing field?? 156 IF( sd(jf)%ln_tint ) THEN 157 ! if we do time interpolation we will need to open next year/month/day file before the end of the current one 158 ! if so, we are still before the end of the year/month/day when calling fld_rec so sd(jf)%nrec_a(1) will be 159 ! larger than the record number that should be read for current year/month/day (for ex. 13 for monthly mean file) 160 161 ! last record to be read in the current file 162 IF( sd(jf)%nfreqh == -1 ) THEN ; ireclast = 12 163 ELSE 164 IF( sd(jf)%cltype == 'monthly' ) THEN ; ireclast = 24 * nmonth_len(nmonth) / sd(jf)%nfreqh 165 ELSEIF( sd(jf)%cltype == 'daily' ) THEN ; ireclast = 24 / sd(jf)%nfreqh 166 ELSE ; ireclast = 24 * nyear_len( 1 ) / sd(jf)%nfreqh 167 ENDIF 168 ENDIF 169 170 ! do we need next file data? 171 IF( sd(jf)%nrec_a(1) > ireclast ) THEN 172 173 sd(jf)%nrec_a(1) = 1 ! force to read the first record of the next file 174 175 IF( .NOT. sd(jf)%ln_clim ) THEN ! close the current file and open a new one. 176 177 llnxtmth = sd(jf)%cltype == 'monthly' .OR. nday == nmonth_len(nmonth) ! open next month file? 178 llnxtyr = sd(jf)%cltype == 'yearly' .OR. (nmonth == 12 .AND. llnxtmth) ! open next year file? 179 180 ! if the run finishes at the end of the current year/month/day, we will allow next year/month/day file to be 181 ! not present. If the run continue further than the current year/month/day, next year/month/day file must exist 182 isecend = nsec_year + nsec1jan000 + (nitend - kt) * NINT(rdttra(1)) ! second at the end of the run 183 llstop = isecend > sd(jf)%nswap_sec ! read more than 1 record of next year 184 185 CALL fld_clopn( sd(jf), nyear + COUNT((/llnxtyr /)) , & 186 & nmonth + COUNT((/llnxtmth/)) - 12 * COUNT((/llnxtyr /)), & 187 & nday + 1 - nmonth_len(nmonth) * COUNT((/llnxtmth/)), llstop ) 188 189 IF( sd(jf)%num <= 0 .AND. .NOT. llstop ) THEN ! next year file does not exist 190 CALL ctl_warn('next year/month/day file: '//TRIM(sd(jf)%clname)// & 191 & ' not present -> back to current year/month/day') 192 CALL fld_clopn( sd(jf), nyear, nmonth, nday ) ! back to the current year/month/day 193 sd(jf)%nrec_a(1) = ireclast ! force to read the last record to be read in the current year file 194 ENDIF 195 196 ENDIF 197 ENDIF 198 199 ELSE 200 ! if we are not doing time interpolation, we must change the year/month/day of the file just after switching 201 ! to the NEW year/month/day. If it is the case, we are at the beginning of the year/month/day when calling 202 ! fld_rec so sd(jf)%nrec_a(1) = 1 203 IF( sd(jf)%nrec_a(1) == 1 .AND. .NOT. sd(jf)%ln_clim ) CALL fld_clopn( sd(jf), nyear, nmonth, nday ) 204 ENDIF 205 206 ! read after data 207 IF( LEN(TRIM(sd(jf)%wgtname)) > 0 ) THEN 208 CALL wgt_list( sd(jf), kw ) 209 CALL fld_interp( sd(jf)%num, sd(jf)%clvar, kw, sd(jf)%fdta(:,:,2), sd(jf)%nrec_a(1) ) 210 ELSE 211 CALL iom_get( sd(jf)%num, jpdom_data, sd(jf)%clvar, sd(jf)%fdta(:,:,2), sd(jf)%nrec_a(1) ) 212 ENDIF 213 sd(jf)%rotn(2) = .FALSE. 214 215 ENDIF 216 ! ! ===================== ! 217 END DO ! END LOOP OVER FIELD ! 218 ! ! ===================== ! 219 220 IF( kt == nit000 .AND. lwp ) CALL wgt_print() 221 222 !! Vector fields may need to be rotated onto the local grid direction 223 !! This has to happen before the time interpolations 224 !! (sga: following code should be modified so that pairs arent searched for each time 225 226 DO jf = 1, imf 227 !! find vector rotations required 228 IF( LEN(TRIM(sd(jf)%vcomp)) > 0 ) THEN 229 !! east-west component has symbolic name starting with 'U' 230 IF( sd(jf)%vcomp(1:1) == 'U' ) THEN 231 !! found an east-west component, look for the north-south component 232 !! which has same symbolic name but with 'U' replaced with 'V' 233 nf = LEN_TRIM( sd(jf)%vcomp ) 234 IF( nf == 1) THEN 235 acomp = 'V' 236 ELSE 237 acomp = 'V' // sd(jf)%vcomp(2:nf) 238 ENDIF 239 kf = -1 240 DO nf = 1, imf 241 IF( TRIM(sd(nf)%vcomp) == TRIM(acomp) ) kf = nf 242 END DO 243 IF( kf > 0 ) THEN 244 !! fields jf,kf are two components which need to be rotated together 245 DO nf = 1,2 246 !! check each time level of this pair 247 IF( .NOT. sd(jf)%rotn(nf) .AND. .NOT. sd(kf)%rotn(nf) ) THEN 248 utmp(:,:) = 0.0 249 vtmp(:,:) = 0.0 250 CALL rot_rep( sd(jf)%fdta(:,:,nf), sd(kf)%fdta(:,:,nf), 'T', 'en->i', utmp(:,:) ) 251 CALL rot_rep( sd(jf)%fdta(:,:,nf), sd(kf)%fdta(:,:,nf), 'T', 'en->j', vtmp(:,:) ) 252 sd(jf)%fdta(:,:,nf) = utmp(:,:) 253 sd(kf)%fdta(:,:,nf) = vtmp(:,:) 254 sd(jf)%rotn(nf) = .TRUE. 255 sd(kf)%rotn(nf) = .TRUE. 256 IF( lwp .AND. kt == nit000 ) & 257 WRITE(numout,*) 'fld_read: vector pair (', & 258 TRIM(sd(jf)%clvar),',',TRIM(sd(kf)%clvar), & 259 ') rotated on to model grid' 260 ENDIF 261 END DO 262 ENDIF 263 ENDIF 264 ENDIF 265 END DO 266 267 ! ! ===================== ! 268 DO jf = 1, imf ! LOOP OVER FIELD ! 269 ! ! ===================== ! 270 ! 271 ! update field at each kn_fsbc time-step 272 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN 217 END DO ! --- end loop over field --- ! 218 219 CALL fld_rot( kt, sd ) ! rotate vector fiels if needed 220 221 DO jf = 1, imf ! --- loop over field --- ! 273 222 ! 274 IF( sd(jf)%ln_tint ) THEN 223 IF( sd(jf)%ln_tint ) THEN ! temporal interpolation 275 224 IF(lwp .AND. kt - nit000 <= 100 ) THEN 276 clfmt = "('fld_read: var ', a, ' kt = ', i8, 'Y/M/D = ', i4.4,'/', i2.2,'/', i2.2," // &277 & "' records b/a: ', i4.4, '/', i4.4, ' (', f7.2,'/', f7.2, ' days)')"278 WRITE(numout, clfmt) TRIM( sd(jf)%clvar ), kt, nyear, nmonth, nday, &225 clfmt = "('fld_read: var ', a, ' kt = ', i8, ' (', f7.2,' days), Y/M/D = ', i4.4,'/', i2.2,'/', i2.2," // & 226 & "', records b/a: ', i4.4, '/', i4.4, ' (days ', f7.2,'/', f7.2, ')')" 227 WRITE(numout, clfmt) TRIM( sd(jf)%clvar ), kt, REAL(isecsbc,wp)/rday, nyear, nmonth, nday, & 279 228 & sd(jf)%nrec_b(1), sd(jf)%nrec_a(1), REAL(sd(jf)%nrec_b(2),wp)/rday, REAL(sd(jf)%nrec_a(2),wp)/rday 280 229 ENDIF 281 ! 230 ! temporal interpolation weights 282 231 ztinta = REAL( isecsbc - sd(jf)%nrec_b(2), wp ) / REAL( sd(jf)%nrec_a(2) - sd(jf)%nrec_b(2), wp ) 283 232 ztintb = 1. - ztinta 284 233 !CDIR COLLAPSE 285 sd(jf)%fnow(:,: ) = ztintb * sd(jf)%fdta(:,:,1) + ztinta * sd(jf)%fdta(:,:,2)286 ELSE 234 sd(jf)%fnow(:,:,:) = ztintb * sd(jf)%fdta(:,:,:,1) + ztinta * sd(jf)%fdta(:,:,:,2) 235 ELSE ! nothing to do... 287 236 IF(lwp .AND. kt - nit000 <= 100 ) THEN 288 clfmt = "('fld_read: var ', a, ' kt = ', i8,' Y/M/D = ', i4.4,'/', i2.2,'/', i2.2," // & 289 & "' record: ', i4.4, ' at ', f7.2, ' day')" 290 WRITE(numout, clfmt) TRIM(sd(jf)%clvar), kt, nyear, nmonth, nday, sd(jf)%nrec_a(1), REAL(sd(jf)%nrec_a(2),wp)/rday 237 clfmt = "('fld_read: var ', a, ' kt = ', i8,' (', f7.2,' days), Y/M/D = ', i4.4,'/', i2.2,'/', i2.2," // & 238 & "', record: ', i4.4, ' (days ', f7.2, ' <-> ', f7.2, ')')" 239 WRITE(numout, clfmt) TRIM(sd(jf)%clvar), kt, REAL(isecsbc,wp)/rday, nyear, nmonth, nday, & 240 & sd(jf)%nrec_a(1), REAL(sd(jf)%nrec_b(2),wp)/rday, REAL(sd(jf)%nrec_a(2),wp)/rday 291 241 ENDIF 292 !CDIR COLLAPSE293 sd(jf)%fnow(:,:) = sd(jf)%fdta(:,:,2) ! piecewise constant field294 295 242 ENDIF 296 243 ! 297 ENDIF 298 299 IF( kt == nitend ) CALL iom_close( sd(jf)%num ) ! Close the input files 300 301 ! ! ===================== ! 302 END DO ! END LOOP OVER FIELD ! 303 ! ! ===================== ! 244 IF( kt == nitend - kn_fsbc + 1 ) CALL iom_close( sd(jf)%num ) ! Close the input files 245 246 END DO ! --- end loop over field --- ! 247 ! 248 ! ! ====================================== ! 249 ENDIF ! update field at each kn_fsbc time-step ! 250 ! ! ====================================== ! 251 ! 304 252 END SUBROUTINE fld_read 305 253 … … 314 262 !! ** Method : 315 263 !!---------------------------------------------------------------------- 316 INTEGER , INTENT(in ) :: kn_fsbc ! sbc computation period (in time step) 317 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables 318 !! 319 LOGICAL :: llprevyr ! are we reading previous year file? 320 LOGICAL :: llprevmth ! are we reading previous month file? 321 LOGICAL :: llprevday ! are we reading previous day file? 322 LOGICAL :: llprev ! llprevyr .OR. llprevmth .OR. llprevday 323 INTEGER :: idvar ! variable id 324 INTEGER :: inrec ! number of record existing for this variable 325 INTEGER :: kwgt 264 INTEGER , INTENT(in ) :: kn_fsbc ! sbc computation period (in time step) 265 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables 266 !! 267 LOGICAL :: llprevyr ! are we reading previous year file? 268 LOGICAL :: llprevmth ! are we reading previous month file? 269 LOGICAL :: llprevweek ! are we reading previous week file? 270 LOGICAL :: llprevday ! are we reading previous day file? 271 LOGICAL :: llprev ! llprevyr .OR. llprevmth .OR. llprevweek .OR. llprevday 272 INTEGER :: idvar ! variable id 273 INTEGER :: inrec ! number of record existing for this variable 274 INTEGER :: iyear, imonth, iday ! first day of the current file in yyyy mm dd 275 INTEGER :: isec_week ! number of seconds since start of the weekly file 326 276 CHARACTER(LEN=1000) :: clfmt ! write format 327 277 !!--------------------------------------------------------------------- 328 278 329 279 ! some default definitions... 330 280 sdjf%num = 0 ! default definition for non-opened file 331 281 IF( sdjf%ln_clim ) sdjf%clname = TRIM( sdjf%clrootname ) ! file name defaut definition, never change in this case 332 llprevyr = .FALSE. 333 llprevmth = .FALSE. 334 llprevday = .FALSE. 282 llprevyr = .FALSE. 283 llprevmth = .FALSE. 284 llprevweek = .FALSE. 285 llprevday = .FALSE. 286 isec_week = 0 335 287 288 IF( sdjf%cltype(1:4) == 'week' .AND. nn_leapy == 0 ) & 289 & CALL ctl_stop('fld_clopn: weekly file ('//TRIM(sdjf%clrootname)//') needs nn_leapy = 1') 290 IF( sdjf%cltype(1:4) == 'week' .AND. sdjf%ln_clim ) & 291 & CALL ctl_stop('fld_clopn: weekly file ('//TRIM(sdjf%clrootname)//') needs ln_clim = .FALSE.') 292 336 293 ! define record informations 337 CALL fld_rec( kn_fsbc, sdjf 338 339 ! Note :shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar294 CALL fld_rec( kn_fsbc, sdjf, ldbefore = .TRUE. ) ! return before values in sdjf%nrec_a (as we will swap it later) 295 296 ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 340 297 341 298 IF( sdjf%ln_tint ) THEN ! we need to read the previous record and we will put it in the current record structure 342 343 IF( sdjf%nrec_b(1) == 0 ) THEN ! we redefine record sdjf%nrec_b(1) with the last record of previous year file 344 IF( sdjf%nfreqh == -1 ) THEN ! monthly mean 345 IF( sdjf%cltype == 'monthly' ) THEN ! monthly file 346 sdjf%nrec_b(1) = 1 ! force to read the unique record 347 llprevmth = .NOT. sdjf%ln_clim ! use previous month file? 299 300 IF( sdjf%nrec_a(1) == 0 ) THEN ! we redefine record sdjf%nrec_a(1) with the last record of previous year file 301 IF ( sdjf%nfreqh == -12 ) THEN ! yearly mean 302 IF( sdjf%cltype == 'yearly' ) THEN ! yearly file 303 sdjf%nrec_a(1) = 1 ! force to read the unique record 304 llprevyr = .NOT. sdjf%ln_clim ! use previous year file? 305 ELSE 306 CALL ctl_stop( "fld_init: yearly mean file must be in a yearly type of file: "//TRIM(sdjf%clname) ) 307 ENDIF 308 ELSEIF( sdjf%nfreqh == -1 ) THEN ! monthly mean 309 IF( sdjf%cltype == 'monthly' ) THEN ! monthly file 310 sdjf%nrec_a(1) = 1 ! force to read the unique record 311 llprevmth = .TRUE. ! use previous month file? 348 312 llprevyr = llprevmth .AND. nmonth == 1 ! use previous year file? 349 ELSE ! yearly file350 sdjf%nrec_ b(1) = 12 ! force to read december mean313 ELSE ! yearly file 314 sdjf%nrec_a(1) = 12 ! force to read december mean 351 315 llprevyr = .NOT. sdjf%ln_clim ! use previous year file? 352 316 ENDIF 353 ELSE 354 IF ( sdjf%cltype== 'monthly' ) THEN ! monthly file355 sdjf%nrec_ b(1) = 24 * nmonth_len(nmonth-1) / sdjf%nfreqh ! last record of previous month356 llprevmth = . NOT. sdjf%ln_clim! use previous month file?317 ELSE ! higher frequency mean (in hours) 318 IF ( sdjf%cltype == 'monthly' ) THEN ! monthly file 319 sdjf%nrec_a(1) = 24 * nmonth_len(nmonth-1) / sdjf%nfreqh ! last record of previous month 320 llprevmth = .TRUE. ! use previous month file? 357 321 llprevyr = llprevmth .AND. nmonth == 1 ! use previous year file? 358 ELSEIF( sdjf%cltype == 'daily' ) THEN ! daily file 359 sdjf%nrec_b(1) = 24 / sdjf%nfreqh ! last record of previous day 360 llprevday = .NOT. sdjf%ln_clim ! use previous day file? 322 ELSEIF( sdjf%cltype(1:4) == 'week' ) THEN ! weekly file 323 llprevweek = .TRUE. ! use previous week file? 324 sdjf%nrec_a(1) = 24 * 7 / sdjf%nfreqh ! last record of previous week 325 isec_week = NINT(rday) * 7 ! add a shift toward previous week 326 ELSEIF( sdjf%cltype == 'daily' ) THEN ! daily file 327 sdjf%nrec_a(1) = 24 / sdjf%nfreqh ! last record of previous day 328 llprevday = .TRUE. ! use previous day file? 361 329 llprevmth = llprevday .AND. nday == 1 ! use previous month file? 362 330 llprevyr = llprevmth .AND. nmonth == 1 ! use previous year file? 363 ELSE ! yearly file364 sdjf%nrec_ b(1) = 24 * nyear_len(0) / sdjf%nfreqh ! last record of year month331 ELSE ! yearly file 332 sdjf%nrec_a(1) = 24 * nyear_len(0) / sdjf%nfreqh ! last record of previous year 365 333 llprevyr = .NOT. sdjf%ln_clim ! use previous year file? 366 334 ENDIF 367 335 ENDIF 368 336 ENDIF 369 llprev = llprevyr .OR. llprevmth .OR. llprevday 370 371 CALL fld_clopn( sdjf, nyear - COUNT((/llprevyr /)) , & 372 & nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /)), & 373 & nday - COUNT((/llprevday/)) + nmonth_len(nmonth-1) * COUNT((/llprevmth/)), .NOT. llprev ) 374 337 IF ( sdjf%cltype(1:4) == 'week' ) THEN 338 isec_week = isec_week + ksec_week( sdjf%cltype(6:8) ) ! second since the beginning of the week 339 llprevmth = isec_week > nsec_month ! longer time since the beginning of the week than the month 340 llprevyr = llprevmth .AND. nmonth == 1 341 ENDIF 342 llprev = llprevyr .OR. llprevmth .OR. llprevweek .OR. llprevday 343 ! 344 iyear = nyear - COUNT((/llprevyr /)) 345 imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /)) 346 iday = nday - COUNT((/llprevday/)) + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday) 347 ! 348 CALL fld_clopn( sdjf, iyear, imonth, iday, .NOT. llprev ) 349 375 350 ! if previous year/month/day file does not exist, we switch to the current year/month/day 376 351 IF( llprev .AND. sdjf%num <= 0 ) THEN 377 CALL ctl_warn( 'previous year/month/day file: '//TRIM(sdjf%clname)//' not present -> back to current year/month/day') 352 CALL ctl_warn( 'previous year/month/week/day file: '//TRIM(sdjf%clname)// & 353 & ' not present -> back to current year/month/week/day' ) 378 354 ! we force to read the first record of the current year/month/day instead of last record of previous year/month/day 379 llprev = . false.380 sdjf%nrec_ b(1) = 1355 llprev = .FALSE. 356 sdjf%nrec_a(1) = 1 381 357 CALL fld_clopn( sdjf, nyear, nmonth, nday ) 382 358 ENDIF … … 386 362 IF( idvar <= 0 ) RETURN 387 363 inrec = iom_file( sdjf%num )%dimsz( iom_file( sdjf%num )%ndims(idvar), idvar ) ! size of the last dim of idvar 388 sdjf%nrec_b(1) = MIN( sdjf%nrec_b(1), inrec ) ! make sure we select an existing record 389 ENDIF 390 391 ! read before data into sdjf%fdta(:,:,2) because we will swap data in the following part of fld_read 392 IF( LEN(TRIM(sdjf%wgtname)) > 0 ) THEN 393 CALL wgt_list( sdjf, kwgt ) 394 CALL fld_interp( sdjf%num, sdjf%clvar, kwgt, sdjf%fdta(:,:,2), sdjf%nrec_b(1) ) 364 sdjf%nrec_a(1) = MIN( sdjf%nrec_a(1), inrec ) ! make sure we select an existing record 365 ENDIF 366 367 ! read before data 368 CALL fld_get( sdjf ) ! read before values in after arrays(as we will swap it later) 369 370 clfmt = "('fld_init : time-interpolation for ', a, ' read previous record = ', i4, ' at time = ', f7.2, ' days')" 371 IF(lwp) WRITE(numout, clfmt) TRIM(sdjf%clvar), sdjf%nrec_a(1), REAL(sdjf%nrec_a(2),wp)/rday 372 373 IF( llprev ) CALL iom_close( sdjf%num ) ! force to close previous year file (-> redefine sdjf%num to 0) 374 375 ENDIF 376 377 ! make sure current year/month/day file is opened 378 IF( sdjf%num <= 0 ) THEN 379 ! 380 IF ( sdjf%cltype(1:4) == 'week' ) THEN 381 isec_week = ksec_week( sdjf%cltype(6:8) ) ! second since the beginning of the week 382 llprevmth = isec_week > nsec_month ! longer time since beginning of the week than the month 383 llprevyr = llprevmth .AND. nmonth == 1 395 384 ELSE 396 CALL iom_get( sdjf%num, jpdom_data, sdjf%clvar, sdjf%fdta(:,:,2), sdjf%nrec_b(1) ) 397 ENDIF 398 sdjf%rotn(2) = .FALSE. 399 400 clfmt = "('fld_init : time-interpolation for ', a, ' read previous record = ', i4, ' at time = ', f7.2, ' days')" 401 IF(lwp) WRITE(numout, clfmt) TRIM(sdjf%clvar), sdjf%nrec_b(1), REAL(sdjf%nrec_b(2),wp)/rday 402 403 IF( llprev ) CALL iom_close( sdjf%num ) ! close previous year file (-> redefine sdjf%num to 0) 404 385 isec_week = 0 386 llprevmth = .FALSE. 387 llprevyr = .FALSE. 388 ENDIF 389 ! 390 iyear = nyear - COUNT((/llprevyr /)) 391 imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /)) 392 iday = nday + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday) 393 ! 394 CALL fld_clopn( sdjf, iyear, imonth, iday ) 395 ENDIF 396 397 END SUBROUTINE fld_init 398 399 400 SUBROUTINE fld_rec( kn_fsbc, sdjf, ldbefore ) 401 !!--------------------------------------------------------------------- 402 !! *** ROUTINE fld_rec *** 403 !! 404 !! ** Purpose : Compute 405 !! if sdjf%ln_tint = .TRUE. 406 !! nrec_a: record number and its time (nrec_b is obtained from nrec_a when swapping) 407 !! if sdjf%ln_tint = .FALSE. 408 !! nrec_a(1): record number 409 !! nrec_b(2) and nrec_a(2): time of the beginning and end of the record (for print only) 410 !! 411 !! ** Method : 412 !!---------------------------------------------------------------------- 413 INTEGER , INTENT(in ) :: kn_fsbc ! sbc computation period (in time step) 414 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables 415 LOGICAL , INTENT(in ), OPTIONAL :: ldbefore ! sent back before record values (default = .FALSE.) 416 ! used only if sdjf%ln_tint = .TRUE. 417 !! 418 LOGICAL :: llbefore ! local definition of ldbefore 419 INTEGER :: iendrec ! end of this record (in seconds) 420 INTEGER :: imth ! month number 421 INTEGER :: ifreq_sec ! frequency mean (in seconds) 422 INTEGER :: isec_week ! number of seconds since the start of the weekly file 423 REAL(wp) :: ztmp ! temporary variable 424 !!---------------------------------------------------------------------- 425 ! 426 ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 427 ! 428 IF( PRESENT(ldbefore) ) THEN ; llbefore = ldbefore .AND. sdjf%ln_tint ! needed only if sdjf%ln_tint = .TRUE. 429 ELSE ; llbefore = .FALSE. 405 430 ENDIF 406 407 IF( sdjf%num <= 0 ) CALL fld_clopn( sdjf, nyear, nmonth, nday ) ! make sure current year/month/day file is opened 408 409 sdjf%nswap_sec = nsec_year + nsec1jan000 - 1 ! force read/update the after data in the following part of fld_read 410 411 END SUBROUTINE fld_init 412 413 414 SUBROUTINE fld_rec( kn_fsbc, sdjf ) 415 !!--------------------------------------------------------------------- 416 !! *** ROUTINE fld_rec *** 417 !! 418 !! ** Purpose : compute nrec_a, nrec_b and nswap_sec 419 !! 420 !! ** Method : 421 !!---------------------------------------------------------------------- 422 INTEGER , INTENT(in ) :: kn_fsbc ! sbc computation period (in time step) 423 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables 424 !! 425 INTEGER :: irec ! record number 426 INTEGER :: isecd ! rday 427 REAL(wp) :: ztmp ! temporary variable 428 INTEGER :: ifreq_sec ! frequency mean (in seconds) 429 !!---------------------------------------------------------------------- 430 ! 431 ! Note: shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 432 ! 433 IF( sdjf%nfreqh == -1 ) THEN ! monthly mean 431 ! 432 ! ! =========== ! 433 IF ( sdjf%nfreqh == -12 ) THEN ! yearly mean 434 ! ! =========== ! 435 ! 436 IF( sdjf%ln_tint ) THEN ! time interpolation, shift by 1/2 record 437 ! 438 ! INT( ztmp ) 439 ! /|\ 440 ! 1 | *---- 441 ! 0 |----( 442 ! |----+----|--> time 443 ! 0 /|\ 1 (nday/nyear_len(1)) 444 ! | 445 ! | 446 ! forcing record : 1 447 ! 448 ztmp = REAL( nday, wp ) / REAL( nyear_len(1), wp ) + 0.5 449 sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/)) 450 ! swap at the middle of the year 451 IF( llbefore ) THEN ; sdjf%nrec_a(2) = nsec1jan000 - NINT(0.5 * rday) * nyear_len(0) 452 ELSE ; sdjf%nrec_a(2) = nsec1jan000 + NINT(0.5 * rday) * nyear_len(1) 453 ENDIF 454 ELSE ! no time interpolation 455 sdjf%nrec_a(1) = 1 456 sdjf%nrec_a(2) = NINT(rday) * nyear_len(1) + nsec1jan000 ! swap at the end of the year 457 sdjf%nrec_b(2) = nsec1jan000 ! beginning of the year (only for print) 458 ENDIF 459 ! 460 ! ! ============ ! 461 ELSEIF( sdjf%nfreqh == -1 ) THEN ! monthly mean ! 462 ! ! ============ ! 434 463 ! 435 464 IF( sdjf%ln_tint ) THEN ! time interpolation, shift by 1/2 record … … 445 474 ! forcing record : nmonth 446 475 ! 447 ztmp = REAL( nday, wp ) / REAL( nmonth_len(nmonth), wp ) + 0.5 448 ELSE 449 ztmp = 0.e0 450 ENDIF 451 irec = nmonth + INT( ztmp ) 452 453 IF( sdjf%ln_tint ) THEN ; sdjf%nswap_sec = nmonth_half(irec) + nsec1jan000 ! swap at the middle of the month 454 ELSE ; sdjf%nswap_sec = nmonth_end (irec) + nsec1jan000 ! swap at the end of the month 455 ENDIF 456 457 sdjf%nrec_a(:) = (/ irec, nmonth_half(irec) + nsec1jan000 /) ! define after record number and time 458 irec = irec - 1 ! move back to previous record 459 sdjf%nrec_b(:) = (/ irec, nmonth_half(irec) + nsec1jan000 /) ! define before record number and time 460 ! 461 ELSE ! higher frequency mean (in hours) 462 ! 463 ifreq_sec = sdjf%nfreqh * 3600 ! frequency mean (in seconds) 476 ztmp = REAL( nday, wp ) / REAL( nmonth_len(nmonth), wp ) + 0.5 477 imth = nmonth + INT( ztmp ) - COUNT((/llbefore/)) 478 IF( sdjf%cltype == 'monthly' ) THEN ; sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/)) 479 ELSE ; sdjf%nrec_a(1) = imth 480 ENDIF 481 sdjf%nrec_a(2) = nmonth_half( imth ) + nsec1jan000 ! swap at the middle of the month 482 ELSE ! no time interpolation 483 IF( sdjf%cltype == 'monthly' ) THEN ; sdjf%nrec_a(1) = 1 484 ELSE ; sdjf%nrec_a(1) = nmonth 485 ENDIF 486 sdjf%nrec_a(2) = nmonth_end(nmonth ) + nsec1jan000 ! swap at the end of the month 487 sdjf%nrec_b(2) = nmonth_end(nmonth-1) + nsec1jan000 ! beginning of the month (only for print) 488 ENDIF 489 ! 490 ! ! ================================ ! 491 ELSE ! higher frequency mean (in hours) 492 ! ! ================================ ! 493 ! 494 ifreq_sec = sdjf%nfreqh * 3600 ! frequency mean (in seconds) 495 IF( sdjf%cltype(1:4) == 'week' ) isec_week = ksec_week( sdjf%cltype(6:8) ) ! since the first day of the current week 464 496 ! number of second since the beginning of the file 465 IF( sdjf%cltype == 'monthly' ) THEN ; ztmp = REAL(nsec_month,wp) ! since 00h on the 1st day of the current month 466 ELSEIF( sdjf%cltype == 'daily' ) THEN ; ztmp = REAL(nsec_day ,wp) ! since 00h of the current day 467 ELSE ; ztmp = REAL(nsec_year ,wp) ! since 00h on Jan 1 of the current year 497 IF( sdjf%cltype == 'monthly' ) THEN ; ztmp = REAL(nsec_month,wp) ! since the first day of the current month 498 ELSEIF( sdjf%cltype(1:4) == 'week' ) THEN ; ztmp = REAL(isec_week ,wp) ! since the first day of the current week 499 ELSEIF( sdjf%cltype == 'daily' ) THEN ; ztmp = REAL(nsec_day ,wp) ! since 00h of the current day 500 ELSE ; ztmp = REAL(nsec_year ,wp) ! since 00h on Jan 1 of the current year 468 501 ENDIF 469 502 ztmp = ztmp + 0.5 * REAL(kn_fsbc - 1, wp) * rdttra(1) ! shift time to be centrered in the middle of sbc time step … … 482 515 ! forcing record : 1 2 3 483 516 ! 484 ztmp 485 ELSE 517 ztmp= ztmp / REAL(ifreq_sec, wp) + 0.5 518 ELSE ! no time interpolation 486 519 ! 487 520 ! INT( ztmp ) … … 496 529 ! forcing record : 1 2 3 497 530 ! 498 ztmp = ztmp / REAL(ifreq_sec, wp) 499 ENDIF 500 irec = 1 + INT( ztmp ) 501 502 isecd = NINT(rday) 503 ! after record index and second since Jan. 1st 00h of nit000 year 504 sdjf%nrec_a(:) = (/ irec, ifreq_sec * irec - ifreq_sec / 2 + nsec1jan000 /) 505 IF( sdjf%cltype == 'monthly' ) & ! add the number of seconds between 00h Jan 1 and the end of previous month 506 sdjf%nrec_a(2) = sdjf%nrec_a(2) + isecd * SUM(nmonth_len(1:nmonth -1)) ! ok if nmonth=1 507 IF( sdjf%cltype == 'daily' ) & ! add the number of seconds between 00h Jan 1 and the end of previous day 508 sdjf%nrec_a(2) = sdjf%nrec_a(2) + isecd * ( nday_year - 1 ) 509 510 ! before record index and second since Jan. 1st 00h of nit000 year 511 irec = irec - 1. ! move back to previous record 512 sdjf%nrec_b(:) = (/ irec, ifreq_sec * irec - ifreq_sec / 2 + nsec1jan000 /) 513 IF( sdjf%cltype == 'monthly' ) & ! add the number of seconds between 00h Jan 1 and the end of previous month 514 sdjf%nrec_b(2) = sdjf%nrec_b(2) + isecd * SUM(nmonth_len(1:nmonth -1)) ! ok if nmonth=1 515 IF( sdjf%cltype == 'daily' ) & ! add the number of seconds between 00h Jan 1 and the end of previous day 516 sdjf%nrec_b(2) = sdjf%nrec_b(2) + isecd * ( nday_year - 1 ) 517 518 ! swapping time in second since Jan. 1st 00h of nit000 year 519 IF( sdjf%ln_tint ) THEN ; sdjf%nswap_sec = sdjf%nrec_a(2) ! swap at the middle of the record 520 ELSE ; sdjf%nswap_sec = sdjf%nrec_a(2) + ifreq_sec / 2 ! swap at the end of the record 521 ENDIF 531 ztmp= ztmp / REAL(ifreq_sec, wp) 532 ENDIF 533 sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/)) ! record nomber to be read 534 535 iendrec = ifreq_sec * sdjf%nrec_a(1) + nsec1jan000 ! end of this record (in second) 536 ! add the number of seconds between 00h Jan 1 and the end of previous month/week/day (ok if nmonth=1) 537 IF( sdjf%cltype == 'monthly' ) iendrec = iendrec + NINT(rday) * SUM(nmonth_len(1:nmonth -1)) 538 IF( sdjf%cltype(1:4) == 'week' ) iendrec = iendrec + ( nsec_year - isec_week ) 539 IF( sdjf%cltype == 'daily' ) iendrec = iendrec + NINT(rday) * ( nday_year - 1 ) 540 IF( sdjf%ln_tint ) THEN 541 sdjf%nrec_a(2) = iendrec - ifreq_sec / 2 ! swap at the middle of the record 542 ELSE 543 sdjf%nrec_a(2) = iendrec ! swap at the end of the record 544 sdjf%nrec_b(2) = iendrec - ifreq_sec ! beginning of the record (only for print) 545 ENDIF 522 546 ! 523 547 ENDIF … … 526 550 527 551 552 SUBROUTINE fld_get( sdjf ) 553 !!--------------------------------------------------------------------- 554 !! *** ROUTINE fld_clopn *** 555 !! 556 !! ** Purpose : read the data 557 !! 558 !! ** Method : 559 !!---------------------------------------------------------------------- 560 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables 561 !! 562 INTEGER :: ipk ! number of vertical levels of sdjf%fdta ( 2D: ipk=1 ; 3D: ipk=jpk ) 563 INTEGER :: iw ! index into wgts array 564 !!--------------------------------------------------------------------- 565 566 ipk = SIZE( sdjf%fnow, 3 ) 567 IF( LEN(TRIM(sdjf%wgtname)) > 0 ) THEN 568 CALL wgt_list( sdjf, iw ) 569 IF( sdjf%ln_tint ) THEN ; CALL fld_interp( sdjf%num, sdjf%clvar, iw , ipk , sdjf%fdta(:,:,:,2), sdjf%nrec_a(1) ) 570 ELSE ; CALL fld_interp( sdjf%num, sdjf%clvar, iw , ipk , sdjf%fnow(:,:,: ), sdjf%nrec_a(1) ) 571 ENDIF 572 ELSE 573 SELECT CASE( ipk ) 574 CASE(1) 575 IF( sdjf%ln_tint ) THEN ; CALL iom_get( sdjf%num, jpdom_data, sdjf%clvar, sdjf%fdta(:,:,1,2), sdjf%nrec_a(1) ) 576 ELSE ; CALL iom_get( sdjf%num, jpdom_data, sdjf%clvar, sdjf%fnow(:,:,1 ), sdjf%nrec_a(1) ) 577 ENDIF 578 CASE DEFAULT 579 IF( sdjf%ln_tint ) THEN ; CALL iom_get( sdjf%num, jpdom_data, sdjf%clvar, sdjf%fdta(:,:,:,2), sdjf%nrec_a(1) ) 580 ELSE ; CALL iom_get( sdjf%num, jpdom_data, sdjf%clvar, sdjf%fnow(:,:,: ), sdjf%nrec_a(1) ) 581 ENDIF 582 END SELECT 583 ENDIF 584 ! 585 sdjf%rotn = .false. ! vector not yet rotated 586 587 END SUBROUTINE fld_get 588 589 590 SUBROUTINE fld_rot( kt, sd ) 591 !!--------------------------------------------------------------------- 592 !! *** ROUTINE fld_clopn *** 593 !! 594 !! ** Purpose : Vector fields may need to be rotated onto the local grid direction 595 !! 596 !! ** Method : 597 !!---------------------------------------------------------------------- 598 INTEGER , INTENT(in ) :: kt ! ocean time step 599 TYPE(FLD), INTENT(inout), DIMENSION(:) :: sd ! input field related variables 600 !! 601 INTEGER :: ju, jv, jk ! loop indices 602 INTEGER :: imf ! size of the structure sd 603 INTEGER :: ill ! character length 604 INTEGER :: iv ! indice of V component 605 REAL(wp), DIMENSION(jpi,jpj) :: utmp, vtmp ! temporary arrays for vector rotation 606 CHARACTER (LEN=100) :: clcomp ! dummy weight name 607 !!--------------------------------------------------------------------- 608 !! (sga: following code should be modified so that pairs arent searched for each time 609 ! 610 imf = SIZE( sd ) 611 DO ju = 1, imf 612 ill = LEN_TRIM( sd(ju)%vcomp ) 613 IF( ill > 0 .AND. .NOT. sd(ju)%rotn ) THEN ! find vector rotations required 614 IF( sd(ju)%vcomp(1:1) == 'U' ) THEN ! east-west component has symbolic name starting with 'U' 615 ! look for the north-south component which has same symbolic name but with 'U' replaced with 'V' 616 clcomp = 'V' // sd(ju)%vcomp(2:ill) ! works even if ill == 1 617 iv = -1 618 DO jv = 1, imf 619 IF( TRIM(sd(jv)%vcomp) == TRIM(clcomp) ) iv = jv 620 END DO 621 IF( iv > 0 ) THEN ! fields ju and iv are two components which need to be rotated together 622 DO jk = 1, SIZE( sd(ju)%fnow, 3 ) 623 IF( sd(ju)%ln_tint )THEN 624 CALL rot_rep( sd(ju)%fdta(:,:,jk,2), sd(iv)%fdta(:,:,jk,2), 'T', 'en->i', utmp(:,:) ) 625 CALL rot_rep( sd(ju)%fdta(:,:,jk,2), sd(iv)%fdta(:,:,jk,2), 'T', 'en->j', vtmp(:,:) ) 626 sd(ju)%fdta(:,:,jk,2) = utmp(:,:) ; sd(iv)%fdta(:,:,jk,2) = vtmp(:,:) 627 ELSE 628 CALL rot_rep( sd(ju)%fnow(:,:,jk ), sd(iv)%fnow(:,:,jk ), 'T', 'en->i', utmp(:,:) ) 629 CALL rot_rep( sd(ju)%fnow(:,:,jk ), sd(iv)%fnow(:,:,jk ), 'T', 'en->j', vtmp(:,:) ) 630 sd(ju)%fnow(:,:,jk ) = utmp(:,:) ; sd(iv)%fnow(:,:,jk ) = vtmp(:,:) 631 ENDIF 632 END DO 633 sd(ju)%rotn = .TRUE. ! vector was rotated 634 IF( lwp .AND. kt == nit000 ) WRITE(numout,*) & 635 & 'fld_read: vector pair ('//TRIM(sd(ju)%clvar)//', '//TRIM(sd(iv)%clvar)//') rotated on to model grid' 636 ENDIF 637 ENDIF 638 ENDIF 639 END DO 640 END SUBROUTINE fld_rot 641 642 528 643 SUBROUTINE fld_clopn( sdjf, kyear, kmonth, kday, ldstop ) 529 644 !!--------------------------------------------------------------------- … … 534 649 !! ** Method : 535 650 !!---------------------------------------------------------------------- 536 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables537 INTEGER , INTENT(in ) :: kyear ! year value538 INTEGER , INTENT(in ) :: kmonth ! month value539 INTEGER , INTENT(in ) :: kday ! day value540 LOGICAL , INTENT(in ), OPTIONAL :: ldstop ! stop if open to read a non-existing file (default = .TRUE.)651 TYPE(FLD), INTENT(inout) :: sdjf ! input field related variables 652 INTEGER , INTENT(in ) :: kyear ! year value 653 INTEGER , INTENT(in ) :: kmonth ! month value 654 INTEGER , INTENT(in ) :: kday ! day value 655 LOGICAL , INTENT(in ), OPTIONAL :: ldstop ! stop if open to read a non-existing file (default = .TRUE.) 541 656 542 657 IF( sdjf%num /= 0 ) CALL iom_close( sdjf%num ) ! close file if already open 543 658 ! build the new filename if not climatological data 544 IF( .NOT. sdjf%ln_clim ) THEN ; WRITE(sdjf%clname, '(a,"_y",i4.4)' ) TRIM( sdjf%clrootname ), kyear ! add year 545 IF( sdjf%cltype /= 'yearly' ) WRITE(sdjf%clname, '(a,"m" ,i2.2)' ) TRIM( sdjf%clname ), kmonth ! add month 546 IF( sdjf%cltype == 'daily' ) WRITE(sdjf%clname, '(a,"d" ,i2.2)' ) TRIM( sdjf%clname ), kday ! add day 659 sdjf%clname=TRIM(sdjf%clrootname) 660 ! 661 ! note that sdjf%ln_clim is is only acting on presence of the year in the file 662 IF( .NOT. sdjf%ln_clim ) THEN 663 WRITE(sdjf%clname, '(a,"_y",i4.4)' ) TRIM( sdjf%clrootname ), kyear ! add year 664 IF( sdjf%cltype /= 'yearly' ) WRITE(sdjf%clname, '(a,"m" ,i2.2)' ) TRIM( sdjf%clname ), kmonth ! add month 665 ELSE 666 ! build the new filename if climatological data 667 IF( sdjf%cltype /= 'yearly' ) WRITE(sdjf%clname, '(a,"_m",i2.2)' ) TRIM( sdjf%clrootname ), kmonth ! add month 547 668 ENDIF 669 IF( sdjf%cltype == 'daily' .OR. sdjf%cltype(1:4) == 'week' ) & 670 & WRITE(sdjf%clname, '(a,"d" ,i2.2)' ) TRIM( sdjf%clname ), kday ! add day 671 ! 548 672 CALL iom_open( sdjf%clname, sdjf%num, ldstop = ldstop, ldiof = LEN(TRIM(sdjf%wgtname)) > 0 ) 549 673 ! … … 575 699 sdf(jf)%ln_tint = sdf_n(jf)%ln_tint 576 700 sdf(jf)%ln_clim = sdf_n(jf)%ln_clim 577 IF( sdf(jf)%nfreqh == -1. ) THEN ; sdf(jf)%cltype = 'yearly' 578 ELSE ; sdf(jf)%cltype = sdf_n(jf)%cltype 579 ENDIF 701 sdf(jf)%cltype = sdf_n(jf)%cltype 580 702 sdf(jf)%wgtname = " " 581 703 IF( LEN( TRIM(sdf_n(jf)%wname) ) > 0 ) sdf(jf)%wgtname = TRIM( cdir )//TRIM( sdf_n(jf)%wname ) … … 598 720 & ' pairing : ' , TRIM( sdf(jf)%vcomp ), & 599 721 & ' data type: ' , sdf(jf)%cltype 722 call flush(numout) 600 723 END DO 601 724 ENDIF … … 672 795 IF( ref_wgts(kw)%cyclic ) THEN 673 796 WRITE(numout,*) ' cyclical' 674 IF( ref_wgts(kw)%o ffset > 0 ) WRITE(numout,*) ' with offset'797 IF( ref_wgts(kw)%overlap > 0 ) WRITE(numout,*) ' with overlap of ', ref_wgts(kw)%overlap 675 798 ELSE 676 799 WRITE(numout,*) ' not cyclical' … … 695 818 INTEGER :: inum ! temporary logical unit 696 819 INTEGER :: id ! temporary variable id 820 INTEGER :: ipk ! temporary vertical dimension 697 821 CHARACTER (len=5) :: aname 698 822 INTEGER , DIMENSION(3) :: ddims 699 823 INTEGER , DIMENSION(jpi, jpj) :: data_src 700 824 REAL(wp), DIMENSION(jpi, jpj) :: data_tmp 701 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: line2, lines ! temporary array to read 2 lineumns702 CHARACTER (len=34) :: lonvar703 825 LOGICAL :: cyclical 704 REAL(wp) :: resid, dlon ! temporary array to read 2 lineumns 705 INTEGER :: offset ! temporary integer 826 INTEGER :: zwrap ! temporary integer 706 827 !!---------------------------------------------------------------------- 707 828 ! … … 721 842 id = iom_varid( inum, sd%clvar, ddims ) 722 843 723 !! check for an east-west cyclic grid724 !! try to guess name of longitude variable725 726 lonvar = 'nav_lon'727 id = iom_varid(inum, TRIM(lonvar), ldstop=.FALSE.)728 IF( id <= 0 ) THEN729 lonvar = 'lon'730 id = iom_varid(inum, TRIM(lonvar), ldstop=.FALSE.)731 ENDIF732 733 offset = -1734 cyclical = .FALSE.735 IF( id > 0 ) THEN736 !! found a longitude variable737 !! now going to assume that grid is regular so we can read a single row738 739 !! because input array is 2d, have to present iom with 2d array even though we only need 1d slice740 !! worse, we cant pass line2(:,1) to iom_get since this is treated as a 1d array which doesnt match input file741 ALLOCATE( lines(ddims(1),2) )742 CALL iom_get(inum, jpdom_unknown, lonvar, lines(:,:), 1, kstart=(/1,1/), kcount=(/ddims(1),2/) )743 744 !! find largest grid spacing745 lines(1:ddims(1)-1,2) = lines(2:ddims(1),1) - lines(1:ddims(1)-1,1)746 dlon = MAXVAL( lines(1:ddims(1)-1,2) )747 748 resid = ABS(ABS(lines(ddims(1),1)-lines(1,1))-360.0)749 IF( resid < rsmall ) THEN750 !! end rows overlap in longitude751 offset = 0752 cyclical = .TRUE.753 ELSEIF( resid < 2.0*dlon ) THEN754 !! also call it cyclic if difference between end points is less than twice dlon from 360755 offset = 1756 cyclical = .TRUE.757 ENDIF758 759 DEALLOCATE( lines )760 761 ELSE762 !! guessing failed763 !! read in first and last columns of data variable764 !! since we dont know the name of the longitude variable (or even if there is one)765 !! we assume that if these two columns are equal, file is cyclic east-west766 767 !! because input array is 2d, have to present iom with 2d array even though we only need 1d slice768 !! worse, we cant pass line2(1,:) to iom_get since this is treated as a 1d array which doesnt match input file769 ALLOCATE( lines(2,ddims(2)), line2(2,ddims(2)) )770 CALL iom_get(inum, jpdom_unknown, sd%clvar, line2(:,:), 1, kstart=(/1,1/), kcount=(/2,ddims(2)/) )771 lines(2,:) = line2(1,:)772 773 CALL iom_get(inum, jpdom_unknown, sd%clvar, line2(:,:), 1, kstart=(/ddims(1)-1,1/), kcount=(/2,ddims(2)/) )774 lines(1,:) = line2(2,:)775 776 resid = SUM( ABS(lines(1,:) - lines(2,:)) )777 IF( resid < ddims(2)*rsmall ) THEN778 offset = 0779 cyclical = .TRUE.780 ENDIF781 782 DEALLOCATE( lines, line2 )783 ENDIF784 785 844 !! close it 786 845 CALL iom_close( inum ) … … 790 849 CALL iom_open ( sd%wgtname, inum ) ! interpolation weights 791 850 IF ( inum > 0 ) THEN 851 852 !! determine whether we have an east-west cyclic grid 853 !! from global attribute called "ew_wrap" in the weights file 854 !! note that if not found, iom_getatt returns -999 and cyclic with no overlap is assumed 855 !! since this is the most common forcing configuration 856 857 CALL iom_getatt(inum, 'ew_wrap', zwrap) 858 IF( zwrap >= 0 ) THEN 859 cyclical = .TRUE. 860 ELSE IF( zwrap == -999 ) THEN 861 cyclical = .TRUE. 862 zwrap = 0 863 ELSE 864 cyclical = .FALSE. 865 ENDIF 792 866 793 867 ref_wgts(nxt_wgt)%ddims(1) = ddims(1) 794 868 ref_wgts(nxt_wgt)%ddims(2) = ddims(2) 795 869 ref_wgts(nxt_wgt)%wgtname = sd%wgtname 796 ref_wgts(nxt_wgt)%offset = -1 797 ref_wgts(nxt_wgt)%cyclic = .FALSE. 798 IF( cyclical ) THEN 799 ref_wgts(nxt_wgt)%offset = offset 800 ref_wgts(nxt_wgt)%cyclic = .TRUE. 801 ENDIF 870 ref_wgts(nxt_wgt)%overlap = zwrap 871 ref_wgts(nxt_wgt)%cyclic = cyclical 802 872 ref_wgts(nxt_wgt)%nestid = 0 803 873 #if defined key_agrif … … 857 927 ! SA: +3 stencil is a patch to avoid out-of-bound computation in some configuration. 858 928 ! a more robust solution will be given in next release 859 ALLOCATE( ref_wgts(nxt_wgt)%fly_dta(ref_wgts(nxt_wgt)%jpiwgt+3, ref_wgts(nxt_wgt)%jpjwgt+3) ) 860 IF( ref_wgts(nxt_wgt)%cyclic ) ALLOCATE( ref_wgts(nxt_wgt)%col2(2,ref_wgts(nxt_wgt)%jpjwgt+3) ) 929 ipk = SIZE(sd%fnow, 3) 930 ALLOCATE( ref_wgts(nxt_wgt)%fly_dta(ref_wgts(nxt_wgt)%jpiwgt+3, ref_wgts(nxt_wgt)%jpjwgt+3 ,ipk) ) 931 IF( ref_wgts(nxt_wgt)%cyclic ) ALLOCATE( ref_wgts(nxt_wgt)%col(1,ref_wgts(nxt_wgt)%jpjwgt+3,ipk) ) 861 932 862 933 nxt_wgt = nxt_wgt + 1 … … 868 939 END SUBROUTINE fld_weight 869 940 870 SUBROUTINE fld_interp(num, clvar, kw, dta, nrec)941 SUBROUTINE fld_interp(num, clvar, kw, kk, dta, nrec) 871 942 !!--------------------------------------------------------------------- 872 943 !! *** ROUTINE fld_interp *** … … 880 951 CHARACTER(LEN=*), INTENT(in) :: clvar ! variable name 881 952 INTEGER, INTENT(in) :: kw ! weights number 882 REAL(wp), INTENT(inout), DIMENSION(jpi,jpj) :: dta ! output field on model grid 953 INTEGER, INTENT(in) :: kk ! vertical dimension of kk 954 REAL(wp), INTENT(inout), DIMENSION(jpi,jpj,kk) :: dta ! output field on model grid 883 955 INTEGER, INTENT(in) :: nrec ! record number to read (ie time slice) 884 956 !! 885 INTEGER, DIMENSION( 2) :: rec1,recn ! temporary arrays for start and length957 INTEGER, DIMENSION(3) :: rec1,recn ! temporary arrays for start and length 886 958 INTEGER :: jk, jn, jm ! loop counters 887 959 INTEGER :: ni, nj ! lengths … … 897 969 !! so we need to have a 4 by 4 subgrid surrounding each model point to cover both cases 898 970 899 !! sub grid where we already have weights971 !! sub grid from non-model input grid which encloses all grid points in this nemo process 900 972 jpimin = ref_wgts(kw)%botleft(1) 901 973 jpjmin = ref_wgts(kw)%botleft(2) … … 903 975 jpjwid = ref_wgts(kw)%jpjwgt 904 976 905 !! wh at we need to read into sub grid in order to calculategradients977 !! when reading in, expand this sub-grid by one halo point all the way round for calculating gradients 906 978 rec1(1) = MAX( jpimin-1, 1 ) 907 979 rec1(2) = MAX( jpjmin-1, 1 ) 980 rec1(3) = 1 908 981 recn(1) = MIN( jpiwid+2, ref_wgts(kw)%ddims(1)-rec1(1)+1 ) 909 982 recn(2) = MIN( jpjwid+2, ref_wgts(kw)%ddims(2)-rec1(2)+1 ) 910 911 !! where we need to read it to 983 recn(3) = kk 984 985 !! where we need to put it in the non-nemo grid fly_dta 986 !! note that jpi1 and jpj1 only differ from 1 when jpimin and jpjmin are 1 987 !! (ie at the extreme west or south of the whole input grid) and similarly for jpi2 and jpj2 912 988 jpi1 = 2 + rec1(1) - jpimin 913 989 jpj1 = 2 + rec1(2) - jpjmin … … 915 991 jpj2 = jpj1 + recn(2) - 1 916 992 917 ref_wgts(kw)%fly_dta(:,:) = 0.0 918 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2), nrec, rec1, recn) 993 ref_wgts(kw)%fly_dta(:,:,:) = 0.0 994 SELECT CASE( SIZE(ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:),3) ) 995 CASE(1) 996 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,1), nrec, rec1, recn) 997 CASE DEFAULT 998 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:), nrec, rec1, recn) 999 END SELECT 919 1000 920 1001 !! first four weights common to both bilinear and bicubic 1002 !! data_jpi, data_jpj have already been shifted to (1,1) corresponding to botleft 921 1003 !! note that we have to offset by 1 into fly_dta array because of halo 922 dta(:,: ) = 0.01004 dta(:,:,:) = 0.0 923 1005 DO jk = 1,4 924 1006 DO jn = 1, jpj … … 926 1008 ni = ref_wgts(kw)%data_jpi(jm,jn,jk) 927 1009 nj = ref_wgts(kw)%data_jpj(jm,jn,jk) 928 dta(jm,jn ) = dta(jm,jn) + ref_wgts(kw)%data_wgt(jm,jn,jk) * ref_wgts(kw)%fly_dta(ni+1,nj+1)1010 dta(jm,jn,:) = dta(jm,jn,:) + ref_wgts(kw)%data_wgt(jm,jn,jk) * ref_wgts(kw)%fly_dta(ni+1,nj+1,:) 929 1011 END DO 930 1012 END DO … … 935 1017 !! fix up halo points that we couldnt read from file 936 1018 IF( jpi1 == 2 ) THEN 937 ref_wgts(kw)%fly_dta(jpi1-1,: ) = ref_wgts(kw)%fly_dta(jpi1,:)1019 ref_wgts(kw)%fly_dta(jpi1-1,:,:) = ref_wgts(kw)%fly_dta(jpi1,:,:) 938 1020 ENDIF 939 1021 IF( jpi2 + jpimin - 1 == ref_wgts(kw)%ddims(1)+1 ) THEN 940 ref_wgts(kw)%fly_dta(jpi2+1,: ) = ref_wgts(kw)%fly_dta(jpi2,:)1022 ref_wgts(kw)%fly_dta(jpi2+1,:,:) = ref_wgts(kw)%fly_dta(jpi2,:,:) 941 1023 ENDIF 942 1024 IF( jpj1 == 2 ) THEN 943 ref_wgts(kw)%fly_dta(:,jpj1-1 ) = ref_wgts(kw)%fly_dta(:,jpj1)1025 ref_wgts(kw)%fly_dta(:,jpj1-1,:) = ref_wgts(kw)%fly_dta(:,jpj1,:) 944 1026 ENDIF 945 1027 IF( jpj2 + jpjmin - 1 == ref_wgts(kw)%ddims(2)+1 .AND. jpj2 .lt. jpjwid+2 ) THEN 946 ref_wgts(kw)%fly_dta(:,jpj2+1 ) = 2.0*ref_wgts(kw)%fly_dta(:,jpj2) - ref_wgts(kw)%fly_dta(:,jpj2-1)1028 ref_wgts(kw)%fly_dta(:,jpj2+1,:) = 2.0*ref_wgts(kw)%fly_dta(:,jpj2,:) - ref_wgts(kw)%fly_dta(:,jpj2-1,:) 947 1029 ENDIF 948 1030 … … 951 1033 IF( ref_wgts(kw)%cyclic ) THEN 952 1034 rec1(2) = MAX( jpjmin-1, 1 ) 953 recn(1) = 21035 recn(1) = 1 954 1036 recn(2) = MIN( jpjwid+2, ref_wgts(kw)%ddims(2)-rec1(2)+1 ) 955 1037 jpj1 = 2 + rec1(2) - jpjmin 956 1038 jpj2 = jpj1 + recn(2) - 1 957 1039 IF( jpi1 == 2 ) THEN 958 rec1(1) = ref_wgts(kw)%ddims(1) - 1 959 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col2(:,jpj1:jpj2), nrec, rec1, recn) 960 ref_wgts(kw)%fly_dta(jpi1-1,jpj1:jpj2) = ref_wgts(kw)%col2(ref_wgts(kw)%offset+1,jpj1:jpj2) 1040 rec1(1) = ref_wgts(kw)%ddims(1) - ref_wgts(kw)%overlap 1041 SELECT CASE( SIZE( ref_wgts(kw)%col(:,jpj1:jpj2,:),3) ) 1042 CASE(1) 1043 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,1), nrec, rec1, recn) 1044 CASE DEFAULT 1045 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn) 1046 END SELECT 1047 ref_wgts(kw)%fly_dta(jpi1-1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:) 961 1048 ENDIF 962 1049 IF( jpi2 + jpimin - 1 == ref_wgts(kw)%ddims(1)+1 ) THEN 963 rec1(1) = 1 964 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col2(:,jpj1:jpj2), nrec, rec1, recn) 965 ref_wgts(kw)%fly_dta(jpi2+1,jpj1:jpj2) = ref_wgts(kw)%col2(2-ref_wgts(kw)%offset,jpj1:jpj2) 1050 rec1(1) = 1 + ref_wgts(kw)%overlap 1051 SELECT CASE( SIZE( ref_wgts(kw)%col(:,jpj1:jpj2,:),3) ) 1052 CASE(1) 1053 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,1), nrec, rec1, recn) 1054 CASE DEFAULT 1055 CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn) 1056 END SELECT 1057 ref_wgts(kw)%fly_dta(jpi2+1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:) 966 1058 ENDIF 967 1059 ENDIF … … 973 1065 ni = ref_wgts(kw)%data_jpi(jm,jn,jk) 974 1066 nj = ref_wgts(kw)%data_jpj(jm,jn,jk) 975 dta(jm,jn ) = dta(jm,jn) + ref_wgts(kw)%data_wgt(jm,jn,jk+4) * 0.5 * &976 (ref_wgts(kw)%fly_dta(ni+2,nj+1 ) - ref_wgts(kw)%fly_dta(ni,nj+1))1067 dta(jm,jn,:) = dta(jm,jn,:) + ref_wgts(kw)%data_wgt(jm,jn,jk+4) * 0.5 * & 1068 (ref_wgts(kw)%fly_dta(ni+2,nj+1,:) - ref_wgts(kw)%fly_dta(ni,nj+1,:)) 977 1069 END DO 978 1070 END DO … … 985 1077 ni = ref_wgts(kw)%data_jpi(jm,jn,jk) 986 1078 nj = ref_wgts(kw)%data_jpj(jm,jn,jk) 987 dta(jm,jn ) = dta(jm,jn) + ref_wgts(kw)%data_wgt(jm,jn,jk+8) * 0.5 * &988 (ref_wgts(kw)%fly_dta(ni+1,nj+2 ) - ref_wgts(kw)%fly_dta(ni+1,nj))1079 dta(jm,jn,:) = dta(jm,jn,:) + ref_wgts(kw)%data_wgt(jm,jn,jk+8) * 0.5 * & 1080 (ref_wgts(kw)%fly_dta(ni+1,nj+2,:) - ref_wgts(kw)%fly_dta(ni+1,nj,:)) 989 1081 END DO 990 1082 END DO … … 997 1089 ni = ref_wgts(kw)%data_jpi(jm,jn,jk) 998 1090 nj = ref_wgts(kw)%data_jpj(jm,jn,jk) 999 dta(jm,jn ) = dta(jm,jn) + ref_wgts(kw)%data_wgt(jm,jn,jk+12) * 0.25 * ( &1000 (ref_wgts(kw)%fly_dta(ni+2,nj+2 ) - ref_wgts(kw)%fly_dta(ni ,nj+2)) - &1001 (ref_wgts(kw)%fly_dta(ni+2,nj ) - ref_wgts(kw)%fly_dta(ni ,nj)))1091 dta(jm,jn,:) = dta(jm,jn,:) + ref_wgts(kw)%data_wgt(jm,jn,jk+12) * 0.25 * ( & 1092 (ref_wgts(kw)%fly_dta(ni+2,nj+2,:) - ref_wgts(kw)%fly_dta(ni ,nj+2,:)) - & 1093 (ref_wgts(kw)%fly_dta(ni+2,nj ,:) - ref_wgts(kw)%fly_dta(ni ,nj ,:))) 1002 1094 END DO 1003 1095 END DO … … 1007 1099 1008 1100 END SUBROUTINE fld_interp 1009 1101 1102 1103 FUNCTION ksec_week( cdday ) 1104 !!--------------------------------------------------------------------- 1105 !! *** FUNCTION kshift_week *** 1106 !! 1107 !! ** Purpose : 1108 !! 1109 !! ** Method : 1110 !!--------------------------------------------------------------------- 1111 CHARACTER(len=*), INTENT(in) :: cdday !3 first letters of the first day of the weekly file 1112 !! 1113 INTEGER :: ksec_week ! output variable 1114 INTEGER :: ijul !temp variable 1115 INTEGER :: ishift !temp variable 1116 CHARACTER(len=3),DIMENSION(7) :: cl_week 1117 !!---------------------------------------------------------------------- 1118 cl_week = (/"sun","sat","fri","thu","wed","tue","mon"/) 1119 DO ijul = 1, 7 1120 IF( cl_week(ijul) == TRIM(cdday) ) EXIT 1121 ENDDO 1122 IF( ijul .GT. 7 ) CALL ctl_stop( 'ksec_week: wrong day for sdjf%cltype(6:8): '//TRIM(cdday) ) 1123 ! 1124 ishift = ijul * NINT(rday) 1125 ! 1126 ksec_week = nsec_week + ishift 1127 ksec_week = MOD( ksec_week, 7*NINT(rday) ) 1128 ! 1129 END FUNCTION ksec_week 1130 1131 1010 1132 END MODULE fldread -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/geo2ocean.F90
- Property svn:eol-style deleted
r1833 r2528 27 27 ! they are only a useless overlay of rot_rep 28 28 29 PUBLIC obs_rot 30 29 31 REAL(wp), DIMENSION(jpi,jpj) :: & 30 32 gsint, gcost, & ! cos/sin between model grid lines and NP direction at T point … … 38 40 # include "vectopt_loop_substitute.h90" 39 41 !!---------------------------------------------------------------------- 40 !! NEMO/OPA 3. 0 , LOCEAN-IPSL (2008)42 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 41 43 !! $Id$ 42 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)44 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 43 45 !!---------------------------------------------------------------------- 44 46 … … 522 524 END SUBROUTINE repere 523 525 526 527 SUBROUTINE obs_rot ( psinu, pcosu, psinv, pcosv ) 528 !!---------------------------------------------------------------------- 529 !! *** ROUTINE obs_rot *** 530 !! 531 !! ** Purpose : Copy gsinu, gcosu, gsinv and gsinv 532 !! to input data for rotations of 533 !! current at observation points 534 !! 535 !! History : 536 !! 9.2 ! 09-02 (K. Mogensen) 537 !!---------------------------------------------------------------------- 538 REAL(wp), DIMENSION(jpi,jpj), INTENT( OUT ):: & 539 & psinu, pcosu, psinv, pcosv! copy of data 540 541 !!---------------------------------------------------------------------- 542 543 ! Initialization of gsin* and gcos* at first call 544 ! ----------------------------------------------- 545 546 IF( lmust_init ) THEN 547 IF(lwp) WRITE(numout,*) 548 IF(lwp) WRITE(numout,*) ' obs_rot : geographic <--> stretched' 549 IF(lwp) WRITE(numout,*) ' ~~~~~~~ coordinate transformation' 550 551 CALL angle ! initialization of the transformation 552 lmust_init = .FALSE. 553 554 ENDIF 555 556 psinu(:,:) = gsinu(:,:) 557 pcosu(:,:) = gcosu(:,:) 558 psinv(:,:) = gsinv(:,:) 559 pcosv(:,:) = gcosv(:,:) 560 561 END SUBROUTINE obs_rot 562 563 524 564 !!====================================================================== 525 565 END MODULE geo2ocean -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/oasis4_date.F90
- Property svn:eol-style deleted
r1156 r2528 10 10 #if defined key_oasis4 11 11 !!---------------------------------------------------------------------- 12 !! OPA 9.0 , LOCEAN-IPSL (2006)12 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 13 13 !! $Id$ 14 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)14 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 15 15 !!---------------------------------------------------------------------- 16 16 !##################### WARNING coupled mode ############################### -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbc_ice.F90
r1482 r2528 9 9 #if defined key_lim3 || defined key_lim2 10 10 !!---------------------------------------------------------------------- 11 !! 'key_lim2' or 'key_lim3' : LIM 2.0 or 3.0sea-ice model11 !! 'key_lim2' or 'key_lim3' : LIM-2 or LIM-3 sea-ice model 12 12 !!---------------------------------------------------------------------- 13 13 USE par_oce ! ocean parameters … … 23 23 24 24 # if defined key_lim2 25 LOGICAL , PUBLIC, PARAMETER :: lk_lim2 = .TRUE. !: LIM-2 ice model 26 LOGICAL , PUBLIC, PARAMETER :: lk_lim3 = .FALSE. !: no LIM-3 27 CHARACTER(len=1), PUBLIC :: cigr_type = 'I' !: 'I'-grid ice-velocity (B-grid lower left corner) 25 LOGICAL , PUBLIC, PARAMETER :: lk_lim2 = .TRUE. !: LIM-2 ice model 26 LOGICAL , PUBLIC, PARAMETER :: lk_lim3 = .FALSE. !: no LIM-3 27 # if defined key_lim2_vp 28 CHARACTER(len=1), PUBLIC, PARAMETER :: cp_ice_msh = 'I' !: VP : 'I'-grid ice-velocity (B-grid lower left corner) 29 # else 30 CHARACTER(len=1), PUBLIC, PARAMETER :: cp_ice_msh = 'C' !: EVP: 'C'-grid ice-velocity 31 # endif 28 32 # endif 29 33 # if defined key_lim3 30 LOGICAL , PUBLIC, PARAMETER :: lk_lim2 = .FALSE.!: no LIM-231 LOGICAL , PUBLIC, PARAMETER :: lk_lim3 = .TRUE.!: LIM-3 ice model32 CHARACTER(len=1), PUBLIC :: cigr_type = 'C'!: 'C'-grid ice-velocity34 LOGICAL , PUBLIC, PARAMETER :: lk_lim2 = .FALSE. !: no LIM-2 35 LOGICAL , PUBLIC, PARAMETER :: lk_lim3 = .TRUE. !: LIM-3 ice model 36 CHARACTER(len=1), PUBLIC, PARAMETER :: cp_ice_msh = 'C' !: 'C'-grid ice-velocity 33 37 # endif 34 38 … … 41 45 REAL(wp), PUBLIC, DIMENSION(jpi,jpj,jpl) :: alb_ice !: albedo of ice 42 46 43 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: utau_ice !: u-stress over ice (I-p oint for LIM2 or U,V-point for LIM3) [N/m2]44 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: vtau_ice !: v-stress over ice (I-p oint for LIM2 or U,V-point for LIM3) [N/m2]45 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: fr1_i0 !: 1st fraction of sol. rad. which penetrateinside the ice cover46 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: fr2_i0 !: 2nd fraction of sol. rad. which penetrateinside the ice cover47 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: utau_ice !: u-stress over ice (I-pt for VP or U,V-pts for EVP) [N/m2] 48 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: vtau_ice !: v-stress over ice (I-pt for VP or U,V-pts for EVP) [N/m2] 49 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: fr1_i0 !: 1st fraction of Qsr which penetrates inside the ice cover 50 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: fr2_i0 !: 2nd fraction of Qsr which penetrates inside the ice cover 47 51 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emp_ice !: solid freshwater budget over ice: sublivation - snow 48 52 … … 55 59 !! Default option NO LIM 2.0 or 3.0 sea-ice model 56 60 !!---------------------------------------------------------------------- 57 LOGICAL , PUBLIC, PARAMETER :: lk_lim2 58 LOGICAL , PUBLIC, PARAMETER :: lk_lim3 59 CHARACTER(len=1), PUBLIC :: cigr_type= '-' !: no grid ice-velocity61 LOGICAL , PUBLIC, PARAMETER :: lk_lim2 = .FALSE. !: no LIM-2 ice model 62 LOGICAL , PUBLIC, PARAMETER :: lk_lim3 = .FALSE. !: no LIM-3 ice model 63 CHARACTER(len=1), PUBLIC, PARAMETER :: cp_ice_msh = '-' !: no grid ice-velocity 60 64 #endif 61 65 62 66 !!---------------------------------------------------------------------- 63 !! NEMO/OPA 3. 2 , LOCEAN-IPSL (2009)67 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 64 68 !! $Id$ 65 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) 66 !!---------------------------------------------------------------------- 67 69 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 68 70 !!====================================================================== 69 71 END MODULE sbc_ice -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbc_oce.F90
r1705 r2528 4 4 !! Surface module : variables defined in core memory 5 5 !!====================================================================== 6 !! History : 3.0 ! 2006-06 (G. Madec) Original code 7 !! - ! 2008-08 (G. Madec) namsbc moved from sbcmod 6 !! History : 3.0 ! 2006-06 (G. Madec) Original code 7 !! - ! 2008-08 (G. Madec) namsbc moved from sbcmod 8 !! 3.3 ! 2010-04 (M. Leclair, G. Madec) Forcing averaged over 2 time steps 9 !! - ! 2010-11 (G. Madec) ice-ocean stress always computed at each ocean time-step 10 !! 3.3 ! 2010-10 (J. Chanut, C. Bricaud) add the surface pressure forcing 8 11 !!---------------------------------------------------------------------- 9 12 USE par_oce ! ocean parameters … … 24 27 LOGICAL , PUBLIC :: ln_rnf = .FALSE. !: runoffs / runoff mouths 25 28 LOGICAL , PUBLIC :: ln_ssr = .FALSE. !: Sea Surface restoring on SST and/or SSS 29 LOGICAL , PUBLIC :: ln_apr_dyn = .FALSE. !: Atmospheric pressure forcing used on dynamics (ocean & ice) 26 30 INTEGER , PUBLIC :: nn_ice = 0 !: flag on ice in the surface boundary condition (=0/1/2/3) 27 31 INTEGER , PUBLIC :: nn_fwb = 0 !: FreshWater Budget: … … 29 33 ! !: = 1 global mean of e-p-r set to zero at each nn_fsbc time step 30 34 ! !: = 2 annual global mean of e-p-r set to zero 31 INTEGER , PUBLIC :: nn_ico_cpl = 0 !: ice-ocean coupling indicator32 ! !: = 0 LIM-3 old case33 ! !: = 1 stresses computed using now ocean velocity34 ! !: = 2 combination of 0 and 1 cases35 35 36 36 !!---------------------------------------------------------------------- 37 37 !! Ocean Surface Boundary Condition fields 38 38 !!---------------------------------------------------------------------- 39 LOGICAL , PUBLIC :: lhftau = .FALSE. !: HF tau contribution: mean of stress module - module of the mean stress 40 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: utau !: sea surface i-stress (ocean referential) [N/m2] 41 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: vtau !: sea surface j-stress (ocean referential) [N/m2] 42 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: taum !: module of sea surface stress (at T-point) [N/m2] 43 !! wndm is used only in PISCES to compute gases exchanges at the surface of the free ocean or in the leads in sea-ice parts 44 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: wndm !: wind speed module at T-point (=|U10m-Uoce|) [m/s] 45 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qsr !: sea heat flux: solar [W/m2] 46 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qns !: sea heat flux: non solar [W/m2] 47 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qsr_tot !: total solar heat flux (over sea and ice) [W/m2] 48 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qns_tot !: total non solar heat flux (over sea and ice) [W/m2] 49 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emp !: freshwater budget: volume flux [Kg/m2/s] 50 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emps !: freshwater budget: concentration/dillution [Kg/m2/s] 51 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emp_tot !: total evaporation - (liquid + solid) precpitation over oce and ice 52 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: tprecip !: total precipitation [Kg/m2/s] 53 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: sprecip !: solid precipitation [Kg/m2/s] 54 !!$ REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: rrunoff !: runoff 55 !!$ REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: calving !: calving 56 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: fr_i !: ice fraction (between 0 to 1) - 39 LOGICAL , PUBLIC :: lhftau = .FALSE. !: HF tau used in TKE: mean(stress module) - module(mean stress) 40 !! !! now ! before !! 41 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: utau , utau_b !: sea surface i-stress (ocean referential) [N/m2] 42 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: vtau , vtau_b !: sea surface j-stress (ocean referential) [N/m2] 43 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: taum !: module of sea surface stress (at T-point) [N/m2] 44 !! wndm is used only in PISCES to compute surface gases exchanges in ice-free ocean or leads 45 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: wndm !: wind speed module at T-point (=|U10m-Uoce|) [m/s] 46 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qsr !: sea heat flux: solar [W/m2] 47 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qns , qns_b !: sea heat flux: non solar [W/m2] 48 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qsr_tot !: total solar heat flux (over sea and ice) [W/m2] 49 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: qns_tot !: total non solar heat flux (over sea and ice) [W/m2] 50 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emp , emp_b !: freshwater budget: volume flux [Kg/m2/s] 51 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emps , emps_b !: freshwater budget: concentration/dillution [Kg/m2/s] 52 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: emp_tot !: total E-P over ocean and ice [Kg/m2/s] 53 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: rnf , rnf_b !: river runoff [Kg/m2/s] 54 !! 55 REAL(wp), PUBLIC, DIMENSION(jpi,jpj,jpts) :: sbc_tsc, sbc_tsc_b !: sbc content trend [K.m/s] 56 REAL(wp), PUBLIC, DIMENSION(jpi,jpj,jpk) :: qsr_hc , qsr_hc_b !: heat content trend due to qsr flux [K.m/s] 57 !! 58 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: tprecip !: total precipitation [Kg/m2/s] 59 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: sprecip !: solid precipitation [Kg/m2/s] 60 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: fr_i !: ice fraction = 1 - lead fraction (between 0 to 1) 57 61 #if defined key_cpl_carbon_cycle 58 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: atm_co2 !: atmospheric pCO2 [ppm]62 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: atm_co2 !: atmospheric pCO2 [ppm] 59 63 #endif 60 64 … … 70 74 71 75 !!---------------------------------------------------------------------- 72 !! OPA 9.0 , LOCEAN-IPSL (2006)73 !! $ Id:$74 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)76 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 77 !! $Id$ 78 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 75 79 !!====================================================================== 76 77 80 END MODULE sbc_oce -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcana.F90
r2147 r2528 39 39 # include "vectopt_loop_substitute.h90" 40 40 !!---------------------------------------------------------------------- 41 !! NEMO/OPA 3. 2 , LOCEAN-IPSL (2009)41 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 42 42 !! $Id$ 43 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)43 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 44 44 !!---------------------------------------------------------------------- 45 45 … … 208 208 209 209 ! Compute the emp flux such as its integration on the whole domain at each time is zero 210 IF( nbench /= 1 .AND. nbit_cmp /= 1) THEN210 IF( nbench /= 1 ) THEN 211 211 zsumemp = 0.e0 ; zsurf = 0.e0 212 212 DO jj = 1, jpj -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_clio.F90
r2388 r2528 37 37 USE ice_2 38 38 #endif 39 39 40 IMPLICIT NONE 40 41 PRIVATE … … 81 82 # include "vectopt_loop_substitute.h90" 82 83 !!---------------------------------------------------------------------- 83 !! NEMO/OPA 3. 2 , LOCEAN-IPSL (2009)84 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 84 85 !! $Id$ 85 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)86 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 86 87 !!---------------------------------------------------------------------- 87 88 88 CONTAINS 89 89 … … 137 137 138 138 ! (NB: frequency positive => hours, negative => months) 139 ! ! file ! frequency ! variable ! time intep ! clim ! 'yearly' or ! weights ! rotation!140 ! ! name ! (hours) ! name ! (T/F) ! (T/F) ! 'monthly' ! filename ! pairs!141 sn_utau = FLD_N( 'utau' , 24 , 'utau' , .true. , .false. , 'yearly' , '' , '')142 sn_vtau = FLD_N( 'vtau' , 24 , 'vtau' , .true. , .false. , 'yearly' , '' , '')143 sn_wndm = FLD_N( 'mwnd10m' , 24 , 'm_10' , .true. , .false. , 'yearly' , '' , '')144 sn_tair = FLD_N( 'tair10m' , 24 , 't_10' , .false. , .false. , 'yearly' , '' , '')145 sn_humi = FLD_N( 'humi10m' , 24 , 'q_10' , .false. , .false. , 'yearly' , '' , '')146 sn_ccov = FLD_N( 'ccover' , -1 , 'cloud' , .true. , .false. , 'yearly' , '' , '')147 sn_prec = FLD_N( 'precip' , -1 , 'precip' , .true. , .false. , 'yearly' , '' , '')139 ! ! file ! frequency ! variable ! time intep ! clim ! 'yearly' or ! weights ! rotation ! 140 ! ! name ! (hours) ! name ! (T/F) ! (T/F) ! 'monthly' ! filename ! pairs ! 141 sn_utau = FLD_N( 'utau' , 24 , 'utau' , .true. , .false. , 'yearly' , '' , '' ) 142 sn_vtau = FLD_N( 'vtau' , 24 , 'vtau' , .true. , .false. , 'yearly' , '' , '' ) 143 sn_wndm = FLD_N( 'mwnd10m', 24 , 'm_10' , .true. , .false. , 'yearly' , '' , '' ) 144 sn_tair = FLD_N( 'tair10m', 24 , 't_10' , .false. , .false. , 'yearly' , '' , '' ) 145 sn_humi = FLD_N( 'humi10m', 24 , 'q_10' , .false. , .false. , 'yearly' , '' , '' ) 146 sn_ccov = FLD_N( 'ccover' , -1 , 'cloud' , .true. , .false. , 'yearly' , '' , '' ) 147 sn_prec = FLD_N( 'precip' , -1 , 'precip' , .true. , .false. , 'yearly' , '' , '' ) 148 148 149 149 REWIND( numnam ) ! ... read in namlist namsbc_clio … … 160 160 CALL ctl_stop( 'sbc_blk_clio: unable to allocate sf structure' ) ; RETURN 161 161 ENDIF 162 163 162 DO ifpr= 1, jpfld 164 ALLOCATE( sf(ifpr)%fnow(jpi,jpj) ) 165 ALLOCATE( sf(ifpr)%fdta(jpi,jpj,2) ) 166 END DO 167 168 163 ALLOCATE( sf(ifpr)%fnow(jpi,jpj,1) ) 164 IF( slf_i(ifpr)%ln_tint ) ALLOCATE( sf(ifpr)%fdta(jpi,jpj,1,2) ) 165 END DO 169 166 ! fill sf with slf_i and control print 170 167 CALL fld_fill( sf, slf_i, cn_dir, 'sbc_blk_clio', 'flux formulation for ocean surface boundary condition', 'namsbc_clio' ) … … 178 175 ! 179 176 #if defined key_lim3 180 tatm_ice(:,:) = sf(jp_tair)%fnow(:,: ) !RB ugly patch177 tatm_ice(:,:) = sf(jp_tair)%fnow(:,:,1) !RB ugly patch 181 178 #endif 182 ! 183 IF(lwp .AND. nitend-nit000 <= 100 ) THEN 184 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN 185 WRITE(numout,*) 186 WRITE(numout,*) ' read monthly CLIO fluxes: ok, kt: ', kt 187 WRITE(numout,*) 188 ifpr = INT(jpi/8) ; jfpr = INT(jpj/10) 189 WRITE(numout,*) TRIM(sf(jp_utau)%clvar),' day: ',ndastp 190 CALL prihre( sf(jp_utau)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 191 WRITE(numout,*) 192 WRITE(numout,*) TRIM(sf(jp_vtau)%clvar),' day: ',ndastp 193 CALL prihre( sf(jp_vtau)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 194 WRITE(numout,*) 195 WRITE(numout,*) TRIM(sf(jp_humi)%clvar),' day: ',ndastp 196 CALL prihre( sf(jp_humi)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 197 WRITE(numout,*) 198 WRITE(numout,*) TRIM(sf(jp_wndm)%clvar),' day: ',ndastp 199 CALL prihre( sf(jp_wndm)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 200 WRITE(numout,*) 201 WRITE(numout,*) TRIM(sf(jp_ccov)%clvar),' day: ',ndastp 202 CALL prihre( sf(jp_ccov)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 203 WRITE(numout,*) 204 WRITE(numout,*) TRIM(sf(jp_prec)%clvar),' day: ',ndastp 205 CALL prihre( sf(jp_prec)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 206 WRITE(numout,*) 207 WRITE(numout,*) TRIM(sf(jp_tair)%clvar),' day: ',ndastp 208 CALL prihre( sf(jp_tair)%fnow,jpi,jpj,1,jpi,ifpr,1,jpj,jfpr,0.,numout ) 209 WRITE(numout,*) 210 ENDIF 211 ENDIF 212 213 IF( MOD( kt - 1, nn_fsbc ) == 0 ) THEN 214 CALL blk_oce_clio( sf, sst_m ) ! compute the surface ocean fluxes using CLIO bulk formulea 215 ENDIF ! 179 ! ! surface ocean fluxes computed with CLIO bulk formulea 180 IF( MOD( kt - 1, nn_fsbc ) == 0 ) CALL blk_oce_clio( sf, sst_m ) 216 181 ! 217 182 END SUBROUTINE sbc_blk_clio … … 270 235 !------------------------------------! 271 236 !CDIR COLLAPSE 272 DO jj = 1 , jpj 273 DO ji = 1, jpi 274 utau(ji,jj) = sf(jp_utau)%fnow(ji,jj) 275 vtau(ji,jj) = sf(jp_vtau)%fnow(ji,jj) 276 END DO 277 END DO 237 utau(:,:) = sf(jp_utau)%fnow(:,:,1) 238 !CDIR COLLAPSE 239 vtau(:,:) = sf(jp_vtau)%fnow(:,:,1) 278 240 279 241 !------------------------------------! … … 295 257 !------------------------------------! 296 258 !CDIR COLLAPSE 297 DO jj = 1 , jpj 298 DO ji = 1, jpi 299 wndm(ji,jj) = sf(jp_wndm)%fnow(ji,jj) 300 END DO 301 END DO 259 wndm(:,:) = sf(jp_wndm)%fnow(:,:,1) 302 260 303 261 !------------------------------------------------! … … 317 275 ! 318 276 zsst = pst(ji,jj) + rt0 ! converte Celcius to Kelvin the SST 319 ztatm = sf(jp_tair)%fnow(ji,jj )! and set minimum value far above 0 K (=rt0 over land)320 zcco1 = 1.0 - sf(jp_ccov)%fnow(ji,jj )! fraction of clear sky ( 1 - cloud cover)277 ztatm = sf(jp_tair)%fnow(ji,jj,1) ! and set minimum value far above 0 K (=rt0 over land) 278 zcco1 = 1.0 - sf(jp_ccov)%fnow(ji,jj,1) ! fraction of clear sky ( 1 - cloud cover) 321 279 zrhoa = zpatm / ( 287.04 * ztatm ) ! air density (equation of state for dry air) 322 280 ztamr = ztatm - rtt ! Saturation water vapour … … 325 283 zmt3 = SIGN( 28.200, -ztamr ) ! \/ 326 284 zes = 611.0 * EXP( ABS( ztamr ) * MIN ( zmt1, zmt2 ) / ( ztatm - 35.86 + MAX( 0.e0, zmt3 ) ) ) 327 zev = sf(jp_humi)%fnow(ji,jj ) * zes! vapour pressure285 zev = sf(jp_humi)%fnow(ji,jj,1) * zes ! vapour pressure 328 286 zevsqr = SQRT( zev * 0.01 ) ! square-root of vapour pressure 329 287 zqatm = 0.622 * zev / ( zpatm - 0.378 * zev ) ! specific humidity … … 333 291 !--------------------------------------! 334 292 ztatm3 = ztatm * ztatm * ztatm 335 zcldeff = 1.0 - sbudyko(ji,jj) * sf(jp_ccov)%fnow(ji,jj ) * sf(jp_ccov)%fnow(ji,jj)293 zcldeff = 1.0 - sbudyko(ji,jj) * sf(jp_ccov)%fnow(ji,jj,1) * sf(jp_ccov)%fnow(ji,jj,1) 336 294 ztaevbk = ztatm * ztatm3 * zcldeff * ( 0.39 - 0.05 * zevsqr ) 337 295 ! … … 351 309 zdeltaq = zqatm - zqsato 352 310 ztvmoy = ztatm * ( 1. + 2.2e-3 * ztatm * zqatm ) 353 zdenum = MAX( sf(jp_wndm)%fnow(ji,jj ) * sf(jp_wndm)%fnow(ji,jj) * ztvmoy, zeps )311 zdenum = MAX( sf(jp_wndm)%fnow(ji,jj,1) * sf(jp_wndm)%fnow(ji,jj,1) * ztvmoy, zeps ) 354 312 zdtetar = zdteta / zdenum 355 313 ztvmoyr = ztvmoy * ztvmoy * zdeltaq / zdenum … … 373 331 zpsil = zpsih 374 332 375 zvatmg = MAX( 0.032 * 1.5e-3 * sf(jp_wndm)%fnow(ji,jj ) * sf(jp_wndm)%fnow(ji,jj) / grav, zeps )333 zvatmg = MAX( 0.032 * 1.5e-3 * sf(jp_wndm)%fnow(ji,jj,1) * sf(jp_wndm)%fnow(ji,jj,1) / grav, zeps ) 376 334 zcmn = vkarmn / LOG ( 10. / zvatmg ) 377 335 zchn = 0.0327 * zcmn … … 387 345 zcleo = zcln * zclcm 388 346 389 zrhova = zrhoa * sf(jp_wndm)%fnow(ji,jj )347 zrhova = zrhoa * sf(jp_wndm)%fnow(ji,jj,1) 390 348 391 349 ! sensible heat flux … … 403 361 404 362 !CDIR COLLAPSE 405 !CDIR NOVERRCHK 406 DO jj = 1, jpj 407 !CDIR NOVERRCHK 408 DO ji = 1, jpi 409 qns (ji,jj) = zqlw(ji,jj) - zqsb(ji,jj) - zqla(ji,jj) ! Downward Non Solar flux 410 emp (ji,jj) = zqla(ji,jj) / cevap - sf(jp_prec)%fnow(ji,jj) / rday * tmask(ji,jj,1) 411 END DO 412 END DO 363 emp (:,:) = zqla(:,:) / cevap - sf(jp_prec)%fnow(:,:,1) / rday * tmask(:,:,1) 364 qns (:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:) ! Downward Non Solar flux 413 365 emps(:,:) = emp(:,:) 414 366 ! … … 476 428 INTEGER :: ijpl ! number of ice categories (size of 3rd dim of input arrays) 477 429 !! 478 REAL(wp) :: zcoef, zmt1, zmt2, zmt3, ztatm3 430 REAL(wp) :: zcoef, zmt1, zmt2, zmt3, ztatm3 ! temporary scalars 479 431 REAL(wp) :: ztaevbk, zind1, zind2, zind3, ztamr ! - - 480 432 REAL(wp) :: zesi, zqsati, zdesidt ! - - … … 499 451 SELECT CASE( cd_grid ) 500 452 CASE( 'C' ) ! C-grid ice dynamics 501 ! Change from wind speed to wind stress over OCEAN (cao is used) 502 zcoef = cai / cao 503 !CDIR COLLAPSE 504 DO jj = 1 , jpj 505 DO ji = 1, jpi 506 p_taui(ji,jj) = zcoef * utau(ji,jj) 507 p_tauj(ji,jj) = zcoef * vtau(ji,jj) 508 END DO 509 END DO 510 CASE( 'B' ) ! B-grid ice dynamics 511 ! Change from wind speed to wind stress over OCEAN (cao is used) 512 zcoef = 0.5 * cai / cao 513 ! stress from ocean U- and V-points to ice U,V point 514 !CDIR COLLAPSE 515 DO jj = 2, jpj 516 DO ji = 2, jpi ! B grid : no vector opt. 453 zcoef = cai / cao ! Change from air-sea stress to air-ice stress 454 p_taui(:,:) = zcoef * utau(:,:) 455 p_tauj(:,:) = zcoef * vtau(:,:) 456 CASE( 'I' ) ! I-grid ice dynamics: I-point (i.e. F-point lower-left corner) 457 zcoef = 0.5_wp * cai / cao ! Change from air-sea stress to air-ice stress 458 DO jj = 2, jpj ! stress from ocean U- and V-points to ice U,V point 459 DO ji = 2, jpi ! I-grid : no vector opt. 517 460 p_taui(ji,jj) = zcoef * ( utau(ji-1,jj ) + utau(ji-1,jj-1) ) 518 461 p_tauj(ji,jj) = zcoef * ( vtau(ji ,jj-1) + vtau(ji-1,jj-1) ) 519 462 END DO 520 463 END DO 521 CALL lbc_lnk( p_taui(:,:), 'I', -1. ) ! I-point (i.e. ice U-V point) 522 CALL lbc_lnk( p_tauj(:,:), 'I', -1. ) ! I-point (i.e. ice U-V point) 464 CALL lbc_lnk( p_taui(:,:), 'I', -1. ) ; CALL lbc_lnk( p_tauj(:,:), 'I', -1. ) ! I-point 523 465 END SELECT 524 466 … … 532 474 !CDIR NOVERRCHK 533 475 DO ji = 1, jpi 534 ztatm (ji,jj) = sf(jp_tair)%fnow(ji,jj )! air temperature in Kelvins476 ztatm (ji,jj) = sf(jp_tair)%fnow(ji,jj,1) ! air temperature in Kelvins 535 477 536 478 zrhoa(ji,jj) = zpatm / ( 287.04 * ztatm(ji,jj) ) ! air density (equation of state for dry air) … … 543 485 & / ( ztatm(ji,jj) - 35.86 + MAX( 0.e0, zmt3 ) ) ) 544 486 545 zev = sf(jp_humi)%fnow(ji,jj ) * zes! vapour pressure487 zev = sf(jp_humi)%fnow(ji,jj,1) * zes ! vapour pressure 546 488 zevsqr(ji,jj) = SQRT( zev * 0.01 ) ! square-root of vapour pressure 547 489 zqatm(ji,jj) = 0.622 * zev / ( zpatm - 0.378 * zev ) ! specific humidity … … 553 495 zmt2 = ( 272.0 - ztatm(ji,jj) ) / 38.0 ; zind2 = MAX( 0.e0, SIGN( 1.e0, zmt2 ) ) 554 496 zmt3 = ( 281.0 - ztatm(ji,jj) ) / 18.0 ; zind3 = MAX( 0.e0, SIGN( 1.e0, zmt3 ) ) 555 p_spr(ji,jj) = sf(jp_prec)%fnow(ji,jj ) / rday &! rday = converte mm/day to kg/m2/s497 p_spr(ji,jj) = sf(jp_prec)%fnow(ji,jj,1) / rday & ! rday = converte mm/day to kg/m2/s 556 498 & * ( zind1 & ! solid (snow) precipitation [kg/m2/s] 557 499 & + ( 1.0 - zind1 ) * ( zind2 * ( 0.5 + zmt2 ) & … … 563 505 ! fraction of qsr_ice which is NOT absorbed in the thin surface layer 564 506 ! and thus which penetrates inside the ice cover ( Maykut and Untersteiner, 1971 ; Elbert anbd Curry, 1993 ) 565 p_fr1(ji,jj) = 0.18 * ( 1.e0 - sf(jp_ccov)%fnow(ji,jj ) ) + 0.35 * sf(jp_ccov)%fnow(ji,jj)566 p_fr2(ji,jj) = 0.82 * ( 1.e0 - sf(jp_ccov)%fnow(ji,jj ) ) + 0.65 * sf(jp_ccov)%fnow(ji,jj)507 p_fr1(ji,jj) = 0.18 * ( 1.e0 - sf(jp_ccov)%fnow(ji,jj,1) ) + 0.35 * sf(jp_ccov)%fnow(ji,jj,1) 508 p_fr2(ji,jj) = 0.82 * ( 1.e0 - sf(jp_ccov)%fnow(ji,jj,1) ) + 0.65 * sf(jp_ccov)%fnow(ji,jj,1) 567 509 END DO 568 510 END DO … … 586 528 !-------------------------------------------! 587 529 ztatm3 = ztatm(ji,jj) * ztatm(ji,jj) * ztatm(ji,jj) 588 zcldeff = 1.0 - sbudyko(ji,jj) * sf(jp_ccov)%fnow(ji,jj ) * sf(jp_ccov)%fnow(ji,jj)530 zcldeff = 1.0 - sbudyko(ji,jj) * sf(jp_ccov)%fnow(ji,jj,1) * sf(jp_ccov)%fnow(ji,jj,1) 589 531 ztaevbk = ztatm3 * ztatm(ji,jj) * zcldeff * ( 0.39 - 0.05 * zevsqr(ji,jj) ) 590 532 ! … … 611 553 612 554 ! sensible and latent fluxes over ice 613 zrhova = zrhoa(ji,jj) * sf(jp_wndm)%fnow(ji,jj ) ! computation of intermediate values555 zrhova = zrhoa(ji,jj) * sf(jp_wndm)%fnow(ji,jj,1) ! computation of intermediate values 614 556 zrhovaclei = zrhova * zcshi * 2.834e+06 615 557 zrhovacshi = zrhova * zclei * 1004.0 … … 641 583 p_qns(:,:,:) = z_qlw (:,:,:) - z_qsb (:,:,:) - p_qla (:,:,:) ! Downward Non Solar flux 642 584 !CDIR COLLAPSE 643 p_tpr(:,:) = sf(jp_prec)%fnow(:,: ) / rday! total precipitation [kg/m2/s]585 p_tpr(:,:) = sf(jp_prec)%fnow(:,:,1) / rday ! total precipitation [kg/m2/s] 644 586 ! 645 587 !!gm : not necessary as all input data are lbc_lnk... … … 737 679 !CDIR NOVERRCHK 738 680 DO ji = 1, jpi 739 ztamr = sf(jp_tair)%fnow(ji,jj ) - rtt681 ztamr = sf(jp_tair)%fnow(ji,jj,1) - rtt 740 682 zmt1 = SIGN( 17.269, ztamr ) 741 683 zmt2 = SIGN( 21.875, ztamr ) 742 684 zmt3 = SIGN( 28.200, -ztamr ) 743 685 zes = 611.0 * EXP( ABS( ztamr ) * MIN ( zmt1, zmt2 ) & ! Saturation water vapour 744 & / ( sf(jp_tair)%fnow(ji,jj ) - 35.86 + MAX( 0.e0, zmt3 ) ) )745 zev(ji,jj) = sf(jp_humi)%fnow(ji,jj ) * zes * 1.0e-05! vapour pressure686 & / ( sf(jp_tair)%fnow(ji,jj,1) - 35.86 + MAX( 0.e0, zmt3 ) ) ) 687 zev(ji,jj) = sf(jp_humi)%fnow(ji,jj,1) * zes * 1.0e-05 ! vapour pressure 746 688 END DO 747 689 END DO … … 800 742 801 743 ! ocean albedo depending on the cloud cover (Payne, 1972) 802 za_oce = ( 1.0 - sf(jp_ccov)%fnow(ji,jj ) ) * 0.05 / ( 1.1 * zcmue**1.4 + 0.15 ) & ! clear sky803 & + sf(jp_ccov)%fnow(ji,jj ) * 0.06 ! overcast744 za_oce = ( 1.0 - sf(jp_ccov)%fnow(ji,jj,1) ) * 0.05 / ( 1.1 * zcmue**1.4 + 0.15 ) & ! clear sky 745 & + sf(jp_ccov)%fnow(ji,jj,1) * 0.06 ! overcast 804 746 805 747 ! solar heat flux absorbed by the ocean (Zillman, 1972) … … 816 758 DO ji = 1, jpi 817 759 zlmunoon = ASIN( zps(ji,jj) + zpc(ji,jj) ) / rad ! local noon solar altitude 818 zcldcor = MIN( 1.e0, ( 1.e0 - 0.62 * sf(jp_ccov)%fnow(ji,jj ) &! cloud correction (Reed 1977)760 zcldcor = MIN( 1.e0, ( 1.e0 - 0.62 * sf(jp_ccov)%fnow(ji,jj,1) & ! cloud correction (Reed 1977) 819 761 & + 0.0019 * zlmunoon ) ) 820 pqsr_oce(ji,jj) = zcoef1 * zcldcor * pqsr_oce(ji,jj) * tmask(ji,jj,1) ! and zcoef1: ellipsity762 pqsr_oce(ji,jj) = zcoef1 * zcldcor * pqsr_oce(ji,jj) * tmask(ji,jj,1) ! and zcoef1: ellipsity 821 763 END DO 822 764 END DO … … 867 809 !CDIR NOVERRCHK 868 810 DO ji = 1, jpi 869 ztamr = sf(jp_tair)%fnow(ji,jj ) - rtt811 ztamr = sf(jp_tair)%fnow(ji,jj,1) - rtt 870 812 zmt1 = SIGN( 17.269, ztamr ) 871 813 zmt2 = SIGN( 21.875, ztamr ) 872 814 zmt3 = SIGN( 28.200, -ztamr ) 873 815 zes = 611.0 * EXP( ABS( ztamr ) * MIN ( zmt1, zmt2 ) & ! Saturation water vapour 874 & / ( sf(jp_tair)%fnow(ji,jj ) - 35.86 + MAX( 0.e0, zmt3 ) ) )875 zev(ji,jj) = sf(jp_humi)%fnow(ji,jj ) * zes * 1.0e-05! vapour pressure816 & / ( sf(jp_tair)%fnow(ji,jj,1) - 35.86 + MAX( 0.e0, zmt3 ) ) ) 817 zev(ji,jj) = sf(jp_humi)%fnow(ji,jj,1) * zes * 1.0e-05 ! vapour pressure 876 818 END DO 877 819 END DO … … 940 882 & / ( 1.0 + 0.139 * stauc(ji,jj) * ( 1.0 - 0.9435 * pa_ice_os(ji,jj,jl) ) ) 941 883 942 pqsr_ice(ji,jj,jl) = pqsr_ice(ji,jj,jl) + ( ( 1.0 - sf(jp_ccov)%fnow(ji,jj ) ) * zqsr_ice_cs &943 & + sf(jp_ccov)%fnow(ji,jj ) * zqsr_ice_os )884 pqsr_ice(ji,jj,jl) = pqsr_ice(ji,jj,jl) + ( ( 1.0 - sf(jp_ccov)%fnow(ji,jj,1) ) * zqsr_ice_cs & 885 & + sf(jp_ccov)%fnow(ji,jj,1) * zqsr_ice_os ) 944 886 END DO 945 887 END DO -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_core.F90
r2419 r2528 12 12 !! 3.0 ! 2006-06 (G. Madec) sbc rewritting 13 13 !! 3.2 ! 2009-04 (B. Lemaire) Introduce iom_put 14 !! 3.3 ! 2010-10 (S. Masson) add diurnal cycle 14 15 !!---------------------------------------------------------------------- 15 16 … … 26 27 USE fldread ! read input fields 27 28 USE sbc_oce ! Surface boundary condition: ocean fields 29 USE sbcdcy ! surface boundary condition: diurnal cycle 28 30 USE iom ! I/O manager library 29 31 USE in_out_manager ! I/O manager … … 34 36 USE sbc_ice ! Surface boundary condition: ice fields 35 37 #endif 36 37 38 38 39 IMPLICIT NONE … … 61 62 REAL(wp), PARAMETER :: Stef = 5.67e-8 ! Stefan Boltzmann constant 62 63 REAL(wp), PARAMETER :: Cice = 1.63e-3 ! transfer coefficient over ice 63 64 ! !!* Namelist namsbc_core : CORE bulk parameters 65 LOGICAL :: ln_2m = .FALSE. ! logical flag for height of air temp. and hum 66 LOGICAL :: ln_taudif = .FALSE. ! logical flag to use the "mean of stress module - module of mean stress" data 67 REAL(wp) :: rn_pfac = 1. ! multiplication factor for precipitation 64 REAL(wp), PARAMETER :: albo = 0.066 ! ocean albedo assumed to be contant 65 66 ! !!* Namelist namsbc_core : CORE bulk parameters 67 LOGICAL :: ln_2m = .FALSE. ! logical flag for height of air temp. and hum 68 LOGICAL :: ln_taudif = .FALSE. ! logical flag to use the "mean of stress module - module of mean stress" data 69 REAL(wp) :: rn_pfac = 1. ! multiplication factor for precipitation 68 70 69 71 !! * Substitutions … … 71 73 # include "vectopt_loop_substitute.h90" 72 74 !!---------------------------------------------------------------------- 73 !! NEMO/OPA 3. 2 , LOCEAN-IPSL (2009)75 !! NEMO/OPA 3.3 , NEMO-consortium (2010) 74 76 !! $Id$ 75 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)77 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 76 78 !!---------------------------------------------------------------------- 77 78 79 CONTAINS 79 80 … … 132 133 ! 133 134 ! (NB: frequency positive => hours, negative => months) 134 ! ! file ! frequency ! variable ! time intep ! clim ! 'yearly' or ! weights ! rotation!135 ! ! name ! (hours) ! name ! (T/F) ! (T/F) ! 'monthly' ! filename ! pairs!136 sn_wndi = FLD_N( 'uwnd10m' , 24 , 'u_10' , .false. , .false. , 'yearly' , '' , '')137 sn_wndj = FLD_N( 'vwnd10m' , 24 , 'v_10' , .false. , .false. , 'yearly' , '' , '')138 sn_qsr = FLD_N( 'qsw' , 24 , 'qsw' , .false. , .false. , 'yearly' , '' , '')139 sn_qlw = FLD_N( 'qlw' , 24 , 'qlw' , .false. , .false. , 'yearly' , '' , '')140 sn_tair = FLD_N( 'tair10m' , 24 , 't_10' , .false. , .false. , 'yearly' , '' , '')141 sn_humi = FLD_N( 'humi10m' , 24 , 'q_10' , .false. , .false. , 'yearly' , '' , '')142 sn_prec = FLD_N( 'precip' , -1 , 'precip' , .true. , .false. , 'yearly' , '' , '')143 sn_snow = FLD_N( 'snow' , -1 , 'snow' , .true. , .false. , 'yearly' , '' , '')144 sn_tdif = FLD_N( 'taudif' , 24 , 'taudif' , .true. , .false. , 'yearly' , '' , '')135 ! ! file ! frequency ! variable ! time intep ! clim ! 'yearly' or ! weights ! rotation ! 136 ! ! name ! (hours) ! name ! (T/F) ! (T/F) ! 'monthly' ! filename ! pairs ! 137 sn_wndi = FLD_N( 'uwnd10m', 24 , 'u_10' , .false. , .false. , 'yearly' , '' , '' ) 138 sn_wndj = FLD_N( 'vwnd10m', 24 , 'v_10' , .false. , .false. , 'yearly' , '' , '' ) 139 sn_qsr = FLD_N( 'qsw' , 24 , 'qsw' , .false. , .false. , 'yearly' , '' , '' ) 140 sn_qlw = FLD_N( 'qlw' , 24 , 'qlw' , .false. , .false. , 'yearly' , '' , '' ) 141 sn_tair = FLD_N( 'tair10m', 24 , 't_10' , .false. , .false. , 'yearly' , '' , '' ) 142 sn_humi = FLD_N( 'humi10m', 24 , 'q_10' , .false. , .false. , 'yearly' , '' , '' ) 143 sn_prec = FLD_N( 'precip' , -1 , 'precip' , .true. , .false. , 'yearly' , '' , '' ) 144 sn_snow = FLD_N( 'snow' , -1 , 'snow' , .true. , .false. , 'yearly' , '' , '' ) 145 sn_tdif = FLD_N( 'taudif' , 24 , 'taudif' , .true. , .false. , 'yearly' , '' , '' ) 145 146 ! 146 REWIND( numnam ) ! ...read in namlist namsbc_core147 REWIND( numnam ) ! read in namlist namsbc_core 147 148 READ ( numnam, namsbc_core ) 148 ! 149 ! store namelist information in an array 149 ! ! check: do we plan to use ln_dm2dc with non-daily forcing? 150 IF( ln_dm2dc .AND. sn_qsr%nfreqh /= 24 ) & 151 & CALL ctl_stop( 'sbc_blk_core: ln_dm2dc can be activated only with daily short-wave forcing' ) 152 IF( ln_dm2dc .AND. sn_qsr%ln_tint ) THEN 153 CALL ctl_warn( 'sbc_blk_core: ln_dm2dc is taking care of the temporal interpolation of daily qsr', & 154 & ' ==> We force time interpolation = .false. for qsr' ) 155 sn_qsr%ln_tint = .false. 156 ENDIF 157 ! ! store namelist information in an array 150 158 slf_i(jp_wndi) = sn_wndi ; slf_i(jp_wndj) = sn_wndj 151 159 slf_i(jp_qsr ) = sn_qsr ; slf_i(jp_qlw ) = sn_qlw … … 153 161 slf_i(jp_prec) = sn_prec ; slf_i(jp_snow) = sn_snow 154 162 slf_i(jp_tdif) = sn_tdif 155 ! 156 ! do we use HF tau information? 157 lhftau = ln_taudif 163 ! 164 lhftau = ln_taudif ! do we use HF tau information? 158 165 jfld = jpfld - COUNT( (/.NOT. lhftau/) ) 159 166 ! 160 ! set sf structure 161 ALLOCATE( sf(jfld), STAT=ierror ) 167 ALLOCATE( sf(jfld), STAT=ierror ) ! set sf structure 162 168 IF( ierror > 0 ) THEN 163 169 CALL ctl_stop( 'sbc_blk_core: unable to allocate sf structure' ) ; RETURN 164 170 ENDIF 165 171 DO ifpr= 1, jfld 166 ALLOCATE( sf(ifpr)%fnow(jpi,jpj ) )167 ALLOCATE( sf(ifpr)%fdta(jpi,jpj,2) )172 ALLOCATE( sf(ifpr)%fnow(jpi,jpj,1) ) 173 IF( slf_i(ifpr)%ln_tint ) ALLOCATE( sf(ifpr)%fdta(jpi,jpj,1,2) ) 168 174 END DO 169 ! 170 ! fill sf with slf_i and control print 171 CALL fld_fill( sf, slf_i, cn_dir, 'sbc_blk_core', 'flux formulattion for ocean surface boundary condition', 'namsbc_core' ) 175 ! ! fill sf with slf_i and control print 176 CALL fld_fill( sf, slf_i, cn_dir, 'sbc_blk_core', 'flux formulation for ocean surface boundary condition', 'namsbc_core' ) 172 177 ! 173 178 ENDIF 174 179 175 CALL fld_read( kt, nn_fsbc, sf ) 180 CALL fld_read( kt, nn_fsbc, sf ) ! input fields provided at the current time-step 176 181 177 182 #if defined key_lim3 178 tatm_ice(:,:) = sf(jp_tair)%fnow(:,: )183 tatm_ice(:,:) = sf(jp_tair)%fnow(:,:,1) ! LIM3: make Tair available in sea-ice 179 184 #endif 180 181 IF( MOD( kt - 1, nn_fsbc ) == 0 ) THEN 182 CALL blk_oce_core( sf, sst_m, ssu_m, ssv_m ) ! compute the surface ocean fluxes using CLIO bulk formulea 183 ENDIF 184 ! ! using CORE bulk formulea 185 ! ! surface ocean fluxes computed with CLIO bulk formulea 186 IF( MOD( kt - 1, nn_fsbc ) == 0 ) CALL blk_oce_core( sf, sst_m, ssu_m, ssv_m ) 187 ! 185 188 END SUBROUTINE sbc_blk_core 186 189 … … 244 247 DO jj = 2, jpjm1 245 248 DO ji = fs_2, fs_jpim1 ! vect. opt. 246 zwnd_i(ji,jj) = ( sf(jp_wndi)%fnow(ji,jj ) - 0.5 * ( pu(ji-1,jj ) + pu(ji,jj) ) )247 zwnd_j(ji,jj) = ( sf(jp_wndj)%fnow(ji,jj ) - 0.5 * ( pv(ji ,jj-1) + pv(ji,jj) ) )249 zwnd_i(ji,jj) = ( sf(jp_wndi)%fnow(ji,jj,1) - 0.5 * ( pu(ji-1,jj ) + pu(ji,jj) ) ) 250 zwnd_j(ji,jj) = ( sf(jp_wndj)%fnow(ji,jj,1) - 0.5 * ( pv(ji ,jj-1) + pv(ji,jj) ) ) 248 251 END DO 249 252 END DO … … 260 263 ! ----------------------------------------------------------------------------- ! 261 264 262 ! ocean albedo assumed to be 0.066 263 !CDIR COLLAPSE 264 qsr (:,:) = ( 1. - 0.066 ) * sf(jp_qsr)%fnow(:,:) * tmask(:,:,1) ! Short Wave 265 !CDIR COLLAPSE 266 zqlw(:,:) = ( sf(jp_qlw)%fnow(:,:) - Stef * zst(:,:)*zst(:,:)*zst(:,:)*zst(:,:) ) * tmask(:,:,1) ! Long Wave 267 265 ! ocean albedo assumed to be constant + modify now Qsr to include the diurnal cycle ! Short Wave 266 zztmp = 1. - albo 267 IF( ln_dm2dc ) THEN ; qsr(:,:) = zztmp * sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) * tmask(:,:,1) 268 ELSE ; qsr(:,:) = zztmp * sf(jp_qsr)%fnow(:,:,1) * tmask(:,:,1) 269 ENDIF 270 !CDIR COLLAPSE 271 zqlw(:,:) = ( sf(jp_qlw)%fnow(:,:,1) - Stef * zst(:,:)*zst(:,:)*zst(:,:)*zst(:,:) ) * tmask(:,:,1) ! Long Wave 268 272 ! ----------------------------------------------------------------------------- ! 269 273 ! II Turbulent FLUXES ! … … 307 311 IF( lhftau ) THEN 308 312 !CDIR COLLAPSE 309 taum(:,:) = taum(:,:) + sf(jp_tdif)%fnow(:,: )313 taum(:,:) = taum(:,:) + sf(jp_tdif)%fnow(:,:,1) 310 314 ENDIF 311 315 CALL iom_put( "taum_oce", taum ) ! output wind stress module … … 330 334 ELSE 331 335 !CDIR COLLAPSE 332 zevap(:,:) = MAX( 0.e0, rhoa *Ce(:,:)*( zqsatw(:,:) - sf(jp_humi)%fnow(:,: ) ) * wndm(:,:) ) ! Evaporation333 !CDIR COLLAPSE 334 zqsb (:,:) = rhoa*cpa*Ch(:,:)*( zst (:,:) - sf(jp_tair)%fnow(:,: ) ) * wndm(:,:) ! Sensible Heat336 zevap(:,:) = MAX( 0.e0, rhoa *Ce(:,:)*( zqsatw(:,:) - sf(jp_humi)%fnow(:,:,1) ) * wndm(:,:) ) ! Evaporation 337 !CDIR COLLAPSE 338 zqsb (:,:) = rhoa*cpa*Ch(:,:)*( zst (:,:) - sf(jp_tair)%fnow(:,:,1) ) * wndm(:,:) ! Sensible Heat 335 339 ENDIF 336 340 !CDIR COLLAPSE … … 355 359 qns(:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:) ! Downward Non Solar flux 356 360 !CDIR COLLAPSE 357 emp (:,:) = zevap(:,:) - sf(jp_prec)%fnow(:,:) * rn_pfac * tmask(:,:,1)361 emp(:,:) = zevap(:,:) - sf(jp_prec)%fnow(:,:,1) * rn_pfac * tmask(:,:,1) 358 362 !CDIR COLLAPSE 359 363 emps(:,:) = emp(:,:) … … 392 396 !! caution : the net upward water flux has with mm/day unit 393 397 !!--------------------------------------------------------------------- 394 REAL(wp), INTENT(in ), DIMENSION(:,:,:):: pst ! ice surface temperature (>0, =rt0 over land) [Kelvin]395 REAL(wp), INTENT(in ), DIMENSION(jpi,jpj):: pui ! ice surface velocity (i- and i- components [m/s]396 REAL(wp), INTENT(in ), DIMENSION(jpi,jpj):: pvi ! at I-point (B-grid) or U & V-point (C-grid)397 REAL(wp), INTENT(in ), DIMENSION(:,:,:):: palb ! ice albedo (clear sky) (alb_ice_cs) [%]398 REAL(wp), INTENT( out), DIMENSION(jpi,jpj):: p_taui ! i- & j-components of surface ice stress [N/m2]399 REAL(wp), INTENT( out), DIMENSION(jpi,jpj):: p_tauj ! at I-point (B-grid) or U & V-point (C-grid)400 REAL(wp), INTENT( out), DIMENSION(:,:,:):: p_qns ! non solar heat flux over ice (T-point) [W/m2]401 REAL(wp), INTENT( out), DIMENSION(:,:,:):: p_qsr ! solar heat flux over ice (T-point) [W/m2]402 REAL(wp), INTENT( out), DIMENSION(:,:,:):: p_qla ! latent heat flux over ice (T-point) [W/m2]403 REAL(wp), INTENT( out), DIMENSION(:,:,:):: p_dqns ! non solar heat sensistivity (T-point) [W/m2]404 REAL(wp), INTENT( out), DIMENSION(:,:,:):: p_dqla ! latent heat sensistivity (T-point) [W/m2]405 REAL(wp), INTENT( out), DIMENSION(jpi,jpj):: p_tpr ! total precipitation (T-point) [Kg/m2/s]406 REAL(wp), INTENT( out), DIMENSION(jpi,jpj):: p_spr ! solid precipitation (T-point) [Kg/m2/s]407 REAL(wp), INTENT( out), DIMENSION(jpi,jpj):: p_fr1 ! 1sr fraction of qsr penetration in ice (T-point) [%]408 REAL(wp), INTENT( out), DIMENSION(jpi,jpj):: p_fr2 ! 2nd fraction of qsr penetration in ice (T-point) [%]409 CHARACTER(len=1) , INTENT(in ):: cd_grid ! ice grid ( C or B-grid)410 INTEGER , INTENT(in ):: pdim ! number of ice categories398 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pst ! ice surface temperature (>0, =rt0 over land) [Kelvin] 399 REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: pui ! ice surface velocity (i- and i- components [m/s] 400 REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: pvi ! at I-point (B-grid) or U & V-point (C-grid) 401 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: palb ! ice albedo (clear sky) (alb_ice_cs) [%] 402 REAL(wp), DIMENSION(jpi,jpj), INTENT( out) :: p_taui ! i- & j-components of surface ice stress [N/m2] 403 REAL(wp), DIMENSION(jpi,jpj), INTENT( out) :: p_tauj ! at I-point (B-grid) or U & V-point (C-grid) 404 REAL(wp), DIMENSION(:,:,:) , INTENT( out) :: p_qns ! non solar heat flux over ice (T-point) [W/m2] 405 REAL(wp), DIMENSION(:,:,:) , INTENT( out) :: p_qsr ! solar heat flux over ice (T-point) [W/m2] 406 REAL(wp), DIMENSION(:,:,:) , INTENT( out) :: p_qla ! latent heat flux over ice (T-point) [W/m2] 407 REAL(wp), DIMENSION(:,:,:) , INTENT( out) :: p_dqns ! non solar heat sensistivity (T-point) [W/m2] 408 REAL(wp), DIMENSION(:,:,:) , INTENT( out) :: p_dqla ! latent heat sensistivity (T-point) [W/m2] 409 REAL(wp), DIMENSION(jpi,jpj), INTENT( out) :: p_tpr ! total precipitation (T-point) [Kg/m2/s] 410 REAL(wp), DIMENSION(jpi,jpj), INTENT( out) :: p_spr ! solid precipitation (T-point) [Kg/m2/s] 411 REAL(wp), DIMENSION(jpi,jpj), INTENT( out) :: p_fr1 ! 1sr fraction of qsr penetration in ice (T-point) [%] 412 REAL(wp), DIMENSION(jpi,jpj), INTENT( out) :: p_fr2 ! 2nd fraction of qsr penetration in ice (T-point) [%] 413 CHARACTER(len=1) , INTENT(in ) :: cd_grid ! ice grid ( C or B-grid) 414 INTEGER , INTENT(in ) :: pdim ! number of ice categories 411 415 !! 412 416 INTEGER :: ji, jj, jl ! dummy loop indices … … 414 418 REAL(wp) :: zst2, zst3 415 419 REAL(wp) :: zcoef_wnorm, zcoef_wnorm2, zcoef_dqlw, zcoef_dqla, zcoef_dqsb 420 REAL(wp) :: zztmp ! temporary variable 416 421 REAL(wp) :: zcoef_frca ! fractional cloud amount 417 422 REAL(wp) :: zwnorm_f, zwndi_f , zwndj_f ! relative wind module and components at F-point … … 427 432 428 433 ! local scalars ( place there for vector optimisation purposes) 429 zcoef_wnorm = rhoa * Cice434 zcoef_wnorm = rhoa * Cice 430 435 zcoef_wnorm2 = rhoa * Cice * 0.5 431 zcoef_dqlw = 4.0 * 0.95 * Stef432 zcoef_dqla = -Ls * Cice * 11637800. * (-5897.8)433 zcoef_dqsb = rhoa * cpa * Cice434 zcoef_frca = 1.0 - 0.3436 zcoef_dqlw = 4.0 * 0.95 * Stef 437 zcoef_dqla = -Ls * Cice * 11637800. * (-5897.8) 438 zcoef_dqsb = rhoa * cpa * Cice 439 zcoef_frca = 1.0 - 0.3 435 440 436 441 !!gm brutal.... … … 444 449 ! ----------------------------------------------------------------------------- ! 445 450 SELECT CASE( cd_grid ) 446 CASE( ' B' ) ! B-grid ice dynamics : I-point (i.e. F-point with sea-ice indexation)451 CASE( 'I' ) ! B-grid ice dynamics : I-point (i.e. F-point with sea-ice indexation) 447 452 ! and scalar wind at T-point ( = | U10m - U_ice | ) (masked) 448 453 !CDIR NOVERRCHK 449 454 DO jj = 2, jpjm1 450 DO ji = 2, jpim1 ! B grid : novector opt455 DO ji = 2, jpim1 ! B grid : NO vector opt 451 456 ! ... scalar wind at I-point (fld being at T-point) 452 zwndi_f = 0.25 * ( sf(jp_wndi)%fnow(ji-1,jj ) + sf(jp_wndi)%fnow(ji ,jj) &453 & + sf(jp_wndi)%fnow(ji-1,jj-1 ) + sf(jp_wndi)%fnow(ji ,jj-1) ) - pui(ji,jj)454 zwndj_f = 0.25 * ( sf(jp_wndj)%fnow(ji-1,jj ) + sf(jp_wndj)%fnow(ji ,jj) &455 & + sf(jp_wndj)%fnow(ji-1,jj-1 ) + sf(jp_wndj)%fnow(ji ,jj-1) ) - pvi(ji,jj)457 zwndi_f = 0.25 * ( sf(jp_wndi)%fnow(ji-1,jj ,1) + sf(jp_wndi)%fnow(ji ,jj ,1) & 458 & + sf(jp_wndi)%fnow(ji-1,jj-1,1) + sf(jp_wndi)%fnow(ji ,jj-1,1) ) - pui(ji,jj) 459 zwndj_f = 0.25 * ( sf(jp_wndj)%fnow(ji-1,jj ,1) + sf(jp_wndj)%fnow(ji ,jj ,1) & 460 & + sf(jp_wndj)%fnow(ji-1,jj-1,1) + sf(jp_wndj)%fnow(ji ,jj-1,1) ) - pvi(ji,jj) 456 461 zwnorm_f = zcoef_wnorm * SQRT( zwndi_f * zwndi_f + zwndj_f * zwndj_f ) 457 462 ! ... ice stress at I-point … … 459 464 p_tauj(ji,jj) = zwnorm_f * zwndj_f 460 465 ! ... scalar wind at T-point (fld being at T-point) 461 zwndi_t = sf(jp_wndi)%fnow(ji,jj ) - 0.25 * ( pui(ji,jj+1) + pui(ji+1,jj+1) &462 & + pui(ji,jj ) + pui(ji+1,jj ) )463 zwndj_t = sf(jp_wndj)%fnow(ji,jj ) - 0.25 * ( pvi(ji,jj+1) + pvi(ji+1,jj+1) &464 & + pvi(ji,jj ) + pvi(ji+1,jj ) )466 zwndi_t = sf(jp_wndi)%fnow(ji,jj,1) - 0.25 * ( pui(ji,jj+1) + pui(ji+1,jj+1) & 467 & + pui(ji,jj ) + pui(ji+1,jj ) ) 468 zwndj_t = sf(jp_wndj)%fnow(ji,jj,1) - 0.25 * ( pvi(ji,jj+1) + pvi(ji+1,jj+1) & 469 & + pvi(ji,jj ) + pvi(ji+1,jj ) ) 465 470 z_wnds_t(ji,jj) = SQRT( zwndi_t * zwndi_t + zwndj_t * zwndj_t ) * tmask(ji,jj,1) 466 471 END DO … … 476 481 DO jj = 2, jpj 477 482 DO ji = fs_2, jpi ! vect. opt. 478 zwndi_t = ( sf(jp_wndi)%fnow(ji,jj ) - 0.5 * ( pui(ji-1,jj ) + pui(ji,jj) ) )479 zwndj_t = ( sf(jp_wndj)%fnow(ji,jj ) - 0.5 * ( pvi(ji ,jj-1) + pvi(ji,jj) ) )483 zwndi_t = ( sf(jp_wndi)%fnow(ji,jj,1) - 0.5 * ( pui(ji-1,jj ) + pui(ji,jj) ) ) 484 zwndj_t = ( sf(jp_wndj)%fnow(ji,jj,1) - 0.5 * ( pvi(ji ,jj-1) + pvi(ji,jj) ) ) 480 485 z_wnds_t(ji,jj) = SQRT( zwndi_t * zwndi_t + zwndj_t * zwndj_t ) * tmask(ji,jj,1) 481 486 END DO … … 486 491 DO jj = 2, jpjm1 487 492 DO ji = fs_2, fs_jpim1 ! vect. opt. 488 p_taui(ji,jj) = zcoef_wnorm2 * ( z_wnds_t(ji+1,jj ) + z_wnds_t(ji,jj) ) &489 & * ( 0.5 * (sf(jp_wndi)%fnow(ji+1,jj ) + sf(jp_wndi)%fnow(ji,jj) ) - pui(ji,jj) )490 p_tauj(ji,jj) = zcoef_wnorm2 * ( z_wnds_t(ji,jj+1 ) + z_wnds_t(ji,jj) ) &491 & * ( 0.5 * (sf(jp_wndj)%fnow(ji,jj+1 ) + sf(jp_wndj)%fnow(ji,jj) ) - pvi(ji,jj) )493 p_taui(ji,jj) = zcoef_wnorm2 * ( z_wnds_t(ji+1,jj ) + z_wnds_t(ji,jj) ) & 494 & * ( 0.5 * (sf(jp_wndi)%fnow(ji+1,jj,1) + sf(jp_wndi)%fnow(ji,jj,1) ) - pui(ji,jj) ) 495 p_tauj(ji,jj) = zcoef_wnorm2 * ( z_wnds_t(ji,jj+1 ) + z_wnds_t(ji,jj) ) & 496 & * ( 0.5 * (sf(jp_wndj)%fnow(ji,jj+1,1) + sf(jp_wndj)%fnow(ji,jj,1) ) - pvi(ji,jj) ) 492 497 END DO 493 498 END DO … … 498 503 END SELECT 499 504 505 zztmp = 1. / ( 1. - albo ) 500 506 ! ! ========================== ! 501 507 DO jl = 1, ijpl ! Loop over ice categories ! … … 512 518 zst3 = pst(ji,jj,jl) * zst2 513 519 ! Short Wave (sw) 514 p_qsr(ji,jj,jl) = ( 1. - palb(ji,jj,jl) ) * sf(jp_qsr)%fnow(ji,jj) * tmask(ji,jj,1)520 p_qsr(ji,jj,jl) = zztmp * ( 1. - palb(ji,jj,jl) ) * qsr(ji,jj) 515 521 ! Long Wave (lw) 516 z_qlw(ji,jj,jl) = 0.95 * ( sf(jp_qlw)%fnow(ji,jj) & 517 & - Stef * pst(ji,jj,jl) * zst3 ) * tmask(ji,jj,1) 522 z_qlw(ji,jj,jl) = 0.95 * ( sf(jp_qlw)%fnow(ji,jj,1) - Stef * pst(ji,jj,jl) * zst3 ) * tmask(ji,jj,1) 518 523 ! lw sensitivity 519 524 z_dqlw(ji,jj,jl) = zcoef_dqlw * zst3 … … 525 530 ! ... turbulent heat fluxes 526 531 ! Sensible Heat 527 z_qsb(ji,jj,jl) = rhoa * cpa * Cice * z_wnds_t(ji,jj) * ( pst(ji,jj,jl) - sf(jp_tair)%fnow(ji,jj ) )532 z_qsb(ji,jj,jl) = rhoa * cpa * Cice * z_wnds_t(ji,jj) * ( pst(ji,jj,jl) - sf(jp_tair)%fnow(ji,jj,1) ) 528 533 ! Latent Heat 529 534 p_qla(ji,jj,jl) = MAX( 0.e0, rhoa * Ls * Cice * z_wnds_t(ji,jj) & 530 & * ( 11637800. * EXP( -5897.8 / pst(ji,jj,jl) ) / rhoa - sf(jp_humi)%fnow(ji,jj ) ) )535 & * ( 11637800. * EXP( -5897.8 / pst(ji,jj,jl) ) / rhoa - sf(jp_humi)%fnow(ji,jj,1) ) ) 531 536 ! Latent heat sensitivity for ice (Dqla/Dt) 532 537 p_dqla(ji,jj,jl) = zcoef_dqla * z_wnds_t(ji,jj) / ( zst2 ) * EXP( -5897.8 / pst(ji,jj,jl) ) … … 558 563 559 564 !CDIR COLLAPSE 560 p_tpr(:,:) = sf(jp_prec)%fnow(:,: ) * rn_pfac ! total precipitation [kg/m2/s]561 !CDIR COLLAPSE 562 p_spr(:,:) = sf(jp_snow)%fnow(:,: ) * rn_pfac ! solid precipitation [kg/m2/s]565 p_tpr(:,:) = sf(jp_prec)%fnow(:,:,1) * rn_pfac ! total precipitation [kg/m2/s] 566 !CDIR COLLAPSE 567 p_spr(:,:) = sf(jp_snow)%fnow(:,:,1) * rn_pfac ! solid precipitation [kg/m2/s] 563 568 CALL iom_put( 'snowpre', p_spr ) ! Snow precipitation 564 569 ! … … 597 602 !! 9.0 ! 05-08 (L. Brodeau) Rewriting and optimization 598 603 !!---------------------------------------------------------------------- 599 !! * Arguments600 601 604 REAL(wp), INTENT(in) :: zu ! altitude of wind measurement [m] 602 605 REAL(wp), INTENT(in), DIMENSION(jpi,jpj) :: & … … 638 641 grav = 9.8, & ! gravity 639 642 kappa = 0.4 ! von Karman s constant 640 643 !!---------------------------------------------------------------------- 641 644 !! * Start 642 645 !! Air/sea differences … … 762 765 grav = 9.8, & ! gravity 763 766 kappa = 0.4 ! von Karman's constant 764 767 !!---------------------------------------------------------------------- 765 768 !! * Start 766 769 -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbccpl.F90
r2090 r2528 4 4 !! Surface Boundary Condition : momentum, heat and freshwater fluxes in coupled mode 5 5 !!====================================================================== 6 !! History : 2.0 ! 06-2007(R. Redler, N. Keenlyside, W. Park) Original code split into flxmod & taumod7 !! 3.0 ! 02-2008(G. Madec, C Talandier) surface module8 !! 3.1 ! 02-2009(G. Madec, S. Masson, E. Maisonave, A. Caubel) generic coupled interface6 !! History : 2.0 ! 2007-06 (R. Redler, N. Keenlyside, W. Park) Original code split into flxmod & taumod 7 !! 3.0 ! 2008-02 (G. Madec, C Talandier) surface module 8 !! 3.1 ! 2009_02 (G. Madec, S. Masson, E. Maisonave, A. Caubel) generic coupled interface 9 9 !!---------------------------------------------------------------------- 10 10 #if defined key_oasis3 || defined key_oasis4 … … 23 23 USE sbc_oce ! Surface boundary condition: ocean fields 24 24 USE sbc_ice ! Surface boundary condition: ice fields 25 USE sbcdcy ! surface boundary condition: diurnal cycle 25 26 USE phycst ! physical constants 26 27 #if defined key_lim3 27 28 USE par_ice ! ice parameters 29 USE ice ! ice variables 28 30 #endif 29 31 #if defined key_lim2 … … 163 165 # include "vectopt_loop_substitute.h90" 164 166 !!---------------------------------------------------------------------- 165 !! NEMO/OPA 3. 0 , LOCEAN-IPSL (2008)167 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 166 168 !! $Id$ 167 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)169 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 168 170 !!---------------------------------------------------------------------- 169 171 … … 527 529 CALL cpl_prism_define(jprcv, jpsnd) 528 530 ! 531 IF( ln_dm2dc .AND. ( cpl_prism_freq( jpr_qsroce ) + cpl_prism_freq( jpr_qsrmix ) /= 86400 ) ) & 532 & CALL ctl_stop( 'sbc_cpl_init: diurnal cycle reconstruction (ln_dm2dc) needs daily couping for solar radiation' ) 533 529 534 END SUBROUTINE sbc_cpl_init 530 535 … … 728 733 IF( srcv(jpr_qsroce)%laction ) qsr(:,:) = frcv(:,:,jpr_qsroce) 729 734 IF( srcv(jpr_qsrmix)%laction ) qsr(:,:) = frcv(:,:,jpr_qsrmix) 735 IF( ln_dm2dc ) qsr(:,:) = sbc_dcy( qsr ) ! modify qsr to include the diurnal cycle 730 736 ! 731 737 ! ! total freshwater fluxes over the ocean (emp, emps) … … 783 789 !! ** Method : transform the received stress from the atmosphere into 784 790 !! an atmosphere-ice stress in the (i,j) ocean referencial 785 !! and at the velocity point of the sea-ice model (c igr_type):791 !! and at the velocity point of the sea-ice model (cp_ice_msh): 786 792 !! 'C'-grid : i- (j-) components given at U- (V-) point 787 !! ' B'-grid: both components given at I-point793 !! 'I'-grid : B-grid lower-left corner: both components given at I-point 788 794 !! 789 795 !! The received stress are : … … 798 804 !! first as 2 components on the sphere 799 805 !! second as 2 components oriented along the local grid 800 !! third as 2 components on the c igr_typepoint806 !! third as 2 components on the cp_ice_msh point 801 807 !! 802 808 !! In 'oce and ice' case, only one vector stress field … … 804 810 !! so that it is now defined as (i,j) components given at U- 805 811 !! and V-points, respectively. Therefore, here only the third 806 !! transformation is done and only if the ice-grid is a ' B'-grid.807 !! 808 !! ** Action : return ptau_i, ptau_j, the stress over the ice at c igr_typepoint812 !! transformation is done and only if the ice-grid is a 'I'-grid. 813 !! 814 !! ** Action : return ptau_i, ptau_j, the stress over the ice at cp_ice_msh point 809 815 !!---------------------------------------------------------------------- 810 816 REAL(wp), INTENT(out), DIMENSION(jpi,jpj) :: p_taui ! i- & j-components of atmos-ice stress [N/m2] … … 867 873 ! 868 874 ! j+1 j -----V---F 869 ! ice stress on ice velocity point (c igr_type)! |875 ! ice stress on ice velocity point (cp_ice_msh) ! | 870 876 ! (C-grid ==>(U,V) or B-grid ==> I or F) j | T U 871 877 ! | | … … 874 880 ! i-1 i i 875 881 ! i i+1 (for I) 876 SELECT CASE ( c igr_type)882 SELECT CASE ( cp_ice_msh ) 877 883 ! 878 884 CASE( 'I' ) ! B-grid ==> I … … 1159 1165 & + palbi (:,:,1) * zicefr(:,:,1) ) ) 1160 1166 END SELECT 1167 IF( ln_dm2dc ) THEN ! modify qsr to include the diurnal cycle 1168 pqsr_tot(:,: ) = sbc_dcy( pqsr_tot(:,: ) ) 1169 pqsr_ice(:,:,1) = sbc_dcy( pqsr_ice(:,:,1) ) 1170 ENDIF 1161 1171 1162 1172 SELECT CASE( TRIM( cn_rcv_dqnsdt ) ) … … 1249 1259 END DO 1250 1260 CASE( 'weighted oce and ice' ) 1251 SELECT CASE ( c igr_type)1261 SELECT CASE ( cp_ice_msh ) 1252 1262 CASE( 'C' ) ! Ocean and Ice on C-grid ==> T 1253 1263 DO jj = 2, jpjm1 … … 1284 1294 CALL lbc_lnk( zitx1, 'T', -1. ) ; CALL lbc_lnk( zity1, 'T', -1. ) 1285 1295 CASE( 'mixed oce-ice' ) 1286 SELECT CASE ( c igr_type)1296 SELECT CASE ( cp_ice_msh ) 1287 1297 CASE( 'C' ) ! Ocean and Ice on C-grid ==> T 1288 1298 DO jj = 2, jpjm1 -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcflx.F90
r1730 r2528 4 4 !! Ocean forcing: momentum, heat and freshwater flux formulation 5 5 !!===================================================================== 6 !! History : 9.0 ! 06-06 (G. Madec) Original code 6 !! History : 1.0 ! 2006-06 (G. Madec) Original code 7 !! 3.3 ! 2010-10 (S. Masson) add diurnal cycle 7 8 !!---------------------------------------------------------------------- 8 9 9 10 !!---------------------------------------------------------------------- 10 11 !! namflx : flux formulation namlist 11 !! sbc_flx : flux formulation as ocean surface boundary condition 12 !! (forced mode, fluxes read in NetCDF files) 13 !!---------------------------------------------------------------------- 14 !! question diverses 15 !! * ajouter un test sur la division entier de freqh et rdttra ??? 16 !! ** ajoute dans namelist: 1 year forcing files 17 !! or forcing file starts at the begining of the run 18 !! *** we assume that the forcing file start and end with the previous 19 !! year last record and the next year first record (useful for 20 !! time interpolation, required even if no time interp???) 21 !! * ajouter un test sur la division de la frequence en pas de temps 22 !! ==> daymod ajout de nsec_year = number of second since the begining of the year 23 !! assumed to be 0 at 0h january the 1st (i.e. 24h december the 31) 24 !! 25 !! *** regrouper dtatem et dtasal 12 !! sbc_flx : flux formulation as ocean surface boundary condition (forced mode, fluxes read in NetCDF files) 26 13 !!---------------------------------------------------------------------- 27 14 USE oce ! ocean dynamics and tracers 28 15 USE dom_oce ! ocean space and time domain 29 USE sbc_oce ! Surface boundary condition: ocean fields 16 USE sbc_oce ! surface boundary condition: ocean fields 17 USE sbcdcy ! surface boundary condition: diurnal cycle on qsr 30 18 USE phycst ! physical constants 31 19 USE fldread ! read input fields … … 52 40 # include "vectopt_loop_substitute.h90" 53 41 !!---------------------------------------------------------------------- 54 !! OPA 9.0 , LOCEAN-IPSL (2006)42 !! NEMO/OPA 3.3 , NEMO-consortium (2010) 55 43 !! $Id$ 56 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)44 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 57 45 !!---------------------------------------------------------------------- 58 59 46 CONTAINS 60 47 … … 98 85 NAMELIST/namsbc_flx/ cn_dir, sn_utau, sn_vtau, sn_qtot, sn_qsr, sn_emp 99 86 !!--------------------------------------------------------------------- 100 ! ! ====================== ! 101 IF( kt == nit000 ) THEN ! First call kt=nit000 ! 102 ! ! ====================== ! 87 ! 88 IF( kt == nit000 ) THEN ! First call kt=nit000 103 89 ! set file information 104 90 cn_dir = './' ! directory in which the model is executed 105 91 ! ... default values (NB: frequency positive => hours, negative => months) 106 ! ! file ! frequency ! variable ! time intep ! clim ! 'yearly' or ! weights ! rotation!107 ! ! name ! (hours) ! name ! (T/F) ! (T/F) ! 'monthly' ! filename ! pairs!108 sn_utau = FLD_N( 'utau' , 24 , 'utau' , .false. , .false. , 'yearly' , '' , '')109 sn_vtau = FLD_N( 'vtau' , 24 , 'vtau' , .false. , .false. , 'yearly' , '' , '')110 sn_qtot = FLD_N( 'qtot' , 24 , 'qtot' , .false. , .false. , 'yearly' , '' , '')111 sn_qsr = FLD_N( 'qsr' , 24 , 'qsr' , .false. , .false. , 'yearly' , '' , '')112 sn_emp = FLD_N( 'emp' , 24 , 'emp' , .false. , .false. , 'yearly' , '' , '')113 114 REWIND ( numnam ) ! ...read in namlist namflx92 ! ! file ! frequency ! variable ! time intep ! clim ! 'yearly' or ! weights ! rotation ! 93 ! ! name ! (hours) ! name ! (T/F) ! (T/F) ! 'monthly' ! filename ! pairs ! 94 sn_utau = FLD_N( 'utau' , 24 , 'utau' , .false. , .false. , 'yearly' , '' , '' ) 95 sn_vtau = FLD_N( 'vtau' , 24 , 'vtau' , .false. , .false. , 'yearly' , '' , '' ) 96 sn_qtot = FLD_N( 'qtot' , 24 , 'qtot' , .false. , .false. , 'yearly' , '' , '' ) 97 sn_qsr = FLD_N( 'qsr' , 24 , 'qsr' , .false. , .false. , 'yearly' , '' , '' ) 98 sn_emp = FLD_N( 'emp' , 24 , 'emp' , .false. , .false. , 'yearly' , '' , '' ) 99 ! 100 REWIND ( numnam ) ! read in namlist namflx 115 101 READ ( numnam, namsbc_flx ) 116 117 ! store namelist information in an array 102 ! 103 ! ! check: do we plan to use ln_dm2dc with non-daily forcing? 104 IF( ln_dm2dc .AND. sn_qsr%nfreqh /= 24 ) & 105 & CALL ctl_stop( 'sbc_blk_core: ln_dm2dc can be activated only with daily short-wave forcing' ) 106 ! 107 ! ! store namelist information in an array 118 108 slf_i(jp_utau) = sn_utau ; slf_i(jp_vtau) = sn_vtau 119 109 slf_i(jp_qtot) = sn_qtot ; slf_i(jp_qsr ) = sn_qsr 120 110 slf_i(jp_emp ) = sn_emp 121 122 ! set sf structure 123 ALLOCATE( sf(jpfld), STAT=ierror ) 111 ! 112 ALLOCATE( sf(jpfld), STAT=ierror ) ! set sf structure 124 113 IF( ierror > 0 ) THEN 125 114 CALL ctl_stop( 'sbc_flx: unable to allocate sf structure' ) ; RETURN 126 115 ENDIF 127 116 DO ji= 1, jpfld 128 ALLOCATE( sf(ji)%fnow(jpi,jpj ) )129 ALLOCATE( sf(ji)%fdta(jpi,jpj,2) )117 ALLOCATE( sf(ji)%fnow(jpi,jpj,1) ) 118 IF( slf_i(ji)%ln_tint ) ALLOCATE( sf(ji)%fdta(jpi,jpj,1,2) ) 130 119 END DO 131 132 133 ! fill sf with slf_i and control print 120 ! ! fill sf with slf_i and control print 134 121 CALL fld_fill( sf, slf_i, cn_dir, 'sbc_flx', 'flux formulation for ocean surface boundary condition', 'namsbc_flx' ) 135 122 ! 136 123 ENDIF 137 124 138 CALL fld_read( kt, nn_fsbc, sf ) ! Read input fields and provides the 139 ! ! input fields at the current time-step 125 CALL fld_read( kt, nn_fsbc, sf ) ! input fields provided at the current time-step 126 127 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN ! update ocean fluxes at each SBC frequency 140 128 141 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN142 !143 ! set the ocean fluxes from read fields129 IF( ln_dm2dc ) THEN ; qsr(:,:) = sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) ! modify now Qsr to include the diurnal cycle 130 ELSE ; qsr(:,:) = sf(jp_qsr)%fnow(:,:,1) 131 ENDIF 144 132 !CDIR COLLAPSE 145 DO jj = 1, jpj 133 DO jj = 1, jpj ! set the ocean fluxes from read fields 146 134 DO ji = 1, jpi 147 utau(ji,jj) = sf(jp_utau)%fnow(ji,jj) 148 vtau(ji,jj) = sf(jp_vtau)%fnow(ji,jj) 149 qns (ji,jj) = sf(jp_qtot)%fnow(ji,jj) - sf(jp_qsr)%fnow(ji,jj) 150 qsr (ji,jj) = sf(jp_qsr )%fnow(ji,jj) 151 emp (ji,jj) = sf(jp_emp )%fnow(ji,jj) 135 utau(ji,jj) = sf(jp_utau)%fnow(ji,jj,1) 136 vtau(ji,jj) = sf(jp_vtau)%fnow(ji,jj,1) 137 qns (ji,jj) = sf(jp_qtot)%fnow(ji,jj,1) - sf(jp_qsr)%fnow(ji,jj,1) 138 emp (ji,jj) = sf(jp_emp )%fnow(ji,jj,1) 152 139 END DO 153 140 END DO 154 155 ! module of wind stress and wind speed at T-point 156 zcoef = 1. / ( zrhoa * zcdrag ) 141 ! ! module of wind stress and wind speed at T-point 142 zcoef = 1. / ( zrhoa * zcdrag ) 157 143 !CDIR NOVERRCHK 158 144 DO jj = 2, jpjm1 … … 168 154 CALL lbc_lnk( taum(:,:), 'T', 1. ) ; CALL lbc_lnk( wndm(:,:), 'T', 1. ) 169 155 170 ! Initialization of emps (when no ice model) 171 emps(:,:) = emp (:,:) 156 emps(:,:) = emp (:,:) ! Initialization of emps (needed when no ice model) 172 157 173 ! control print (if less than 100 time-step asked) 174 IF( nitend-nit000 <= 100 .AND. lwp ) THEN 158 IF( nitend-nit000 <= 100 .AND. lwp ) THEN ! control print (if less than 100 time-step asked) 175 159 WRITE(numout,*) 176 160 WRITE(numout,*) ' read daily momentum, heat and freshwater fluxes OK' -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcfwb.F90
r2471 r2528 4 4 !! Ocean fluxes : domain averaged freshwater budget 5 5 !!====================================================================== 6 !! History : 8.2 !01-02 (E. Durand) Original code7 !! 8.5 !02-06 (G. Madec) F90: Free form and module8 !! 9.0 !06-08 (G. Madec) Surface module9 !! 9.2 !09-07 (C. Talandier) emp mean s spread over erp area6 !! History : OPA ! 2001-02 (E. Durand) Original code 7 !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module 8 !! 3.0 ! 2006-08 (G. Madec) Surface module 9 !! 3.2 ! 2009-07 (C. Talandier) emp mean s spread over erp area 10 10 !!---------------------------------------------------------------------- 11 11 … … 23 23 USE lib_mpp ! distribued memory computing library 24 24 USE lbclnk ! ocean lateral boundary conditions 25 USE lib_fortran 25 26 26 27 IMPLICIT NONE … … 31 32 REAL(wp) :: a_fwb_b ! annual domain averaged freshwater budget 32 33 REAL(wp) :: a_fwb ! for 2 year before (_b) and before year. 33 REAL(wp) :: empold ! empold to be suppressed34 REAL(wp) :: fwfold ! fwfold to be suppressed 34 35 REAL(wp) :: area ! global mean ocean surface (interior domain) 35 36 36 REAL(wp), DIMENSION(jpi,jpj) :: e1e2 _i ! area of the interior domain (e1t*e2t*tmask_i)37 REAL(wp), DIMENSION(jpi,jpj) :: e1e2 ! area of the interior domain (e1t*e2t) 37 38 38 39 !! * Substitutions … … 40 41 # include "vectopt_loop_substitute.h90" 41 42 !!---------------------------------------------------------------------- 42 !! OPA 9.0 , LOCEAN-IPSL (2006)43 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 43 44 !! $Id$ 44 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)45 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 45 46 !!---------------------------------------------------------------------- 46 47 CONTAINS … … 65 66 INTEGER :: inum ! temporary logical unit 66 67 INTEGER :: ikty, iyear ! 67 REAL(wp) :: z_ emp, z_emp_nsrf, zsum_emp, zsum_erp ! temporary scalars68 REAL(wp) :: z_fwf, z_fwf_nsrf, zsum_fwf, zsum_erp ! temporary scalars 68 69 REAL(wp) :: zsurf_neg, zsurf_pos, zsurf_tospread 69 70 REAL(wp), DIMENSION(jpi,jpj) :: ztmsk_neg, ztmsk_pos, ztmsk_tospread … … 72 73 ! 73 74 IF( kt == nit000 ) THEN 74 !75 75 IF(lwp) THEN 76 76 WRITE(numout,*) … … 79 79 IF( kn_fwb == 1 ) WRITE(numout,*) ' instantaneously set to zero' 80 80 IF( kn_fwb == 2 ) WRITE(numout,*) ' adjusted from previous year budget' 81 IF( kn_fwb == 3 ) WRITE(numout,*) ' empset to zero and spread out over erp area'81 IF( kn_fwb == 3 ) WRITE(numout,*) ' fwf set to zero and spread out over erp area' 82 82 ENDIF 83 83 ! 84 84 IF( kn_fwb == 3 .AND. nn_sssr /= 2 ) CALL ctl_stop( 'sbc_fwb: nn_fwb = 3 requires nn_sssr = 2, we stop ' ) 85 85 ! 86 e1e2_i(:,:) = e1t(:,:) * e2t(:,:) * tmask_i(:,:) 87 area = SUM( e1e2_i(:,:) ) 88 IF( lk_mpp ) CALL mpp_sum( area ) ! sum over the global domain 89 ! 86 e1e2(:,:) = e1t(:,:) * e2t(:,:) 87 area = glob_sum( e1e2(:,:) ) ! interior global domain surface 90 88 ENDIF 91 89 … … 93 91 SELECT CASE ( kn_fwb ) 94 92 ! 95 CASE ( 0 ) 96 WRITE(ctmp1,*)'sbc_fwb : nn_fwb = ', kn_fwb, ' is not yet associated to an option, choose either 1/2' 97 CALL ctl_stop( ctmp1 ) 93 CASE ( 1 ) !== global mean fwf set to zero ==! 98 94 ! 99 100 !101 CASE ( 1 ) ! global mean emp set to zero102 95 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN 103 z_emp = SUM( e1e2_i(:,:) * emp(:,:) ) / area 104 IF( lk_mpp ) CALL mpp_sum( z_emp ) ! sum over the global domain 105 emp (:,:) = emp (:,:) - z_emp 106 emps(:,:) = emps(:,:) - z_emp 96 z_fwf = glob_sum( e1e2(:,:) * ( emp(:,:) - rnf(:,:) ) ) / area ! sum over the global domain 97 emp (:,:) = emp (:,:) - z_fwf 98 emps(:,:) = emps(:,:) - z_fwf 107 99 ENDIF 108 100 ! 109 CASE ( 2 ) ! emp budget adjusted from the previous year110 ! initialisation111 IF( kt == nit000 ) THEN 112 ! Read the corrective factor on precipitations (empold)101 CASE ( 2 ) !== fwf budget adjusted from the previous year ==! 102 ! 103 IF( kt == nit000 ) THEN ! initialisation 104 ! ! Read the corrective factor on precipitations (fwfold) 113 105 CALL ctl_opn( inum, 'EMPave_old.dat', 'OLD', 'FORMATTED', 'SEQUENTIAL', -1, numout, .FALSE. ) 114 106 READ ( inum, "(24X,I8,2ES24.16)" ) iyear, a_fwb_b, a_fwb 115 107 CLOSE( inum ) 116 empold = a_fwb! current year freshwater budget correction117 ! ! estimate from the previous year budget108 fwfold = a_fwb ! current year freshwater budget correction 109 ! ! estimate from the previous year budget 118 110 IF(lwp)WRITE(numout,*) 119 IF(lwp)WRITE(numout,*)'sbc_fwb : year = ',iyear , ' freshwater budget correction = ', empold111 IF(lwp)WRITE(numout,*)'sbc_fwb : year = ',iyear , ' freshwater budget correction = ', fwfold 120 112 IF(lwp)WRITE(numout,*)' year = ',iyear-1, ' freshwater budget read = ', a_fwb 121 113 IF(lwp)WRITE(numout,*)' year = ',iyear-2, ' freshwater budget read = ', a_fwb_b 122 114 ENDIF 123 ! 124 ! Update empold if new year start 115 ! ! Update fwfold if new year start 125 116 ikty = 365 * 86400 / rdttra(1) !!bug use of 365 days leap year or 360d year !!!!!!! 126 117 IF( MOD( kt, ikty ) == 0 ) THEN 127 118 a_fwb_b = a_fwb 128 a_fwb = SUM( e1e2_i(:,:) * sshn(:,:) ) 129 IF( lk_mpp ) CALL mpp_sum( a_fwb ) ! sum over the global domain 119 a_fwb = glob_sum( e1e2(:,:) * sshn(:,:) ) ! sum over the global domain 130 120 a_fwb = a_fwb * 1.e+3 / ( area * 86400. * 365. ) ! convert in Kg/m3/s = mm/s 131 121 !!gm ! !!bug 365d year 132 empold = a_fwb! current year freshwater budget correction133 ! ! estimate from the previous year budget122 fwfold = a_fwb ! current year freshwater budget correction 123 ! ! estimate from the previous year budget 134 124 ENDIF 135 125 ! 136 ! correct the freshwater fluxes 137 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN 138 emp (:,:) = emp (:,:) + empold 139 emps(:,:) = emps(:,:) + empold 126 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN ! correct the freshwater fluxes 127 emp (:,:) = emp (:,:) + fwfold 128 emps(:,:) = emps(:,:) + fwfold 140 129 ENDIF 141 130 ! 142 ! save empold value in a file 143 IF( kt == nitend .AND. lwp ) THEN 131 IF( kt == nitend .AND. lwp ) THEN ! save fwfold value in a file 144 132 CALL ctl_opn( inum, 'EMPave.dat', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, numout, .FALSE., narea ) 145 133 WRITE( inum, "(24X,I8,2ES24.16)" ) nyear, a_fwb_b, a_fwb … … 147 135 ENDIF 148 136 ! 149 CASE ( 3 ) ! global emp set to zero and spread out over erp area137 CASE ( 3 ) !== global fwf set to zero and spread out over erp area ==! 150 138 ! 151 139 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN 152 ! Select <0 and >0 area of erp 153 ztmsk_pos(:,:) = tmask_i(:,:) 154 WHERE( erp < 0.e0 ) ztmsk_pos = 0.e0 140 ztmsk_pos(:,:) = tmask_i(:,:) ! Select <0 and >0 area of erp 141 WHERE( erp < 0._wp ) ztmsk_pos = 0._wp 155 142 ztmsk_neg(:,:) = tmask_i(:,:) - ztmsk_pos(:,:) 156 157 ! Area filled by <0 and >0 erp158 zsurf_neg = SUM( e1e2_i(:,:)*ztmsk_neg(:,:) )159 zsurf_pos = SUM( e1e2_i(:,:)*ztmsk_pos(:,:) )160 161 ! emp global mean162 z_emp = SUM( e1e2_i(:,:) * emp(:,:) ) / area163 143 ! 164 IF( lk_mpp ) CALL mpp_sum( z_emp )165 IF( lk_mpp ) CALL mpp_sum( zsurf_neg)166 IF( lk_mpp ) CALL mpp_sum( zsurf_pos )167 168 IF( z_emp < 0.e0 ) THEN169 ! to spread out over >0 erp area to increase evaporation damping process170 zsurf_tospread = zsurf_pos144 zsurf_neg = glob_sum( e1e2(:,:)*ztmsk_neg(:,:) ) ! Area filled by <0 and >0 erp 145 zsurf_pos = glob_sum( e1e2(:,:)*ztmsk_pos(:,:) ) 146 ! ! fwf global mean 147 z_fwf = glob_sum( e1e2(:,:) * ( emp(:,:) - rnf(:,:) ) ) / area 148 ! 149 IF( z_fwf < 0._wp ) THEN ! spread out over >0 erp area to increase evaporation 150 zsurf_tospread = zsurf_pos 171 151 ztmsk_tospread(:,:) = ztmsk_pos(:,:) 172 ELSE 173 ! to spread out over <0 erp area to increase precipitation damping process 174 zsurf_tospread = zsurf_neg 152 ELSE ! spread out over <0 erp area to increase precipitation 153 zsurf_tospread = zsurf_neg 175 154 ztmsk_tospread(:,:) = ztmsk_neg(:,:) 176 155 ENDIF 177 178 ! emp global mean over <0 or >0 erp area 179 zsum_emp = SUM( e1e2_i(:,:) * z_emp ) 180 IF( lk_mpp ) CALL mpp_sum( zsum_emp ) 181 z_emp_nsrf = zsum_emp / ( zsurf_tospread + rsmall ) 182 ! weight to respect erp field 2D structure 183 zsum_erp = SUM( ztmsk_tospread(:,:) * erp(:,:) * e1e2_i(:,:) ) 184 IF( lk_mpp ) CALL mpp_sum( zsum_erp ) 156 ! 157 zsum_fwf = glob_sum( e1e2(:,:) * z_fwf ) ! fwf global mean over <0 or >0 erp area 158 !!gm : zsum_fwf = z_fwf * area ??? it is right? I think so.... 159 z_fwf_nsrf = zsum_fwf / ( zsurf_tospread + rsmall ) 160 ! ! weight to respect erp field 2D structure 161 zsum_erp = glob_sum( ztmsk_tospread(:,:) * erp(:,:) * e1e2(:,:) ) 185 162 z_wgt(:,:) = ztmsk_tospread(:,:) * erp(:,:) / ( zsum_erp + rsmall ) 186 187 ! final correction term to apply188 zerp_cor(:,:) = -1. * z_emp_nsrf * zsurf_tospread * z_wgt(:,:)189 163 ! ! final correction term to apply 164 zerp_cor(:,:) = -1. * z_fwf_nsrf * zsurf_tospread * z_wgt(:,:) 165 ! 166 !!gm ===>>>> lbc_lnk should be useless as all the computation is done over the whole domain ! 190 167 CALL lbc_lnk( zerp_cor, 'T', 1. ) 191 168 ! 192 169 emp (:,:) = emp (:,:) + zerp_cor(:,:) 193 170 emps(:,:) = emps(:,:) + zerp_cor(:,:) 194 171 erp (:,:) = erp (:,:) + zerp_cor(:,:) 195 196 IF( nprint == 1 .AND. lwp ) THEN 197 IF( z_ emp < 0.e0) THEN198 WRITE(numout,*)' z_emp< 0'199 WRITE(numout,*)' SUM(erp+) = ', SUM( ztmsk_tospread(:,:)*erp(:,:)*e1e2_i(:,:) )*1.e-3,' m3.s-1'172 ! 173 IF( nprint == 1 .AND. lwp ) THEN ! control print 174 IF( z_fwf < 0._wp ) THEN 175 WRITE(numout,*)' z_fwf < 0' 176 WRITE(numout,*)' SUM(erp+) = ', SUM( ztmsk_tospread(:,:)*erp(:,:)*e1e2(:,:) )*1.e-9,' Sv' 200 177 ELSE 201 WRITE(numout,*)' z_emp>= 0'202 WRITE(numout,*)' SUM(erp-) = ', SUM( ztmsk_tospread(:,:)*erp(:,:)*e1e2_i(:,:) )*1.e-3,' m3.s-1'178 WRITE(numout,*)' z_fwf >= 0' 179 WRITE(numout,*)' SUM(erp-) = ', SUM( ztmsk_tospread(:,:)*erp(:,:)*e1e2(:,:) )*1.e-9,' Sv' 203 180 ENDIF 204 WRITE(numout,*)' SUM(empG) = ', SUM( z_emp*e1e2_i(:,:) )*1.e-3,' m3.s-1'205 WRITE(numout,*)' z_emp = ', z_emp ,' mm.s-1'206 WRITE(numout,*)' z_emp_nsrf = ', z_emp_nsrf ,' mm.s-1'207 WRITE(numout,*)' MIN(zerp_cor)= ', MINVAL(zerp_cor)208 WRITE(numout,*)' MAX(zerp_cor)= ', MAXVAL(zerp_cor)181 WRITE(numout,*)' SUM(empG) = ', SUM( z_fwf*e1e2(:,:) )*1.e-9,' Sv' 182 WRITE(numout,*)' z_fwf = ', z_fwf ,' Kg/m2/s' 183 WRITE(numout,*)' z_fwf_nsrf = ', z_fwf_nsrf ,' Kg/m2/s' 184 WRITE(numout,*)' MIN(zerp_cor) = ', MINVAL(zerp_cor) 185 WRITE(numout,*)' MAX(zerp_cor) = ', MAXVAL(zerp_cor) 209 186 ENDIF 210 !211 187 ENDIF 212 188 ! 213 CASE DEFAULT ! you should never be there 214 WRITE(ctmp1,*)'sbc_fwb : nn_fwb = ', kn_fwb, ' is not permitted for the FreshWater Budget correction, choose either 1/2' 215 CALL ctl_stop( ctmp1 ) 189 CASE DEFAULT !== you should never be there ==! 190 CALL ctl_stop( 'sbc_fwb : wrong nn_fwb value for the FreshWater Budget correction, choose either 1, 2 or 3' ) 216 191 ! 217 192 END SELECT -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcice_if.F90
r1730 r2528 30 30 # include "domzgr_substitute.h90" 31 31 !!---------------------------------------------------------------------- 32 !! NEMO/OPA 3. 0 , LOCEAN-IPSL (2008)32 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 33 33 !! $Id$ 34 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)34 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 35 35 !!---------------------------------------------------------------------- 36 36 … … 81 81 CALL ctl_stop( 'sbc_ice_if: unable to allocate sf_ice structure' ) ; RETURN 82 82 ENDIF 83 ALLOCATE( sf_ice(1)%fnow(jpi,jpj ) )84 ALLOCATE( sf_ice(1)%fdta(jpi,jpj,2) )83 ALLOCATE( sf_ice(1)%fnow(jpi,jpj,1) ) 84 IF( sn_ice%ln_tint ) ALLOCATE( sf_ice(1)%fdta(jpi,jpj,1,2) ) 85 85 86 86 … … 107 107 ! 108 108 zt_fzp = fr_i(ji,jj) ! freezing point temperature 109 zfr_obs = sf_ice(1)%fnow(ji,jj )! observed ice cover109 zfr_obs = sf_ice(1)%fnow(ji,jj,1) ! observed ice cover 110 110 ! ! ocean ice fraction (0/1) from the freezing point temperature 111 111 IF( sst_m(ji,jj) <= zt_fzp ) THEN ; fr_i(ji,jj) = 1.e0 -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcice_lim.F90
r1715 r2528 5 5 !! & covered area using LIM sea-ice model 6 6 !! Sea-Ice model : LIM 3.0 Sea ice model time-stepping 7 !!====================================================================== 8 !! History : 2.0 ! 2006-12 (M. Vancoppenolle) Original code 9 !! 3.0 ! 2008-02 (C. Talandier) Surface module from icestp.F90 10 !! 9.0 ! 2008-04 (G. Madec) sltyle and lim_ctl routine 7 !!===================================================================== 8 !! History : 2.0 ! 2006-12 (M. Vancoppenolle) Original code 9 !! 3.0 ! 2008-02 (C. Talandier) Surface module from icestp.F90 10 !! - ! 2008-04 (G. Madec) sltyle and lim_ctl routine 11 !! 3.3 ! 2010-11 (G. Madec) ice-ocean stress always computed at each ocean time-step 11 12 !!---------------------------------------------------------------------- 12 13 #if defined key_lim3 … … 19 20 !!---------------------------------------------------------------------- 20 21 USE oce ! ocean dynamics and tracers 21 USE c1d ! 1d configuration22 22 USE dom_oce ! ocean space and time domain 23 USE lib_mpp 23 USE lib_mpp ! MPP library 24 24 USE par_ice ! sea-ice parameters 25 USE ice 26 USE iceini 27 USE dom_ice 25 USE ice ! LIM-3: ice variables 26 USE iceini ! LIM-3: ice initialisation 27 USE dom_ice ! LIM-3: ice domain 28 28 29 29 USE sbc_oce ! Surface boundary condition: ocean fields … … 31 31 USE sbcblk_core ! Surface boundary condition: CORE bulk 32 32 USE sbcblk_clio ! Surface boundary condition: CLIO bulk 33 USE albedo 33 USE albedo ! ocean & ice albedo 34 34 35 35 USE phycst ! Define parameters for the routines … … 47 47 USE limvar ! Ice variables switch 48 48 49 USE lbclnk 49 USE c1d ! 1D vertical configuration 50 USE lbclnk ! lateral boundary condition - MPP link 50 51 USE iom ! I/O manager library 51 52 USE in_out_manager ! I/O manager … … 57 58 PUBLIC sbc_ice_lim ! routine called by sbcmod.F90 58 59 59 CHARACTER(len=1) :: cl_grid = 'C' ! type of grid used in ice dynamics60 61 60 !! * Substitutions 62 61 # include "domzgr_substitute.h90" 63 62 # include "vectopt_loop_substitute.h90" 64 63 !!---------------------------------------------------------------------- 65 !! NEMO/ LIM 3.0 , UCL-LOCEAN-IPSL (2008)64 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 66 65 !! $Id$ 67 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) 68 !!---------------------------------------------------------------------- 69 66 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 67 !!---------------------------------------------------------------------- 70 68 CONTAINS 71 69 72 SUBROUTINE sbc_ice_lim( kt, kblk , kico)70 SUBROUTINE sbc_ice_lim( kt, kblk ) 73 71 !!--------------------------------------------------------------------- 74 72 !! *** ROUTINE sbc_ice_lim *** … … 92 90 INTEGER, INTENT(in) :: kt ! ocean time step 93 91 INTEGER, INTENT(in) :: kblk ! type of bulk (=3 CLIO, =4 CORE) 94 INTEGER, INTENT(in) :: kico ! ice-ocean stress treatment95 92 !! 96 93 INTEGER :: jl ! loop index … … 143 140 & qla_ice , dqns_ice , dqla_ice , & 144 141 & tprecip , sprecip , & 145 & fr1_i0 , fr2_i0 , c l_grid, jpl )142 & fr1_i0 , fr2_i0 , cp_ice_msh, jpl ) 146 143 ! 147 144 CASE( 4 ) ! CORE bulk formulation … … 150 147 & qla_ice , dqns_ice , dqla_ice , & 151 148 & tprecip , sprecip , & 152 & fr1_i0 , fr2_i0 , c l_grid, jpl )149 & fr1_i0 , fr2_i0 , cp_ice_msh, jpl ) 153 150 END SELECT 154 151 … … 161 158 ! ! Store previous ice values 162 159 !!gm : remark old_... should becomes ...b as tn versus tb 163 old_a_i (:,:,:) = a_i(:,:,:) ! ice area164 old_e_i (:,:,:,:) = e_i(:,:,:,:) ! ice thermal energy165 old_v_i (:,:,:) = v_i(:,:,:) ! ice volume166 old_v_s (:,:,:) = v_s(:,:,:) ! snow volume167 old_e_s (:,:,:,:) = e_s(:,:,:,:) ! snow thermal energy168 old_smv_i(:,:,:) = smv_i(:,:,:)! salt content169 old_oa_i (:,:,:) = oa_i(:,:,:)! areal age content160 old_a_i (:,:,:) = a_i (:,:,:) ! ice area 161 old_e_i (:,:,:,:) = e_i (:,:,:,:) ! ice thermal energy 162 old_v_i (:,:,:) = v_i (:,:,:) ! ice volume 163 old_v_s (:,:,:) = v_s (:,:,:) ! snow volume 164 old_e_s (:,:,:,:) = e_s (:,:,:,:) ! snow thermal energy 165 old_smv_i(:,:,:) = smv_i(:,:,:) ! salt content 166 old_oa_i (:,:,:) = oa_i (:,:,:) ! areal age content 170 167 171 168 ! ! intialisation to zero !!gm is it truly necessary ??? 172 d_a_i_thd (:,:,:) = 0.e0 ; d_a_i_trp(:,:,:) = 0.e0173 d_v_i_thd (:,:,:) = 0.e0 ; d_v_i_trp(:,:,:) = 0.e0174 d_e_i_thd (:,:,:,:) = 0.e0 ; d_e_i_trp(:,:,:,:) = 0.e0175 d_v_s_thd (:,:,:) = 0.e0 ; d_v_s_trp(:,:,:) = 0.e0176 d_e_s_thd (:,:,:,:) = 0.e0 ; d_e_s_trp(:,:,:,:) = 0.e0177 d_smv_i_thd(:,:,:) = 0.e0 ; d_smv_i_trp(:,:,:)= 0.e0178 d_oa_i_thd (:,:,:) = 0.e0 ; d_oa_i_trp(:,:,:)= 0.e0179 ! 180 fseqv (:,:)= 0.e0181 fsbri (:,:) = 0.e0 ;fsalt_res(:,:) = 0.e0169 d_a_i_thd (:,:,:) = 0.e0 ; d_a_i_trp (:,:,:) = 0.e0 170 d_v_i_thd (:,:,:) = 0.e0 ; d_v_i_trp (:,:,:) = 0.e0 171 d_e_i_thd (:,:,:,:) = 0.e0 ; d_e_i_trp (:,:,:,:) = 0.e0 172 d_v_s_thd (:,:,:) = 0.e0 ; d_v_s_trp (:,:,:) = 0.e0 173 d_e_s_thd (:,:,:,:) = 0.e0 ; d_e_s_trp (:,:,:,:) = 0.e0 174 d_smv_i_thd(:,:,:) = 0.e0 ; d_smv_i_trp(:,:,:) = 0.e0 175 d_oa_i_thd (:,:,:) = 0.e0 ; d_oa_i_trp (:,:,:) = 0.e0 176 ! 177 fseqv (:,:) = 0.e0 178 fsbri (:,:) = 0.e0 ; fsalt_res(:,:) = 0.e0 182 179 fsalt_rpo(:,:) = 0.e0 183 fhmec (:,:) = 0.e0 ; fhbri(:,:)= 0.e0184 fmmec (:,:) = 0.e0 ;fheat_res(:,:) = 0.e0185 fheat_rpo(:,:) = 0.e0 ; focea2D(:,:)= 0.e0186 fsup2D (:,:)= 0.e0180 fhmec (:,:) = 0.e0 ; fhbri (:,:) = 0.e0 181 fmmec (:,:) = 0.e0 ; fheat_res(:,:) = 0.e0 182 fheat_rpo(:,:) = 0.e0 ; focea2D (:,:) = 0.e0 183 fsup2D (:,:) = 0.e0 187 184 ! 188 diag_sni_gr(:,:) = 0.e0 ; diag_lat_gr(:,:) = 0.e0189 diag_bot_gr(:,:) = 0.e0 ; diag_dyn_gr(:,:) = 0.e0190 diag_bot_me(:,:) = 0.e0 ; diag_sur_me(:,:) = 0.e0185 diag_sni_gr(:,:) = 0.e0 ; diag_lat_gr(:,:) = 0.e0 186 diag_bot_gr(:,:) = 0.e0 ; diag_dyn_gr(:,:) = 0.e0 187 diag_bot_me(:,:) = 0.e0 ; diag_sur_me(:,:) = 0.e0 191 188 ! dynamical invariants 192 delta_i(:,:) = 0.e0 ; divu_i (:,:) = 0.e0 ;shear_i(:,:) = 0.e0189 delta_i(:,:) = 0.e0 ; divu_i(:,:) = 0.e0 ; shear_i(:,:) = 0.e0 193 190 194 191 CALL lim_rst_opn( kt ) ! Open Ice restart file … … 196 193 IF( ln_nicep ) CALL lim_prt_state( jiindx, jjindx, 1, ' - Beginning the time step - ' ) ! control print 197 194 ! 198 IF( .NOT. lk_c1d ) THEN ! Ice dynamics & transport (not in 1D case) 195 IF( .NOT. lk_c1d ) THEN 196 ! Ice dynamics & transport (not in 1D case) 199 197 CALL lim_dyn( kt ) ! Ice dynamics ( rheology/dynamics ) 200 198 CALL lim_trp( kt ) ! Ice transport ( Advection/diffusion ) … … 204 202 CALL lim_itd_me ! Mechanical redistribution ! (ridging/rafting) 205 203 ENDIF 206 !207 204 ! ! Ice thermodynamics 208 205 CALL lim_var_glo2eqv ! equivalent variables … … 216 213 CALL lim_itd_th( kt ) ! Remap ice categories, lateral accretion ! 217 214 ! 218 ! ! Global variables update |215 ! ! Global variables update 219 216 CALL lim_var_agg( 1 ) ! requested by limupdate 220 217 CALL lim_update ! Global variables update … … 223 220 IF( ln_nicep ) CALL lim_prt_state( jiindx, jjindx, 2, ' - Final state - ' ) ! control print 224 221 ! 225 ! ! Fluxes of mass and heat to the ocean | 226 CALL lim_sbc_flx( kt ) ! Ice/Ocean heat freshwater/salt fluxes 227 IF( ln_limdyn .AND. kico == 0 ) & ! Ice/Ocean stresses (only in ice-dynamic case) 228 & CALL lim_sbc_tau( kt, kico ) ! otherwise the atm.-ocean stresses are used everywhere 222 CALL lim_sbc_flx( kt ) ! Update surface ocean mass, heat and salt fluxes 229 223 ! 230 224 IF( ln_nicep ) CALL lim_prt_state( jiindx, jjindx, 3, ' - Final state lim_sbc - ' ) ! control print … … 239 233 IF( ln_nicep ) CALL lim_ctl ! alerts in case of model crash 240 234 ! 241 ENDIF ! End sea-ice time step only 242 243 ! !--------------------------! 244 ! Ice/Ocean stresses (nn_ico_cpl=1 or 2 cases) ! at all ocean time step ! 245 ! !--------------------------! 246 IF( ln_limdyn .AND. kico /= 0 ) & 247 & CALL lim_sbc_tau( kt, kico ) 248 !!gm remark, in this case the ocean-ice stress is not saved in diag call above ..... find a solution!!! 235 ENDIF ! End sea-ice time step only 236 237 ! !--------------------------! 238 ! ! at all ocean time step ! 239 ! !--------------------------! 240 ! 241 ! ! Update surface ocean stresses (only in ice-dynamic case) 242 ! ! otherwise the atm.-ocean stresses are used everywhere 243 IF( ln_limdyn ) CALL lim_sbc_tau( kt, ub(:,:,1), vb(:,:,1) ) ! using before instantaneous surf. currents 244 245 !!gm remark, the ocean-ice stress is not saved in ice diag call above ..... find a solution!!! 249 246 ! 250 247 END SUBROUTINE sbc_ice_lim … … 664 661 !!---------------------------------------------------------------------- 665 662 CONTAINS 666 SUBROUTINE sbc_ice_lim ( kt, kblk , kico) ! Dummy routine667 WRITE(*,*) 'sbc_ice_lim: You should not have seen this print! error?', kt, kblk , kico663 SUBROUTINE sbc_ice_lim ( kt, kblk ) ! Dummy routine 664 WRITE(*,*) 'sbc_ice_lim: You should not have seen this print! error?', kt, kblk 668 665 END SUBROUTINE sbc_ice_lim 669 666 #endif -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcice_lim_2.F90
r2090 r2528 2 2 !!====================================================================== 3 3 !! *** MODULE sbcice_lim_2 *** 4 !! Surface module : update surface ocean boundary condition over ice 5 !! covered area using LIM sea-ice model 6 !! Sea-Ice model : LIM 2.0 Sea ice model time-stepping 4 !! Surface module : update surface ocean boundary condition over ice covered area using LIM sea-ice model 5 !! Sea-Ice model : LIM-2 Sea ice model time-stepping 7 6 !!====================================================================== 8 7 !! History : 1.0 ! 06-2006 (G. Madec) from icestp_2.F90 9 8 !! 3.0 ! 08-2008 (S. Masson, E. .... ) coupled interface 9 !! 3.3 ! 05-2009 (G.Garric) addition of the lim2_evp case 10 10 !!---------------------------------------------------------------------- 11 11 #if defined key_lim2 12 12 !!---------------------------------------------------------------------- 13 !! 'key_lim2' : LIM 2.0 sea-ice model 14 !!---------------------------------------------------------------------- 15 !! sbc_ice_lim_2 : sea-ice model time-stepping and 16 !! update ocean sbc over ice-covered area 17 !!---------------------------------------------------------------------- 18 USE oce ! ocean dynamics and tracers 19 USE c1d ! 1d configuration 20 USE dom_oce ! ocean space and time domain 21 USE lib_mpp 13 !! 'key_lim2' : LIM-2 sea-ice model 14 !!---------------------------------------------------------------------- 15 !! sbc_ice_lim_2 : sea-ice model time-stepping and update ocean sbc over ice-covered area 16 !!---------------------------------------------------------------------- 17 USE oce ! ocean dynamics and tracers 18 USE dom_oce ! ocean space and time domain 22 19 USE ice_2 23 20 USE par_ice_2 … … 25 22 USE dom_ice_2 26 23 27 USE sbc_oce ! Surface boundary condition: ocean fields28 USE sbc_ice ! Surface boundary condition: ice fields29 USE sbcblk_core ! Surface boundary condition: CORE bulk30 USE sbcblk_clio ! Surface boundary condition: CLIO bulk31 USE sbccpl ! Surface boundary condition: coupled interface24 USE sbc_oce ! Surface boundary condition: ocean fields 25 USE sbc_ice ! Surface boundary condition: ice fields 26 USE sbcblk_core ! Surface boundary condition: CORE bulk 27 USE sbcblk_clio ! Surface boundary condition: CLIO bulk 28 USE sbccpl ! Surface boundary condition: coupled interface 32 29 USE albedo 33 30 34 USE phycst ! Define parameters for the routines35 USE eosbn2 ! equation of state31 USE phycst ! Define parameters for the routines 32 USE eosbn2 ! equation of state 36 33 USE limdyn_2 37 34 USE limtrp_2 38 35 USE limdmp_2 39 36 USE limthd_2 40 USE limsbc_2 ! sea surface boundary condition37 USE limsbc_2 ! sea surface boundary condition 41 38 USE limdia_2 42 39 USE limwri_2 43 40 USE limrst_2 44 41 45 USE lbclnk 46 USE iom ! I/O manager library 47 USE in_out_manager ! I/O manager 48 USE prtctl ! Print control 42 USE c1d ! 1D vertical configuration 43 44 USE lbclnk ! lateral boundary condition - MPP link 45 USE lib_mpp ! MPP library 46 USE iom ! I/O manager library 47 USE in_out_manager ! I/O manager 48 USE prtctl ! Print control 49 49 50 50 IMPLICIT NONE … … 52 52 53 53 PUBLIC sbc_ice_lim_2 ! routine called by sbcmod.F90 54 55 CHARACTER(len=1) :: cl_grid = 'B' ! type of grid used in ice dynamics56 54 57 55 !! * Substitutions … … 59 57 # include "vectopt_loop_substitute.h90" 60 58 !!---------------------------------------------------------------------- 61 !! NEMO/ SBC 3.0 , LOCEAN-IPSL (2008)59 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 62 60 !! $Id$ 63 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) 64 !!---------------------------------------------------------------------- 65 61 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 62 !!---------------------------------------------------------------------- 66 63 CONTAINS 67 64 … … 99 96 IF(lwp) WRITE(numout,*) 'sbc_ice_lim_2 : update ocean surface boudary condition' 100 97 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~ via Louvain la Neuve Ice Model (LIM) time stepping' 101 98 ! 102 99 CALL ice_init_2 103 104 100 ENDIF 105 101 106 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN 107 ! 102 ! !----------------------! 103 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN ! Ice time-step only ! 104 ! !----------------------! 105 ! Bulk Formulea ! 106 !----------------! 108 107 ! ... mean surface ocean current at ice dynamics point 109 ! B-grid dynamics : I-point 110 DO jj = 2, jpj 111 DO ji = 2, jpi ! B grid : no vector opt. 112 u_oce(ji,jj) = 0.5 * ( ssu_m(ji-1,jj ) + ssu_m(ji-1,jj-1) ) * tmu(ji,jj) 113 v_oce(ji,jj) = 0.5 * ( ssv_m(ji ,jj-1) + ssv_m(ji-1,jj-1) ) * tmu(ji,jj) 108 SELECT CASE( cp_ice_msh ) 109 CASE( 'I' ) !== B-grid ice dynamics : I-point (i.e. F-point with sea-ice indexation) 110 DO jj = 2, jpj 111 DO ji = 2, jpi ! NO vector opt. possible 112 u_oce(ji,jj) = 0.5_wp * ( ssu_m(ji-1,jj ) + ssu_m(ji-1,jj-1) ) * tmu(ji,jj) 113 v_oce(ji,jj) = 0.5_wp * ( ssv_m(ji ,jj-1) + ssv_m(ji-1,jj-1) ) * tmu(ji,jj) 114 END DO 114 115 END DO 115 END DO 116 CALL lbc_lnk( u_oce, 'I', -1. ) ! I-point (i.e. F-point with ice indices) 117 CALL lbc_lnk( v_oce, 'I', -1. ) ! I-point (i.e. F-point with ice indices) 116 CALL lbc_lnk( u_oce, 'I', -1. ) ! I-point (i.e. F-point with ice indices) 117 CALL lbc_lnk( v_oce, 'I', -1. ) ! I-point (i.e. F-point with ice indices) 118 ! 119 CASE( 'C' ) !== C-grid ice dynamics : U & V-points (same as ocean) 120 u_oce(:,:) = ssu_m(:,:) ! mean surface ocean current at ice velocity point 121 v_oce(:,:) = ssv_m(:,:) 122 ! 123 END SELECT 118 124 119 125 ! ... masked sea surface freezing temperature [Kelvin] (set to rt0 over land) … … 144 150 & qla_ice , dqns_ice , dqla_ice , & 145 151 & tprecip , sprecip , & 146 & fr1_i0 , fr2_i0 , c l_grid, jpl )152 & fr1_i0 , fr2_i0 , cp_ice_msh , jpl ) 147 153 148 154 CASE( 4 ) ! CORE bulk formulation … … 151 157 & qla_ice , dqns_ice , dqla_ice , & 152 158 & tprecip , sprecip , & 153 & fr1_i0 , fr2_i0 , c l_grid, jpl )159 & fr1_i0 , fr2_i0 , cp_ice_msh , jpl ) 154 160 CASE( 5 ) ! Coupled formulation : atmosphere-ice stress only (fluxes provided after ice dynamics) 155 161 CALL sbc_cpl_ice_tau( utau_ice , vtau_ice ) … … 172 178 ! Ice model step ! 173 179 ! ---------------- ! 174 175 CALL lim_rst_opn_2 ( kt ) ! Open Ice restart file 176 IF( .NOT. lk_c1d ) THEN ! Ice dynamics & transport (not in 1D case) 177 CALL lim_dyn_2 ( kt ) ! Ice dynamics ( rheology/dynamics ) 178 CALL lim_trp_2 ( kt ) ! Ice transport ( Advection/diffusion ) 179 IF( ln_limdmp ) CALL lim_dmp_2 ( kt ) ! Ice damping 180 ENDIF 180 numit = numit + nn_fsbc ! Ice model time step 181 182 CALL lim_rst_opn_2 ( kt ) ! Open Ice restart file 183 IF( .NOT. lk_c1d ) THEN ! Ice dynamics & transport (except in 1D case) 184 CALL lim_dyn_2 ( kt ) ! Ice dynamics ( rheology/dynamics ) 185 CALL lim_trp_2 ( kt ) ! Ice transport ( Advection/diffusion ) 186 IF( ln_limdmp ) CALL lim_dmp_2 ( kt ) ! Ice damping 187 END IF 181 188 #if defined key_coupled 182 IF( ksbc == 5 ) CALL sbc_cpl_ice_flx( reshape( frld, (/jpi,jpj,1/) ), & 183 & qns_tot, qns_ice, qsr_tot , qsr_ice, & 184 & emp_tot, emp_ice, dqns_ice, sprecip, & 189 ! ! Ice surface fluxes in coupled mode 190 IF( ksbc == 5 ) CALL sbc_cpl_ice_flx( reshape( frld, (/jpi,jpj,1/) ), & 191 & qns_tot, qns_ice, qsr_tot , qsr_ice, & 192 & emp_tot, emp_ice, dqns_ice, sprecip, & 185 193 ! optional arguments, used only in 'mixed oce-ice' case 186 & 194 & palbi = zalb_ice_cs, psst = sst_m, pist = sist ) 187 195 #endif 188 189 CALL lim_sbc_2 ( kt ) ! Ice/Ocean Mass & Heat fluxes196 CALL lim_thd_2 ( kt ) ! Ice thermodynamics 197 CALL lim_sbc_flx_2 ( kt ) ! update surface ocean mass, heat & salt fluxes 190 198 191 199 IF( ( MOD( kt+nn_fsbc-1, ninfo ) == 0 .OR. ntmoy == 1 ) .AND. .NOT. lk_mpp ) & 192 & 200 & CALL lim_dia_2 ( kt ) ! Ice Diagnostics 193 201 # if ! defined key_iomput 194 202 CALL lim_wri_2 ( kt ) ! Ice outputs 195 203 # endif 196 IF( lrst_ice )CALL lim_rst_write_2( kt ) ! Ice restart file204 IF( lrst_ice ) CALL lim_rst_write_2( kt ) ! Ice restart file 197 205 ! 198 ENDIF 206 ENDIF ! End sea-ice time step only 207 ! 208 ! !--------------------------! 209 ! ! at all ocean time step ! 210 ! !--------------------------! 211 ! 212 ! ! Update surface ocean stresses (only in ice-dynamic case) 213 ! ! otherwise the atm.-ocean stresses are used everywhere 214 IF( ln_limdyn ) CALL lim_sbc_tau_2( kt, ub(:,:,1), vb(:,:,1) ) ! using before instantaneous surf. currents 199 215 ! 200 216 END SUBROUTINE sbc_ice_lim_2 -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcmod.F90
r2502 r2528 4 4 !! Surface module : provide to the ocean its surface boundary condition 5 5 !!====================================================================== 6 !! History : 3.0 ! 07-2006 (G. Madec) Original code 7 !! - ! 08-2008 (S. Masson, E. .... ) coupled interface 6 !! History : 3.0 ! 2006-07 (G. Madec) Original code 7 !! 3.1 ! 2008-08 (S. Masson, A. Caubel, E. Maisonnave, G. Madec) coupled interface 8 !! 3.3 ! 2010-04 (M. Leclair, G. Madec) Forcing averaged over 2 time steps 9 !! 3.3 ! 2010-10 (S. Masson) add diurnal cycle 10 !! 3.3 ! 2010-09 (D. Storkey) add ice boundary conditions (BDY) 11 !! - ! 2010-11 (G. Madec) ice-ocean stress always computed at each ocean time-step 12 !! - ! 2010-10 (J. Chanut, C. Bricaud, G. Madec) add the surface pressure forcing 8 13 !!---------------------------------------------------------------------- 9 14 … … 12 17 !! sbc : surface ocean momentum, heat and freshwater boundary conditions 13 18 !!---------------------------------------------------------------------- 14 USE oce ! ocean dynamics and tracers 15 USE dom_oce ! ocean space and time domain 16 USE phycst ! physical constants 17 18 USE sbc_oce ! Surface boundary condition: ocean fields 19 USE sbc_ice ! Surface boundary condition: ice fields 20 USE sbcssm ! surface boundary condition: sea-surface mean variables 21 USE sbcana ! surface boundary condition: analytical formulation 22 USE sbcflx ! surface boundary condition: flux formulation 23 USE sbcblk_clio ! surface boundary condition: bulk formulation : CLIO 24 USE sbcblk_core ! surface boundary condition: bulk formulation : CORE 25 USE sbcice_if ! surface boundary condition: ice-if sea-ice model 26 USE sbcice_lim ! surface boundary condition: LIM 3.0 sea-ice model 27 USE sbcice_lim_2 ! surface boundary condition: LIM 2.0 sea-ice model 28 USE sbccpl ! surface boundary condition: coupled florulation 19 USE oce ! ocean dynamics and tracers 20 USE dom_oce ! ocean space and time domain 21 USE phycst ! physical constants 22 USE sbc_oce ! Surface boundary condition: ocean fields 23 USE sbc_ice ! Surface boundary condition: ice fields 24 USE sbcdcy ! surface boundary condition: diurnal cycle 25 USE sbcssm ! surface boundary condition: sea-surface mean variables 26 USE sbcapr ! surface boundary condition: atmospheric pressure 27 USE sbcana ! surface boundary condition: analytical formulation 28 USE sbcflx ! surface boundary condition: flux formulation 29 USE sbcblk_clio ! surface boundary condition: bulk formulation : CLIO 30 USE sbcblk_core ! surface boundary condition: bulk formulation : CORE 31 USE sbcice_if ! surface boundary condition: ice-if sea-ice model 32 USE sbcice_lim ! surface boundary condition: LIM 3.0 sea-ice model 33 USE sbcice_lim_2 ! surface boundary condition: LIM 2.0 sea-ice model 34 USE sbccpl ! surface boundary condition: coupled florulation 29 35 USE cpl_oasis3, ONLY:lk_cpl ! are we in coupled mode? 30 USE sbcssr ! surface boundary condition: sea surface restoring 31 USE sbcrnf ! surface boundary condition: runoffs 32 USE sbcfwb ! surface boundary condition: freshwater budget 33 USE closea ! closed sea 34 35 USE prtctl ! Print control (prt_ctl routine) 36 USE restart ! ocean restart 37 USE iom 38 USE in_out_manager ! I/O manager 36 USE sbcssr ! surface boundary condition: sea surface restoring 37 USE sbcrnf ! surface boundary condition: runoffs 38 USE sbcfwb ! surface boundary condition: freshwater budget 39 USE closea ! closed sea 40 USE bdy_par ! unstructured open boundary data variables 41 USE bdyice ! unstructured open boundary data (bdy_ice_frs routine) 42 43 USE prtctl ! Print control (prt_ctl routine) 44 USE restart ! ocean restart 45 USE iom ! IOM library 46 USE in_out_manager ! I/O manager 39 47 40 48 IMPLICIT NONE … … 49 57 # include "domzgr_substitute.h90" 50 58 !!---------------------------------------------------------------------- 51 !! NEMO/OPA 3. 0 , LOCEAN-IPSL (2008)59 !! NEMO/OPA 3.3 , NEMO-consortium (2010) 52 60 !! $Id$ 53 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt) 54 !!---------------------------------------------------------------------- 55 61 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 62 !!---------------------------------------------------------------------- 56 63 CONTAINS 57 64 … … 69 76 INTEGER :: icpt ! temporary integer 70 77 !! 71 NAMELIST/namsbc/ nn_fsbc, ln_ana , ln_flx, ln_blk_clio, ln_blk_core, ln_cpl, &72 & nn_ice , ln_dm2dc, ln_rnf, ln_ssr, nn_fwb, nn_ico_cpl78 NAMELIST/namsbc/ nn_fsbc, ln_ana , ln_flx, ln_blk_clio, ln_blk_core, ln_cpl , & 79 & ln_apr_dyn, nn_ice , ln_dm2dc, ln_rnf, ln_ssr , nn_fwb 73 80 !!---------------------------------------------------------------------- 74 81 … … 79 86 ENDIF 80 87 81 REWIND( numnam ) 88 REWIND( numnam ) ! Read Namelist namsbc 82 89 READ ( numnam, namsbc ) 83 90 84 ! overwrite namelist parameter using CPP key information 85 !!gm here no overwrite, test all option via namelist change: require more incore memory 86 !!gm IF( lk_sbc_cpl ) THEN ; ln_cpl = .TRUE. ; ELSE ; ln_cpl = .FALSE. ; ENDIF 87 88 IF ( Agrif_Root() ) THEN 89 IF( lk_lim2 ) nn_ice = 2 90 IF( lk_lim3 ) nn_ice = 3 91 ENDIF 92 ! 93 IF( cp_cfg == 'gyre' ) THEN 91 ! ! overwrite namelist parameter using CPP key information 92 IF( Agrif_Root() ) THEN ! AGRIF zoom 93 IF( lk_lim2 ) nn_ice = 2 94 IF( lk_lim3 ) nn_ice = 3 95 ENDIF 96 IF( cp_cfg == 'gyre' ) THEN ! GYRE configuration 94 97 ln_ana = .TRUE. 95 98 nn_ice = 0 96 99 ENDIF 97 100 98 ! Control print 99 IF(lwp) THEN 101 IF(lwp) THEN ! Control print 100 102 WRITE(numout,*) ' Namelist namsbc (partly overwritten with CPP key setting)' 101 103 WRITE(numout,*) ' frequency update of sbc (and ice) nn_fsbc = ', nn_fsbc … … 107 109 WRITE(numout,*) ' coupled formulation (T if key_sbc_cpl) ln_cpl = ', ln_cpl 108 110 WRITE(numout,*) ' Misc. options of sbc : ' 111 WRITE(numout,*) ' Patm gradient added in ocean & ice Eqs. ln_apr_dyn = ', ln_apr_dyn 109 112 WRITE(numout,*) ' ice management in the sbc (=0/1/2/3) nn_ice = ', nn_ice 110 WRITE(numout,*) ' ice-ocean stress computation (=0/1/2) nn_ico_cpl = ', nn_ico_cpl111 113 WRITE(numout,*) ' daily mean to diurnal cycle qsr ln_dm2dc = ', ln_dm2dc 112 114 WRITE(numout,*) ' runoff / runoff mouths ln_rnf = ', ln_rnf … … 116 118 ENDIF 117 119 120 ! ! Checks: 118 121 IF( .NOT. ln_rnf ) THEN ! no specific treatment in vicinity of river mouths 119 122 ln_rnf_mouth = .false. 120 123 nkrnf = 0 124 rnf (:,:) = 0.e0 121 125 rnfmsk (:,:) = 0.e0 122 126 rnfmsk_z(:) = 0.e0 … … 138 142 & CALL ctl_stop( 'sea-ice model requires a bulk formulation or coupled configuration' ) 139 143 140 ! Choice of the Surface Boudary Condition (set nsbc) 144 IF( ln_dm2dc ) nday_qsr = -1 ! initialisation flag 145 146 IF( ln_dm2dc .AND. .NOT.( ln_flx .OR. ln_blk_core ) ) & 147 & CALL ctl_stop( 'diurnal cycle into qsr field from daily values requires a flux or core-bulk formulation' ) 148 149 IF( ln_dm2dc .AND. ( ( NINT(rday) / ( nn_fsbc * NINT(rdt) ) ) < 8 ) ) & 150 & CALL ctl_warn( 'diurnal cycle for qsr: the sampling of the diurnal cycle is too small...' ) 151 152 ! ! Choice of the Surface Boudary Condition (set nsbc) 141 153 icpt = 0 142 154 IF( ln_ana ) THEN ; nsbc = 1 ; icpt = icpt + 1 ; ENDIF ! analytical formulation … … 147 159 IF( cp_cfg == 'gyre') THEN ; nsbc = 0 ; ENDIF ! GYRE analytical formulation 148 160 IF( lk_esopa ) nsbc = -1 ! esopa test, ALL formulations 149 161 ! 150 162 IF( icpt /= 1 .AND. .NOT.lk_esopa ) THEN 151 163 WRITE(numout,*) … … 179 191 !! CAUTION : never mask the surface stress field (tke sbc) 180 192 !! 181 !! ** Action : - set the ocean surface boundary condition, i.e. 182 !! utau, vtau, qns, qsr, emp, emps, qrp, erp 193 !! ** Action : - set the ocean surface boundary condition at before and now 194 !! time step, i.e. 195 !! utau_b, vtau_b, qns_b, qsr_b, emp_n, emps_b, qrp_b, erp_b 196 !! utau , vtau , qns , qsr , emp , emps , qrp , erp 183 197 !! - updte the ice fraction : fr_i 184 198 !!---------------------------------------------------------------------- … … 186 200 !!--------------------------------------------------------------------- 187 201 188 CALL iom_setkt( kt + nn_fsbc - 1 ) ! in sbc, iom_put is called every nn_fsbc time step 189 ! 190 ! ocean to sbc mean sea surface variables (ss._m) 191 ! --------------------------------------- 192 CALL sbc_ssm( kt ) ! sea surface mean currents (at U- and V-points), 193 ! ! temperature and salinity (at T-point) over nf_sbc time-step 194 ! ! (i.e. sst_m, sss_m, ssu_m, ssv_m) 195 196 ! sbc formulation 197 ! --------------- 198 199 SELECT CASE( nsbc ) ! Compute ocean surface boundary condition 200 ! ! (i.e. utau,vtau, qns, qsr, emp, emps) 202 ! ! ---------------------------------------- ! 203 IF( kt /= nit000 ) THEN ! Swap of forcing fields ! 204 ! ! ---------------------------------------- ! 205 utau_b(:,:) = utau(:,:) ! Swap the ocean forcing fields 206 vtau_b(:,:) = vtau(:,:) ! (except at nit000 where before fields 207 qns_b (:,:) = qns (:,:) ! are set at the end of the routine) 208 ! The 3D heat content due to qsr forcing is treated in traqsr 209 ! qsr_b (:,:) = qsr (:,:) 210 emp_b (:,:) = emp (:,:) 211 emps_b(:,:) = emps(:,:) 212 ENDIF 213 ! ! ---------------------------------------- ! 214 ! ! forcing field computation ! 215 ! ! ---------------------------------------- ! 216 217 CALL iom_setkt( kt + nn_fsbc - 1 ) ! in sbc, iom_put is called every nn_fsbc time step 218 ! 219 IF( ln_apr_dyn ) CALL sbc_apr( kt ) ! atmospheric pressure provided at kt+0.5*nn_fsbc 220 ! (caution called before sbc_ssm) 221 ! 222 CALL sbc_ssm( kt ) ! ocean sea surface variables (sst_m, sss_m, ssu_m, ssv_m) 223 ! ! averaged over nf_sbc time-step 224 225 !== sbc formulation ==! 226 227 SELECT CASE( nsbc ) ! Compute ocean surface boundary condition 228 ! ! (i.e. utau,vtau, qns, qsr, emp, emps) 201 229 CASE( 0 ) ; CALL sbc_gyre ( kt ) ! analytical formulation : GYRE configuration 202 230 CASE( 1 ) ; CALL sbc_ana ( kt ) ! analytical formulation : uniform sbc … … 214 242 END SELECT 215 243 216 ! Misc. Options 217 ! ------------- 218 219 !!gm IF( ln_dm2dc ) CALL sbc_dcy( kt ) ! Daily mean qsr distributed over the Diurnal Cycle 244 ! !== Misc. Options ==! 220 245 221 246 SELECT CASE( nn_ice ) ! Update heat and freshwater fluxes over sea-ice areas 222 CASE( 1 ) ; CALL sbc_ice_if ( kt ) 247 CASE( 1 ) ; CALL sbc_ice_if ( kt ) ! Ice-cover climatology ("Ice-if" model) 223 248 ! 224 CASE( 2 ) ; CALL sbc_ice_lim_2( kt, nsbc ) ! LIM 2.0 ice model 249 CASE( 2 ) ; CALL sbc_ice_lim_2( kt, nsbc ) ! LIM-2 ice model 250 IF( lk_bdy ) CALL bdy_ice_frs ( kt ) ! BDY boundary condition 225 251 ! 226 CASE( 3 ) ; CALL sbc_ice_lim ( kt, nsbc , nn_ico_cpl) ! LIM 3.0ice model252 CASE( 3 ) ; CALL sbc_ice_lim ( kt, nsbc ) ! LIM-3 ice model 227 253 END SELECT 228 254 … … 235 261 IF( nclosea == 1 ) CALL sbc_clo( kt ) ! treatment of closed sea in the model domain 236 262 ! ! (update freshwater fluxes) 237 !238 263 !RBbug do not understand why see ticket 667 239 CALL lbc_lnk( emp, 'T', 1. ) 240 ! 264 CALL lbc_lnk( emp, 'T', 1. ) 265 ! 266 IF( kt == nit000 ) THEN ! set the forcing field at nit000 - 1 ! 267 ! ! ---------------------------------------- ! 268 IF( ln_rstart .AND. & !* Restart: read in restart file 269 & iom_varid( numror, 'utau_b', ldstop = .FALSE. ) > 0 ) THEN 270 IF(lwp) WRITE(numout,*) ' nit000-1 surface forcing fields red in the restart file' 271 CALL iom_get( numror, jpdom_autoglo, 'utau_b', utau_b ) ! before i-stress (U-point) 272 CALL iom_get( numror, jpdom_autoglo, 'vtau_b', vtau_b ) ! before j-stress (V-point) 273 CALL iom_get( numror, jpdom_autoglo, 'qns_b' , qns_b ) ! before non solar heat flux (T-point) 274 ! The 3D heat content due to qsr forcing is treated in traqsr 275 ! CALL iom_get( numror, jpdom_autoglo, 'qsr_b' , qsr_b ) ! before solar heat flux (T-point) 276 CALL iom_get( numror, jpdom_autoglo, 'emp_b' , emp_b ) ! before freshwater flux (T-point) 277 CALL iom_get( numror, jpdom_autoglo, 'emps_b', emps_b ) ! before C/D freshwater flux (T-point) 278 ELSE !* no restart: set from nit000 values 279 IF(lwp) WRITE(numout,*) ' nit000-1 surface forcing fields set to nit000' 280 utau_b(:,:) = utau(:,:) 281 vtau_b(:,:) = vtau(:,:) 282 qns_b (:,:) = qns (:,:) 283 ! qsr_b (:,:) = qsr (:,:) 284 emp_b (:,:) = emp (:,:) 285 emps_b(:,:) = emps(:,:) 286 ENDIF 287 ENDIF 288 ! ! ---------------------------------------- ! 289 IF( lrst_oce ) THEN ! Write in the ocean restart file ! 290 ! ! ---------------------------------------- ! 291 IF(lwp) WRITE(numout,*) 292 IF(lwp) WRITE(numout,*) 'sbc : ocean surface forcing fields written in ocean restart file ', & 293 & 'at it= ', kt,' date= ', ndastp 294 IF(lwp) WRITE(numout,*) '~~~~' 295 CALL iom_rstput( kt, nitrst, numrow, 'utau_b' , utau ) 296 CALL iom_rstput( kt, nitrst, numrow, 'vtau_b' , vtau ) 297 CALL iom_rstput( kt, nitrst, numrow, 'qns_b' , qns ) 298 ! The 3D heat content due to qsr forcing is treated in traqsr 299 ! CALL iom_rstput( kt, nitrst, numrow, 'qsr_b' , qsr ) 300 CALL iom_rstput( kt, nitrst, numrow, 'emp_b' , emp ) 301 CALL iom_rstput( kt, nitrst, numrow, 'emps_b' , emps ) 302 ENDIF 303 304 ! ! ---------------------------------------- ! 305 ! ! Outputs and control print ! 306 ! ! ---------------------------------------- ! 241 307 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN 242 CALL iom_put( "emp " , emp) ! upward water flux243 CALL iom_put( "emps " , emps) ! c/d water flux244 CALL iom_put( "qns+qsr" , qns + qsr ) ! total heat flux (caution if ln_dm2dc=true, to be245 CALL iom_put( "qns" , qns ) ! solar heat flux moved after the call to iom_setkt)246 CALL iom_put( "qsr" , qsr ) ! solar heat flux moved after the call to iom_setkt)247 IF( nn_ice > 0 ) CALL iom_put( "ice_cover", fr_i )! ice fraction308 CALL iom_put( "emp-rnf" , emp - rnf ) ! upward water flux 309 CALL iom_put( "emps-rnf", emps - rnf ) ! c/d water flux 310 CALL iom_put( "qns+qsr" , qns + qsr ) ! total heat flux 311 CALL iom_put( "qns" , qns ) ! solar heat flux 312 CALL iom_put( "qsr" , qsr ) ! solar heat flux 313 IF( nn_ice > 0 ) CALL iom_put( "ice_cover", fr_i ) ! ice fraction 248 314 ENDIF 249 315 ! … … 256 322 ! 257 323 IF(ln_ctl) THEN ! print mean trends (used for debugging) 258 CALL prt_ctl(tab2d_1=fr_i , clinfo1=' fr_i- : ', mask1=tmask, ovlap=1 )259 CALL prt_ctl(tab2d_1= emp , clinfo1=' emp- : ', mask1=tmask, ovlap=1 )260 CALL prt_ctl(tab2d_1= emps , clinfo1=' emps- : ', mask1=tmask, ovlap=1 )261 CALL prt_ctl(tab2d_1=qns , clinfo1=' qns- : ', mask1=tmask, ovlap=1 )262 CALL prt_ctl(tab2d_1=qsr , clinfo1=' qsr- : ', mask1=tmask, ovlap=1 )263 CALL prt_ctl(tab3d_1=tmask , clinfo1=' tmask: ', mask1=tmask, ovlap=1, kdim=jpk )264 CALL prt_ctl(tab3d_1=tn , clinfo1=' sst- : ', mask1=tmask, ovlap=1, kdim=1 )265 CALL prt_ctl(tab3d_1=sn , clinfo1=' sss- : ', mask1=tmask, ovlap=1, kdim=1 )266 CALL prt_ctl(tab2d_1=utau , clinfo1=' utau- : ', mask1=umask, &267 & tab2d_2=vtau , clinfo2=' vtau- : ', mask2=vmask, ovlap=1 )324 CALL prt_ctl(tab2d_1=fr_i , clinfo1=' fr_i - : ', mask1=tmask, ovlap=1 ) 325 CALL prt_ctl(tab2d_1=(emp-rnf) , clinfo1=' emp-rnf - : ', mask1=tmask, ovlap=1 ) 326 CALL prt_ctl(tab2d_1=(emps-rnf), clinfo1=' emps-rnf - : ', mask1=tmask, ovlap=1 ) 327 CALL prt_ctl(tab2d_1=qns , clinfo1=' qns - : ', mask1=tmask, ovlap=1 ) 328 CALL prt_ctl(tab2d_1=qsr , clinfo1=' qsr - : ', mask1=tmask, ovlap=1 ) 329 CALL prt_ctl(tab3d_1=tmask , clinfo1=' tmask - : ', mask1=tmask, ovlap=1, kdim=jpk ) 330 CALL prt_ctl(tab3d_1=tn , clinfo1=' sst - : ', mask1=tmask, ovlap=1, kdim=1 ) 331 CALL prt_ctl(tab3d_1=sn , clinfo1=' sss - : ', mask1=tmask, ovlap=1, kdim=1 ) 332 CALL prt_ctl(tab2d_1=utau , clinfo1=' utau - : ', mask1=umask, & 333 & tab2d_2=vtau , clinfo2=' vtau - : ', mask2=vmask, ovlap=1 ) 268 334 ENDIF 269 335 ! -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcrnf.F90
r1730 r2528 4 4 !! Ocean forcing: river runoff 5 5 !!===================================================================== 6 !! History : OPA ! 2000-11 (R. Hordoir, E. Durand) NetCDF FORMAT 7 !! NEMO 1.0 ! 2002-09 (G. Madec) F90: Free form and module 8 !! 3.0 ! 2006-07 (G. Madec) Surface module 9 !! 3.2 ! 2009-04 (B. Lemaire) Introduce iom_put 6 !! History : OPA ! 2000-11 (R. Hordoir, E. Durand) NetCDF FORMAT 7 !! NEMO 1.0 ! 2002-09 (G. Madec) F90: Free form and module 8 !! 3.0 ! 2006-07 (G. Madec) Surface module 9 !! 3.2 ! 2009-04 (B. Lemaire) Introduce iom_put 10 !! 3.3 ! 2010-10 (R. Furner, G. Madec) runoff distributed over ocean levels 10 11 !!---------------------------------------------------------------------- 11 12 … … 18 19 USE phycst ! physical constants 19 20 USE sbc_oce ! surface boundary condition variables 20 USE fldread ! ???21 USE fldread ! read input field at current time step 21 22 USE in_out_manager ! I/O manager 22 23 USE iom ! I/O module 24 USE restart ! restart 25 USE closea ! closed seas 23 26 24 27 IMPLICIT NONE 25 28 PRIVATE 26 29 27 PUBLIC sbc_rnf ! routine call in step module 28 29 ! !!* namsbc_rnf namelist * 30 PUBLIC sbc_rnf ! routine call in sbcmod module 31 PUBLIC sbc_rnf_div ! routine called in sshwzv module 32 33 ! !!* namsbc_rnf namelist * 30 34 CHARACTER(len=100), PUBLIC :: cn_dir = './' !: Root directory for location of ssr files 35 LOGICAL , PUBLIC :: ln_rnf_depth = .false. !: depth river runoffs attribute specified in a file 36 LOGICAL , PUBLIC :: ln_rnf_tem = .false. !: temperature river runoffs attribute specified in a file 37 LOGICAL , PUBLIC :: ln_rnf_sal = .false. !: salinity river runoffs attribute specified in a file 31 38 LOGICAL , PUBLIC :: ln_rnf_emp = .false. !: runoffs into a file to be read or already into precipitation 32 39 TYPE(FLD_N) , PUBLIC :: sn_rnf !: information about the runoff file to be read 33 40 TYPE(FLD_N) , PUBLIC :: sn_cnf !: information about the runoff mouth file to be read 41 TYPE(FLD_N) :: sn_s_rnf !: information about the salinities of runoff file to be read 42 TYPE(FLD_N) :: sn_t_rnf !: information about the temperatures of runoff file to be read 43 TYPE(FLD_N) :: sn_dep_rnf !: information about the depth which river inflow affects 34 44 LOGICAL , PUBLIC :: ln_rnf_mouth = .false. !: specific treatment in mouths vicinity 35 REAL(wp) , PUBLIC :: rn_hrnf = 0.e0 !: runoffs, depth over which enhanced vertical mixing is used 36 REAL(wp) , PUBLIC :: rn_avt_rnf = 0.e0 !: runoffs, value of the additional vertical mixing coef. [m2/s] 37 REAL(wp) , PUBLIC :: rn_rfact = 1.e0 !: multiplicative factor for runoff 38 39 INTEGER , PUBLIC :: nkrnf = 0 !: number of levels over which Kz is increased at river mouths 40 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: rnfmsk !: river mouth mask (hori.) 41 REAL(wp), PUBLIC, DIMENSION(jpk) :: rnfmsk_z !: river mouth mask (vert.) 42 43 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_rnf ! structure of input SST (file information, fields read) 44 45 REAL(wp) , PUBLIC :: rn_hrnf = 0._wp !: runoffs, depth over which enhanced vertical mixing is used 46 REAL(wp) , PUBLIC :: rn_avt_rnf = 0._wp !: runoffs, value of the additional vertical mixing coef. [m2/s] 47 REAL(wp) , PUBLIC :: rn_rfact = 1._wp !: multiplicative factor for runoff 48 49 INTEGER , PUBLIC :: nkrnf = 0 !: nb of levels over which Kz is increased at river mouths 50 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: rnfmsk !: river mouth mask (hori.) 51 REAL(wp), PUBLIC, DIMENSION(jpk) :: rnfmsk_z !: river mouth mask (vert.) 52 REAL(wp), PUBLIC, DIMENSION(jpi,jpj) :: h_rnf !: depth of runoff in m 53 INTEGER, PUBLIC, DIMENSION(jpi,jpj) :: nk_rnf !: depth of runoff in model levels 54 REAL(wp), PUBLIC, DIMENSION(jpi,jpj,jpts) :: rnf_tsc_b, rnf_tsc !: before and now T & S contents of runoffs [K.m/s & PSU.m/s] 55 56 REAL(wp) :: r1_rau0 ! = 1 / rau0 57 58 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_rnf ! structure: river runoff (file information, fields read) 59 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_s_rnf ! structure: river runoff salinity (file information, fields read) 60 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_t_rnf ! structure: river runoff temperature (file information, fields read) 61 62 !! * Substitutions 63 # include "domzgr_substitute.h90" 45 64 !!---------------------------------------------------------------------- 46 !! NEMO/OPA 3. 2 , LOCEAN-IPSL (2009)65 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 47 66 !! $Id$ 48 !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)67 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 49 68 !!---------------------------------------------------------------------- 50 51 69 CONTAINS 52 70 … … 66 84 !! 67 85 INTEGER :: ji, jj ! dummy loop indices 68 INTEGER :: ierror ! temporary integer69 86 !!---------------------------------------------------------------------- 70 87 ! 71 IF( kt == nit000 ) THEN 72 IF( .NOT. ln_rnf_emp ) THEN 73 ALLOCATE( sf_rnf(1), STAT=ierror ) 74 IF( ierror > 0 ) THEN 75 CALL ctl_stop( 'sbc_rnf: unable to allocate sf_rnf structure' ) ; RETURN 76 ENDIF 77 ALLOCATE( sf_rnf(1)%fnow(jpi,jpj) ) 78 ALLOCATE( sf_rnf(1)%fdta(jpi,jpj,2) ) 79 ENDIF 80 CALL sbc_rnf_init(sf_rnf) 88 IF( kt == nit000 ) CALL sbc_rnf_init ! Read namelist and allocate structures 89 90 ! ! ---------------------------------------- ! 91 IF( kt /= nit000 ) THEN ! Swap of forcing fields ! 92 ! ! ---------------------------------------- ! 93 rnf_b (:,: ) = rnf (:,: ) ! Swap the ocean forcing fields except at nit000 94 rnf_tsc_b(:,:,:) = rnf_tsc(:,:,:) ! where before fields are set at the end of the routine 95 ! 81 96 ENDIF 82 97 … … 85 100 ! !-------------------! 86 101 ! 87 CALL fld_read( kt, nn_fsbc, sf_rnf ) ! Read Runoffs data and provides it 88 ! ! at the current time-step 89 102 CALL fld_read ( kt, nn_fsbc, sf_rnf ) ! Read Runoffs data and provide it at kt 103 IF( ln_rnf_tem ) CALL fld_read ( kt, nn_fsbc, sf_t_rnf ) ! idem for runoffs temperature if required 104 IF( ln_rnf_sal ) CALL fld_read ( kt, nn_fsbc, sf_s_rnf ) ! idem for runoffs salinity if required 105 ! 90 106 ! Runoff reduction only associated to the ORCA2_LIM configuration 91 107 ! when reading the NetCDF file runoff_1m_nomask.nc 92 108 IF( cp_cfg == 'orca' .AND. jp_cfg == 2 ) THEN 109 WHERE( 40._wp < gphit(:,:) .AND. gphit(:,:) < 65._wp ) 110 sf_rnf(1)%fnow(:,:,1) = 0.85 * sf_rnf(1)%fnow(:,:,1) 111 END WHERE 112 ENDIF 113 ! 114 IF( MOD( kt - 1, nn_fsbc ) == 0 ) THEN 115 rnf(:,:) = rn_rfact * ( sf_rnf(1)%fnow(:,:,1) ) 116 ! 117 r1_rau0 = 1._wp / rau0 118 ! ! set temperature & salinity content of runoffs 119 IF( ln_rnf_tem ) THEN ! use runoffs temperature data 120 rnf_tsc(:,:,jp_tem) = ( sf_t_rnf(1)%fnow(:,:,1) ) * rnf(:,:) * r1_rau0 121 WHERE( sf_t_rnf(1)%fnow(:,:,1) == -999 ) ! if missing data value use SST as runoffs temperature 122 rnf_tsc(:,:,jp_tem) = sst_m(:,:) * rnf(:,:) * r1_rau0 123 END WHERE 124 ELSE ! use SST as runoffs temperature 125 rnf_tsc(:,:,jp_tem) = sst_m(:,:) * rnf(:,:) * r1_rau0 126 ENDIF 127 ! ! use runoffs salinity data 128 IF( ln_rnf_sal ) rnf_tsc(:,:,jp_sal) = ( sf_s_rnf(1)%fnow(:,:,1) ) * rnf(:,:) * r1_rau0 129 ! ! else use S=0 for runoffs (done one for all in the init) 130 ! 131 IF( ln_rnf_tem .OR. ln_rnf_sal ) THEN ! runoffs as outflow: use ocean SST and SSS 132 WHERE( rnf(:,:) < 0._wp ) ! example baltic model when flow is out of domain 133 rnf_tsc(:,:,jp_tem) = sst_m(:,:) * rnf(:,:) * r1_rau0 134 rnf_tsc(:,:,jp_sal) = sss_m(:,:) * rnf(:,:) * r1_rau0 135 END WHERE 136 ENDIF 137 ! 138 CALL iom_put( "runoffs", rnf ) ! output runoffs arrays 139 ENDIF 140 ! 141 ENDIF 142 ! 143 IF( kt == nit000 ) THEN ! set the forcing field at nit000 - 1 ! 144 ! ! ---------------------------------------- ! 145 IF( ln_rstart .AND. & !* Restart: read in restart file 146 & iom_varid( numror, 'rnf_b', ldstop = .FALSE. ) > 0 ) THEN 147 IF(lwp) WRITE(numout,*) ' nit000-1 runoff forcing fields red in the restart file' 148 CALL iom_get( numror, jpdom_autoglo, 'rnf_b', rnf_b ) ! before runoff 149 CALL iom_get( numror, jpdom_autoglo, 'rnf_hc_b', rnf_tsc_b(:,:,jp_tem) ) ! before heat content of runoff 150 CALL iom_get( numror, jpdom_autoglo, 'rnf_sc_b', rnf_tsc_b(:,:,jp_sal) ) ! before salinity content of runoff 151 ELSE !* no restart: set from nit000 values 152 IF(lwp) WRITE(numout,*) ' nit000-1 runoff forcing fields set to nit000' 153 rnf_b (:,: ) = rnf (:,: ) 154 rnf_tsc_b(:,:,:) = rnf_tsc(:,:,:) 155 ENDIF 156 ENDIF 157 ! ! ---------------------------------------- ! 158 IF( lrst_oce ) THEN ! Write in the ocean restart file ! 159 ! ! ---------------------------------------- ! 160 IF(lwp) WRITE(numout,*) 161 IF(lwp) WRITE(numout,*) 'sbcrnf : runoff forcing fields written in ocean restart file ', & 162 & 'at it= ', kt,' date= ', ndastp 163 IF(lwp) WRITE(numout,*) '~~~~' 164 CALL iom_rstput( kt, nitrst, numrow, 'rnf_b' , rnf ) 165 CALL iom_rstput( kt, nitrst, numrow, 'rnf_hc_b', rnf_tsc(:,:,jp_tem) ) 166 CALL iom_rstput( kt, nitrst, numrow, 'rnf_sc_b', rnf_tsc(:,:,jp_sal) ) 167 ENDIF 168 ! 169 END SUBROUTINE sbc_rnf 170 171 172 SUBROUTINE sbc_rnf_div( phdivn ) 173 !!---------------------------------------------------------------------- 174 !! *** ROUTINE sbc_rnf *** 175 !! 176 !! ** Purpose : update the horizontal divergence with the runoff inflow 177 !! 178 !! ** Method : 179 !! CAUTION : rnf is positive (inflow) decreasing the 180 !! divergence and expressed in m/s 181 !! 182 !! ** Action : phdivn decreased by the runoff inflow 183 !!---------------------------------------------------------------------- 184 REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) :: phdivn ! horizontal divergence 185 !! 186 INTEGER :: ji, jj, jk ! dummy loop indices 187 REAL(wp) :: r1_rau0 ! local scalar 188 REAL(wp) :: zfact ! local scalar 189 !!---------------------------------------------------------------------- 190 ! 191 zfact = 0.5_wp 192 ! 193 r1_rau0 = 1._wp / rau0 194 IF( ln_rnf_depth ) THEN !== runoff distributed over several levels ==! 195 IF( lk_vvl ) THEN ! variable volume case 196 DO jj = 1, jpj ! update the depth over which runoffs are distributed 197 DO ji = 1, jpi 198 h_rnf(ji,jj) = 0._wp 199 DO jk = 1, nk_rnf(ji,jj) ! recalculates h_rnf to be the depth in metres 200 h_rnf(ji,jj) = h_rnf(ji,jj) + fse3t(ji,jj,jk) ! to the bottom of the relevant grid box 201 END DO 202 ! ! apply the runoff input flow 203 DO jk = 1, nk_rnf(ji,jj) 204 phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rau0 / h_rnf(ji,jj) 205 END DO 206 END DO 207 END DO 208 ELSE ! constant volume case : just apply the runoff input flow 93 209 DO jj = 1, jpj 94 210 DO ji = 1, jpi 95 IF( gphit(ji,jj) > 40 .AND. gphit(ji,jj) < 65 ) sf_rnf(1)%fnow(ji,jj) = 0.85 * sf_rnf(1)%fnow(ji,jj) 211 DO jk = 1, nk_rnf(ji,jj) 212 phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rau0 / h_rnf(ji,jj) 213 END DO 96 214 END DO 97 215 END DO 98 216 ENDIF 99 100 ! C a u t i o n : runoff is negative and in kg/m2/s 101 102 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN 103 emp (:,:) = emp (:,:) - rn_rfact * ABS( sf_rnf(1)%fnow(:,:) ) 104 emps(:,:) = emps(:,:) - rn_rfact * ABS( sf_rnf(1)%fnow(:,:) ) 105 CALL iom_put( "runoffs", sf_rnf(1)%fnow ) ! runoffs 106 ENDIF 107 ! 108 ENDIF 109 ! 110 END SUBROUTINE sbc_rnf 111 112 113 SUBROUTINE sbc_rnf_init( sf_rnf ) 217 ELSE !== runoff put only at the surface ==! 218 IF( lk_vvl ) THEN ! variable volume case 219 h_rnf(:,:) = fse3t(:,:,1) ! recalculate h_rnf to be depth of top box 220 ENDIF 221 phdivn(:,:,1) = phdivn(:,:,1) - ( rnf(:,:) + rnf_b(:,:) ) * zfact * r1_rau0 / fse3t(:,:,1) 222 ENDIF 223 ! 224 END SUBROUTINE sbc_rnf_div 225 226 227 SUBROUTINE sbc_rnf_init 114 228 !!---------------------------------------------------------------------- 115 229 !! *** ROUTINE sbc_rnf_init *** … … 121 235 !! ** Action : - read parameters 122 236 !!---------------------------------------------------------------------- 123 TYPE(FLD), INTENT(inout), DIMENSION(:) :: sf_rnf ! input data 124 !! 125 NAMELIST/namsbc_rnf/ cn_dir, ln_rnf_emp, sn_rnf, sn_cnf, ln_rnf_mouth, & 126 & rn_hrnf, rn_avt_rnf, rn_rfact 237 CHARACTER(len=32) :: rn_dep_file ! runoff file name 238 INTEGER :: ji, jj, jk ! dummy loop indices 239 INTEGER :: ierror, inum ! temporary integer 240 !! 241 NAMELIST/namsbc_rnf/ cn_dir, ln_rnf_emp, ln_rnf_depth, ln_rnf_tem, ln_rnf_sal, & 242 & sn_rnf, sn_cnf , sn_s_rnf , sn_t_rnf , sn_dep_rnf, & 243 & ln_rnf_mouth , rn_hrnf , rn_avt_rnf, rn_rfact 127 244 !!---------------------------------------------------------------------- 128 245 … … 136 253 sn_cnf = FLD_N( 'runoffs', 0 , 'sorunoff' , .FALSE. , .true. , 'yearly' , '' , '' ) 137 254 255 sn_s_rnf = FLD_N( 'runoffs', 24. , 'rosaline' , .TRUE. , .true. , 'yearly' , '' , '' ) 256 sn_t_rnf = FLD_N( 'runoffs', 24. , 'rotemper' , .TRUE. , .true. , 'yearly' , '' , '' ) 257 sn_dep_rnf = FLD_N( 'runoffs', 0. , 'rodepth' , .FALSE. , .true. , 'yearly' , '' , '' ) 138 258 ! 139 259 REWIND ( numnam ) ! Read Namelist namsbc_rnf … … 157 277 ! ! ================== 158 278 ! 159 IF( ln_rnf_emp ) THEN ! runoffs directly provided in the precipitations279 IF( ln_rnf_emp ) THEN !== runoffs directly provided in the precipitations ==! 160 280 IF(lwp) WRITE(numout,*) 161 281 IF(lwp) WRITE(numout,*) ' runoffs directly provided in the precipitations' 162 ! 163 ELSE ! runoffs read in a file : set sf_rnf structure 164 ! 165 ! sf_rnf already allocated in main routine 166 ! fill sf_rnf with sn_rnf and control print 282 IF( ln_rnf_depth .OR. ln_rnf_tem .OR. ln_rnf_sal ) THEN 283 CALL ctl_warn( 'runoffs already included in precipitations, so runoff (T,S, depth) attributes will not be used' ) 284 ln_rnf_depth = .FALSE. ; ln_rnf_tem = .FALSE. ; ln_rnf_sal = .FALSE. 285 ENDIF 286 ! 287 ELSE !== runoffs read in a file : set sf_rnf structure ==! 288 ! 289 ALLOCATE( sf_rnf(1), STAT=ierror ) ! Create sf_rnf structure (runoff inflow) 290 IF(lwp) WRITE(numout,*) 291 IF(lwp) WRITE(numout,*) ' runoffs inflow read in a file' 292 IF( ierror > 0 ) THEN 293 CALL ctl_stop( 'sbc_rnf: unable to allocate sf_rnf structure' ) ; RETURN 294 ENDIF 295 ALLOCATE( sf_rnf(1)%fnow(jpi,jpj,1) ) 296 IF( sn_rnf%ln_tint ) ALLOCATE( sf_rnf(1)%fdta(jpi,jpj,1,2) ) 297 ! ! fill sf_rnf with the namelist (sn_rnf) and control print 167 298 CALL fld_fill( sf_rnf, (/ sn_rnf /), cn_dir, 'sbc_rnf_init', 'read runoffs data', 'namsbc_rnf' ) 168 299 ! 169 ENDIF 170 300 IF( ln_rnf_tem ) THEN ! Create (if required) sf_t_rnf structure 301 IF(lwp) WRITE(numout,*) 302 IF(lwp) WRITE(numout,*) ' runoffs temperatures read in a file' 303 ALLOCATE( sf_t_rnf(1), STAT=ierror ) 304 IF( ierror > 0 ) THEN 305 CALL ctl_stop( 'sbc_rnf_init: unable to allocate sf_t_rnf structure' ) ; RETURN 306 ENDIF 307 ALLOCATE( sf_t_rnf(1)%fnow(jpi,jpj,1) ) 308 IF( sn_t_rnf%ln_tint ) ALLOCATE( sf_t_rnf(1)%fdta(jpi,jpj,1,2) ) 309 CALL fld_fill (sf_t_rnf, (/ sn_t_rnf /), cn_dir, 'sbc_rnf_init', 'read runoff temperature data', 'namsbc_rnf' ) 310 ENDIF 311 ! 312 IF( ln_rnf_sal ) THEN ! Create (if required) sf_s_rnf and sf_t_rnf structures 313 IF(lwp) WRITE(numout,*) 314 IF(lwp) WRITE(numout,*) ' runoffs salinities read in a file' 315 ALLOCATE( sf_s_rnf(1), STAT=ierror ) 316 IF( ierror > 0 ) THEN 317 CALL ctl_stop( 'sbc_rnf_init: unable to allocate sf_s_rnf structure' ) ; RETURN 318 ENDIF 319 ALLOCATE( sf_s_rnf(1)%fnow(jpi,jpj,1) ) 320 IF( sn_s_rnf%ln_tint ) ALLOCATE( sf_s_rnf(1)%fdta(jpi,jpj,1,2) ) 321 CALL fld_fill (sf_s_rnf, (/ sn_s_rnf /), cn_dir, 'sbc_rnf_init', 'read runoff salinity data', 'namsbc_rnf' ) 322 ENDIF 323 ! 324 IF( ln_rnf_depth ) THEN ! depth of runoffs set from a file 325 IF(lwp) WRITE(numout,*) 326 IF(lwp) WRITE(numout,*) ' runoffs depth read in a file' 327 rn_dep_file = TRIM( cn_dir )//TRIM( sn_dep_rnf%clname ) 328 CALL iom_open ( rn_dep_file, inum ) ! open file 329 CALL iom_get ( inum, jpdom_data, sn_dep_rnf%clvar, h_rnf ) ! read the river mouth array 330 CALL iom_close( inum ) ! close file 331 ! 332 nk_rnf(:,:) = 0 ! set the number of level over which river runoffs are applied 333 DO jj = 1, jpj 334 DO ji = 1, jpi 335 IF( h_rnf(ji,jj) > 0._wp ) THEN 336 jk = 2 337 DO WHILE ( jk /= mbkt(ji,jj) .AND. fsdept(ji,jj,jk) < h_rnf(ji,jj) ) ; jk = jk + 1 ; END DO 338 nk_rnf(ji,jj) = jk 339 ELSEIF( h_rnf(ji,jj) == -1 ) THEN ; nk_rnf(ji,jj) = 1 340 ELSEIF( h_rnf(ji,jj) == -999 ) THEN ; nk_rnf(ji,jj) = mbkt(ji,jj) 341 ELSEIF( h_rnf(ji,jj) /= 0 ) THEN 342 CALL ctl_stop( 'runoff depth not positive, and not -999 or -1, rnf value in file fort.999' ) 343 WRITE(999,*) 'ji, jj, rnf(ji,jj) :', ji, jj, rnf(ji,jj) 344 ENDIF 345 END DO 346 END DO 347 DO jj = 1, jpj ! set the associated depth 348 DO ji = 1, jpi 349 h_rnf(ji,jj) = 0._wp 350 DO jk = 1, nk_rnf(ji,jj) 351 h_rnf(ji,jj) = h_rnf(ji,jj) + fse3t(ji,jj,jk) 352 END DO 353 END DO 354 END DO 355 ELSE ! runoffs applied at the surface 356 nk_rnf(:,:) = 1 357 h_rnf (:,:) = fse3t(:,:,1) 358 ENDIF 359 ! 360 ENDIF 361 ! 362 rnf_tsc(:,:,:) = 0._wp ! runoffs temperature & salinty contents initilisation 363 ! 171 364 ! ! ======================== 172 365 ! ! River mouth vicinity … … 178 371 ! ! - mixed upstream-centered (ln_traadv_cen2=T) 179 372 ! 180 ! ! Number of level over which Kz increase 181 nkrnf = 0 182 IF( rn_hrnf > 0.e0 ) THEN 373 IF ( ln_rnf_depth ) CALL ctl_warn( 'sbc_rnf_init: increased mixing turned on but effects may already', & 374 & 'be spread through depth by ln_rnf_depth' ) 375 ! 376 nkrnf = 0 ! Number of level over which Kz increase 377 IF( rn_hrnf > 0._wp ) THEN 183 378 nkrnf = 2 184 379 DO WHILE( nkrnf /= jpkm1 .AND. gdepw_0(nkrnf+1) < rn_hrnf ) ; nkrnf = nkrnf + 1 ; END DO … … 198 393 IF(lwp) WRITE(numout,*) 199 394 IF(lwp) WRITE(numout,*) ' No specific treatment at river mouths' 200 rnfmsk (:,:) = 0. e0201 rnfmsk_z(:) = 0. e0395 rnfmsk (:,:) = 0._wp 396 rnfmsk_z(:) = 0._wp 202 397 nkrnf = 0 203 398 ENDIF … … 226 421 !! rnfmsk_z vertical structure 227 422 !!---------------------------------------------------------------------- 228 USE closea, ONLY : clo_rnf ! rnfmsk update routine229 423 ! 230 424 INTEGER :: inum ! temporary integers … … 248 442 IF( nclosea == 1 ) CALL clo_rnf( rnfmsk ) ! closed sea inflow set as ruver mouth 249 443 250 rnfmsk_z(:) = 0. e0! vertical structure444 rnfmsk_z(:) = 0._wp ! vertical structure 251 445 rnfmsk_z(1) = 1.0 252 446 rnfmsk_z(2) = 1.0 ! ********** -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcssm.F90
r1715 r2528 5 5 !!====================================================================== 6 6 !! History : 9.0 ! 06-07 (G. Madec) Original code 7 !! 3.3 ! 2010-10 (C. Bricaud, G. Madec) add the Patm forcing for sea-ice 7 8 !!---------------------------------------------------------------------- 8 9 … … 14 15 USE dom_oce ! ocean space and time domain 15 16 USE sbc_oce ! Surface boundary condition: ocean fields 17 USE sbc_oce ! surface boundary condition: ocean fields 18 USE sbcapr ! surface boundary condition: atmospheric pressure 16 19 USE prtctl ! Print control (prt_ctl routine) 17 20 USE restart ! ocean restart … … 27 30 # include "domzgr_substitute.h90" 28 31 !!---------------------------------------------------------------------- 29 !! OPA 9.0 , LOCEAN-IPSL (2006)32 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 30 33 !! $Id$ 31 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)34 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 32 35 !!---------------------------------------------------------------------- 33 36 … … 44 47 !! V-points) [m/s], temperature [Celcius] and salinity [psu] over 45 48 !! the periode (kt - nn_fsbc) to kt 49 !! Note that the inverse barometer ssh (i.e. ssh associated with Patm) 50 !! is add to ssh_m when ln_apr_dyn = T. Required for sea-ice dynamics. 46 51 !!--------------------------------------------------------------------- 47 52 INTEGER, INTENT(in) :: kt ! ocean time step … … 63 68 sst_m(:,:) = tn(:,:,1) 64 69 sss_m(:,:) = sn(:,:,1) 65 ssh_m(:,:) = sshn(:,:) 70 ! ! removed inverse barometer ssh when Patm forcing is used (for sea-ice dynamics) 71 IF( ln_apr_dyn ) THEN ; ssh_m(:,:) = sshn(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 72 ELSE ; ssh_m(:,:) = sshn(:,:) 73 ENDIF 74 66 75 ! 67 76 ELSE … … 99 108 sst_m(:,:) = zcoef * tn(:,:,1) 100 109 sss_m(:,:) = zcoef * sn(:,:,1) 101 ssh_m(:,:) = zcoef * sshn(:,:) 110 ! ! removed inverse barometer ssh when Patm forcing is used 111 IF( ln_apr_dyn ) THEN ; ssh_m(:,:) = zcoef * ( sshn(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) ) 112 ELSE ; ssh_m(:,:) = zcoef * sshn(:,:) 113 ENDIF 114 102 115 ENDIF 103 116 ! ! ---------------------------------------- ! … … 117 130 sst_m(:,:) = sst_m(:,:) + tn(:,:,1) 118 131 sss_m(:,:) = sss_m(:,:) + sn(:,:,1) 119 ssh_m(:,:) = ssh_m(:,:) + sshn(:,:) 132 ! ! removed inverse barometer ssh when Patm forcing is used (for sea-ice dynamics) 133 IF( ln_apr_dyn ) THEN ; ssh_m(:,:) = ssh_m(:,:) + sshn(:,:) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 134 ELSE ; ssh_m(:,:) = ssh_m(:,:) + sshn(:,:) 135 ENDIF 120 136 121 137 ! ! ---------------------------------------- ! -
trunk/NEMOGCM/NEMO/OPA_SRC/SBC/sbcssr.F90
r1730 r2528 46 46 # include "domzgr_substitute.h90" 47 47 !!---------------------------------------------------------------------- 48 !! NEMO/OPA 3. 2 , LOCEAN-IPSL (2009)48 !! NEMO/OPA 3.3 , NEMO Consortium (2010) 49 49 !! $Id$ 50 !! Software governed by the CeCILL licence ( modipsl/doc/NEMO_CeCILL.txt)50 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) 51 51 !!---------------------------------------------------------------------- 52 52 … … 115 115 CALL ctl_stop( 'sbc_ssr: unable to allocate sf_sst structure' ) ; RETURN 116 116 ENDIF 117 ALLOCATE( sf_sst(1)%fnow(jpi,jpj) ) 118 ALLOCATE( sf_sst(1)%fdta(jpi,jpj,2) ) 117 ALLOCATE( sf_sst(1)%fnow(jpi,jpj,1) ) 119 118 ! 120 119 ! fill sf_sst with sn_sst and control print 121 120 CALL fld_fill( sf_sst, (/ sn_sst /), cn_dir, 'sbc_ssr', 'SST restoring term toward SST data', 'namsbc_ssr' ) 121 IF( sf_sst(1)%ln_tint ) ALLOCATE( sf_sst(1)%fdta(jpi,jpj,1,2) ) 122 122 ENDIF 123 123 ! … … 128 128 CALL ctl_stop( 'sbc_ssr: unable to allocate sf_sss structure' ) ; RETURN 129 129 ENDIF 130 ALLOCATE( sf_sss(1)%fnow(jpi,jpj) ) 131 ALLOCATE( sf_sss(1)%fdta(jpi,jpj,2) ) 130 ALLOCATE( sf_sss(1)%fnow(jpi,jpj,1) ) 132 131 ! 133 132 ! fill sf_sss with sn_sss and control print 134 133 CALL fld_fill( sf_sss, (/ sn_sss /), cn_dir, 'sbc_ssr', 'SSS restoring term toward SSS data', 'namsbc_ssr' ) 134 IF( sf_sss(1)%ln_tint )ALLOCATE( sf_sss(1)%fdta(jpi,jpj,1,2) ) 135 135 ENDIF 136 136 ! … … 153 153 DO jj = 1, jpj 154 154 DO ji = 1, jpi 155 zqrp = rn_dqdt * ( sst_m(ji,jj) - sf_sst(1)%fnow(ji,jj ) )155 zqrp = rn_dqdt * ( sst_m(ji,jj) - sf_sst(1)%fnow(ji,jj,1) ) 156 156 qns(ji,jj) = qns(ji,jj) + zqrp 157 157 qrp(ji,jj) = zqrp … … 167 167 DO ji = 1, jpi 168 168 zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) ) & ! No damping in vicinity of river mouths 169 & * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj ) ) &169 & * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj,1) ) & 170 170 & / ( sss_m(ji,jj) + 1.e-20 ) 171 171 emps(ji,jj) = emps(ji,jj) + zerp … … 182 182 DO ji = 1, jpi 183 183 zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) ) & ! No damping in vicinity of river mouths 184 & * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj ) ) &184 & * ( sss_m(ji,jj) - sf_sss(1)%fnow(ji,jj,1) ) & 185 185 & / ( sss_m(ji,jj) + 1.e-20 ) 186 186 IF( ln_sssr_bnd ) zerp = SIGN( 1., zerp ) * MIN( zerp_bnd, ABS(zerp) )
Note: See TracChangeset
for help on using the changeset viewer.