Changeset 14072 for NEMO/trunk/src/OCE
- Timestamp:
- 2020-12-04T08:48:38+01:00 (3 years ago)
- Location:
- NEMO/trunk/src/OCE
- Files:
-
- 1 deleted
- 87 edited
- 11 copied
Legend:
- Unmodified
- Added
- Removed
-
NEMO/trunk/src/OCE/ASM/asminc.F90
r13982 r14072 9 9 !! ! 2007-04 (A. Weaver) Merge with OPAVAR/NEMOVAR 10 10 !! NEMO 3.3 ! 2010-05 (D. Lea) Update to work with NEMO v3.2 11 !! - ! 2010-05 (D. Lea) add calc_month_len routine based on day_init 11 !! - ! 2010-05 (D. Lea) add calc_month_len routine based on day_init 12 12 !! 3.4 ! 2012-10 (A. Weaver and K. Mogensen) Fix for direct initialization 13 13 !! ! 2014-09 (D. Lea) Local calc_date removed use routine from OBS … … 32 32 USE zpshde ! Partial step : Horizontal Derivative 33 33 USE asmpar ! Parameters for the assmilation interface 34 USE asmbkg ! 34 USE asmbkg ! 35 35 USE c1d ! 1D initialization 36 36 USE sbc_oce ! Surface boundary condition variables. … … 46 46 IMPLICIT NONE 47 47 PRIVATE 48 48 49 49 PUBLIC asm_inc_init !: Initialize the increment arrays and IAU weights 50 50 PUBLIC tra_asm_inc !: Apply the tracer (T and S) increments … … 73 73 REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE :: u_bkg , v_bkg !: Background u- & v- velocity components 74 74 REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE :: t_bkginc, s_bkginc !: Increment to the background T & S 75 REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE :: u_bkginc, v_bkginc !: Increment to the u- & v-components 75 REAL(wp), PUBLIC, DIMENSION(:,:,:), ALLOCATABLE :: u_bkginc, v_bkginc !: Increment to the u- & v-components 76 76 REAL(wp), PUBLIC, DIMENSION(:) , ALLOCATABLE :: wgtiau !: IAU weights for each time step 77 77 #if defined key_asminc … … 81 81 INTEGER , PUBLIC :: nitbkg !: Time step of the background state used in the Jb term 82 82 INTEGER , PUBLIC :: nitdin !: Time step of the background state for direct initialization 83 INTEGER , PUBLIC :: nitiaustr !: Time step of the start of the IAU interval 83 INTEGER , PUBLIC :: nitiaustr !: Time step of the start of the IAU interval 84 84 INTEGER , PUBLIC :: nitiaufin !: Time step of the end of the IAU interval 85 ! 85 ! 86 86 INTEGER , PUBLIC :: niaufn !: Type of IAU weighing function: = 0 Constant weighting 87 ! !: = 1 Linear hat-like, centred in middle of IAU interval 87 ! !: = 1 Linear hat-like, centred in middle of IAU interval 88 88 REAL(wp), PUBLIC :: salfixmin !: Ensure that the salinity is larger than this value if (ln_salfix) 89 89 … … 107 107 !!---------------------------------------------------------------------- 108 108 !! *** ROUTINE asm_inc_init *** 109 !! 109 !! 110 110 !! ** Purpose : Initialize the assimilation increment and IAU weights. 111 111 !! 112 112 !! ** Method : Initialize the assimilation increment and IAU weights. 113 113 !! 114 !! ** Action : 114 !! ** Action : 115 115 !!---------------------------------------------------------------------- 116 116 INTEGER, INTENT(in) :: Kbb, Kmm, Krhs ! time level indices … … 264 264 ! 265 265 ! !--------------------------------------------------------- 266 IF( niaufn == 0 ) THEN ! Constant IAU forcing 266 IF( niaufn == 0 ) THEN ! Constant IAU forcing 267 267 ! !--------------------------------------------------------- 268 268 DO jt = 1, iiauper … … 270 270 END DO 271 271 ! !--------------------------------------------------------- 272 ELSEIF ( niaufn == 1 ) THEN ! Linear hat-like, centred in middle of IAU interval 272 ELSEIF ( niaufn == 1 ) THEN ! Linear hat-like, centred in middle of IAU interval 273 273 ! !--------------------------------------------------------- 274 274 ! Compute the normalization factor 275 275 znorm = 0._wp 276 276 IF( MOD( iiauper, 2 ) == 0 ) THEN ! Even number of time steps in IAU interval 277 imid = iiauper / 2 277 imid = iiauper / 2 278 278 DO jt = 1, imid 279 279 znorm = znorm + REAL( jt ) … … 281 281 znorm = 2.0 * znorm 282 282 ELSE ! Odd number of time steps in IAU interval 283 imid = ( iiauper + 1 ) / 2 283 imid = ( iiauper + 1 ) / 2 284 284 DO jt = 1, imid - 1 285 285 znorm = znorm + REAL( jt ) … … 308 308 DO jt = 1, icycper 309 309 ztotwgt = ztotwgt + wgtiau(jt) 310 WRITE(numout,*) ' ', jt, ' ', wgtiau(jt) 311 END DO 310 WRITE(numout,*) ' ', jt, ' ', wgtiau(jt) 311 END DO 312 312 WRITE(numout,*) ' ===================================' 313 313 WRITE(numout,*) ' Time-integrated weight = ', ztotwgt 314 314 WRITE(numout,*) ' ===================================' 315 315 ENDIF 316 316 317 317 ENDIF 318 318 … … 339 339 CALL iom_open( c_asminc, inum ) 340 340 ! 341 CALL iom_get( inum, 'time' , zdate_inc ) 341 CALL iom_get( inum, 'time' , zdate_inc ) 342 342 CALL iom_get( inum, 'z_inc_dateb', z_inc_dateb ) 343 343 CALL iom_get( inum, 'z_inc_datef', z_inc_datef ) … … 346 346 ! 347 347 IF(lwp) THEN 348 WRITE(numout,*) 348 WRITE(numout,*) 349 349 WRITE(numout,*) 'asm_inc_init : Assimilation increments valid between dates ', z_inc_dateb,' and ', z_inc_datef 350 350 WRITE(numout,*) '~~~~~~~~~~~~' … … 360 360 & ' not agree with Direct Initialization time' ) 361 361 362 IF ( ln_trainc ) THEN 362 IF ( ln_trainc ) THEN 363 363 CALL iom_get( inum, jpdom_auto, 'bckint', t_bkginc, 1 ) 364 364 CALL iom_get( inum, jpdom_auto, 'bckins', s_bkginc, 1 ) … … 372 372 ENDIF 373 373 374 IF ( ln_dyninc ) THEN 375 CALL iom_get( inum, jpdom_auto, 'bckinu', u_bkginc, 1 ) 376 CALL iom_get( inum, jpdom_auto, 'bckinv', v_bkginc, 1 ) 374 IF ( ln_dyninc ) THEN 375 CALL iom_get( inum, jpdom_auto, 'bckinu', u_bkginc, 1 ) 376 CALL iom_get( inum, jpdom_auto, 'bckinv', v_bkginc, 1 ) 377 377 ! Apply the masks 378 378 u_bkginc(:,:,:) = u_bkginc(:,:,:) * umask(:,:,:) … … 383 383 WHERE( ABS( v_bkginc(:,:,:) ) > 1.0e+10 ) v_bkginc(:,:,:) = 0.0 384 384 ENDIF 385 385 386 386 IF ( ln_sshinc ) THEN 387 387 CALL iom_get( inum, jpdom_auto, 'bckineta', ssh_bkginc, 1 ) … … 409 409 IF ( ln_dyninc .AND. nn_divdmp > 0 ) THEN ! Apply divergence damping filter 410 410 ! !-------------------------------------- 411 ALLOCATE( zhdiv(jpi,jpj) ) 411 ALLOCATE( zhdiv(jpi,jpj) ) 412 412 ! 413 413 DO jt = 1, nn_divdmp … … 428 428 & + 0.2_wp * ( zhdiv(ji+1,jj) - zhdiv(ji ,jj) ) * r1_e1u(ji,jj) * umask(ji,jj,jk) 429 429 v_bkginc(ji,jj,jk) = v_bkginc(ji,jj,jk) & 430 & + 0.2_wp * ( zhdiv(ji,jj+1) - zhdiv(ji,jj ) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk) 430 & + 0.2_wp * ( zhdiv(ji,jj+1) - zhdiv(ji,jj ) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk) 431 431 END_2D 432 432 END DO … … 434 434 END DO 435 435 ! 436 DEALLOCATE( zhdiv ) 436 DEALLOCATE( zhdiv ) 437 437 ! 438 438 ENDIF … … 455 455 CALL iom_open( c_asmdin, inum ) 456 456 ! 457 CALL iom_get( inum, 'rdastp', zdate_bkg ) 457 CALL iom_get( inum, 'rdastp', zdate_bkg ) 458 458 ! 459 459 IF(lwp) THEN 460 WRITE(numout,*) 460 WRITE(numout,*) 461 461 WRITE(numout,*) ' ==>>> Assimilation background state valid at : ', zdate_bkg 462 462 WRITE(numout,*) … … 467 467 & ' not agree with Direct Initialization time' ) 468 468 ! 469 IF ( ln_trainc ) THEN 469 IF ( ln_trainc ) THEN 470 470 CALL iom_get( inum, jpdom_auto, 'tn', t_bkg ) 471 471 CALL iom_get( inum, jpdom_auto, 'sn', s_bkg ) … … 474 474 ENDIF 475 475 ! 476 IF ( ln_dyninc ) THEN 476 IF ( ln_dyninc ) THEN 477 477 CALL iom_get( inum, jpdom_auto, 'un', u_bkg, cd_type = 'U', psgn = 1._wp ) 478 478 CALL iom_get( inum, jpdom_auto, 'vn', v_bkg, cd_type = 'V', psgn = 1._wp ) … … 502 502 ! 503 503 END SUBROUTINE asm_inc_init 504 505 504 505 506 506 SUBROUTINE tra_asm_inc( kt, Kbb, Kmm, pts, Krhs ) 507 507 !!---------------------------------------------------------------------- 508 508 !! *** ROUTINE tra_asm_inc *** 509 !! 509 !! 510 510 !! ** Purpose : Apply the tracer (T and S) assimilation increments 511 511 !! 512 512 !! ** Method : Direct initialization or Incremental Analysis Updating 513 513 !! 514 !! ** Action : 514 !! ** Action : 515 515 !!---------------------------------------------------------------------- 516 516 INTEGER , INTENT(in ) :: kt ! Current time step … … 524 524 !!---------------------------------------------------------------------- 525 525 ! 526 ! freezing point calculation taken from oc_fz_pt (but calculated for all depths) 527 ! used to prevent the applied increments taking the temperature below the local freezing point 526 ! freezing point calculation taken from oc_fz_pt (but calculated for all depths) 527 ! used to prevent the applied increments taking the temperature below the local freezing point 528 528 IF( ln_temnofreeze ) THEN 529 529 DO jk = 1, jpkm1 … … 587 587 ELSEIF ( ln_asmdin ) THEN ! Direct Initialization 588 588 ! !-------------------------------------- 589 ! 589 ! 590 590 IF ( kt == nitdin_r ) THEN 591 591 ! … … 647 647 ! 648 648 ENDIF 649 ! 649 ! 650 650 ENDIF 651 651 ! Perhaps the following call should be in step … … 658 658 !!---------------------------------------------------------------------- 659 659 !! *** ROUTINE dyn_asm_inc *** 660 !! 660 !! 661 661 !! ** Purpose : Apply the dynamics (u and v) assimilation increments. 662 662 !! 663 663 !! ** Method : Direct initialization or Incremental Analysis Updating. 664 664 !! 665 !! ** Action : 665 !! ** Action : 666 666 !!---------------------------------------------------------------------- 667 667 INTEGER , INTENT( in ) :: kt ! ocean time-step index … … 684 684 ! 685 685 IF(lwp) THEN 686 WRITE(numout,*) 686 WRITE(numout,*) 687 687 WRITE(numout,*) 'dyn_asm_inc : Dynamics IAU at time step = ', kt,' with IAU weight = ', wgtiau(it) 688 688 WRITE(numout,*) '~~~~~~~~~~~~' … … 704 704 ELSEIF ( ln_asmdin ) THEN ! Direct Initialization 705 705 ! !----------------------------------------- 706 ! 706 ! 707 707 IF ( kt == nitdin_r ) THEN 708 708 ! … … 711 711 ! Initialize the now fields with the background + increment 712 712 puu(:,:,:,Kmm) = u_bkg(:,:,:) + u_bkginc(:,:,:) 713 pvv(:,:,:,Kmm) = v_bkg(:,:,:) + v_bkginc(:,:,:) 713 pvv(:,:,:,Kmm) = v_bkg(:,:,:) + v_bkginc(:,:,:) 714 714 ! 715 715 puu(:,:,:,Kbb) = puu(:,:,:,Kmm) ! Update before fields … … 730 730 !!---------------------------------------------------------------------- 731 731 !! *** ROUTINE ssh_asm_inc *** 732 !! 732 !! 733 733 !! ** Purpose : Apply the sea surface height assimilation increment. 734 734 !! 735 735 !! ** Method : Direct initialization or Incremental Analysis Updating. 736 736 !! 737 !! ** Action : 737 !! ** Action : 738 738 !!---------------------------------------------------------------------- 739 739 INTEGER, INTENT(IN) :: kt ! Current time step … … 755 755 ! 756 756 IF(lwp) THEN 757 WRITE(numout,*) 757 WRITE(numout,*) 758 758 WRITE(numout,*) 'ssh_asm_inc : SSH IAU at time step = ', & 759 759 & kt,' with IAU weight = ', wgtiau(it) … … 807 807 !! *** ROUTINE ssh_asm_div *** 808 808 !! 809 !! ** Purpose : ssh increment with z* is incorporated via a correction of the local divergence 809 !! ** Purpose : ssh increment with z* is incorporated via a correction of the local divergence 810 810 !! across all the water column 811 811 !! … … 823 823 REAL(wp), DIMENSION(:,:) , POINTER :: ztim ! local array 824 824 !!---------------------------------------------------------------------- 825 ! 825 ! 826 826 #if defined key_asminc 827 827 CALL ssh_asm_inc( kt, Kbb, Kmm ) !== (calculate increments) 828 828 ! 829 IF( ln_linssh ) THEN 829 IF( ln_linssh ) THEN 830 830 phdivn(:,:,1) = phdivn(:,:,1) - ssh_iau(:,:) / e3t(:,:,1,Kmm) * tmask(:,:,1) 831 ELSE 831 ELSE 832 832 ALLOCATE( ztim(jpi,jpj) ) 833 833 ztim(:,:) = ssh_iau(:,:) / ( ht(:,:) + 1.0 - ssmask(:,:) ) 834 DO jk = 1, jpkm1 835 phdivn(:,:,jk) = phdivn(:,:,jk) - ztim(:,:) * tmask(:,:,jk) 834 DO jk = 1, jpkm1 835 phdivn(:,:,jk) = phdivn(:,:,jk) - ztim(:,:) * tmask(:,:,jk) 836 836 END DO 837 837 ! … … 846 846 !!---------------------------------------------------------------------- 847 847 !! *** ROUTINE seaice_asm_inc *** 848 !! 848 !! 849 849 !! ** Purpose : Apply the sea ice assimilation increment. 850 850 !! 851 851 !! ** Method : Direct initialization or Incremental Analysis Updating. 852 852 !! 853 !! ** Action : 853 !! ** Action : 854 854 !! 855 855 !!---------------------------------------------------------------------- … … 873 873 ! 874 874 it = kt - nit000 + 1 875 zincwgt = wgtiau(it) ! IAU weight for the current time step 875 zincwgt = wgtiau(it) ! IAU weight for the current time step 876 876 ! note this is not a tendency so should not be divided by rn_Dt (as with the tracer and other increments) 877 877 ! … … 997 997 !#if defined defined key_si3 || defined key_cice 998 998 ! 999 ! IF (ln_seaicebal ) THEN 999 ! IF (ln_seaicebal ) THEN 1000 1000 ! !! balancing salinity increments 1001 1001 ! !! simple case from limflx.F90 (doesn't include a mass flux) … … 1009 1009 ! 1010 1010 ! DO jj = 1, jpj 1011 ! DO ji = 1, jpi 1011 ! DO ji = 1, jpi 1012 1012 ! ! calculate change in ice and snow mass per unit area 1013 1013 ! ! positive values imply adding salt to the ocean (results from ice formation) … … 1020 1020 ! 1021 1021 ! ! prevent small mld 1022 ! ! less than 10m can cause salinity instability 1022 ! ! less than 10m can cause salinity instability 1023 1023 ! IF (mld < 10) mld=10 1024 1024 ! 1025 ! ! set to bottom of a level 1025 ! ! set to bottom of a level 1026 1026 ! DO jk = jpk-1, 2, -1 1027 1027 ! IF ((mld > gdepw(ji,jj,jk,Kmm)) .and. (mld < gdepw(ji,jj,jk+1,Kmm))) THEN … … 1032 1032 ! 1033 1033 ! ! avoid applying salinity balancing in shallow water or on land 1034 ! ! 1034 ! ! 1035 1035 ! 1036 1036 ! ! dsal_ocn (psu kg m^-2) / (kg m^-3 * m) … … 1043 1043 ! 1044 1044 ! ! put increments in for levels in the mixed layer 1045 ! ! but prevent salinity below a threshold value 1046 ! 1047 ! DO jk = 1, jkmax 1048 ! 1049 ! IF (dsal_ocn > 0.0_wp .or. sb(ji,jj,jk)+dsal_ocn > sal_thresh) THEN 1045 ! ! but prevent salinity below a threshold value 1046 ! 1047 ! DO jk = 1, jkmax 1048 ! 1049 ! IF (dsal_ocn > 0.0_wp .or. sb(ji,jj,jk)+dsal_ocn > sal_thresh) THEN 1050 1050 ! sb(ji,jj,jk) = sb(ji,jj,jk) + dsal_ocn 1051 1051 ! sn(ji,jj,jk) = sn(ji,jj,jk) + dsal_ocn … … 1058 1058 ! ! 1059 1059 ! !! Adjust fsalt. A +ve fsalt means adding salt to ocean 1060 ! !! fsalt(ji,jj) = fsalt(ji,jj) + zpmess ! adjust fsalt 1061 ! !! 1062 ! !! emps(ji,jj) = emps(ji,jj) + zpmess ! or adjust emps (see icestp1d) 1060 ! !! fsalt(ji,jj) = fsalt(ji,jj) + zpmess ! adjust fsalt 1061 ! !! 1062 ! !! emps(ji,jj) = emps(ji,jj) + zpmess ! or adjust emps (see icestp1d) 1063 1063 ! !! ! E-P (kg m-2 s-2) 1064 1064 ! ! emp(ji,jj) = emp(ji,jj) + zpmess ! E-P (kg m-2 s-2) … … 1073 1073 ! 1074 1074 END SUBROUTINE seaice_asm_inc 1075 1075 1076 1076 !!====================================================================== 1077 1077 END MODULE asminc -
NEMO/trunk/src/OCE/BDY/bdytra.F90
r13982 r14072 30 30 END TYPE 31 31 32 PUBLIC bdy_tra ! called in tranxt.F90 33 PUBLIC bdy_tra_dmp ! called in step.F90 32 PUBLIC bdy_tra ! called in tranxt.F90 33 PUBLIC bdy_tra_dmp ! called in step.F90 34 34 35 35 !!---------------------------------------------------------------------- 36 36 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 37 !! $Id$ 37 !! $Id$ 38 38 !! Software governed by the CeCILL license (see ./LICENSE) 39 39 !!---------------------------------------------------------------------- … … 56 56 LOGICAL, DIMENSION(4) :: llsend1, llrecv1 ! indicate how communications are to be carried out 57 57 !!---------------------------------------------------------------------- 58 igrd = 1 58 igrd = 1 59 59 llsend1(:) = .false. ; llrecv1(:) = .false. 60 60 DO ir = 1, 0, -1 ! treat rim 1 before rim 0 … … 83 83 CASE DEFAULT ; CALL ctl_stop( 'bdy_tra : unrecognised option for open boundaries for T and S' ) 84 84 END SELECT 85 ! 85 ! 86 86 END DO 87 87 END DO … … 111 111 !!---------------------------------------------------------------------- 112 112 !! *** SUBROUTINE bdy_rnf *** 113 !! 113 !! 114 114 !! ** Purpose : Specialized routine to apply TRA runoff values at OBs: 115 115 !! - duplicate the neighbour value for the temperature 116 116 !! - specified to 0.1 PSU for the salinity 117 !! 117 !! 118 118 !!---------------------------------------------------------------------- 119 119 TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices … … 143 143 !!---------------------------------------------------------------------- 144 144 !! *** SUBROUTINE bdy_tra_dmp *** 145 !! 145 !! 146 146 !! ** Purpose : Apply damping for tracers at open boundaries. 147 !! 147 !! 148 148 !!---------------------------------------------------------------------- 149 149 INTEGER , INTENT(in) :: kt ! time step … … 181 181 ! 182 182 END SUBROUTINE bdy_tra_dmp 183 183 184 184 !!====================================================================== 185 185 END MODULE bdytra -
NEMO/trunk/src/OCE/C1D/step_c1d.F90
r14010 r14072 11 11 !!---------------------------------------------------------------------- 12 12 !! 'key_c1d' 1D Configuration 13 !!---------------------------------------------------------------------- 13 !!---------------------------------------------------------------------- 14 14 !! stp_c1d : NEMO system time-stepping in c1d case 15 15 !!---------------------------------------------------------------------- 16 USE step_oce ! time stepping definition modules 16 USE step_oce ! time stepping definition modules 17 17 USE step, ONLY : Nbb, Nnn, Naa, Nrhs ! time level indices 18 18 #if defined key_top … … 22 22 USE dynatf ! time filtering (dyn_atf routine) 23 23 USE dyndmp ! U & V momentum damping (dyn_dmp routine) 24 USE restart ! restart 24 USE restart ! restart 25 25 26 26 IMPLICIT NONE … … 39 39 !!---------------------------------------------------------------------- 40 40 !! *** ROUTINE stp_c1d *** 41 !! 41 !! 42 42 !! ** Purpose : - Time stepping of SBC including sea ice (dynamic and thermodynamic eqs.) 43 43 !! - Time stepping of OPA (momentum and active tracer eqs.) 44 44 !! - Time stepping of TOP (passive tracer eqs.) 45 !! 46 !! ** Method : -1- Update forcings and data 47 !! -2- Update vertical ocean physics 48 !! -3- Compute the t and s trends 49 !! -4- Update t and s 45 !! 46 !! ** Method : -1- Update forcings and data 47 !! -2- Update vertical ocean physics 48 !! -3- Compute the t and s trends 49 !! -4- Update t and s 50 50 !! -5- Compute the momentum trends 51 51 !! -6- Update the horizontal velocity … … 67 67 68 68 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 69 ! Ocean physics update 69 ! Ocean physics update 70 70 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 71 71 CALL eos_rab( ts(:,:,:,:,Nbb), rab_b, Nnn ) ! before local thermal/haline expension ratio at T-points … … 73 73 CALL bn2( ts(:,:,:,:,Nbb), rab_b, rn2b, Nnn ) ! before Brunt-Vaisala frequency 74 74 CALL bn2( ts(:,:,:,:,Nnn), rab_n, rn2 , Nnn ) ! now Brunt-Vaisala frequency 75 75 76 76 ! VERTICAL PHYSICS 77 77 CALL zdf_phy( kstp, Nbb, Nnn, Nrhs ) ! vertical physics update (bfr, avt, avs, avm + MLD) 78 78 79 79 IF(.NOT.ln_linssh ) CALL ssh_nxt ( kstp, Nbb, Nnn, ssh, Naa ) ! after ssh (includes call to div_hor) 80 IF(.NOT.ln_linssh ) CALL dom_vvl_sf_nxt( kstp, Nbb, Nnn, Naa ) ! after vertical scale factors 80 IF(.NOT.ln_linssh ) CALL dom_vvl_sf_nxt( kstp, Nbb, Nnn, Naa ) ! after vertical scale factors 81 81 82 IF(.NOT.ln_linssh ) CALL wzv ( kstp, Nbb, Nnn, Naa, ww ) ! now cross-level velocity 82 IF(.NOT.ln_linssh ) CALL wzv ( kstp, Nbb, Nnn, Naa, ww ) ! now cross-level velocity 83 83 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 84 ! diagnostics and outputs 84 ! diagnostics and outputs 85 85 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 86 86 CALL dia_wri( kstp, Nnn ) ! ocean model: outputs … … 123 123 CALL dyn_atf ( kstp, Nbb, Nnn, Naa , uu, vv, e3t, e3u, e3v ) ! time filtering of "now" fields 124 124 IF(.NOT.ln_linssh)CALL ssh_atf ( kstp, Nbb, Nnn, Naa , ssh ) ! time filtering of "now" sea surface height 125 IF( kstp == nit000 .AND. ln_linssh) THEN 126 ssh(:,:,Naa) = ssh(:,:,Nnn) ! init ssh after in ln_linssh case 125 IF( kstp == nit000 .AND. ln_linssh) THEN 126 ssh(:,:,Naa) = ssh(:,:,Nnn) ! init ssh after in ln_linssh case 127 127 ENDIF 128 128 ! -
NEMO/trunk/src/OCE/DIA/diaar5.F90
r13982 r14072 10 10 !! dia_ar5_init : initialisation of AR5 diagnostics 11 11 !!---------------------------------------------------------------------- 12 USE oce ! ocean dynamics and active tracers 12 USE oce ! ocean dynamics and active tracers 13 13 USE dom_oce ! ocean space and time domain 14 14 USE eosbn2 ! equation of state (eos_bn2 routine) … … 37 37 38 38 LOGICAL :: l_ar5 39 39 40 40 !! * Substitutions 41 41 # include "do_loop_substitute.h90" … … 78 78 REAL(wp) :: zaw, zbw, zrw 79 79 ! 80 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zarea_ssh , zbotpres ! 2D workspace 81 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: z2d, zpe ! 2D workspace 80 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zarea_ssh , zbotpres ! 2D workspace 81 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: z2d, zpe ! 2D workspace 82 82 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: z3d, zrhd, ztpot, zgdept ! 3D workspace (zgdept: needed to use the substitute) 83 83 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: ztsn ! 4D workspace … … 85 85 !!-------------------------------------------------------------------- 86 86 IF( ln_timing ) CALL timing_start('dia_ar5') 87 87 88 88 IF( kt == nit000 ) CALL dia_ar5_init 89 89 90 IF( l_ar5 ) THEN 90 IF( l_ar5 ) THEN 91 91 ALLOCATE( zarea_ssh(jpi,jpj), zbotpres(jpi,jpj), z2d(jpi,jpj) ) 92 92 ALLOCATE( zrhd(jpi,jpj,jpk) ) … … 99 99 CALL iom_put( 'areacello', e1e2t(:,:) ) 100 100 ! 101 IF( iom_use( 'volcello' ) .OR. iom_use( 'masscello' ) ) THEN 101 IF( iom_use( 'volcello' ) .OR. iom_use( 'masscello' ) ) THEN 102 102 zrhd(:,:,jpk) = 0._wp ! ocean volume ; rhd is used as workspace 103 103 DO jk = 1, jpkm1 … … 106 106 DO jk = 1, jpk 107 107 z3d(:,:,jk) = rho0 * e3t(:,:,jk,Kmm) * tmask(:,:,jk) 108 END DO 108 END DO 109 109 CALL iom_put( 'volcello' , zrhd(:,:,:) ) ! WARNING not consistent with CMIP DR where volcello is at ca. 2000 110 110 CALL iom_put( 'masscello' , z3d (:,:,:) ) ! ocean mass 111 ENDIF 111 ENDIF 112 112 ! 113 113 IF( iom_use( 'e3tb' ) ) THEN ! bottom layer thickness … … 117 117 END_2D 118 118 CALL iom_put( 'e3tb', z2d ) 119 ENDIF 120 ! 121 IF( iom_use( 'voltot' ) .OR. iom_use( 'sshtot' ) .OR. iom_use( 'sshdyn' ) ) THEN 119 ENDIF 120 ! 121 IF( iom_use( 'voltot' ) .OR. iom_use( 'sshtot' ) .OR. iom_use( 'sshdyn' ) ) THEN 122 122 ! ! total volume of liquid seawater 123 zvolssh = glob_sum( 'diaar5', zarea_ssh(:,:) ) 123 zvolssh = glob_sum( 'diaar5', zarea_ssh(:,:) ) 124 124 zvol = vol0 + zvolssh 125 125 126 126 CALL iom_put( 'voltot', zvol ) 127 127 CALL iom_put( 'sshtot', zvolssh / area_tot ) … … 130 130 ENDIF 131 131 132 IF( iom_use( 'botpres' ) .OR. iom_use( 'sshthster' ) .OR. iom_use( 'sshsteric' ) ) THEN 133 ! 132 IF( iom_use( 'botpres' ) .OR. iom_use( 'sshthster' ) .OR. iom_use( 'sshsteric' ) ) THEN 133 ! 134 134 ztsn(:,:,:,jp_tem) = ts(:,:,:,jp_tem,Kmm) ! thermosteric ssh 135 135 ztsn(:,:,:,jp_sal) = sn0(:,:,:) … … 157 157 !!gm 158 158 END IF 159 ! 160 zarho = glob_sum( 'diaar5', e1e2t(:,:) * zbotpres(:,:) ) 159 ! 160 zarho = glob_sum( 'diaar5', e1e2t(:,:) * zbotpres(:,:) ) 161 161 zssh_steric = - zarho / area_tot 162 162 CALL iom_put( 'sshthster', zssh_steric ) 163 163 164 164 ! ! steric sea surface height 165 165 zbotpres(:,:) = 0._wp ! no atmospheric surface pressure, levitating sea-ice … … 179 179 END IF 180 180 END IF 181 ! 182 zarho = glob_sum( 'diaar5', e1e2t(:,:) * zbotpres(:,:) ) 181 ! 182 zarho = glob_sum( 'diaar5', e1e2t(:,:) * zbotpres(:,:) ) 183 183 zssh_steric = - zarho / area_tot 184 184 CALL iom_put( 'sshsteric', zssh_steric ) … … 192 192 ENDIF 193 193 194 IF( iom_use( 'masstot' ) .OR. iom_use( 'temptot' ) .OR. iom_use( 'saltot' ) ) THEN 194 IF( iom_use( 'masstot' ) .OR. iom_use( 'temptot' ) .OR. iom_use( 'saltot' ) ) THEN 195 195 ! ! Mean density anomalie, temperature and salinity 196 196 ztsn(:,:,:,:) = 0._wp ! ztsn(:,:,1,jp_tem/sal) is used here as 2D Workspace for temperature & salinity … … 206 206 DO jj = 1, jpj 207 207 iks = mikt(ji,jj) 208 ztsn(ji,jj,1,jp_tem) = ztsn(ji,jj,1,jp_tem) + zarea_ssh(ji,jj) * ts(ji,jj,iks,jp_tem,Kmm) 209 ztsn(ji,jj,1,jp_sal) = ztsn(ji,jj,1,jp_sal) + zarea_ssh(ji,jj) * ts(ji,jj,iks,jp_sal,Kmm) 208 ztsn(ji,jj,1,jp_tem) = ztsn(ji,jj,1,jp_tem) + zarea_ssh(ji,jj) * ts(ji,jj,iks,jp_tem,Kmm) 209 ztsn(ji,jj,1,jp_sal) = ztsn(ji,jj,1,jp_sal) + zarea_ssh(ji,jj) * ts(ji,jj,iks,jp_sal,Kmm) 210 210 END DO 211 211 END DO 212 212 ELSE 213 ztsn(:,:,1,jp_tem) = ztsn(:,:,1,jp_tem) + zarea_ssh(:,:) * ts(:,:,1,jp_tem,Kmm) 214 ztsn(:,:,1,jp_sal) = ztsn(:,:,1,jp_sal) + zarea_ssh(:,:) * ts(:,:,1,jp_sal,Kmm) 213 ztsn(:,:,1,jp_tem) = ztsn(:,:,1,jp_tem) + zarea_ssh(:,:) * ts(:,:,1,jp_tem,Kmm) 214 ztsn(:,:,1,jp_sal) = ztsn(:,:,1,jp_sal) + zarea_ssh(:,:) * ts(:,:,1,jp_sal,Kmm) 215 215 END IF 216 216 ENDIF … … 218 218 ztemp = glob_sum( 'diaar5', ztsn(:,:,1,jp_tem) ) 219 219 zsal = glob_sum( 'diaar5', ztsn(:,:,1,jp_sal) ) 220 zmass = rho0 * ( zarho + zvol ) 220 zmass = rho0 * ( zarho + zvol ) 221 221 ! 222 222 CALL iom_put( 'masstot', zmass ) … … 224 224 CALL iom_put( 'saltot' , zsal / zvol ) 225 225 ! 226 ENDIF 226 ENDIF 227 227 228 228 IF( ln_teos10 ) THEN ! ! potential temperature (TEOS-10 case) … … 244 244 z2d(:,:) = z2d(:,:) + e1e2t(:,:) * e3t(:,:,jk,Kmm) * ztpot(:,:,jk) 245 245 END DO 246 ztemp = glob_sum( 'diaar5', z2d(:,:) ) 246 ztemp = glob_sum( 'diaar5', z2d(:,:) ) 247 247 CALL iom_put( 'temptot_pot', ztemp / zvol ) 248 248 ENDIF 249 249 ! 250 250 IF( iom_use( 'ssttot' ) ) THEN ! Output potential temperature in case we use TEOS-10 251 zsst = glob_sum( 'diaar5', e1e2t(:,:) * ztpot(:,:,1) ) 251 zsst = glob_sum( 'diaar5', e1e2t(:,:) * ztpot(:,:,1) ) 252 252 CALL iom_put( 'ssttot', zsst / area_tot ) 253 253 ENDIF … … 258 258 z2d(ji,jj) = z2d(ji,jj) + rho0 * e3t(ji,jj,jk,Kmm) * ztpot(ji,jj,jk) 259 259 END_3D 260 CALL iom_put( 'tosmint_pot', z2d ) 260 CALL iom_put( 'tosmint_pot', z2d ) 261 261 ENDIF 262 262 DEALLOCATE( ztpot ) 263 263 ENDIF 264 ELSE 264 ELSE 265 265 IF( iom_use('ssttot') ) THEN ! Output sst in case we use EOS-80 266 266 zsst = glob_sum( 'diaar5', e1e2t(:,:) * ts(:,:,1,jp_tem,Kmm) ) … … 269 269 ENDIF 270 270 271 IF( iom_use( 'tnpeo' )) THEN 271 IF( iom_use( 'tnpeo' )) THEN 272 272 ! Work done against stratification by vertical mixing 273 273 ! Exclude points where rn2 is negative as convection kicks in here and … … 358 358 ENDIF 359 359 ENDIF 360 360 361 361 END SUBROUTINE dia_ar5_hst 362 362 … … 365 365 !!---------------------------------------------------------------------- 366 366 !! *** ROUTINE dia_ar5_init *** 367 !! 367 !! 368 368 !! ** Purpose : initialization for AR5 diagnostic computation 369 369 !!---------------------------------------------------------------------- … … 371 371 INTEGER :: ik, idep 372 372 INTEGER :: ji, jj, jk ! dummy loop indices 373 REAL(wp) :: zztmp 373 REAL(wp) :: zztmp 374 374 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: zsaldta ! Jan/Dec levitus salinity 375 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zvol0 375 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zvol0 376 376 ! 377 377 !!---------------------------------------------------------------------- 378 378 ! 379 379 l_ar5 = .FALSE. 380 IF( iom_use( 'voltot' ) .OR. iom_use( 'sshtot' ) .OR. iom_use( 'sshdyn' ) .OR. & 381 & iom_use( 'masstot' ) .OR. iom_use( 'temptot' ) .OR. iom_use( 'saltot' ) .OR. & 380 IF( iom_use( 'voltot' ) .OR. iom_use( 'sshtot' ) .OR. iom_use( 'sshdyn' ) .OR. & 381 & iom_use( 'masstot' ) .OR. iom_use( 'temptot' ) .OR. iom_use( 'saltot' ) .OR. & 382 382 & iom_use( 'botpres' ) .OR. iom_use( 'sshthster' ) .OR. iom_use( 'sshsteric' ) .OR. & 383 383 & iom_use( 'uadv_heattr' ) .OR. iom_use( 'udiff_heattr' ) .OR. & … … 386 386 & iom_use( 'vadv_salttr' ) .OR. iom_use( 'vdiff_salttr' ) .OR. & 387 387 & iom_use( 'rhop' ) ) L_ar5 = .TRUE. 388 388 389 389 IF( l_ar5 ) THEN 390 390 ! … … 400 400 idep = tmask(ji,jj,jk) * e3t_0(ji,jj,jk) 401 401 zvol0 (ji,jj) = zvol0 (ji,jj) + idep * e1e2t(ji,jj) 402 thick0(ji,jj) = thick0(ji,jj) + idep 402 thick0(ji,jj) = thick0(ji,jj) + idep 403 403 END_3D 404 404 vol0 = glob_sum( 'diaar5', zvol0 ) … … 412 412 CALL iom_close( inum ) 413 413 414 sn0(:,:,:) = 0.5_wp * ( zsaldta(:,:,:,1) + zsaldta(:,:,:,2) ) 414 sn0(:,:,:) = 0.5_wp * ( zsaldta(:,:,:,1) + zsaldta(:,:,:,2) ) 415 415 sn0(:,:,:) = sn0(:,:,:) * tmask(:,:,:) 416 416 IF( ln_zps ) THEN ! z-coord. partial steps -
NEMO/trunk/src/OCE/DIA/diahsb.F90
r13970 r14072 4 4 !! Ocean diagnostics: Heat, salt and volume budgets 5 5 !!====================================================================== 6 !! History : 3.3 ! 2010-09 (M. Leclair) Original code 6 !! History : 3.3 ! 2010-09 (M. Leclair) Original code 7 7 !! ! 2012-10 (C. Rousset) add iom_put 8 8 !!---------------------------------------------------------------------- … … 21 21 USE domvvl ! vertical scale factors 22 22 USE traqsr ! penetrative solar radiation 23 USE trabbc ! bottom boundary condition 23 USE trabbc ! bottom boundary condition 24 24 USE trabbc ! bottom boundary condition 25 25 USE restart ! ocean restart … … 44 44 REAL(wp) :: frc_wn_t, frc_wn_s ! global forcing trends 45 45 ! 46 REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: surf 46 REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: surf 47 47 REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: surf_ini , ssh_ini ! 48 48 REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: ssh_hc_loc_ini, ssh_sc_loc_ini ! … … 62 62 !!--------------------------------------------------------------------------- 63 63 !! *** ROUTINE dia_hsb *** 64 !! 64 !! 65 65 !! ** Purpose: Compute the ocean global heat content, salt content and volume conservation 66 !! 66 !! 67 67 !! ** Method : - Compute the deviation of heat content, salt content and volume 68 68 !! at the current time step from their values at nit000 … … 75 75 INTEGER :: ji, jj, jk ! dummy loop indice 76 76 REAL(wp) :: zdiff_hc , zdiff_sc ! heat and salt content variations 77 REAL(wp) :: zdiff_hc1 , zdiff_sc1 ! - - - - 77 REAL(wp) :: zdiff_hc1 , zdiff_sc1 ! - - - - 78 78 REAL(wp) :: zdiff_v1 , zdiff_v2 ! volume variation 79 79 REAL(wp) :: zerr_hc1 , zerr_sc1 ! heat and salt content misfit … … 86 86 REAL(wp), DIMENSION(jpi,jpj,jpkm1) :: zwrk ! 3D workspace 87 87 !!--------------------------------------------------------------------------- 88 IF( ln_timing ) CALL timing_start('dia_hsb') 88 IF( ln_timing ) CALL timing_start('dia_hsb') 89 89 ! 90 90 ts(:,:,:,1,Kmm) = ts(:,:,:,1,Kmm) * tmask(:,:,:) ; ts(:,:,:,1,Kbb) = ts(:,:,:,1,Kbb) * tmask(:,:,:) ; … … 119 119 z2d1(:,:) = surf(:,:) * ww(:,:,1) * ts(:,:,1,jp_sal,Kbb) 120 120 END IF 121 z_wn_trd_t = - glob_sum( 'diahsb', z2d0 ) 121 z_wn_trd_t = - glob_sum( 'diahsb', z2d0 ) 122 122 z_wn_trd_s = - glob_sum( 'diahsb', z2d1 ) 123 123 ENDIF … … 145 145 DO ji = 1, jpi 146 146 DO jj = 1, jpj 147 z2d0(ji,jj) = surf(ji,jj) * ( ts(ji,jj,mikt(ji,jj),jp_tem,Kmm) * ssh(ji,jj,Kmm) - ssh_hc_loc_ini(ji,jj) ) 148 z2d1(ji,jj) = surf(ji,jj) * ( ts(ji,jj,mikt(ji,jj),jp_sal,Kmm) * ssh(ji,jj,Kmm) - ssh_sc_loc_ini(ji,jj) ) 147 z2d0(ji,jj) = surf(ji,jj) * ( ts(ji,jj,mikt(ji,jj),jp_tem,Kmm) * ssh(ji,jj,Kmm) - ssh_hc_loc_ini(ji,jj) ) 148 z2d1(ji,jj) = surf(ji,jj) * ( ts(ji,jj,mikt(ji,jj),jp_sal,Kmm) * ssh(ji,jj,Kmm) - ssh_sc_loc_ini(ji,jj) ) 149 149 END DO 150 150 END DO 151 151 ELSE ! no under ice-shelf seas 152 z2d0(:,:) = surf(:,:) * ( ts(:,:,1,jp_tem,Kmm) * ssh(:,:,Kmm) - ssh_hc_loc_ini(:,:) ) 153 z2d1(:,:) = surf(:,:) * ( ts(:,:,1,jp_sal,Kmm) * ssh(:,:,Kmm) - ssh_sc_loc_ini(:,:) ) 152 z2d0(:,:) = surf(:,:) * ( ts(:,:,1,jp_tem,Kmm) * ssh(:,:,Kmm) - ssh_hc_loc_ini(:,:) ) 153 z2d1(:,:) = surf(:,:) * ( ts(:,:,1,jp_sal,Kmm) * ssh(:,:,Kmm) - ssh_sc_loc_ini(:,:) ) 154 154 END IF 155 z_ssh_hc = glob_sum_full( 'diahsb', z2d0 ) 156 z_ssh_sc = glob_sum_full( 'diahsb', z2d1 ) 155 z_ssh_hc = glob_sum_full( 'diahsb', z2d0 ) 156 z_ssh_sc = glob_sum_full( 'diahsb', z2d1 ) 157 157 ENDIF 158 158 ! … … 181 181 zdiff_sc = zdiff_sc - frc_s 182 182 IF( ln_linssh ) THEN 183 zdiff_hc1 = zdiff_hc + z_ssh_hc 183 zdiff_hc1 = zdiff_hc + z_ssh_hc 184 184 zdiff_sc1 = zdiff_sc + z_ssh_sc 185 185 zerr_hc1 = z_ssh_hc - frc_wn_t … … 201 201 !!gm end 202 202 203 CALL iom_put( 'bgfrcvol' , frc_v * 1.e-9 ) ! vol - surface forcing (km3) 204 CALL iom_put( 'bgfrctem' , frc_t * rho0 * rcp * 1.e-20 ) ! hc - surface forcing (1.e20 J) 205 CALL iom_put( 'bgfrchfx' , frc_t * rho0 * rcp / & ! hc - surface forcing (W/m2) 203 CALL iom_put( 'bgfrcvol' , frc_v * 1.e-9 ) ! vol - surface forcing (km3) 204 CALL iom_put( 'bgfrctem' , frc_t * rho0 * rcp * 1.e-20 ) ! hc - surface forcing (1.e20 J) 205 CALL iom_put( 'bgfrchfx' , frc_t * rho0 * rcp / & ! hc - surface forcing (W/m2) 206 206 & ( surf_tot * kt * rn_Dt ) ) 207 CALL iom_put( 'bgfrcsal' , frc_s * 1.e-9 ) ! sc - surface forcing (psu*km3) 207 CALL iom_put( 'bgfrcsal' , frc_s * 1.e-9 ) ! sc - surface forcing (psu*km3) 208 208 209 209 IF( .NOT. ln_linssh ) THEN 210 CALL iom_put( 'bgtemper' , zdiff_hc / zvol_tot ) ! Temperature drift (C) 210 CALL iom_put( 'bgtemper' , zdiff_hc / zvol_tot ) ! Temperature drift (C) 211 211 CALL iom_put( 'bgsaline' , zdiff_sc / zvol_tot ) ! Salinity drift (PSU) 212 CALL iom_put( 'bgheatco' , zdiff_hc * 1.e-20 * rho0 * rcp ) ! Heat content drift (1.e20 J) 213 CALL iom_put( 'bgheatfx' , zdiff_hc * rho0 * rcp / & ! Heat flux drift (W/m2) 212 CALL iom_put( 'bgheatco' , zdiff_hc * 1.e-20 * rho0 * rcp ) ! Heat content drift (1.e20 J) 213 CALL iom_put( 'bgheatfx' , zdiff_hc * rho0 * rcp / & ! Heat flux drift (W/m2) 214 214 & ( surf_tot * kt * rn_Dt ) ) 215 215 CALL iom_put( 'bgsaltco' , zdiff_sc * 1.e-9 ) ! Salt content drift (psu*km3) 216 CALL iom_put( 'bgvolssh' , zdiff_v1 * 1.e-9 ) ! volume ssh drift (km3) 217 CALL iom_put( 'bgvole3t' , zdiff_v2 * 1.e-9 ) ! volume e3t drift (km3) 216 CALL iom_put( 'bgvolssh' , zdiff_v1 * 1.e-9 ) ! volume ssh drift (km3) 217 CALL iom_put( 'bgvole3t' , zdiff_v2 * 1.e-9 ) ! volume e3t drift (km3) 218 218 ! 219 219 IF( kt == nitend .AND. lwp ) THEN … … 228 228 ! 229 229 ELSE 230 CALL iom_put( 'bgtemper' , zdiff_hc1 / zvol_tot) ! Heat content drift (C) 230 CALL iom_put( 'bgtemper' , zdiff_hc1 / zvol_tot) ! Heat content drift (C) 231 231 CALL iom_put( 'bgsaline' , zdiff_sc1 / zvol_tot) ! Salt content drift (PSU) 232 CALL iom_put( 'bgheatco' , zdiff_hc1 * 1.e-20 * rho0 * rcp ) ! Heat content drift (1.e20 J) 233 CALL iom_put( 'bgheatfx' , zdiff_hc1 * rho0 * rcp / & ! Heat flux drift (W/m2) 232 CALL iom_put( 'bgheatco' , zdiff_hc1 * 1.e-20 * rho0 * rcp ) ! Heat content drift (1.e20 J) 233 CALL iom_put( 'bgheatfx' , zdiff_hc1 * rho0 * rcp / & ! Heat flux drift (W/m2) 234 234 & ( surf_tot * kt * rn_Dt ) ) 235 235 CALL iom_put( 'bgsaltco' , zdiff_sc1 * 1.e-9 ) ! Salt content drift (psu*km3) 236 CALL iom_put( 'bgvolssh' , zdiff_v1 * 1.e-9 ) ! volume ssh drift (km3) 236 CALL iom_put( 'bgvolssh' , zdiff_v1 * 1.e-9 ) ! volume ssh drift (km3) 237 237 CALL iom_put( 'bgmistem' , zerr_hc1 / zvol_tot ) ! hc - error due to free surface (C) 238 238 CALL iom_put( 'bgmissal' , zerr_sc1 / zvol_tot ) ! sc - error due to free surface (psu) … … 249 249 !!--------------------------------------------------------------------- 250 250 !! *** ROUTINE dia_hsb_rst *** 251 !! 251 !! 252 252 !! ** Purpose : Read or write DIA file in restart file 253 253 !! … … 261 261 !!---------------------------------------------------------------------- 262 262 ! 263 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 263 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 264 264 IF( ln_rstart ) THEN !* Read the restart file 265 265 ! … … 298 298 END DO 299 299 frc_v = 0._wp ! volume trend due to forcing 300 frc_t = 0._wp ! heat content - - - - 301 frc_s = 0._wp ! salt content - - - - 300 frc_t = 0._wp ! heat content - - - - 301 frc_s = 0._wp ! salt content - - - - 302 302 IF( ln_linssh ) THEN 303 303 IF( ln_isfcav ) THEN … … 349 349 !!--------------------------------------------------------------------------- 350 350 !! *** ROUTINE dia_hsb *** 351 !! 351 !! 352 352 !! ** Purpose: Initialization for the heat salt volume budgets 353 !! 353 !! 354 354 !! ** Method : Compute initial heat content, salt content and volume 355 355 !! … … 403 403 surf_tot = glob_sum( 'diahsb', surf(:,:) ) ! total ocean surface area 404 404 405 IF( ln_bdy ) CALL ctl_warn( 'dia_hsb_init: heat/salt budget does not consider open boundary fluxes' ) 405 IF( ln_bdy ) CALL ctl_warn( 'dia_hsb_init: heat/salt budget does not consider open boundary fluxes' ) 406 406 ! 407 407 ! ---------------------------------- ! -
NEMO/trunk/src/OCE/DIA/diaptr.F90
r13982 r14072 66 66 !!---------------------------------------------------------------------- 67 67 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 68 !! $Id$ 68 !! $Id$ 69 69 !! Software governed by the CeCILL license (see ./LICENSE) 70 70 !!---------------------------------------------------------------------- … … 75 75 !! *** ROUTINE dia_ptr *** 76 76 !!---------------------------------------------------------------------- 77 INTEGER , INTENT(in) :: kt ! ocean time-step index 77 INTEGER , INTENT(in) :: kt ! ocean time-step index 78 78 INTEGER , INTENT(in) :: Kmm ! time level index 79 79 REAL(wp), DIMENSION(A2D(nn_hls),jpk) , INTENT(in), OPTIONAL :: pvtr ! j-effective transport … … 177 177 178 178 IF( iom_use( 'sopstbtr' ) .OR. iom_use( 'sophtbtr' ) ) THEN 179 ! Calculate barotropic heat and salt transport here 179 ! Calculate barotropic heat and salt transport here 180 180 ALLOCATE( sjk(jpj,1,nbasin), r1_sjk(jpj,1,nbasin) ) 181 181 ! … … 245 245 ! 246 246 ! ! Advective and diffusive heat and salt transport 247 IF( iom_use( 'sophtadv' ) .OR. iom_use( 'sopstadv' ) ) THEN 248 ! 247 IF( iom_use( 'sophtadv' ) .OR. iom_use( 'sopstadv' ) ) THEN 248 ! 249 249 DO jn = 1, nbasin 250 250 z3dtr(1,:,jn) = hstr_adv(:,jp_tem,jn) * rc_pwatt ! (conversion in PW) … … 263 263 ENDIF 264 264 ! 265 IF( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) THEN 266 ! 265 IF( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) THEN 266 ! 267 267 DO jn = 1, nbasin 268 268 z3dtr(1,:,jn) = hstr_ldf(:,jp_tem,jn) * rc_pwatt ! (conversion in PW) … … 281 281 ENDIF 282 282 ! 283 IF( iom_use( 'sophteiv' ) .OR. iom_use( 'sopsteiv' ) ) THEN 284 ! 283 IF( iom_use( 'sophteiv' ) .OR. iom_use( 'sopsteiv' ) ) THEN 284 ! 285 285 DO jn = 1, nbasin 286 286 z3dtr(1,:,jn) = hstr_eiv(:,jp_tem,jn) * rc_pwatt ! (conversion in PW) … … 319 319 IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 ) ! Use full domain 320 320 CALL iom_get_var( 'uocetr_vsum_op', z2d ) ! get uocetr_vsum_op from xml 321 z2d(:,:) = ptr_ci_2d( z2d(:,:) ) 321 z2d(:,:) = ptr_ci_2d( z2d(:,:) ) 322 322 CALL iom_put( 'uocetr_vsum_cumul', z2d ) 323 323 IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = nijtile ) ! Revert to tile domain … … 455 455 !!---------------------------------------------------------------------- 456 456 !! *** ROUTINE dia_ptr_init *** 457 !! 457 !! 458 458 !! ** Purpose : Initialization 459 459 !!---------------------------------------------------------------------- … … 472 472 & iom_use( 'sophteiv' ) .OR. iom_use( 'sopsteiv' ) .OR. iom_use( 'sopstvtr' ) .OR. & 473 473 & iom_use( 'sophtvtr' ) .OR. iom_use( 'uocetr_vsum_cumul' ) 474 474 475 475 IF(lwp) THEN ! Control print 476 476 WRITE(numout,*) … … 480 480 ENDIF 481 481 482 IF( l_diaptr ) THEN 482 IF( l_diaptr ) THEN 483 483 ! 484 484 IF( dia_ptr_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'dia_ptr_init : unable to allocate arrays' ) … … 489 489 IF( lk_mpp ) CALL mpp_ini_znl( numout ) ! Define MPI communicator for zonal sum 490 490 491 btmsk(:,:,1) = tmask_i(:,:) 491 btmsk(:,:,1) = tmask_i(:,:) 492 492 IF( nbasin == 5 ) THEN ! nbasin has been initialized in iom_init to define the axis "basin" 493 493 CALL iom_open( 'subbasins', inum ) … … 504 504 WHERE( gphit(:,:)*tmask_i(:,:) < -34._wp) 505 505 zmsk(:,:) = 0._wp ! mask out Southern Ocean 506 ELSE WHERE 506 ELSE WHERE 507 507 zmsk(:,:) = ssmask(:,:) 508 508 END WHERE 509 btmsk34(:,:,1) = btmsk(:,:,1) 509 btmsk34(:,:,1) = btmsk(:,:,1) 510 510 DO jn = 2, nbasin 511 511 btmsk34(:,:,jn) = btmsk(:,:,jn) * zmsk(:,:) ! interior domain only … … 514 514 ! Initialise arrays to zero because diatpr is called before they are first calculated 515 515 ! Note that this means diagnostics will not be exactly correct when model run is restarted. 516 hstr_adv(:,:,:) = 0._wp 517 hstr_ldf(:,:,:) = 0._wp 518 hstr_eiv(:,:,:) = 0._wp 519 hstr_ove(:,:,:) = 0._wp 516 hstr_adv(:,:,:) = 0._wp 517 hstr_ldf(:,:,:) = 0._wp 518 hstr_eiv(:,:,:) = 0._wp 519 hstr_ove(:,:,:) = 0._wp 520 520 hstr_btr(:,:,:) = 0._wp ! 521 521 hstr_vtr(:,:,:) = 0._wp ! … … 525 525 ll_init = .FALSE. 526 526 ! 527 ENDIF 528 ! 527 ENDIF 528 ! 529 529 END SUBROUTINE dia_ptr_init 530 530 531 531 532 SUBROUTINE dia_ptr_hst( ktra, cptr, pvflx ) 532 SUBROUTINE dia_ptr_hst( ktra, cptr, pvflx ) 533 533 !!---------------------------------------------------------------------- 534 534 !! *** ROUTINE dia_ptr_hst *** … … 727 727 ! 728 728 INTEGER :: ji,jj,jc ! dummy loop arguments 729 INTEGER :: ijpj ! ??? 729 INTEGER :: ijpj ! ??? 730 730 REAL(wp), DIMENSION(jpi,jpj) :: p_fval ! function value 731 731 !!-------------------------------------------------------------------- 732 ! 732 ! 733 733 ijpj = jpj ! ??? 734 734 p_fval(:,:) = 0._wp … … 738 738 END_2D 739 739 END DO 740 ! 740 ! 741 741 END FUNCTION ptr_ci_2d 742 742 -
NEMO/trunk/src/OCE/DIU/diu_coolskin.F90
r13722 r14072 20 20 USE lib_mpp 21 21 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 22 22 23 23 IMPLICIT NONE 24 24 PRIVATE … … 34 34 REAL(wp), PRIVATE, PARAMETER :: pp_rhoa = 1.20421_wp ! density of air (at 20C) 35 35 REAL(wp), PRIVATE, PARAMETER :: pp_cda = 1.45e-3_wp ! assumed air-sea drag coefficient for calculating wind speed 36 36 37 37 ! Key variables 38 38 REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:) :: x_csdsst ! Cool skin delta SST … … 46 46 !! $Id$ 47 47 !! Software governed by the CeCILL license (see ./LICENSE) 48 !!---------------------------------------------------------------------- 49 CONTAINS 50 48 !!---------------------------------------------------------------------- 49 CONTAINS 50 51 51 SUBROUTINE diurnal_sst_coolskin_init 52 52 !!---------------------------------------------------------------------- … … 55 55 !! ** Purpose : initialise the cool skin model 56 56 !! 57 !! ** Method : 57 !! ** Method : 58 58 !! 59 59 !! ** Reference : 60 !! 60 !! 61 61 !!---------------------------------------------------------------------- 62 62 ALLOCATE( x_csdsst(jpi,jpj), x_csthick(jpi,jpj) ) … … 73 73 !! ** Purpose : Time-step the Artale cool skin model 74 74 !! 75 !! ** Method : 75 !! ** Method : 76 76 !! 77 !! ** Reference : 77 !! ** Reference : 78 78 !!---------------------------------------------------------------------- 79 79 ! Dummy variables … … 82 82 REAL(wp), INTENT(IN), DIMENSION(jpi,jpj) :: psrho ! Water density (kg/m^3) 83 83 REAL(wp), INTENT(IN) :: pDt ! Time-step 84 84 85 85 ! Local variables 86 REAL(wp), DIMENSION(jpi,jpj) :: z_fv ! Friction velocity 86 REAL(wp), DIMENSION(jpi,jpj) :: z_fv ! Friction velocity 87 87 REAL(wp), DIMENSION(jpi,jpj) :: z_gamma ! Dimensionless function of wind speed 88 88 REAL(wp), DIMENSION(jpi,jpj) :: z_lamda ! Sauders (dimensionless) proportionality constant … … 91 91 REAL(wp) :: z_zty ! Temporary v wind stress 92 92 REAL(wp) :: z_zmod ! Temporary total wind stress 93 93 94 94 INTEGER :: ji,jj 95 95 !!---------------------------------------------------------------------- … … 105 105 ELSE 106 106 z_fv(ji,jj) = 0. 107 z_wspd(ji,jj) = 0. 107 z_wspd(ji,jj) = 0. 108 108 ENDIF 109 109 ! -
NEMO/trunk/src/OCE/DOM/daymod.F90
r13970 r14072 19 19 !! ----------- WARNING ----------- 20 20 !! ------------------------------- 21 !! sbcmod assume that the time step is dividing the number of second of 22 !! in a day, i.e. ===> MOD( rday, rn_Dt ) == 0 21 !! sbcmod assume that the time step is dividing the number of second of 22 !! in a day, i.e. ===> MOD( rday, rn_Dt ) == 0 23 23 !! except when user defined forcing is used (see sbcmod.F90) 24 24 !!---------------------------------------------------------------------- … … 84 84 lrst_oce = .NOT. l_offline ! force definition of offline 85 85 IF( lrst_oce ) CALL day_rst( nit000, 'READ' ) 86 86 87 87 ! set the calandar from ndastp (read in restart file and namelist) 88 88 nyear = ndastp / 10000 … … 94 94 isecrst = ( nhour * NINT(rhhmm) + nminute ) * NINT(rmmss) 95 95 96 CALL ymds2ju( nyear, nmonth, nday, REAL(isecrst,wp), fjulday ) 96 CALL ymds2ju( nyear, nmonth, nday, REAL(isecrst,wp), fjulday ) 97 97 IF( ABS(fjulday - REAL(NINT(fjulday),wp)) < 0.1 / rday ) fjulday = REAL(NINT(fjulday),wp) ! avoid truncation error 98 98 IF( nhour*NINT(rhhmm*rmmss) + nminute*NINT(rmmss) - ndt05 .LT. 0 ) fjulday = fjulday+1. ! move back to the day at nit000 (and not at nit000 - 1) … … 124 124 IF( isecrst - ndt05 .GT. 0 ) THEN 125 125 ! 1 timestep before current middle of first time step is still the same day 126 nsec_year = (nday_year-1) * nsecd + isecrst - ndt05 127 nsec_month = (nday-1) * nsecd + isecrst - ndt05 126 nsec_year = (nday_year-1) * nsecd + isecrst - ndt05 127 nsec_month = (nday-1) * nsecd + isecrst - ndt05 128 128 ELSE 129 ! 1 time step before the middle of the first time step is the previous day 130 nsec_year = nday_year * nsecd + isecrst - ndt05 131 nsec_month = nday * nsecd + isecrst - ndt05 129 ! 1 time step before the middle of the first time step is the previous day 130 nsec_year = nday_year * nsecd + isecrst - ndt05 131 nsec_month = nday * nsecd + isecrst - ndt05 132 132 ENDIF 133 133 nsec_monday = imonday * nsecd + isecrst - ndt05 134 nsec_day = isecrst - ndt05 134 nsec_day = isecrst - ndt05 135 135 IF( nsec_day .LT. 0 ) nsec_day = nsec_day + nsecd 136 136 IF( nsec_monday .LT. 0 ) nsec_monday = nsec_monday + nsecd*7 … … 144 144 nsec000_1jan000 = nsec1jan000 + nsec_year + ndt05 145 145 nsecend_1jan000 = nsec000_1jan000 + ndt * ( nitend - nit000 + 1 ) 146 146 147 147 ! Up to now, calendar parameters are related to the end of previous run (nit000-1) 148 148 ! call day to set the calendar parameters at the begining of the current simulaton. needed by iom_init … … 344 344 ! calculate start time in hours and minutes 345 345 zdayfrac = adatrj - REAL(INT(adatrj), wp) 346 ksecs = NINT(zdayfrac * rday) ! Nearest second to catch rounding errors in adatrj 346 ksecs = NINT(zdayfrac * rday) ! Nearest second to catch rounding errors in adatrj 347 347 ihour = ksecs / NINT( rhhmm*rmmss ) 348 348 iminute = ksecs / NINT(rmmss) - ihour*NINT(rhhmm) 349 349 350 350 ! Add to nn_time0 351 351 nhour = nn_time0 / 100 352 352 nminute = ( nn_time0 - nhour * 100 ) 353 353 nminute = nminute + iminute 354 354 355 355 IF( nminute >= NINT(rhhmm) ) THEN 356 356 nminute = nminute - NINT(rhhmm) … … 361 361 nhour = nhour - NINT(rjjhh) 362 362 adatrj = adatrj + 1. 363 ENDIF 363 ENDIF 364 364 nn_time0 = nhour * 100 + nminute 365 adatrj = REAL(INT(adatrj), wp) ! adatrj set to integer as nn_time0 updated 365 adatrj = REAL(INT(adatrj), wp) ! adatrj set to integer as nn_time0 updated 366 366 ELSE 367 367 ! parameters corresponding to nit000 - 1 (as we start the step loop with a call to day) -
NEMO/trunk/src/OCE/DOM/dom_oce.F90
r14053 r14072 4 4 !! ** Purpose : Define in memory all the ocean space domain variables 5 5 !!====================================================================== 6 !! History : 1.0 ! 2005-10 (A. Beckmann, G. Madec) reactivate s-coordinate 6 !! History : 1.0 ! 2005-10 (A. Beckmann, G. Madec) reactivate s-coordinate 7 7 !! 3.3 ! 2010-11 (G. Madec) add mbk. arrays associated to the deepest ocean level 8 8 !! 3.4 ! 2011-01 (A. R. Porter, STFC Daresbury) dynamical allocation … … 72 72 ! ! = 6 cyclic East-West AND North fold F-point pivot 73 73 ! ! = 7 bi-cyclic East-West AND North-South 74 LOGICAL, PUBLIC :: l_Iperio, l_Jperio ! should we explicitely take care I/J periodicity 74 LOGICAL, PUBLIC :: l_Iperio, l_Jperio ! should we explicitely take care I/J periodicity 75 75 76 76 ! Tiling namelist … … 91 91 INTEGER, ALLOCATABLE, PUBLIC :: nbondi_bdy(:) !: mark i-direction local boundaries for BDY open boundaries 92 92 INTEGER, ALLOCATABLE, PUBLIC :: nbondj_bdy(:) !: mark j-direction local boundaries for BDY open boundaries 93 INTEGER, ALLOCATABLE, PUBLIC :: nbondi_bdy_b(:) !: mark i-direction of neighbours local boundaries for BDY open boundaries 94 INTEGER, ALLOCATABLE, PUBLIC :: nbondj_bdy_b(:) !: mark j-direction of neighbours local boundaries for BDY open boundaries 93 INTEGER, ALLOCATABLE, PUBLIC :: nbondi_bdy_b(:) !: mark i-direction of neighbours local boundaries for BDY open boundaries 94 INTEGER, ALLOCATABLE, PUBLIC :: nbondj_bdy_b(:) !: mark j-direction of neighbours local boundaries for BDY open boundaries 95 95 96 96 INTEGER, PUBLIC :: npolj !: north fold mark (0, 3 or 4) 97 97 INTEGER, PUBLIC :: noea, nowe !: index of the local neighboring processors in 98 98 INTEGER, PUBLIC :: noso, nono !: east, west, south and north directions 99 INTEGER, PUBLIC :: nones, nonws !: north-east, north-west directions for sending 99 INTEGER, PUBLIC :: nones, nonws !: north-east, north-west directions for sending 100 100 INTEGER, PUBLIC :: noses, nosws !: south-east, south-west directions for sending 101 101 INTEGER, PUBLIC :: noner, nonwr !: north-east, north-west directions for receiving … … 142 142 LOGICAL, PUBLIC :: ln_zps !: z-coordinate - partial step 143 143 LOGICAL, PUBLIC :: ln_sco !: s-coordinate or hybrid z-s coordinate 144 LOGICAL, PUBLIC :: ln_isfcav !: presence of ISF 144 LOGICAL, PUBLIC :: ln_isfcav !: presence of ISF 145 145 ! ! reference scale factors 146 146 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: e3t_0 !: t- vert. scale factor [m] … … 166 166 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: gde3w_0 !: w- depth (sum of e3w) [m] 167 167 ! ! time-dependent depths of cells 168 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) :: gdept, gdepw 169 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: gde3w 170 168 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) :: gdept, gdepw 169 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: gde3w 170 171 171 ! ! reference heights of ocean water column and its inverse 172 172 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: ht_0, r1_ht_0 !: t-depth [m] and [1/m] … … 182 182 183 183 INTEGER, PUBLIC :: nla10 !: deepest W level Above ~10m (nlb10 - 1) 184 INTEGER, PUBLIC :: nlb10 !: shallowest W level Bellow ~10m (nla10 + 1) 184 INTEGER, PUBLIC :: nlb10 !: shallowest W level Bellow ~10m (nla10 + 1) 185 185 186 186 !! 1D reference vertical coordinate … … 207 207 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:), TARGET :: tmask, umask, vmask, wmask, fmask !: land/ocean mask at T-, U-, V-, W- and F-pts 208 208 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:), TARGET :: wumask, wvmask !: land/ocean mask at WU- and WV-pts 209 #if defined key_qco 209 #if defined key_qco 210 210 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:), TARGET :: fe3mask !: land/ocean mask at F-pts for qco 211 211 #endif … … 224 224 INTEGER , PUBLIC :: nsec_monday !: seconds between 00h of the last Monday and half of the current time step 225 225 INTEGER , PUBLIC :: nsec_day !: seconds between 00h of the current day and half of the current time step 226 REAL(wp), PUBLIC :: fjulday !: current julian day 226 REAL(wp), PUBLIC :: fjulday !: current julian day 227 227 REAL(wp), PUBLIC :: fjulstartyear !: first day of the current year in julian days 228 228 REAL(wp), PUBLIC :: adatrj !: number of elapsed days since the begining of the whole simulation … … 252 252 !!---------------------------------------------------------------------- 253 253 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 254 !! $Id$ 254 !! $Id$ 255 255 !! Software governed by the CeCILL license (see ./LICENSE) 256 256 !!---------------------------------------------------------------------- … … 270 270 271 271 CHARACTER(len=3) FUNCTION Agrif_CFixed() 272 Agrif_CFixed = '0' 272 Agrif_CFixed = '0' 273 273 END FUNCTION Agrif_CFixed 274 274 #endif … … 311 311 ii = ii+1 312 312 ALLOCATE( r3t (jpi,jpj,jpt) , r3u (jpi,jpj,jpt) , r3v (jpi,jpj,jpt) , r3f (jpi,jpj) , & 313 & r3t_f(jpi,jpj) , r3u_f(jpi,jpj) , r3v_f(jpi,jpj) , STAT=ierr(ii) ) 313 & r3t_f(jpi,jpj) , r3u_f(jpi,jpj) , r3v_f(jpi,jpj) , STAT=ierr(ii) ) 314 314 #else 315 315 ii = ii+1 -
NEMO/trunk/src/OCE/DOM/domain.F90
r14053 r14072 6 6 !! History : OPA ! 1990-10 (C. Levy - G. Madec) Original code 7 7 !! ! 1992-01 (M. Imbard) insert time step initialization 8 !! ! 1996-06 (G. Madec) generalized vertical coordinate 8 !! ! 1996-06 (G. Madec) generalized vertical coordinate 9 9 !! ! 1997-02 (G. Madec) creation of domwri.F 10 10 !! ! 2001-05 (E.Durand - G. Madec) insert closed sea … … 17 17 !! 4.1 ! 2020-02 (G. Madec, S. Techene) introduce ssh to h0 ratio 18 18 !!---------------------------------------------------------------------- 19 19 20 20 !!---------------------------------------------------------------------- 21 21 !! dom_init : initialize the space and time domain … … 33 33 USE domvvl ! variable volume 34 34 #endif 35 USE sshwzv , ONLY : ssh_init_rst ! set initial ssh 35 USE sshwzv , ONLY : ssh_init_rst ! set initial ssh 36 36 USE sbc_oce ! surface boundary condition: ocean 37 37 USE trc_oce ! shared ocean & passive tracers variab … … 72 72 !!---------------------------------------------------------------------- 73 73 !! *** ROUTINE dom_init *** 74 !! 75 !! ** Purpose : Domain initialization. Call the routines that are 76 !! required to create the arrays which define the space 74 !! 75 !! ** Purpose : Domain initialization. Call the routines that are 76 !! required to create the arrays which define the space 77 77 !! and time domain of the ocean model. 78 78 !! … … 89 89 INTEGER :: iconf = 0 ! local integers 90 90 REAL(wp):: zrdt 91 CHARACTER (len=64) :: cform = "(A12, 3(A13, I7))" 91 CHARACTER (len=64) :: cform = "(A12, 3(A13, I7))" 92 92 INTEGER , DIMENSION(jpi,jpj) :: ik_top , ik_bot ! top and bottom ocean level 93 93 REAL(wp), DIMENSION(jpi,jpj) :: z1_hu_0, z1_hv_0 … … 126 126 WRITE(numout,*) ' cn_cfg = ', TRIM( cn_cfg ), ' nn_cfg = ', nn_cfg 127 127 ENDIF 128 128 129 129 ! 130 130 ! !== Reference coordinate system ==! … … 240 240 WRITE(numout,*) 'dom_init : ==>>> END of domain initialization' 241 241 WRITE(numout,*) '~~~~~~~~' 242 WRITE(numout,*) 242 WRITE(numout,*) 243 243 ENDIF 244 244 ! … … 252 252 !! ** Purpose : initialization of global domain <--> local domain indices 253 253 !! 254 !! ** Method : 254 !! ** Method : 255 255 !! 256 256 !! ** Action : - mig , mjg : local domain indices ==> global domain, including halos, indices … … 271 271 ! 272 272 mig0(:) = mig(:) - nn_hls 273 mjg0(:) = mjg(:) - nn_hls 274 ! WARNING: to keep compatibility with the trunk that was including periodocity into the input data, 273 mjg0(:) = mjg(:) - nn_hls 274 ! WARNING: to keep compatibility with the trunk that was including periodocity into the input data, 275 275 ! we must define mig0 and mjg0 as bellow. 276 276 ! Once we decide to forget trunk compatibility, we must simply define mig0 and mjg0 as: … … 279 279 ! 280 280 ! ! global domain, including halos, indices ==> local domain indices 281 ! ! (return (m.0,m.1)=(1,0) if data domain gridpoint is to the west/south of the 282 ! ! local domain, or (m.0,m.1)=(jp.+1,jp.) to the east/north of local domain. 281 ! ! (return (m.0,m.1)=(1,0) if data domain gridpoint is to the west/south of the 282 ! ! local domain, or (m.0,m.1)=(jp.+1,jp.) to the east/north of local domain. 283 283 DO ji = 1, jpiglo 284 284 mi0(ji) = MAX( 1 , MIN( ji - nimpp + 1, jpi+1 ) ) … … 387 387 !!---------------------------------------------------------------------- 388 388 !! *** ROUTINE dom_nam *** 389 !! 389 !! 390 390 !! ** Purpose : read domaine namelists and print the variables. 391 391 !! … … 549 549 ! 550 550 IF( .NOT.l_SAS .AND. iom_varid( numror, 'sshb', ldstop = .FALSE. ) <= 0 ) THEN !- Check absence of one of the Kbb field (here sshb) 551 ! ! (any Kbb field is missing ==> all Kbb fields are missing) 551 ! ! (any Kbb field is missing ==> all Kbb fields are missing) 552 552 IF( .NOT.l_1st_euler ) THEN 553 553 CALL ctl_warn('dom_nam : ssh at Kbb not found in restart files ', & … … 558 558 ENDIF 559 559 ELSEIF( .NOT.l_1st_euler ) THEN !* Initialization case 560 IF(lwp) WRITE(numout,*) 560 IF(lwp) WRITE(numout,*) 561 561 IF(lwp) WRITE(numout,*)' ==>>> Start from rest (ln_rstart=F)' 562 IF(lwp) WRITE(numout,*)' an Euler initial time step is used : l_1st_euler is forced to .true. ' 562 IF(lwp) WRITE(numout,*)' an Euler initial time step is used : l_1st_euler is forced to .true. ' 563 563 l_1st_euler = .TRUE. 564 564 ENDIF … … 586 586 IF(lwp) WRITE(numout,*) 587 587 SELECT CASE ( nleapy ) !== Choose calendar for IOIPSL ==! 588 CASE ( 1 ) 588 CASE ( 1 ) 589 589 CALL ioconf_calendar('gregorian') 590 590 IF(lwp) WRITE(numout,*) ' ==>>> The IOIPSL calendar is "gregorian", i.e. leap year' … … 699 699 !!---------------------------------------------------------------------- 700 700 !! *** ROUTINE domain_cfg *** 701 !! 701 !! 702 702 !! ** Purpose : read the domain size in domain configuration file 703 703 !! … … 706 706 CHARACTER(len=*) , INTENT(out) :: cd_cfg ! configuration name 707 707 INTEGER , INTENT(out) :: kk_cfg ! configuration resolution 708 INTEGER , INTENT(out) :: kpi, kpj, kpk ! global domain sizes 709 INTEGER , INTENT(out) :: kperio ! lateral global domain b.c. 708 INTEGER , INTENT(out) :: kpi, kpj, kpk ! global domain sizes 709 INTEGER , INTENT(out) :: kperio ! lateral global domain b.c. 710 710 ! 711 711 INTEGER :: inum ! local integer … … 739 739 cd_cfg = 'UNKNOWN' 740 740 kk_cfg = -9999999 741 !- or they may be present as global attributes 742 !- (netcdf only) 741 !- or they may be present as global attributes 742 !- (netcdf only) 743 743 CALL iom_getatt( inum, 'cn_cfg', cd_cfg ) ! returns ! if not found 744 744 CALL iom_getatt( inum, 'nn_cfg', kk_cfg ) ! returns -999 if not found … … 762 762 WRITE(numout,*) ' type of global domain lateral boundary jperio = ', kperio 763 763 ENDIF 764 ! 764 ! 765 765 END SUBROUTINE domain_cfg 766 767 766 767 768 768 SUBROUTINE cfg_write 769 769 !!---------------------------------------------------------------------- 770 770 !! *** ROUTINE cfg_write *** 771 !! 772 !! ** Purpose : Create the "cn_domcfg_out" file, a NetCDF file which 773 !! contains all the ocean domain informations required to 771 !! 772 !! ** Purpose : Create the "cn_domcfg_out" file, a NetCDF file which 773 !! contains all the ocean domain informations required to 774 774 !! define an ocean configuration. 775 775 !! … … 777 777 !! ocean configuration. 778 778 !! 779 !! ** output file : domcfg_out.nc : domain size, characteristics, horizontal 779 !! ** output file : domcfg_out.nc : domain size, characteristics, horizontal 780 780 !! mesh, Coriolis parameter, and vertical scale factors 781 781 !! NB: also contain ORCA family information … … 794 794 ! ! create 'domcfg_out.nc' file ! 795 795 ! ! ============================= ! 796 ! 796 ! 797 797 clnam = cn_domcfg_out ! filename (configuration information) 798 CALL iom_open( TRIM(clnam), inum, ldwrt = .TRUE. ) 798 CALL iom_open( TRIM(clnam), inum, ldwrt = .TRUE. ) 799 799 ! 800 800 ! !== ORCA family specificities ==! 801 801 IF( TRIM(cn_cfg) == "orca" .OR. TRIM(cn_cfg) == "ORCA" ) THEN 802 802 CALL iom_rstput( 0, 0, inum, 'ORCA' , 1._wp , ktype = jp_i4 ) 803 CALL iom_rstput( 0, 0, inum, 'ORCA_index', REAL( nn_cfg, wp), ktype = jp_i4 ) 803 CALL iom_rstput( 0, 0, inum, 'ORCA_index', REAL( nn_cfg, wp), ktype = jp_i4 ) 804 804 ENDIF 805 805 ! … … 823 823 CALL iom_rstput( 0, 0, inum, 'glamv', glamv, ktype = jp_r8 ) 824 824 CALL iom_rstput( 0, 0, inum, 'glamf', glamf, ktype = jp_r8 ) 825 ! 825 ! 826 826 CALL iom_rstput( 0, 0, inum, 'gphit', gphit, ktype = jp_r8 ) ! longitude 827 827 CALL iom_rstput( 0, 0, inum, 'gphiu', gphiu, ktype = jp_r8 ) 828 828 CALL iom_rstput( 0, 0, inum, 'gphiv', gphiv, ktype = jp_r8 ) 829 829 CALL iom_rstput( 0, 0, inum, 'gphif', gphif, ktype = jp_r8 ) 830 ! 830 ! 831 831 CALL iom_rstput( 0, 0, inum, 'e1t' , e1t , ktype = jp_r8 ) ! i-scale factors (e1.) 832 832 CALL iom_rstput( 0, 0, inum, 'e1u' , e1u , ktype = jp_r8 ) … … 843 843 ! 844 844 ! !== vertical mesh ==! 845 ! 845 ! 846 846 CALL iom_rstput( 0, 0, inum, 'e3t_1d' , e3t_1d , ktype = jp_r8 ) ! reference 1D-coordinate 847 847 CALL iom_rstput( 0, 0, inum, 'e3w_1d' , e3w_1d , ktype = jp_r8 ) … … 854 854 CALL iom_rstput( 0, 0, inum, 'e3uw_0' , e3uw_0 , ktype = jp_r8 ) 855 855 CALL iom_rstput( 0, 0, inum, 'e3vw_0' , e3vw_0 , ktype = jp_r8 ) 856 ! 856 ! 857 857 ! !== wet top and bottom level ==! (caution: multiplied by ssmask) 858 858 ! … … 874 874 ! 875 875 ! ! ============================ 876 ! ! close the files 876 ! ! close the files 877 877 ! ! ============================ 878 878 CALL iom_close( inum ) -
NEMO/trunk/src/OCE/DOM/domutl.F90
r13982 r14072 31 31 !!---------------------------------------------------------------------- 32 32 !! NEMO/OCE 4.2 , NEMO Consortium (2020) 33 !! $Id$ 33 !! $Id$ 34 34 !! Software governed by the CeCILL license (see ./LICENSE) 35 35 !!---------------------------------------------------------------------- … … 42 42 !! ** Purpose : find the closest grid point from a given lon/lat position 43 43 !! 44 !! ** Method : look for minimum distance in cylindrical projection 44 !! ** Method : look for minimum distance in cylindrical projection 45 45 !! -> not good if located at too high latitude... 46 46 !!---------------------------------------------------------------------- … … 86 86 !!---------------------------------------------------------------------- 87 87 !! *** ROUTINE dom_uniq *** 88 !! 88 !! 89 89 !! ** Purpose : identify unique point of a grid (TUVF) 90 90 !! … … 92 92 !! 2) check which elements have been changed 93 93 !!---------------------------------------------------------------------- 94 CHARACTER(len=1) , INTENT(in ) :: cdgrd ! 95 REAL(wp), DIMENSION(:,:), INTENT(inout) :: puniq ! 94 CHARACTER(len=1) , INTENT(in ) :: cdgrd ! 95 REAL(wp), DIMENSION(:,:), INTENT(inout) :: puniq ! 96 96 ! 97 97 REAL(wp) :: zshift ! shift value link to the process number … … 101 101 !!---------------------------------------------------------------------- 102 102 ! 103 ! build an array with different values for each element 103 ! build an array with different values for each element 104 104 ! in mpp: make sure that these values are different even between process 105 105 ! -> apply a shift value according to the process number … … 109 109 puniq(:,:) = ztstref(:,:) ! default definition 110 110 CALL lbc_lnk( 'domwri', puniq, cdgrd, 1. ) ! apply boundary conditions 111 lluniq(:,:,1) = puniq(:,:) == ztstref(:,:) ! check which values have not been changed 111 lluniq(:,:,1) = puniq(:,:) == ztstref(:,:) ! check which values have not been changed 112 112 ! 113 113 puniq(:,:) = REAL( COUNT( lluniq(:,:,:), dim = 3 ), wp ) -
NEMO/trunk/src/OCE/DOM/domvvl.F90
r14053 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE domvvl *** 4 !! Ocean : 4 !! Ocean : 5 5 !!====================================================================== 6 6 !! History : 2.0 ! 2006-06 (B. Levier, L. Marie) original code … … 58 58 !! Default key Old management of time varying vertical coordinate 59 59 !!---------------------------------------------------------------------- 60 60 61 61 !!---------------------------------------------------------------------- 62 62 !! dom_vvl_init : define initial vertical scale factors, depths and column thickness … … 73 73 PUBLIC dom_vvl_sf_update ! called by step.F90 74 74 PUBLIC dom_vvl_interpol ! called by dynnxt.F90 75 75 76 76 !! * Substitutions 77 77 # include "do_loop_substitute.h90" … … 109 109 !!---------------------------------------------------------------------- 110 110 !! *** ROUTINE dom_vvl_init *** 111 !! 111 !! 112 112 !! ** Purpose : Initialization of all scale factors, depths 113 113 !! and water column heights … … 118 118 !! ** Action : - e3t_(n/b) and tilde_e3t_(n/b) 119 119 !! - Regrid: e3[u/v](:,:,:,Kmm) 120 !! e3[u/v](:,:,:,Kmm) 121 !! e3w(:,:,:,Kmm) 120 !! e3[u/v](:,:,:,Kmm) 121 !! e3w(:,:,:,Kmm) 122 122 !! e3[u/v]w_b 123 !! e3[u/v]w_n 123 !! e3[u/v]w_n 124 124 !! gdept(:,:,:,Kmm), gdepw(:,:,:,Kmm) and gde3w 125 125 !! - h(t/u/v)_0 … … 151 151 !!---------------------------------------------------------------------- 152 152 !! *** ROUTINE dom_vvl_init *** 153 !! 154 !! ** Purpose : Interpolation of all scale factors, 153 !! 154 !! ** Purpose : Interpolation of all scale factors, 155 155 !! depths and water column heights 156 156 !! … … 159 159 !! ** Action : - e3t_(n/b) and tilde_e3t_(n/b) 160 160 !! - Regrid: e3(u/v)_n 161 !! e3(u/v)_b 162 !! e3w_n 163 !! e3(u/v)w_b 164 !! e3(u/v)w_n 161 !! e3(u/v)_b 162 !! e3w_n 163 !! e3(u/v)w_b 164 !! e3(u/v)w_n 165 165 !! gdept_n, gdepw_n and gde3w_n 166 166 !! - h(t/u/v)_0 … … 180 180 CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3u(:,:,:,Kbb), 'U' ) ! from T to U 181 181 CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3u(:,:,:,Kmm), 'U' ) 182 CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3v(:,:,:,Kbb), 'V' ) ! from T to V 182 CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3v(:,:,:,Kbb), 'V' ) ! from T to V 183 183 CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3v(:,:,:,Kmm), 'V' ) 184 184 CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3f(:,:,:), 'F' ) ! from U to F 185 ! ! Vertical interpolation of e3t,u,v 185 ! ! Vertical interpolation of e3t,u,v 186 186 CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3w (:,:,:,Kmm), 'W' ) ! from T to W 187 187 CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3w (:,:,:,Kbb), 'W' ) … … 205 205 ! zcoef = tmask - wmask ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt 206 206 ! ! 1 everywhere from mbkt to mikt + 1 or 1 (if no isf) 207 ! ! 0.5 where jk = mikt 207 ! ! 0.5 where jk = mikt 208 208 !!gm ??????? BUG ? gdept(:,:,:,Kmm) as well as gde3w does not include the thickness of ISF ?? 209 209 zcoef = ( tmask(ji,jj,jk) - wmask(ji,jj,jk) ) 210 210 gdepw(ji,jj,jk,Kmm) = gdepw(ji,jj,jk-1,Kmm) + e3t(ji,jj,jk-1,Kmm) 211 211 gdept(ji,jj,jk,Kmm) = zcoef * ( gdepw(ji,jj,jk ,Kmm) + 0.5 * e3w(ji,jj,jk,Kmm)) & 212 & + (1-zcoef) * ( gdept(ji,jj,jk-1,Kmm) + e3w(ji,jj,jk,Kmm)) 212 & + (1-zcoef) * ( gdept(ji,jj,jk-1,Kmm) + e3w(ji,jj,jk,Kmm)) 213 213 gde3w(ji,jj,jk) = gdept(ji,jj,jk,Kmm) - ssh(ji,jj,Kmm) 214 214 gdepw(ji,jj,jk,Kbb) = gdepw(ji,jj,jk-1,Kbb) + e3t(ji,jj,jk-1,Kbb) 215 215 gdept(ji,jj,jk,Kbb) = zcoef * ( gdepw(ji,jj,jk ,Kbb) + 0.5 * e3w(ji,jj,jk,Kbb)) & 216 & + (1-zcoef) * ( gdept(ji,jj,jk-1,Kbb) + e3w(ji,jj,jk,Kbb)) 216 & + (1-zcoef) * ( gdept(ji,jj,jk-1,Kbb) + e3w(ji,jj,jk,Kbb)) 217 217 END_3D 218 218 ! … … 273 273 IF( cn_cfg == "orca" .OR. cn_cfg == "ORCA" ) THEN 274 274 IF( nn_cfg == 3 ) THEN ! ORCA2: Suppress ztilde in the Foxe Basin for ORCA2 275 ii0 = 103 + nn_hls - 1 ; ii1 = 111 + nn_hls - 1 275 ii0 = 103 + nn_hls - 1 ; ii1 = 111 + nn_hls - 1 276 276 ij0 = 128 + nn_hls ; ij1 = 135 + nn_hls 277 277 frq_rst_e3t( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.0_wp … … 285 285 286 286 287 SUBROUTINE dom_vvl_sf_nxt( kt, Kbb, Kmm, Kaa, kcall ) 287 SUBROUTINE dom_vvl_sf_nxt( kt, Kbb, Kmm, Kaa, kcall ) 288 288 !!---------------------------------------------------------------------- 289 289 !! *** ROUTINE dom_vvl_sf_nxt *** 290 !! 290 !! 291 291 !! ** Purpose : - compute the after scale factors used in tra_zdf, dynnxt, 292 292 !! tranxt and dynspg routines 293 293 !! 294 294 !! ** Method : - z_star case: Repartition of ssh INCREMENT proportionnaly to the level thickness. 295 !! - z_tilde_case: after scale factor increment = 295 !! - z_tilde_case: after scale factor increment = 296 296 !! high frequency part of horizontal divergence 297 297 !! + retsoring towards the background grid … … 301 301 !! 302 302 !! ** Action : - hdiv_lf : restoring towards full baroclinic divergence in z_tilde case 303 !! - tilde_e3t_a: after increment of vertical scale factor 303 !! - tilde_e3t_a: after increment of vertical scale factor 304 304 !! in z_tilde case 305 305 !! - e3(t/u/v)_a … … 405 405 un_td(ji,jj,jk) = rn_ahe3 * umask(ji,jj,jk) * e2_e1u(ji,jj) & 406 406 & * ( tilde_e3t_b(ji,jj,jk) - tilde_e3t_b(ji+1,jj ,jk) ) 407 vn_td(ji,jj,jk) = rn_ahe3 * vmask(ji,jj,jk) * e1_e2v(ji,jj) & 407 vn_td(ji,jj,jk) = rn_ahe3 * vmask(ji,jj,jk) * e1_e2v(ji,jj) & 408 408 & * ( tilde_e3t_b(ji,jj,jk) - tilde_e3t_b(ji ,jj+1,jk) ) 409 409 zwu(ji,jj) = zwu(ji,jj) + un_td(ji,jj,jk) … … 450 450 WRITE(numout, *) 'at i, j, k=', ijk_max 451 451 WRITE(numout, *) 'MIN( tilde_e3t_a(:,:,:) / e3t_0(:,:,:) ) =', z_tmin 452 WRITE(numout, *) 'at i, j, k=', ijk_min 452 WRITE(numout, *) 'at i, j, k=', ijk_min 453 453 CALL ctl_stop( 'STOP', 'MAX( ABS( tilde_e3t_a(:,:,: ) ) / e3t_0(:,:,:) ) too high') 454 454 ENDIF … … 566 566 !!---------------------------------------------------------------------- 567 567 !! *** ROUTINE dom_vvl_sf_update *** 568 !! 569 !! ** Purpose : for z tilde case: compute time filter and swap of scale factors 568 !! 569 !! ** Purpose : for z tilde case: compute time filter and swap of scale factors 570 570 !! compute all depths and related variables for next time step 571 571 !! write outputs and restart file … … 577 577 !! ** Action : - tilde_e3t_(b/n) ready for next time step 578 578 !! - Recompute: 579 !! e3(u/v)_b 580 !! e3w(:,:,:,Kmm) 581 !! e3(u/v)w_b 582 !! e3(u/v)w_n 579 !! e3(u/v)_b 580 !! e3w(:,:,:,Kmm) 581 !! e3(u/v)w_b 582 !! e3(u/v)w_n 583 583 !! gdept(:,:,:,Kmm), gdepw(:,:,:,Kmm) and gde3w 584 584 !! h(u/v) and h(u/v)r … … 611 611 tilde_e3t_b(:,:,:) = tilde_e3t_n(:,:,:) 612 612 ELSE 613 tilde_e3t_b(:,:,:) = tilde_e3t_n(:,:,:) & 613 tilde_e3t_b(:,:,:) = tilde_e3t_n(:,:,:) & 614 614 & + rn_atfp * ( tilde_e3t_b(:,:,:) - 2.0_wp * tilde_e3t_n(:,:,:) + tilde_e3t_a(:,:,:) ) 615 615 ENDIF … … 623 623 ! - ML - e3u(:,:,:,Kbb) and e3v(:,:,:,Kbb) are already computed in dynnxt 624 624 ! - JC - hu(:,:,:,Kbb), hv(:,:,:,:,Kbb), hur_b, hvr_b also 625 625 626 626 CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3f(:,:,:), 'F' ) 627 627 628 628 ! Vertical scale factor interpolations 629 629 CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3w(:,:,:,Kmm), 'W' ) … … 644 644 gdepw(ji,jj,jk,Kmm) = gdepw(ji,jj,jk-1,Kmm) + e3t(ji,jj,jk-1,Kmm) 645 645 gdept(ji,jj,jk,Kmm) = zcoef * ( gdepw(ji,jj,jk ,Kmm) + 0.5 * e3w(ji,jj,jk,Kmm) ) & 646 & + (1-zcoef) * ( gdept(ji,jj,jk-1,Kmm) + e3w(ji,jj,jk,Kmm) ) 646 & + (1-zcoef) * ( gdept(ji,jj,jk-1,Kmm) + e3w(ji,jj,jk,Kmm) ) 647 647 gde3w(ji,jj,jk) = gdept(ji,jj,jk,Kmm) - ssh(ji,jj,Kmm) 648 648 END_3D … … 763 763 !!--------------------------------------------------------------------- 764 764 !! *** ROUTINE dom_vvl_rst *** 765 !! 765 !! 766 766 !! ** Purpose : Read or write VVL file in restart file 767 767 !! … … 807 807 IF(lwp) WRITE(numout,*) ' Kmm scale factor read in the restart file' 808 808 CALL iom_get( numror, jpdom_auto, 'e3t_n', e3t(:,:,:,Kmm) ) 809 WHERE ( tmask(:,:,:) == 0.0_wp ) 809 WHERE ( tmask(:,:,:) == 0.0_wp ) 810 810 e3t(:,:,:,Kmm) = e3t_0(:,:,:) 811 811 END WHERE … … 816 816 IF(lwp) WRITE(numout,*) ' Kbb scale factor read in the restart file' 817 817 CALL iom_get( numror, jpdom_auto, 'e3t_b', e3t(:,:,:,Kbb) ) 818 WHERE ( tmask(:,:,:) == 0.0_wp ) 818 WHERE ( tmask(:,:,:) == 0.0_wp ) 819 819 e3t(:,:,:,Kbb) = e3t_0(:,:,:) 820 820 END WHERE … … 840 840 CALL iom_get( numror, jpdom_auto, 'tilde_e3t_b', tilde_e3t_b(:,:,:) ) 841 841 ENDIF 842 ELSE 842 ELSE 843 843 tilde_e3t_b(:,:,:) = 0.0_wp 844 844 tilde_e3t_n(:,:,:) = 0.0_wp … … 850 850 CALL iom_get( numror, jpdom_auto, 'hdiv_lf', hdiv_lf(:,:,:) ) 851 851 ELSE ! array is missing 852 hdiv_lf(:,:,:) = 0.0_wp 852 hdiv_lf(:,:,:) = 0.0_wp 853 853 ENDIF 854 854 ENDIF … … 884 884 CALL iom_rstput( kt, nitrst, numrow, 'tilde_e3t_n', tilde_e3t_n(:,:,:)) 885 885 END IF 886 ! ! -------------! 886 ! ! -------------! 887 887 IF( ln_vvl_ztilde ) THEN ! z_tilde case ! 888 888 ! ! ------------ ! … … 898 898 !!--------------------------------------------------------------------- 899 899 !! *** ROUTINE dom_vvl_ctl *** 900 !! 900 !! 901 901 !! ** Purpose : Control the consistency between namelist options 902 902 !! for vertical coordinate … … 907 907 & ln_vvl_zstar_at_eqtor , rn_ahe3 , rn_rst_e3t , & 908 908 & rn_lf_cutoff , rn_zdef_max , ln_vvl_dbg ! not yet implemented: ln_vvl_kepe 909 !!---------------------------------------------------------------------- 909 !!---------------------------------------------------------------------- 910 910 ! 911 911 READ ( numnam_ref, nam_vvl, IOSTAT = ios, ERR = 901) -
NEMO/trunk/src/OCE/DOM/dtatsd.F90
r13982 r14072 6 6 !! History : OPA ! 1991-03 () Original code 7 7 !! - ! 1992-07 (M. Imbard) 8 !! 8.0 ! 1999-10 (M.A. Foujols, M. Imbard) NetCDF FORMAT 9 !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module 8 !! 8.0 ! 1999-10 (M.A. Foujols, M. Imbard) NetCDF FORMAT 9 !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module 10 10 !! 3.3 ! 2010-10 (C. Bricaud, S. Masson) use of fldread 11 11 !! 3.4 ! 2010-11 (G. Madec, C. Ethe) Merge of dtatem and dtasal + remove CPP keys … … 40 40 !!---------------------------------------------------------------------- 41 41 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 42 !! $Id$ 42 !! $Id$ 43 43 !! Software governed by the CeCILL license (see ./LICENSE) 44 44 !!---------------------------------------------------------------------- … … 48 48 !!---------------------------------------------------------------------- 49 49 !! *** ROUTINE dta_tsd_init *** 50 !! 51 !! ** Purpose : initialisation of T & S input data 52 !! 50 !! 51 !! ** Purpose : initialisation of T & S input data 52 !! 53 53 !! ** Method : - Read namtsd namelist 54 !! - allocates T & S data structure 54 !! - allocates T & S data structure 55 55 !!---------------------------------------------------------------------- 56 56 LOGICAL, INTENT(in), OPTIONAL :: ld_tradmp ! force the initialization when tradp is used … … 75 75 76 76 IF( PRESENT( ld_tradmp ) ) ln_tsd_dmp = .TRUE. ! forces the initialization when tradmp is used 77 77 78 78 IF(lwp) THEN ! control print 79 79 WRITE(numout,*) … … 124 124 !!---------------------------------------------------------------------- 125 125 !! *** ROUTINE dta_tsd *** 126 !! 126 !! 127 127 !! ** Purpose : provides T and S data at kt 128 !! 128 !! 129 129 !! ** Method : - call fldread routine 130 !! - ORCA_R2: add some hand made alteration to read data 130 !! - ORCA_R2: add some hand made alteration to read data 131 131 !! - 'key_orca_lev10' interpolates on 10 times more levels 132 132 !! - s- or mixed z-s coordinate: vertical interpolation on model mesh … … 211 211 IF( (zl-gdept_1d(jkk)) * (zl-gdept_1d(jkk+1)) <= 0._wp ) THEN 212 212 zi = ( zl - gdept_1d(jkk) ) / (gdept_1d(jkk+1)-gdept_1d(jkk)) 213 ztp(jk) = ptsd(ji,jj,jkk,jp_tem) + ( ptsd(ji,jj,jkk+1,jp_tem) - ptsd(ji,jj,jkk,jp_tem) ) * zi 213 ztp(jk) = ptsd(ji,jj,jkk,jp_tem) + ( ptsd(ji,jj,jkk+1,jp_tem) - ptsd(ji,jj,jkk,jp_tem) ) * zi 214 214 zsp(jk) = ptsd(ji,jj,jkk,jp_sal) + ( ptsd(ji,jj,jkk+1,jp_sal) - ptsd(ji,jj,jkk,jp_sal) ) * zi 215 215 ENDIF … … 224 224 ptsd(ji,jj,jpk,jp_sal) = 0._wp 225 225 END_2D 226 ! 226 ! 227 227 ELSE !== z- or zps- coordinate ==! 228 ! 228 ! 229 229 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk ) 230 230 ptsd(ji,jj,jk,jp_tem) = ptsd(ji,jj,jk,jp_tem) * tmask(ji,jj,jk) ! Mask … … 235 235 ! NOTE: [tiling-comms-merge] This fix was necessary to take out tra_adv lbc_lnk statements in the zps case 236 236 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 237 ik = mbkt(ji,jj) 237 ik = mbkt(ji,jj) 238 238 IF( ik > 1 ) THEN 239 239 zl = ( gdept_1d(ik) - gdept_0(ji,jj,ik) ) / ( gdept_1d(ik) - gdept_1d(ik-1) ) … … 243 243 ik = mikt(ji,jj) 244 244 IF( ik > 1 ) THEN 245 zl = ( gdept_0(ji,jj,ik) - gdept_1d(ik) ) / ( gdept_1d(ik+1) - gdept_1d(ik) ) 245 zl = ( gdept_0(ji,jj,ik) - gdept_1d(ik) ) / ( gdept_1d(ik+1) - gdept_1d(ik) ) 246 246 ptsd(ji,jj,ik,jp_tem) = (1.-zl) * ptsd(ji,jj,ik,jp_tem) + zl * ptsd(ji,jj,ik+1,jp_tem) 247 247 ptsd(ji,jj,ik,jp_sal) = (1.-zl) * ptsd(ji,jj,ik,jp_sal) + zl * ptsd(ji,jj,ik+1,jp_sal) … … 252 252 ENDIF 253 253 ! 254 IF( .NOT.ln_tsd_dmp ) THEN !== deallocate T & S structure ==! 254 IF( .NOT.ln_tsd_dmp ) THEN !== deallocate T & S structure ==! 255 255 ! (data used only for initialisation) 256 256 IF(lwp) WRITE(numout,*) 'dta_tsd: deallocte T & S arrays as they are only use to initialize the run' -
NEMO/trunk/src/OCE/DOM/phycst.F90
r14053 r14072 7 7 !! 8.1 ! 1991-11 (G. Madec, M. Imbard) cosmetic changes 8 8 !! NEMO 1.0 ! 2002-08 (G. Madec, C. Ethe) F90, add ice constants 9 !! - ! 2006-08 (G. Madec) style 10 !! 3.2 ! 2006-08 (S. Masson, G. Madec) suppress useless variables + style 11 !! 3.4 ! 2011-11 (C. Harris) minor changes for CICE constants 9 !! - ! 2006-08 (G. Madec) style 10 !! 3.2 ! 2006-08 (S. Masson, G. Madec) suppress useless variables + style 11 !! 3.4 ! 2011-11 (C. Harris) minor changes for CICE constants 12 12 !!---------------------------------------------------------------------- 13 13 … … 26 26 REAL(wp), PUBLIC :: rad = 3.141592653589793_wp / 180._wp !: conversion from degre into radian 27 27 REAL(wp), PUBLIC :: rsmall = 0.5 * EPSILON( 1.e0 ) !: smallest real computer value 28 28 29 29 REAL(wp), PUBLIC :: rday = 24.*60.*60. !: day [s] 30 30 REAL(wp), PUBLIC :: rsiyea !: sideral year [s] … … 36 36 REAL(wp), PUBLIC :: omega !: earth rotation parameter [s-1] 37 37 REAL(wp), PUBLIC :: ra = 6371229._wp !: earth radius [m] 38 REAL(wp), PUBLIC :: grav = 9.80665_wp !: gravity [m/s2] 38 REAL(wp), PUBLIC :: grav = 9.80665_wp !: gravity [m/s2] 39 39 REAL(wp), PUBLIC :: rt0 = 273.15_wp !: freezing point of fresh water [Kelvin] 40 40 … … 43 43 REAL(wp), PUBLIC :: rcp !: ocean specific heat [J/Kelvin] 44 44 REAL(wp), PUBLIC :: r1_rcp !: = 1. / rcp [Kelvin/J] 45 REAL(wp), PUBLIC :: rho0_rcp !: = rho0 * rcp 45 REAL(wp), PUBLIC :: rho0_rcp !: = rho0 * rcp 46 46 REAL(wp), PUBLIC :: r1_rho0_rcp !: = 1. / ( rho0 * rcp ) 47 47 … … 52 52 REAL(wp), PUBLIC :: rLevap = 2.5e+6_wp !: latent heat of evaporation (water) 53 53 REAL(wp), PUBLIC :: vkarmn = 0.4_wp !: von Karman constant 54 REAL(wp), PUBLIC :: stefan = 5.67e-8_wp !: Stefan-Boltzmann constant 54 REAL(wp), PUBLIC :: vkarmn2 = 0.4_wp*0.4_wp !: square of von Karman constant 55 REAL(wp), PUBLIC :: stefan = 5.67e-8_wp !: Stefan-Boltzmann constant 55 56 56 57 REAL(wp), PUBLIC :: rhos = 330._wp !: volumic mass of snow [kg/m3] … … 66 67 REAL(wp), PUBLIC :: r1_rhos !: 1 / rhos 67 68 REAL(wp), PUBLIC :: r1_rcpi !: 1 / rcpi 68 69 69 70 !!---------------------------------------------------------------------- 70 71 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 71 !! $Id$ 72 !! $Id$ 72 73 !! Software governed by the CeCILL license (see ./LICENSE) 73 74 !!---------------------------------------------------------------------- 74 75 75 76 CONTAINS 76 77 77 78 SUBROUTINE phy_cst 78 79 !!---------------------------------------------------------------------- … … 87 88 omega = 7.292116e-05 88 89 #else 89 omega = 2._wp * rpi / rsiday 90 omega = 2._wp * rpi / rsiday 90 91 #endif 91 92 … … 126 127 WRITE(numout,*) ' salinity of ice (for pisces) = ', sice , ' psu' 127 128 WRITE(numout,*) ' salinity of sea (for pisces and isf) = ', soce , ' psu' 128 WRITE(numout,*) ' latent heat of evaporation (water) = ', rLevap , ' J/m^3' 129 WRITE(numout,*) ' von Karman constant = ', vkarmn 129 WRITE(numout,*) ' latent heat of evaporation (water) = ', rLevap , ' J/m^3' 130 WRITE(numout,*) ' von Karman constant = ', vkarmn 130 131 WRITE(numout,*) ' Stefan-Boltzmann constant = ', stefan , ' J/s/m^2/K^4' 131 132 WRITE(numout,*) -
NEMO/trunk/src/OCE/DYN/dynatf.F90
r13472 r14072 13 13 !! - ! 2002-10 (C. Talandier, A-M. Treguier) Open boundary cond. 14 14 !! 2.0 ! 2005-11 (V. Garnier) Surface pressure gradient organization 15 !! 2.3 ! 2007-07 (D. Storkey) Calls to BDY routines. 15 !! 2.3 ! 2007-07 (D. Storkey) Calls to BDY routines. 16 16 !! 3.2 ! 2009-06 (G. Madec, R.Benshila) re-introduce the vvl option 17 17 !! 3.3 ! 2010-09 (D. Storkey, E.O'Dea) Bug fix for BDY module … … 22 22 !! 4.1 ! 2019-08 (A. Coward, D. Storkey) Rename dynnxt.F90 -> dynatf.F90. Now just does time filtering. 23 23 !!------------------------------------------------------------------------- 24 24 25 25 !!---------------------------------------------------------------------------------------------- 26 26 !! dyn_atf : apply Asselin time filtering to "now" velocities and vertical scale factors … … 42 42 USE trdken ! trend manager: kinetic energy 43 43 USE isf_oce , ONLY: ln_isf ! ice shelf 44 USE isfdynatf , ONLY: isf_dynatf ! ice shelf volume filter correction subroutine 44 USE isfdynatf , ONLY: isf_dynatf ! ice shelf volume filter correction subroutine 45 45 ! 46 46 USE in_out_manager ! I/O manager … … 81 81 !!---------------------------------------------------------------------- 82 82 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 83 !! $Id$ 83 !! $Id$ 84 84 !! Software governed by the CeCILL license (see ./LICENSE) 85 85 !!---------------------------------------------------------------------- … … 89 89 !!---------------------------------------------------------------------- 90 90 !! *** ROUTINE dyn_atf *** 91 !! 92 !! ** Purpose : Finalize after horizontal velocity. Apply the boundary 91 !! 92 !! ** Purpose : Finalize after horizontal velocity. Apply the boundary 93 93 !! condition on the after velocity and apply the Asselin time 94 94 !! filter to the now fields. … … 97 97 !! estimate (ln_dynspg_ts=T) 98 98 !! 99 !! * Apply lateral boundary conditions on after velocity 99 !! * Apply lateral boundary conditions on after velocity 100 100 !! at the local domain boundaries through lbc_lnk call, 101 101 !! at the one-way open boundaries (ln_bdy=T), … … 104 104 !! * Apply the Asselin time filter to the now fields 105 105 !! arrays to start the next time step: 106 !! (puu(Kmm),pvv(Kmm)) = (puu(Kmm),pvv(Kmm)) 106 !! (puu(Kmm),pvv(Kmm)) = (puu(Kmm),pvv(Kmm)) 107 107 !! + rn_atfp [ (puu(Kbb),pvv(Kbb)) + (puu(Kaa),pvv(Kaa)) - 2 (puu(Kmm),pvv(Kmm)) ] 108 108 !! Note that with flux form advection and non linear free surface, … … 110 110 !! As a result, dyn_atf MUST be called after tra_atf. 111 111 !! 112 !! ** Action : puu(Kmm),pvv(Kmm) filtered now horizontal velocity 112 !! ** Action : puu(Kmm),pvv(Kmm) filtered now horizontal velocity 113 113 !!---------------------------------------------------------------------- 114 114 INTEGER , INTENT(in ) :: kt ! ocean time-step index … … 122 122 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zue, zve, zwfld 123 123 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zutau, zvtau 124 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: ze3t_f, ze3u_f, ze3v_f, zua, zva 124 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: ze3t_f, ze3u_f, ze3v_f, zua, zva 125 125 !!---------------------------------------------------------------------- 126 126 ! … … 150 150 ! 151 151 IF( .NOT.ln_bt_fw ) THEN 152 ! Remove advective velocity from "now velocities" 153 ! prior to asselin filtering 154 ! In the forward case, this is done below after asselin filtering 155 ! so that asselin contribution is removed at the same time 152 ! Remove advective velocity from "now velocities" 153 ! prior to asselin filtering 154 ! In the forward case, this is done below after asselin filtering 155 ! so that asselin contribution is removed at the same time 156 156 DO jk = 1, jpkm1 157 157 puu(:,:,jk,Kmm) = ( puu(:,:,jk,Kmm) - un_adv(:,:)*r1_hu(:,:,Kmm) + uu_b(:,:,Kmm) )*umask(:,:,jk) 158 158 pvv(:,:,jk,Kmm) = ( pvv(:,:,jk,Kmm) - vn_adv(:,:)*r1_hv(:,:,Kmm) + vv_b(:,:,Kmm) )*vmask(:,:,jk) 159 END DO 159 END DO 160 160 ENDIF 161 161 ENDIF 162 162 163 163 ! Update after velocity on domain lateral boundaries 164 ! -------------------------------------------------- 164 ! -------------------------------------------------- 165 165 # if defined key_agrif 166 166 CALL Agrif_dyn( kt ) !* AGRIF zoom boundaries … … 194 194 ! Time filter and swap of dynamics arrays 195 195 ! ------------------------------------------ 196 197 IF( .NOT. l_1st_euler ) THEN !* Leap-Frog : Asselin time filter 196 197 IF( .NOT. l_1st_euler ) THEN !* Leap-Frog : Asselin time filter 198 198 ! ! =============! 199 199 IF( ln_linssh ) THEN ! Fixed volume ! … … 220 220 DO jk = 1, jpkm1 221 221 ze3t_f(:,:,jk) = ze3t_f(:,:,jk) - zcoef * zwfld(:,:) * tmask(:,:,jk) & 222 & * pe3t(:,:,jk,Kmm) / ( ht(:,:) + 1._wp - ssmask(:,:) ) 222 & * pe3t(:,:,jk,Kmm) / ( ht(:,:) + 1._wp - ssmask(:,:) ) 223 223 END DO 224 224 ! … … 257 257 pvv(ji,jj,jk,Kmm) = ( zve3n + rn_atfp * ( zve3b - 2._wp * zve3n + zve3a ) ) / ze3v_f(ji,jj,jk) 258 258 END_3D 259 pe3u(:,:,1:jpkm1,Kmm) = ze3u_f(:,:,1:jpkm1) 259 pe3u(:,:,1:jpkm1,Kmm) = ze3u_f(:,:,1:jpkm1) 260 260 pe3v(:,:,1:jpkm1,Kmm) = ze3v_f(:,:,1:jpkm1) 261 261 ! … … 268 268 IF( ln_dynspg_ts .AND. ln_bt_fw ) THEN 269 269 ! Revert filtered "now" velocities to time split estimate 270 ! Doing it here also means that asselin filter contribution is removed 270 ! Doing it here also means that asselin filter contribution is removed 271 271 zue(:,:) = pe3u(:,:,1,Kmm) * puu(:,:,1,Kmm) * umask(:,:,1) 272 zve(:,:) = pe3v(:,:,1,Kmm) * pvv(:,:,1,Kmm) * vmask(:,:,1) 272 zve(:,:) = pe3v(:,:,1,Kmm) * pvv(:,:,1,Kmm) * vmask(:,:,1) 273 273 DO jk = 2, jpkm1 274 274 zue(:,:) = zue(:,:) + pe3u(:,:,jk,Kmm) * puu(:,:,jk,Kmm) * umask(:,:,jk) 275 zve(:,:) = zve(:,:) + pe3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm) * vmask(:,:,jk) 275 zve(:,:) = zve(:,:) + pe3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm) * vmask(:,:,jk) 276 276 END DO 277 277 DO jk = 1, jpkm1 … … 325 325 IF ( iom_use("utau") ) THEN 326 326 IF ( ln_drgice_imp.OR.ln_isfcav ) THEN 327 ALLOCATE(zutau(jpi,jpj)) 327 ALLOCATE(zutau(jpi,jpj)) 328 328 DO_2D( 0, 0, 0, 0 ) 329 jk = miku(ji,jj) 329 jk = miku(ji,jj) 330 330 zutau(ji,jj) = utau(ji,jj) + 0.5_wp * rho0 * ( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) * puu(ji,jj,jk,Kaa) 331 331 END_2D … … 353 353 IF(sn_cfctl%l_prtctl) CALL prt_ctl( tab3d_1=puu(:,:,:,Kaa), clinfo1=' nxt - puu(:,:,:,Kaa): ', mask1=umask, & 354 354 & tab3d_2=pvv(:,:,:,Kaa), clinfo2=' pvv(:,:,:,Kaa): ' , mask2=vmask ) 355 ! 355 ! 356 356 IF( ln_dynspg_ts ) DEALLOCATE( zue, zve ) 357 357 IF( l_trddyn ) DEALLOCATE( zua, zva ) -
NEMO/trunk/src/OCE/DYN/dynspg.F90
r14064 r14072 11 11 12 12 !!---------------------------------------------------------------------- 13 !! dyn_spg : update the dynamics trend with surface pressure gradient 13 !! dyn_spg : update the dynamics trend with surface pressure gradient 14 14 !! dyn_spg_init: initialization, namelist read, and parameters control 15 15 !!---------------------------------------------------------------------- … … 39 39 PUBLIC dyn_spg_init ! routine called by opa module 40 40 41 INTEGER :: nspg = 0 ! type of surface pressure gradient scheme defined from lk_dynspg_... 41 INTEGER :: nspg = 0 ! type of surface pressure gradient scheme defined from lk_dynspg_... 42 42 43 43 ! ! Parameter to control the surface pressure gradient scheme … … 52 52 !!---------------------------------------------------------------------- 53 53 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 54 !! $Id$ 54 !! $Id$ 55 55 !! Software governed by the CeCILL license (see ./LICENSE) 56 56 !!---------------------------------------------------------------------- … … 61 61 !! *** ROUTINE dyn_spg *** 62 62 !! 63 !! ** Purpose : compute surface pressure gradient including the 63 !! ** Purpose : compute surface pressure gradient including the 64 64 !! atmospheric pressure forcing (ln_apr_dyn=T). 65 65 !! … … 68 68 !! - split-explicit : a time splitting technique is used 69 69 !! 70 !! ln_apr_dyn=T : the atmospheric pressure forcing is applied 70 !! ln_apr_dyn=T : the atmospheric pressure forcing is applied 71 71 !! as the gradient of the inverse barometer ssh: 72 72 !! apgu = - 1/rho0 di[apr] = 0.5*grav di[ssh_ib+ssh_ibb] … … 90 90 ! 91 91 IF( l_trddyn ) THEN ! temporary save of ta and sa trends 92 ALLOCATE( ztrdu(jpi,jpj,jpk) , ztrdv(jpi,jpj,jpk) ) 92 ALLOCATE( ztrdu(jpi,jpj,jpk) , ztrdv(jpi,jpj,jpk) ) 93 93 ztrdu(:,:,:) = puu(:,:,:,Krhs) 94 94 ztrdv(:,:,:) = pvv(:,:,:,Krhs) … … 144 144 zpgv(ji,jj) = zpgv(ji,jj) + ( zpice(ji,jj+1) - zpice(ji,jj) ) * r1_e2v(ji,jj) 145 145 END_2D 146 DEALLOCATE( zpice ) 146 DEALLOCATE( zpice ) 147 147 ENDIF 148 148 ! … … 160 160 ! 161 161 !!gm add here a call to dyn_trd for ice pressure gradient, the surf pressure trends ???? 162 ! 162 ! 163 163 ENDIF 164 164 ! … … 167 167 CASE ( np_TS ) ; CALL dyn_spg_ts ( kt, Kbb, Kmm, Krhs, puu, pvv, pssh, puu_b, pvv_b, Kaa ) ! time-splitting 168 168 END SELECT 169 ! 169 ! 170 170 IF( l_trddyn ) THEN ! save the surface pressure gradient trends for further diagnostics 171 171 ztrdu(:,:,:) = puu(:,:,:,Krhs) - ztrdu(:,:,:) 172 172 ztrdv(:,:,:) = pvv(:,:,:,Krhs) - ztrdv(:,:,:) 173 173 CALL trd_dyn( ztrdu, ztrdv, jpdyn_spg, kt, Kmm ) 174 DEALLOCATE( ztrdu , ztrdv ) 174 DEALLOCATE( ztrdu , ztrdv ) 175 175 ENDIF 176 176 ! ! print mean trends (used for debugging) … … 186 186 !!--------------------------------------------------------------------- 187 187 !! *** ROUTINE dyn_spg_init *** 188 !! 189 !! ** Purpose : Control the consistency between namelist options for 188 !! 189 !! ** Purpose : Control the consistency between namelist options for 190 190 !! surface pressure gradient schemes 191 191 !!---------------------------------------------------------------------- -
NEMO/trunk/src/OCE/DYN/dynvor.F90
r14053 r14072 15 15 !! 3.2 ! 2009-04 (R. Benshila) vvl: correction of een scheme 16 16 !! 3.3 ! 2010-10 (C. Ethe, G. Madec) reorganisation of initialisation phase 17 !! 3.7 ! 2014-04 (G. Madec) trend simplification: suppress jpdyn_trd_dat vorticity 17 !! 3.7 ! 2014-04 (G. Madec) trend simplification: suppress jpdyn_trd_dat vorticity 18 18 !! - ! 2014-06 (G. Madec) suppression of velocity curl from in-core memory 19 19 !! - ! 2016-12 (G. Madec, E. Clementi) add Stokes-Coriolis trends (ln_stcor=T) … … 74 74 INTEGER, PUBLIC, PARAMETER :: np_MIX = 5 ! MIX scheme 75 75 76 INTEGER :: ncor, nrvm, ntot ! choice of calculated vorticity 76 INTEGER :: ncor, nrvm, ntot ! choice of calculated vorticity 77 77 ! ! associated indices: 78 78 INTEGER, PUBLIC, PARAMETER :: np_COR = 1 ! Coriolis (planetary) … … 83 83 84 84 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: di_e2u_2 ! = di(e2u)/2 used in T-point metric term calculation 85 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: dj_e1v_2 ! = dj(e1v)/2 - - - - 85 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: dj_e1v_2 ! = dj(e1v)/2 - - - - 86 86 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: di_e2v_2e1e2f ! = di(e2u)/(2*e1e2f) used in F-point metric term calculation 87 87 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: dj_e1u_2e1e2f ! = dj(e1v)/(2*e1e2f) - - - - 88 88 ! 89 89 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: e3f_0vor ! e3f used in EEN, ENE and ENS cases (key_qco only) 90 90 91 91 REAL(wp) :: r1_4 = 0.250_wp ! =1/4 92 92 REAL(wp) :: r1_8 = 0.125_wp ! =1/8 93 93 REAL(wp) :: r1_12 = 1._wp / 12._wp ! 1/12 94 94 95 95 !! * Substitutions 96 96 # include "do_loop_substitute.h90" … … 111 111 !! ** Action : - Update (puu(:,:,:,Krhs),pvv(:,:,:,Krhs)) with the now vorticity term trend 112 112 !! - save the trends in (ztrdu,ztrdv) in 2 parts (relative 113 !! and planetary vorticity trends) and send them to trd_dyn 113 !! and planetary vorticity trends) and send them to trd_dyn 114 114 !! for futher diagnostics (l_trddyn=T) 115 115 !!---------------------------------------------------------------------- … … 163 163 CALL vor_enT( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! total vorticity trend 164 164 IF( ln_stcor .AND. .NOT. ln_vortex_force ) THEN 165 CALL vor_enT( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend 165 CALL vor_enT( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend 166 166 ELSE IF( ln_stcor .AND. ln_vortex_force ) THEN 167 167 CALL vor_enT( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) ) ! add the Stokes-Coriolis trend and vortex force … … 218 218 !! *** ROUTINE vor_enT *** 219 219 !! 220 !! ** Purpose : Compute the now total vorticity trend and add it to 220 !! ** Purpose : Compute the now total vorticity trend and add it to 221 221 !! the general trend of the momentum equation. 222 222 !! 223 !! ** Method : Trend evaluated using now fields (centered in time) 223 !! ** Method : Trend evaluated using now fields (centered in time) 224 224 !! and t-point evaluation of vorticity (planetary and relative). 225 225 !! conserves the horizontal kinetic energy. 226 !! The general trend of momentum is increased due to the vorticity 226 !! The general trend of momentum is increased due to the vorticity 227 227 !! term which is given by: 228 228 !! voru = 1/bu mj[ ( mi(mj(bf*rvor))+bt*f_t)/e3t mj[vn] ] … … 260 260 & - e1u(ji,jj+1) * pu(ji,jj+1,jk) + e1u(ji,jj) * pu(ji,jj,jk) ) * r1_e1e2f(ji,jj) 261 261 END_2D 262 IF( ln_dynvor_msk ) THEN ! mask relative vorticity 262 IF( ln_dynvor_msk ) THEN ! mask relative vorticity 263 263 DO_2D( 1, 0, 1, 0 ) 264 264 zwz(ji,jj,jk) = zwz(ji,jj,jk) * fmask(ji,jj,jk) … … 314 314 ! 315 315 pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) - r1_4 * r1_e1e2v(ji,jj) / e3v(ji,jj,jk,Kmm) & 316 & * ( zwt(ji,jj+1) * ( pu(ji,jj+1,jk) + pu(ji-1,jj+1,jk) ) & 317 & + zwt(ji,jj ) * ( pu(ji,jj ,jk) + pu(ji-1,jj ,jk) ) ) 316 & * ( zwt(ji,jj+1) * ( pu(ji,jj+1,jk) + pu(ji-1,jj+1,jk) ) & 317 & + zwt(ji,jj ) * ( pu(ji,jj ,jk) + pu(ji-1,jj ,jk) ) ) 318 318 END_2D 319 319 ! ! =============== … … 332 332 !! *** ROUTINE vor_ene *** 333 333 !! 334 !! ** Purpose : Compute the now total vorticity trend and add it to 334 !! ** Purpose : Compute the now total vorticity trend and add it to 335 335 !! the general trend of the momentum equation. 336 336 !! 337 !! ** Method : Trend evaluated using now fields (centered in time) 337 !! ** Method : Trend evaluated using now fields (centered in time) 338 338 !! and the Sadourny (1975) flux form formulation : conserves the 339 339 !! horizontal kinetic energy. 340 !! The general trend of momentum is increased due to the vorticity 340 !! The general trend of momentum is increased due to the vorticity 341 341 !! term which is given by: 342 342 !! voru = 1/e1u mj-1[ (rvor+f)/e3f mi(e1v*e3v pvv(:,:,:,Kmm)) ] … … 371 371 SELECT CASE( kvor ) !== vorticity considered ==! 372 372 CASE ( np_COR ) !* Coriolis (planetary vorticity) 373 zwz(:,:) = ff_f(:,:) 373 zwz(:,:) = ff_f(:,:) 374 374 CASE ( np_RVO ) !* relative vorticity 375 375 DO_2D( 1, 0, 1, 0 ) … … 447 447 zx2 = zwx(ji ,jj) + zwx(ji ,jj+1) 448 448 pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + r1_4 * r1_e1u(ji,jj) * ( zwz(ji ,jj-1) * zy1 + zwz(ji,jj) * zy2 ) 449 pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) - r1_4 * r1_e2v(ji,jj) * ( zwz(ji-1,jj ) * zx1 + zwz(ji,jj) * zx2 ) 449 pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) - r1_4 * r1_e2v(ji,jj) * ( zwz(ji-1,jj ) * zx1 + zwz(ji,jj) * zx2 ) 450 450 END_2D 451 451 ! ! =============== … … 497 497 SELECT CASE( kvor ) !== vorticity considered ==! 498 498 CASE ( np_COR ) !* Coriolis (planetary vorticity) 499 zwz(:,:) = ff_f(:,:) 499 zwz(:,:) = ff_f(:,:) 500 500 CASE ( np_RVO ) !* relative vorticity 501 501 DO_2D( 1, 0, 1, 0 ) … … 586 586 !! *** ROUTINE vor_een *** 587 587 !! 588 !! ** Purpose : Compute the now total vorticity trend and add it to 588 !! ** Purpose : Compute the now total vorticity trend and add it to 589 589 !! the general trend of the momentum equation. 590 590 !! 591 !! ** Method : Trend evaluated using now fields (centered in time) 592 !! and the Arakawa and Lamb (1980) flux form formulation : conserves 591 !! ** Method : Trend evaluated using now fields (centered in time) 592 !! and the Arakawa and Lamb (1980) flux form formulation : conserves 593 593 !! both the horizontal kinetic energy and the potential enstrophy 594 594 !! when horizontal divergence is zero (see the NEMO documentation) … … 684 684 IF( ln_dynvor_msk ) THEN ! mask the relative vorticity 685 685 DO_2D( 1, 0, 1, 0 ) 686 zwz(ji,jj,jk) = ( zwz(ji,jj,jk) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj) 686 zwz(ji,jj,jk) = ( zwz(ji,jj,jk) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj) 687 687 END_2D 688 688 ENDIF … … 735 735 !! *** ROUTINE vor_eeT *** 736 736 !! 737 !! ** Purpose : Compute the now total vorticity trend and add it to 737 !! ** Purpose : Compute the now total vorticity trend and add it to 738 738 !! the general trend of the momentum equation. 739 739 !! 740 !! ** Method : Trend evaluated using now fields (centered in time) 741 !! and the Arakawa and Lamb (1980) vector form formulation using 740 !! ** Method : Trend evaluated using now fields (centered in time) 741 !! and the Arakawa and Lamb (1980) vector form formulation using 742 742 !! a modified version of Arakawa and Lamb (1980) scheme (see vor_een). 743 !! The change consists in 743 !! The change consists in 744 744 !! Add this trend to the general momentum trend (pu_rhs,pv_rhs). 745 745 !! … … 758 758 REAL(wp) :: zua, zva ! local scalars 759 759 REAL(wp) :: zmsk, z1_e3t ! local scalars 760 REAL(wp), DIMENSION(jpi,jpj) :: zwx , zwy 760 REAL(wp), DIMENSION(jpi,jpj) :: zwx , zwy 761 761 REAL(wp), DIMENSION(jpi,jpj) :: ztnw, ztne, ztsw, ztse 762 762 REAL(wp), DIMENSION(jpi,jpj,jpkm1) :: zwz ! 3D workspace, avoid lbc_lnk on jpk that is not defined … … 803 803 IF( ln_dynvor_msk ) THEN ! mask the relative vorticity 804 804 DO_2D( 1, 0, 1, 0 ) 805 zwz(ji,jj,jk) = ( zwz(ji,jj,jk) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj) 805 zwz(ji,jj,jk) = ( zwz(ji,jj,jk) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj) 806 806 END_2D 807 807 ENDIF … … 916 916 ! 917 917 IF( ioptio /= 1 ) CALL ctl_stop( ' use ONE and ONLY one vorticity scheme' ) 918 ! 918 ! 919 919 IF(lwp) WRITE(numout,*) ! type of calculated vorticity (set ncor, nrvm, ntot) 920 920 ncor = np_COR ! planetary vorticity … … 925 925 ntot = np_COR ! - - 926 926 CASE( np_VEC_c2 ) 927 IF(lwp) WRITE(numout,*) ' ==>>> vector form dynamics : total vorticity = Coriolis + relative vorticity' 927 IF(lwp) WRITE(numout,*) ' ==>>> vector form dynamics : total vorticity = Coriolis + relative vorticity' 928 928 nrvm = np_RVO ! relative vorticity 929 ntot = np_CRV ! relative + planetary vorticity 929 ntot = np_CRV ! relative + planetary vorticity 930 930 CASE( np_FLX_c2 , np_FLX_ubs ) 931 931 IF(lwp) WRITE(numout,*) ' ==>>> flux form dynamics : total vorticity = Coriolis + metric term' … … 971 971 & + tmask(ji,jj ,jk) +tmask(ji+1,jj ,jk) ) 972 972 ! 973 IF( zmsk /= 0._wp ) THEN 973 IF( zmsk /= 0._wp ) THEN 974 974 e3f_0vor(ji,jj,jk) = ( e3t_0(ji ,jj+1,jk)*tmask(ji ,jj+1,jk) & 975 975 & + e3t_0(ji+1,jj+1,jk)*tmask(ji+1,jj+1,jk) & … … 997 997 CASE( np_EEN ) ; WRITE(numout,*) ' ==>>> energy and enstrophy conserving scheme (EEN)' 998 998 CASE( np_MIX ) ; WRITE(numout,*) ' ==>>> mixed enstrophy/energy conserving scheme (MIX)' 999 END SELECT 999 END SELECT 1000 1000 ENDIF 1001 1001 ! -
NEMO/trunk/src/OCE/DYN/dynzad.F90
r14007 r14072 7 7 !! NEMO 0.5 ! 2002-07 (G. Madec) Free form, F90 8 8 !!---------------------------------------------------------------------- 9 9 10 10 !!---------------------------------------------------------------------- 11 11 !! dyn_zad : vertical advection momentum trend … … 25 25 IMPLICIT NONE 26 26 PRIVATE 27 27 28 28 PUBLIC dyn_zad ! routine called by dynadv.F90 29 29 … … 41 41 !!---------------------------------------------------------------------- 42 42 !! *** ROUTINE dynzad *** 43 !! 44 !! ** Purpose : Compute the now vertical momentum advection trend and 43 !! 44 !! ** Purpose : Compute the now vertical momentum advection trend and 45 45 !! add it to the general trend of momentum equation. 46 46 !! … … 73 73 74 74 IF( l_trddyn ) THEN ! Save puu(:,:,:,Krhs) and pvv(:,:,:,Krhs) trends 75 ALLOCATE( ztrdu(jpi,jpj,jpk) , ztrdv(jpi,jpj,jpk) ) 76 ztrdu(:,:,:) = puu(:,:,:,Krhs) 77 ztrdv(:,:,:) = pvv(:,:,:,Krhs) 75 ALLOCATE( ztrdu(jpi,jpj,jpk) , ztrdv(jpi,jpj,jpk) ) 76 ztrdu(:,:,:) = puu(:,:,:,Krhs) 77 ztrdv(:,:,:) = pvv(:,:,:,Krhs) 78 78 ENDIF 79 79 80 80 DO jk = 2, jpkm1 ! Vertical momentum advection at level w and u- and v- vertical 81 81 DO_2D( 0, 1, 0, 1 ) ! vertical fluxes … … 111 111 ztrdv(:,:,:) = pvv(:,:,:,Krhs) - ztrdv(:,:,:) 112 112 CALL trd_dyn( ztrdu, ztrdv, jpdyn_zad, kt, Kmm ) 113 DEALLOCATE( ztrdu, ztrdv ) 113 DEALLOCATE( ztrdu, ztrdv ) 114 114 ENDIF 115 115 ! ! Control print -
NEMO/trunk/src/OCE/IOM/in_out_manager.F90
r13970 r14072 1 MODULE in_out_manager 1 MODULE in_out_manager 2 2 !!====================================================================== 3 3 !! *** MODULE in_out_manager *** … … 53 53 ! The following four values determine the partitioning of the output fields 54 54 ! into netcdf4 chunks. They are unrelated to the nn_chunk_sz setting which is 55 ! for runtime optimisation. The individual netcdf4 chunks can be optionally 56 ! gzipped (recommended) leading to significant reductions in I/O volumes 55 ! for runtime optimisation. The individual netcdf4 chunks can be optionally 56 ! gzipped (recommended) leading to significant reductions in I/O volumes 57 57 ! !!!** variables only used with iom_nf90 routines and key_netcdf4 ** 58 INTEGER :: nn_nchunks_i !: number of chunks required in the i-dimension 59 INTEGER :: nn_nchunks_j !: number of chunks required in the j-dimension 60 INTEGER :: nn_nchunks_k !: number of chunks required in the k-dimension 61 INTEGER :: nn_nchunks_t !: number of chunks required in the t-dimension 58 INTEGER :: nn_nchunks_i !: number of chunks required in the i-dimension 59 INTEGER :: nn_nchunks_j !: number of chunks required in the j-dimension 60 INTEGER :: nn_nchunks_k !: number of chunks required in the k-dimension 61 INTEGER :: nn_nchunks_t !: number of chunks required in the t-dimension 62 62 LOGICAL :: ln_nc4zip !: netcdf4 usage: (T) chunk and compress output using the HDF5 sublayers of netcdf4 63 ! ! (F) ignore chunking request and use the netcdf4 library 64 ! ! to produce netcdf3-compatible files 63 ! ! (F) ignore chunking request and use the netcdf4 library 64 ! ! to produce netcdf3-compatible files 65 65 #endif 66 66 … … 85 85 !!---------------------------------------------------------------------- 86 86 INTEGER :: nitrst !: time step at which restart file should be written 87 LOGICAL :: lrst_oce !: logical to control the oce restart write 88 LOGICAL :: lrst_ice !: logical to control the ice restart write 89 LOGICAL :: lrst_abl !: logical to control the abl restart write 87 LOGICAL :: lrst_oce !: logical to control the oce restart write 88 LOGICAL :: lrst_ice !: logical to control the ice restart write 89 LOGICAL :: lrst_abl !: logical to control the abl restart write 90 90 INTEGER :: numror = 0 !: logical unit for ocean restart (read). Init to 0 is needed for SAS (in daymod.F90) 91 91 INTEGER :: numrir = 0 !: logical unit for ice restart (read) … … 155 155 156 156 !!---------------------------------------------------------------------- 157 !! Run control 157 !! Run control 158 158 !!---------------------------------------------------------------------- 159 159 INTEGER :: no_print = 0 !: optional argument of fld_fill (if present, suppress some control print) -
NEMO/trunk/src/OCE/IOM/iom.F90
r14068 r14072 7 7 !! 2.0 ! 2006-02 (S. Masson) Adaptation to NEMO 8 8 !! 3.0 ! 2007-07 (D. Storkey) Changes to iom_gettime 9 !! 3.4 ! 2012-12 (R. Bourdalle-Badie and G. Reffray) add C1D case 9 !! 3.4 ! 2012-12 (R. Bourdalle-Badie and G. Reffray) add C1D case 10 10 !! 3.6 ! 2014-15 DIMG format removed 11 11 !! 3.6 ! 2015-15 (J. Harle) Added procedure to read REAL attributes … … 21 21 !!---------------------------------------------------------------------- 22 22 USE dom_oce ! ocean space and time domain 23 USE domutl ! 23 USE domutl ! 24 24 USE c1d ! 1D vertical configuration 25 25 USE flo_oce ! floats module declarations … … 44 44 USE trc, ONLY : profsed 45 45 #endif 46 USE lib_fortran 46 USE lib_fortran 47 47 USE diu_bulk, ONLY : ln_diurnal_only, ln_diurnal 48 48 USE iom_nf90 … … 51 51 IMPLICIT NONE 52 52 PUBLIC ! must be public to be able to access iom_def through iom 53 53 54 54 #if defined key_iomput 55 55 LOGICAL, PUBLIC, PARAMETER :: lk_iomput = .TRUE. !: iom_put flag … … 95 95 MODULE PROCEDURE iom_p0d_dp, iom_p1d_dp, iom_p2d_dp, iom_p3d_dp, iom_p4d_dp 96 96 END INTERFACE iom_put 97 97 98 98 !! * Substitutions 99 99 # include "do_loop_substitute.h90" … … 105 105 CONTAINS 106 106 107 SUBROUTINE iom_init( cdname, kdid, ld_closedef ) 107 SUBROUTINE iom_init( cdname, kdid, ld_closedef ) 108 108 !!---------------------------------------------------------------------- 109 109 !! *** ROUTINE *** 110 110 !! 111 !! ** Purpose : 111 !! ** Purpose : 112 112 !! 113 113 !!---------------------------------------------------------------------- 114 114 CHARACTER(len=*), INTENT(in) :: cdname 115 INTEGER , OPTIONAL, INTENT(in) :: kdid 115 INTEGER , OPTIONAL, INTENT(in) :: kdid 116 116 LOGICAL , OPTIONAL, INTENT(in) :: ld_closedef 117 117 #if defined key_iomput … … 123 123 INTEGER :: ji 124 124 LOGICAL :: llrst_context ! is context related to restart 125 LOGICAL :: llrstr, llrstw 125 LOGICAL :: llrstr, llrstw 126 126 INTEGER :: inum 127 127 ! … … 152 152 llrst_context = llrstr .OR. llrstw 153 153 154 ! Calendar type is now defined in xml file 154 ! Calendar type is now defined in xml file 155 155 IF (.NOT.(xios_getvar('ref_year' ,irefyear ))) irefyear = 1900 156 156 IF (.NOT.(xios_getvar('ref_month',irefmonth))) irefmonth = 01 … … 169 169 IF(.NOT.llrst_context) CALL set_scalar 170 170 ! 171 IF( cdname == cxios_context ) THEN 172 CALL set_grid( "T", glamt, gphit, .FALSE., .FALSE. ) 171 IF( cdname == cxios_context ) THEN 172 CALL set_grid( "T", glamt, gphit, .FALSE., .FALSE. ) 173 173 CALL set_grid( "U", glamu, gphiu, .FALSE., .FALSE. ) 174 174 CALL set_grid( "V", glamv, gphiv, .FALSE., .FALSE. ) … … 191 191 ENDIF 192 192 ! 193 IF( TRIM(cdname) == TRIM(cxios_context)//"_crs" ) THEN 193 IF( TRIM(cdname) == TRIM(cxios_context)//"_crs" ) THEN 194 194 CALL dom_grid_crs ! Save the parent grid information & Switch to coarse grid domain 195 195 ! … … 223 223 224 224 ! ABL 225 IF( .NOT. ALLOCATED(ght_abl) ) THEN ! force definition for xml files (xios) 225 IF( .NOT. ALLOCATED(ght_abl) ) THEN ! force definition for xml files (xios) 226 226 ALLOCATE( ght_abl(jpka), ghw_abl(jpka), e3t_abl(jpka), e3w_abl(jpka) ) ! default allocation needed by iom 227 227 ght_abl(:) = -1._wp ; ghw_abl(:) = -1._wp … … 230 230 CALL iom_set_axis_attr( "ght_abl", ght_abl(2:jpka) ) 231 231 CALL iom_set_axis_attr( "ghw_abl", ghw_abl(2:jpka) ) 232 232 233 233 ! Add vertical grid bounds 234 234 zt_bnds(2,: ) = gdept_1d(:) … … 338 338 !! 339 339 !! ** Purpose : define filename in XIOS context for reading file, 340 !! enable variables present in a file for reading with XIOS 340 !! enable variables present in a file for reading with XIOS 341 341 !! id of the file is assumed to be rrestart. 342 342 !!--------------------------------------------------------------------- 343 INTEGER, INTENT(IN) :: idnum 344 343 INTEGER, INTENT(IN) :: idnum 344 345 345 #if defined key_iomput 346 346 INTEGER :: ndims, nvars, natts, unlimitedDimId, dimlen, xtype,mdims … … 423 423 CALL xios_set_attr (field_hdl, enabled = .TRUE., name = varname, & 424 424 domain_ref="grid_N", prec = 8, & 425 operation = "instant" ) 425 operation = "instant" ) 426 426 ELSEIF(mdims == 1) THEN 427 427 CALL xios_set_attr (field_hdl, enabled = .TRUE., name = varname, & … … 433 433 operation = "instant" ) 434 434 ELSE 435 WRITE(ctmp1,*) 'iom_set_vars_active: variable ', TRIM(varname) ,' incorrect number of dimensions' 435 WRITE(ctmp1,*) 'iom_set_vars_active: variable ', TRIM(varname) ,' incorrect number of dimensions' 436 436 CALL ctl_stop( 'iom_set_vars_active:', ctmp1 ) 437 437 ENDIF … … 457 457 CALL xios_get_handle("file_definition", filegroup_hdl ) 458 458 CALL xios_add_child(filegroup_hdl, file_hdl, 'wrestart') 459 IF(nxioso.eq.1) THEN 460 CALL xios_set_file_attr( "wrestart", type="one_file", enabled=.TRUE.,& 461 mode="write", output_freq=xios_timestep) 462 IF(lwp) write(numout,*) 'OPEN ', trim(cdrst_file), ' in one_file mode' 463 ELSE 464 CALL xios_set_file_attr( "wrestart", type="multiple_file", enabled=.TRUE.,& 465 mode="write", output_freq=xios_timestep) 466 IF(lwp) write(numout,*) 'OPEN ', trim(cdrst_file), ' in multiple_file mode' 467 ENDIF 459 IF(nxioso.eq.1) THEN 460 CALL xios_set_file_attr( "wrestart", type="one_file", enabled=.TRUE.,& 461 mode="write", output_freq=xios_timestep) 462 IF(lwp) write(numout,*) 'OPEN ', trim(cdrst_file), ' in one_file mode' 463 ELSE 464 CALL xios_set_file_attr( "wrestart", type="multiple_file", enabled=.TRUE.,& 465 mode="write", output_freq=xios_timestep) 466 IF(lwp) write(numout,*) 'OPEN ', trim(cdrst_file), ' in multiple_file mode' 467 ENDIF 468 468 CALL xios_set_file_attr( "wrestart", name=trim(cdrst_file)) 469 469 #endif … … 486 486 REAL(dp), OPTIONAL, INTENT(IN), DIMENSION(:, :) :: rd2 487 487 REAL(sp), OPTIONAL, INTENT(IN), DIMENSION(:, :) :: rs2 488 REAL(dp), OPTIONAL, INTENT(IN), DIMENSION(:, :, :) :: rd3 488 REAL(dp), OPTIONAL, INTENT(IN), DIMENSION(:, :, :) :: rd3 489 489 REAL(sp), OPTIONAL, INTENT(IN), DIMENSION(:, :, :) :: rs3 490 490 #if defined key_iomput … … 509 509 CALL xios_set_attr (field_hdl, enabled = .TRUE., name = sdfield, & 510 510 domain_ref = "grid_N", prec = 8, & 511 operation = "instant" ) 511 operation = "instant" ) 512 512 ELSEIF(PRESENT(rs2)) THEN 513 513 CALL xios_set_attr (field_hdl, enabled = .TRUE., name = sdfield, & … … 540 540 !! ** Purpose : Used for grid definition when XIOS is used to read/write 541 541 !! restart. Returns axis corresponding to the number of levels 542 !! given as an input variable. Axes are defined in routine 542 !! given as an input variable. Axes are defined in routine 543 543 !! iom_set_rst_context 544 544 !!--------------------------------------------------------------------- … … 551 551 ELSEIF(idlev == jpl) THEN 552 552 axis_ref="numcat" 553 #endif 553 #endif 554 554 ELSE 555 555 write(str, *) idlev … … 562 562 !! *** FUNCTION *** 563 563 !! 564 !! ** Purpose : this function returns first available id to keep information about file 564 !! ** Purpose : this function returns first available id to keep information about file 565 565 !! sets filename in iom_file structure and sets name 566 566 !! of XIOS context depending on cdcomp … … 583 583 END FUNCTION iom_xios_setid 584 584 585 SUBROUTINE iom_set_rst_context(ld_rstr) 585 SUBROUTINE iom_set_rst_context(ld_rstr) 586 586 !!--------------------------------------------------------------------- 587 587 !! *** SUBROUTINE iom_set_rst_context *** 588 588 !! 589 !! ** Purpose : Define domain, axis and grid for restart (read/write) 590 !! context 591 !! 589 !! ** Purpose : Define domain, axis and grid for restart (read/write) 590 !! context 591 !! 592 592 !!--------------------------------------------------------------------- 593 593 LOGICAL, INTENT(IN) :: ld_rstr 594 594 INTEGER :: ji 595 595 #if defined key_iomput 596 TYPE(xios_domaingroup) :: domaingroup_hdl 597 TYPE(xios_domain) :: domain_hdl 598 TYPE(xios_axisgroup) :: axisgroup_hdl 599 TYPE(xios_axis) :: axis_hdl 600 TYPE(xios_scalar) :: scalar_hdl 601 TYPE(xios_scalargroup) :: scalargroup_hdl 602 603 CALL xios_get_handle("domain_definition",domaingroup_hdl) 604 CALL xios_add_child(domaingroup_hdl, domain_hdl, "grid_N") 605 CALL set_grid("N", glamt, gphit, .TRUE., ld_rstr) 606 607 CALL xios_get_handle("axis_definition",axisgroup_hdl) 608 CALL xios_add_child(axisgroup_hdl, axis_hdl, "nav_lev") 596 TYPE(xios_domaingroup) :: domaingroup_hdl 597 TYPE(xios_domain) :: domain_hdl 598 TYPE(xios_axisgroup) :: axisgroup_hdl 599 TYPE(xios_axis) :: axis_hdl 600 TYPE(xios_scalar) :: scalar_hdl 601 TYPE(xios_scalargroup) :: scalargroup_hdl 602 603 CALL xios_get_handle("domain_definition",domaingroup_hdl) 604 CALL xios_add_child(domaingroup_hdl, domain_hdl, "grid_N") 605 CALL set_grid("N", glamt, gphit, .TRUE., ld_rstr) 606 607 CALL xios_get_handle("axis_definition",axisgroup_hdl) 608 CALL xios_add_child(axisgroup_hdl, axis_hdl, "nav_lev") 609 609 !AGRIF fails to compile when unit= is in call to xios_set_axis_attr 610 ! CALL xios_set_axis_attr( "nav_lev", long_name="Vertical levels", unit="m", positive="down") 610 ! CALL xios_set_axis_attr( "nav_lev", long_name="Vertical levels", unit="m", positive="down") 611 611 CALL xios_set_axis_attr( "nav_lev", long_name = "Vertical levels in meters", positive = "down") 612 CALL iom_set_axis_attr( "nav_lev", paxis = gdept_1d ) 612 CALL iom_set_axis_attr( "nav_lev", paxis = gdept_1d ) 613 613 #if defined key_si3 614 614 CALL xios_add_child(axisgroup_hdl, axis_hdl, "numcat") 615 615 CALL iom_set_axis_attr( "numcat", (/ (REAL(ji,wp), ji=1,jpl) /) ) 616 616 #endif 617 CALL xios_get_handle("scalar_definition", scalargroup_hdl) 618 CALL xios_add_child(scalargroup_hdl, scalar_hdl, "grid_scalar") 617 CALL xios_get_handle("scalar_definition", scalargroup_hdl) 618 CALL xios_add_child(scalargroup_hdl, scalar_hdl, "grid_scalar") 619 619 #endif 620 620 END SUBROUTINE iom_set_rst_context 621 621 622 622 623 SUBROUTINE set_xios_context(kdid, cdcont) 623 SUBROUTINE set_xios_context(kdid, cdcont) 624 624 !!--------------------------------------------------------------------- 625 625 !! *** SUBROUTINE iom_set_rst_context *** 626 626 !! 627 627 !! ** Purpose : set correct XIOS context based on kdid 628 !! 628 !! 629 629 !!--------------------------------------------------------------------- 630 630 INTEGER, INTENT(IN) :: kdid ! Identifier of the file 631 631 CHARACTER(LEN=lc), INTENT(OUT) :: cdcont ! name of the context for XIOS read/write 632 632 633 633 cdcont = "NONE" 634 634 … … 637 637 cdcont = cr_ocerst_cxt 638 638 ELSEIF(kdid == numrir) THEN 639 cdcont = cr_icerst_cxt 639 cdcont = cr_icerst_cxt 640 640 ELSEIF(kdid == numrtr) THEN 641 641 cdcont = cr_toprst_cxt … … 696 696 CHARACTER(LEN=256) :: clname ! the name of the file based on cdname [[+clcpu]+clcpu] 697 697 CHARACTER(LEN=256) :: cltmpn ! tempory name to store clname (in writting mode) 698 CHARACTER(LEN=10) :: clsuffix ! ".nc" 698 CHARACTER(LEN=10) :: clsuffix ! ".nc" 699 699 CHARACTER(LEN=15) :: clcpu ! the cpu number (max jpmax_digits digits) 700 700 CHARACTER(LEN=256) :: clinfo ! info character 701 LOGICAL :: llok ! check the existence 701 LOGICAL :: llok ! check the existence 702 702 LOGICAL :: llwrt ! local definition of ldwrt 703 703 LOGICAL :: llstop ! local definition of ldstop … … 705 705 INTEGER :: icnt ! counter for digits in clcpu (max = jpmax_digits) 706 706 INTEGER :: iln, ils ! lengths of character 707 INTEGER :: istop ! 707 INTEGER :: istop ! 708 708 ! local number of points for x,y dimensions 709 709 ! position of first local point for x,y dimensions … … 741 741 clname = trim(cdname) 742 742 IF ( .NOT. Agrif_Root() .AND. .NOT. lliof ) THEN 743 iln = INDEX(clname,'/') 743 iln = INDEX(clname,'/') 744 744 cltmpn = clname(1:iln) 745 745 clname = clname(iln+1:LEN_TRIM(clname)) … … 765 765 clname = clname(1:iln-1)//'_'//TRIM(clcpu)//TRIM(clsuffix) 766 766 icnt = 0 767 INQUIRE( FILE = clname, EXIST = llok ) 767 INQUIRE( FILE = clname, EXIST = llok ) 768 768 ! we try different formats for the cpu number by adding 0 769 769 DO WHILE( .NOT.llok .AND. icnt < jpmax_digits ) … … 783 783 ! if no file was found... 784 784 IF( .NOT. llok ) THEN 785 IF( .NOT. llwrt ) THEN ! we are in read mode 785 IF( .NOT. llwrt ) THEN ! we are in read mode 786 786 IF( llstop ) THEN ; CALL ctl_stop( TRIM(clinfo), 'File '//TRIM(cltmpn)//'* not found' ) 787 787 ELSE ; istop = nstop + 1 ! make sure that istop /= nstop so we don't open the file 788 788 ENDIF 789 ELSE ! we are in write mode so we 789 ELSE ! we are in write mode so we 790 790 clname = cltmpn ! get back the file name without the cpu number 791 791 ENDIF 792 792 ELSE 793 IF( llwrt .AND. .NOT. ln_clobber ) THEN ! we stop as we want to write in a new file 793 IF( llwrt .AND. .NOT. ln_clobber ) THEN ! we stop as we want to write in a new file 794 794 CALL ctl_stop( TRIM(clinfo), 'We want to write in a new file but '//TRIM(clname)//' already exists...' ) 795 795 istop = nstop + 1 ! make sure that istop /= nstop so we don't open the file 796 ELSEIF( llwrt ) THEN ! the file exists and we are in write mode with permission to 796 ELSEIF( llwrt ) THEN ! the file exists and we are in write mode with permission to 797 797 clname = cltmpn ! overwrite so get back the file name without the cpu number 798 798 ENDIF … … 835 835 IF( iom_file(jf)%nfid > 0 ) THEN 836 836 CALL iom_nf90_close( jf ) 837 iom_file(jf)%nfid = 0 ! free the id 837 iom_file(jf)%nfid = 0 ! free the id 838 838 IF( PRESENT(kiomid) ) kiomid = 0 ! return 0 as id to specify that the file was closed 839 839 IF(lwp) WRITE(numout,*) TRIM(clinfo)//' close file: '//TRIM(iom_file(jf)%name)//' ok' … … 844 844 END DO 845 845 ENDIF 846 ! 846 ! 847 847 END SUBROUTINE iom_close 848 848 849 849 850 FUNCTION iom_varid ( kiomid, cdvar, kdimsz, kndims, lduld, ldstop ) 850 FUNCTION iom_varid ( kiomid, cdvar, kdimsz, kndims, lduld, ldstop ) 851 851 !!----------------------------------------------------------------------- 852 852 !! *** FUNCTION iom_varid *** … … 874 874 IF( kiomid > 0 ) THEN 875 875 clinfo = 'iom_varid, file: '//trim(iom_file(kiomid)%name)//', var: '//trim(cdvar) 876 IF( iom_file(kiomid)%nfid == 0 ) THEN 876 IF( iom_file(kiomid)%nfid == 0 ) THEN 877 877 CALL ctl_stop( trim(clinfo), 'the file is not open' ) 878 878 ELSE … … 893 893 & 'increase the parameter jpmax_vars') 894 894 ENDIF 895 IF( llstop .AND. iom_varid == -1 ) CALL ctl_stop( TRIM(clinfo)//' not found' ) 895 IF( llstop .AND. iom_varid == -1 ) CALL ctl_stop( TRIM(clinfo)//' not found' ) 896 896 ELSE 897 897 iom_varid = iiv 898 IF( PRESENT(kdimsz) ) THEN 898 IF( PRESENT(kdimsz) ) THEN 899 899 i_nvd = iom_file(kiomid)%ndims(iiv) 900 900 IF( i_nvd <= size(kdimsz) ) THEN … … 1022 1022 REAL(dp) , ALLOCATABLE , DIMENSION(:) :: ztmp_pvar ! tmp var to read field 1023 1023 INTEGER , INTENT(in ) , OPTIONAL :: ktime ! record number 1024 INTEGER , INTENT(in ), DIMENSION(1), OPTIONAL :: kstart ! start axis position of the reading 1024 INTEGER , INTENT(in ), DIMENSION(1), OPTIONAL :: kstart ! start axis position of the reading 1025 1025 INTEGER , INTENT(in ), DIMENSION(1), OPTIONAL :: kcount ! number of points in each axis 1026 1026 ! … … 1043 1043 REAL(dp) , INTENT( out), DIMENSION(:) :: pvar ! read field 1044 1044 INTEGER , INTENT(in ) , OPTIONAL :: ktime ! record number 1045 INTEGER , INTENT(in ), DIMENSION(1), OPTIONAL :: kstart ! start axis position of the reading 1045 INTEGER , INTENT(in ), DIMENSION(1), OPTIONAL :: kstart ! start axis position of the reading 1046 1046 INTEGER , INTENT(in ), DIMENSION(1), OPTIONAL :: kcount ! number of points in each axis 1047 1047 ! … … 1062 1062 REAL(dp) , INTENT(in ) , OPTIONAL :: psgn ! -1.(1.): (not) change sign across the north fold 1063 1063 INTEGER , INTENT(in ) , OPTIONAL :: kfill ! value of kfillmode in lbc_lbk 1064 INTEGER , INTENT(in ), DIMENSION(2), OPTIONAL :: kstart ! start axis position of the reading 1064 INTEGER , INTENT(in ), DIMENSION(2), OPTIONAL :: kstart ! start axis position of the reading 1065 1065 INTEGER , INTENT(in ), DIMENSION(2), OPTIONAL :: kcount ! number of points in each axis 1066 1066 ! … … 1086 1086 REAL(dp) , INTENT(in ) , OPTIONAL :: psgn ! -1.(1.): (not) change sign across the north fold 1087 1087 INTEGER , INTENT(in ) , OPTIONAL :: kfill ! value of kfillmode in lbc_lbk 1088 INTEGER , INTENT(in ), DIMENSION(2), OPTIONAL :: kstart ! start axis position of the reading 1088 INTEGER , INTENT(in ), DIMENSION(2), OPTIONAL :: kstart ! start axis position of the reading 1089 1089 INTEGER , INTENT(in ), DIMENSION(2), OPTIONAL :: kcount ! number of points in each axis 1090 1090 ! … … 1106 1106 REAL(dp) , INTENT(in ) , OPTIONAL :: psgn ! -1.(1.) : (not) change sign across the north fold 1107 1107 INTEGER , INTENT(in ) , OPTIONAL :: kfill ! value of kfillmode in lbc_lbk 1108 INTEGER , INTENT(in ), DIMENSION(3), OPTIONAL :: kstart ! start axis position of the reading 1108 INTEGER , INTENT(in ), DIMENSION(3), OPTIONAL :: kstart ! start axis position of the reading 1109 1109 INTEGER , INTENT(in ), DIMENSION(3), OPTIONAL :: kcount ! number of points in each axis 1110 1110 ! … … 1130 1130 REAL(dp) , INTENT(in ) , OPTIONAL :: psgn ! -1.(1.) : (not) change sign across the north fold 1131 1131 INTEGER , INTENT(in ) , OPTIONAL :: kfill ! value of kfillmode in lbc_lbk 1132 INTEGER , INTENT(in ), DIMENSION(3), OPTIONAL :: kstart ! start axis position of the reading 1132 INTEGER , INTENT(in ), DIMENSION(3), OPTIONAL :: kstart ! start axis position of the reading 1133 1133 INTEGER , INTENT(in ), DIMENSION(3), OPTIONAL :: kcount ! number of points in each axis 1134 1134 ! … … 1163 1163 REAL(dp) , INTENT(in ), OPTIONAL :: psgn ! -1.(1.) : (not) change sign across the north fold 1164 1164 INTEGER , INTENT(in ), OPTIONAL :: kfill ! value of kfillmode in lbc_lbk 1165 INTEGER , DIMENSION(:) , INTENT(in ), OPTIONAL :: kstart ! start position of the reading in each axis 1165 INTEGER , DIMENSION(:) , INTENT(in ), OPTIONAL :: kstart ! start position of the reading in each axis 1166 1166 INTEGER , DIMENSION(:) , INTENT(in ), OPTIONAL :: kcount ! number of points to be read in each axis 1167 1167 ! 1168 1168 LOGICAL :: llok ! true if ok! 1169 INTEGER :: jl ! loop on number of dimension 1169 INTEGER :: jl ! loop on number of dimension 1170 1170 INTEGER :: idom ! type of domain 1171 1171 INTEGER :: idvar ! id of the variable 1172 1172 INTEGER :: inbdim ! number of dimensions of the variable 1173 INTEGER :: idmspc ! number of spatial dimensions 1173 INTEGER :: idmspc ! number of spatial dimensions 1174 1174 INTEGER :: itime ! record number 1175 1175 INTEGER :: istop ! temporary value of nstop 1176 1176 INTEGER :: ix1, ix2, iy1, iy2 ! subdomain indexes 1177 1177 INTEGER :: ji, jj ! loop counters 1178 INTEGER :: irankpv ! 1178 INTEGER :: irankpv ! 1179 1179 INTEGER :: ind1, ind2 ! substring index 1180 1180 INTEGER, DIMENSION(jpmax_dims) :: istart ! starting point to read for each axis 1181 INTEGER, DIMENSION(jpmax_dims) :: icnt ! number of value to read along each axis 1181 INTEGER, DIMENSION(jpmax_dims) :: icnt ! number of value to read along each axis 1182 1182 INTEGER, DIMENSION(jpmax_dims) :: idimsz ! size of the dimensions of the variable 1183 1183 INTEGER, DIMENSION(jpmax_dims) :: ishape ! size of the dimensions of the variable … … 1187 1187 CHARACTER(LEN=256) :: clinfo ! info character 1188 1188 CHARACTER(LEN=256) :: clname ! file name 1189 CHARACTER(LEN=1) :: clrankpv, cldmspc ! 1189 CHARACTER(LEN=1) :: clrankpv, cldmspc ! 1190 1190 CHARACTER(LEN=1) :: cl_type ! local value of cd_type 1191 1191 LOGICAL :: ll_only3rd ! T => if kstart, kcount present then *only* use values for 3rd spatial dimension. … … 1215 1215 ! Search for the variable in the data base (eventually actualize data) 1216 1216 ! 1217 idvar = iom_varid( kiomid, cdvar ) 1217 idvar = iom_varid( kiomid, cdvar ) 1218 1218 IF( idvar > 0 ) THEN 1219 1219 ! … … 1222 1222 idmspc = inbdim ! number of spatial dimensions in the file 1223 1223 IF( iom_file(kiomid)%luld(idvar) ) idmspc = inbdim - 1 1224 IF( idmspc > 3 ) CALL ctl_stop(trim(clinfo), 'the file has more than 3 spatial dimensions this case is not coded...') 1224 IF( idmspc > 3 ) CALL ctl_stop(trim(clinfo), 'the file has more than 3 spatial dimensions this case is not coded...') 1225 1225 ! 1226 1226 ! Identify the domain in case of jpdom_auto definition 1227 IF( idom == jpdom_auto .OR. idom == jpdom_auto_xy ) THEN 1227 IF( idom == jpdom_auto .OR. idom == jpdom_auto_xy ) THEN 1228 1228 idom = jpdom_global ! default 1229 1229 ! else: if the file name finishes with _xxxx.nc with xxxx any number … … 1262 1262 CALL ctl_warn( trim(clinfo), '2D array input but 3 spatial dimensions in the file...' , & 1263 1263 & 'As the size of the z dimension is 1 and as we try to read the first record, ', & 1264 & 'we accept this case, even if there is a possible mix-up between z and time dimension' ) 1264 & 'we accept this case, even if there is a possible mix-up between z and time dimension' ) 1265 1265 idmspc = idmspc - 1 1266 1266 !!GS: possibility to read 3D ABL atmopsheric forcing and use 1st level to force BULK simulation … … 1274 1274 ! definition of istart and icnt 1275 1275 ! 1276 icnt (:) = 1 ! default definition (simple way to deal with special cases listed above) 1277 istart(:) = 1 ! default definition (simple way to deal with special cases listed above) 1276 icnt (:) = 1 ! default definition (simple way to deal with special cases listed above) 1277 istart(:) = 1 ! default definition (simple way to deal with special cases listed above) 1278 1278 istart(idmspc+1) = itime ! temporal dimenstion 1279 1279 ! 1280 1280 IF( idom == jpdom_unknown ) THEN 1281 IF( PRESENT(kstart) .AND. idom /= jpdom_auto_xy ) THEN 1282 istart(1:idmspc) = kstart(1:idmspc) 1281 IF( PRESENT(kstart) .AND. idom /= jpdom_auto_xy ) THEN 1282 istart(1:idmspc) = kstart(1:idmspc) 1283 1283 icnt (1:idmspc) = kcount(1:idmspc) 1284 1284 ELSE … … 1286 1286 ENDIF 1287 1287 ELSE ! not a 1D array as pv_r1d requires jpdom_unknown 1288 ! we do not read the overlap and the extra-halos -> from Nis0 to Nie0 and from Njs0 to Nje0 1288 ! we do not read the overlap and the extra-halos -> from Nis0 to Nie0 and from Njs0 to Nje0 1289 1289 IF( idom == jpdom_global ) istart(1:2) = (/ mig0(Nis0), mjg0(Njs0) /) 1290 1290 icnt(1:2) = (/ Ni_0, Nj_0 /) … … 1306 1306 WRITE( ctmp1, FMT="('(istart(', i1, ') + icnt(', i1, ') - 1) = ', i5)" ) jl, jl, itmp 1307 1307 WRITE( ctmp2, FMT="(' is larger than idimsz(', i1,') = ', i5)" ) jl, idimsz(jl) 1308 CALL ctl_stop( trim(clinfo), 'start and count too big regarding to the size of the data, ', ctmp1, ctmp2 ) 1308 CALL ctl_stop( trim(clinfo), 'start and count too big regarding to the size of the data, ', ctmp1, ctmp2 ) 1309 1309 ENDIF 1310 1310 END DO 1311 1311 ! 1312 1312 ! check that icnt matches the input array 1313 !- 1313 !- 1314 1314 IF( idom == jpdom_unknown ) THEN 1315 1315 IF( irankpv == 1 ) ishape(1:1) = SHAPE(pv_r1d) … … 1321 1321 ishape(1:2) = SHAPE(pv_r2d(Nis0:Nie0,Njs0:Nje0 )) ; ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0)' 1322 1322 ENDIF 1323 IF( irankpv == 3 ) THEN 1323 IF( irankpv == 3 ) THEN 1324 1324 ishape(1:3) = SHAPE(pv_r3d(Nis0:Nie0,Njs0:Nje0,:)) ; ctmp1 = 'd(Nis0:Nie0,Njs0:Nje0,:)' 1325 1325 ENDIF 1326 ENDIF 1326 ENDIF 1327 1327 DO jl = 1, irankpv 1328 1328 WRITE( ctmp2, FMT="(', ', i1,'): ', i5,' /= icnt(', i1,'):', i5)" ) jl, ishape(jl), jl, icnt(jl) … … 1333 1333 1334 1334 ! read the data 1335 !- 1335 !- 1336 1336 IF( idvar > 0 .AND. istop == nstop ) THEN ! no additional errors until this point... 1337 1337 ! … … 1340 1340 ELSE ; ix1 = 1 ; ix2 = icnt(1) ; iy1 = 1 ; iy2 = icnt(2) 1341 1341 ENDIF 1342 1342 1343 1343 CALL iom_nf90_get( kiomid, idvar, inbdim, istart, icnt, ix1, ix2, iy1, iy2, pv_r1d, pv_r2d, pv_r3d ) 1344 1344 … … 1394 1394 CALL iom_swap(cxios_context) 1395 1395 #else 1396 istop = istop + 1 1396 istop = istop + 1 1397 1397 clinfo = 'Can not use XIOS in iom_get_123d, file: '//trim(clname)//', var:'//trim(cdvar) 1398 1398 #endif … … 1407 1407 zofs = iom_file(kiomid)%ofs(idvar) ! offset 1408 1408 IF( PRESENT(pv_r1d) ) THEN 1409 IF( zscf /= 1._wp ) pv_r1d(:) = pv_r1d(:) * zscf 1409 IF( zscf /= 1._wp ) pv_r1d(:) = pv_r1d(:) * zscf 1410 1410 IF( zofs /= 0._wp ) pv_r1d(:) = pv_r1d(:) + zofs 1411 1411 ELSEIF( PRESENT(pv_r2d) ) THEN … … 1421 1421 SUBROUTINE iom_get_var( cdname, z2d) 1422 1422 CHARACTER(LEN=*), INTENT(in ) :: cdname 1423 REAL(wp), DIMENSION(jpi,jpj) :: z2d 1423 REAL(wp), DIMENSION(jpi,jpj) :: z2d 1424 1424 #if defined key_iomput 1425 1425 IF( xios_field_is_active( cdname, at_current_timestep_arg = .TRUE. ) ) THEN … … 1433 1433 1434 1434 1435 FUNCTION iom_getszuld ( kiomid ) 1435 FUNCTION iom_getszuld ( kiomid ) 1436 1436 !!----------------------------------------------------------------------- 1437 1437 !! *** FUNCTION iom_getszuld *** … … 1449 1449 ENDIF 1450 1450 END FUNCTION iom_getszuld 1451 1451 1452 1452 1453 1453 !!---------------------------------------------------------------------- … … 1513 1513 ENDIF 1514 1514 END SUBROUTINE iom_g1d_ratt 1515 1515 1516 1516 SUBROUTINE iom_g0d_catt( kiomid, cdatt, cdatt0d, cdvar ) 1517 1517 INTEGER , INTENT(in ) :: kiomid ! Identifier of the file … … 1572 1572 ENDIF 1573 1573 END SUBROUTINE iom_p1d_ratt 1574 1574 1575 1575 SUBROUTINE iom_p0d_catt( kiomid, cdatt, cdatt0d, cdvar ) 1576 1576 INTEGER , INTENT(in ) :: kiomid ! Identifier of the file … … 1591 1591 INTEGER , INTENT(in) :: kt ! ocean time-step 1592 1592 INTEGER , INTENT(in) :: kwrite ! writing time-step 1593 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1593 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1594 1594 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1595 1595 REAL(sp) , INTENT(in) :: pvar ! written field … … 1614 1614 IF(lwp) write(numout,*) 'RESTART: define (XIOS 0D) ',trim(cdvar) 1615 1615 CALL iom_swap(context) 1616 CALL iom_set_rstw_active( trim(cdvar), rs0 = pvar ) 1616 CALL iom_set_rstw_active( trim(cdvar), rs0 = pvar ) 1617 1617 CALL iom_swap(cxios_context) 1618 1618 ENDIF … … 1631 1631 INTEGER , INTENT(in) :: kt ! ocean time-step 1632 1632 INTEGER , INTENT(in) :: kwrite ! writing time-step 1633 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1633 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1634 1634 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1635 1635 REAL(dp) , INTENT(in) :: pvar ! written field … … 1654 1654 IF(lwp) write(numout,*) 'RESTART: define (XIOS 0D) ',trim(cdvar) 1655 1655 CALL iom_swap(context) 1656 CALL iom_set_rstw_active( trim(cdvar), rd0 = pvar ) 1656 CALL iom_set_rstw_active( trim(cdvar), rd0 = pvar ) 1657 1657 CALL iom_swap(cxios_context) 1658 1658 ENDIF … … 1672 1672 INTEGER , INTENT(in) :: kt ! ocean time-step 1673 1673 INTEGER , INTENT(in) :: kwrite ! writing time-step 1674 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1674 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1675 1675 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1676 1676 REAL(sp) , INTENT(in), DIMENSION( :) :: pvar ! written field … … 1712 1712 INTEGER , INTENT(in) :: kt ! ocean time-step 1713 1713 INTEGER , INTENT(in) :: kwrite ! writing time-step 1714 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1714 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1715 1715 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1716 1716 REAL(dp) , INTENT(in), DIMENSION( :) :: pvar ! written field … … 1753 1753 INTEGER , INTENT(in) :: kt ! ocean time-step 1754 1754 INTEGER , INTENT(in) :: kwrite ! writing time-step 1755 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1755 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1756 1756 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1757 1757 REAL(sp) , INTENT(in), DIMENSION(:, : ) :: pvar ! written field … … 1793 1793 INTEGER , INTENT(in) :: kt ! ocean time-step 1794 1794 INTEGER , INTENT(in) :: kwrite ! writing time-step 1795 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1795 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1796 1796 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1797 1797 REAL(dp) , INTENT(in), DIMENSION(:, : ) :: pvar ! written field … … 1834 1834 INTEGER , INTENT(in) :: kt ! ocean time-step 1835 1835 INTEGER , INTENT(in) :: kwrite ! writing time-step 1836 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1836 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1837 1837 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1838 1838 REAL(sp) , INTENT(in), DIMENSION(:,:,:) :: pvar ! written field … … 1874 1874 INTEGER , INTENT(in) :: kt ! ocean time-step 1875 1875 INTEGER , INTENT(in) :: kwrite ! writing time-step 1876 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1876 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 1877 1877 CHARACTER(len=*), INTENT(in) :: cdvar ! time axis name 1878 1878 REAL(dp) , INTENT(in), DIMENSION(:,:,:) :: pvar ! written field … … 1954 1954 ! 1955 1955 ENDIF 1956 1956 1957 1957 END SUBROUTINE iom_delay_rst 1958 1959 1958 1959 1960 1960 1961 1961 !!---------------------------------------------------------------------- … … 1969 1969 !!clem zz(:,:)=pfield0d 1970 1970 !!clem CALL xios_send_field(cdname, zz) 1971 CALL xios_send_field(cdname, (/pfield0d/)) 1971 CALL xios_send_field(cdname, (/pfield0d/)) 1972 1972 #else 1973 1973 IF( .FALSE. ) WRITE(numout,*) cdname, pfield0d ! useless test to avoid compilation warnings … … 1982 1982 !!clem zz(:,:)=pfield0d 1983 1983 !!clem CALL xios_send_field(cdname, zz) 1984 CALL xios_send_field(cdname, (/pfield0d/)) 1984 CALL xios_send_field(cdname, (/pfield0d/)) 1985 1985 #else 1986 1986 IF( .FALSE. ) WRITE(numout,*) cdname, pfield0d ! useless test to avoid compilation warnings … … 2126 2126 TYPE(xios_gridgroup) :: gridgroup_hdl 2127 2127 TYPE(xios_grid) :: grid_hdl 2128 TYPE(xios_domain) :: domain_hdl 2129 TYPE(xios_axis) :: axis_hdl 2128 TYPE(xios_domain) :: domain_hdl 2129 TYPE(xios_axis) :: axis_hdl 2130 2130 CHARACTER(LEN=64) :: cldomrefid ! domain_ref name 2131 2131 CHARACTER(len=1) :: cl1 ! last character of this name … … 2147 2147 CALL xios_add_child(grid_hdl, axis_hdl, 'depth'//cl1) ! add its axis 2148 2148 ENDIF 2149 ! 2149 ! 2150 2150 END SUBROUTINE iom_set_zoom_domain_attr 2151 2151 … … 2240 2240 !!---------------------------------------------------------------------- 2241 2241 !!---------------------------------------------------------------------- 2242 INTEGER , INTENT(in) :: kt 2242 INTEGER , INTENT(in) :: kt 2243 2243 CHARACTER(LEN=*), INTENT(in) :: cdname 2244 2244 !!---------------------------------------------------------------------- … … 2255 2255 !!---------------------------------------------------------------------- 2256 2256 clname = cdname 2257 IF( TRIM(Agrif_CFixed()) .NE. '0' ) clname = TRIM(Agrif_CFixed())//"_"//clname 2257 IF( TRIM(Agrif_CFixed()) .NE. '0' ) clname = TRIM(Agrif_CFixed())//"_"//clname 2258 2258 IF( xios_is_valid_context(clname) ) THEN 2259 2259 CALL iom_swap( cdname ) ! swap to cdname context … … 2281 2281 CALL iom_set_domain_attr("grid_"//cdgrd, ni_glo=Ni0glo,nj_glo=Nj0glo,ibegin=mig0(Nis0)-1,jbegin=mjg0(Njs0)-1,ni=Ni_0,nj=Nj_0) 2282 2282 CALL iom_set_domain_attr("grid_"//cdgrd, data_dim=2, data_ibegin = -nn_hls, data_ni=jpi, data_jbegin = -nn_hls, data_nj=jpj) 2283 !don't define lon and lat for restart reading context. 2283 !don't define lon and lat for restart reading context. 2284 2284 IF ( .NOT.ldrxios ) & 2285 2285 CALL iom_set_domain_attr("grid_"//cdgrd, lonvalue = real(RESHAPE(plon(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp), & 2286 & latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp )) 2286 & latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp )) 2287 2287 ! 2288 2288 IF ( ln_mskland .AND. (.NOT.ldxios) ) THEN … … 2384 2384 CALL iom_set_domain_attr("gznl", data_dim=2, data_ibegin = -nn_hls, data_ni = jpi, data_jbegin = -nn_hls, data_nj = jpj) 2385 2385 CALL iom_set_domain_attr("gznl", lonvalue = real(zlon, dp), & 2386 & latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp)) 2386 & latvalue = real(RESHAPE(plat(Nis0:Nie0, Njs0:Nje0),(/ Ni_0*Nj_0 /)),dp)) 2387 2387 CALL iom_set_zoom_domain_attr("ptr", ibegin=ix-1, jbegin=0, ni=1, nj=Nj0glo) 2388 2388 ! … … 2433 2433 TYPE(xios_duration) :: f_op, f_of 2434 2434 !!---------------------------------------------------------------------- 2435 ! 2435 ! 2436 2436 ! frequency of the call of iom_put (attribut: freq_op) 2437 2437 f_op%timestep = 1 ; f_of%timestep = 0 ; CALL iom_set_field_attr('field_definition', freq_op=f_op, freq_offset=f_of) … … 2444 2444 ! output file names (attribut: name) 2445 2445 DO ji = 1, 9 2446 WRITE(cl1,'(i1)') ji 2446 WRITE(cl1,'(i1)') ji 2447 2447 CALL iom_update_file_name('file'//cl1) 2448 2448 END DO 2449 2449 DO ji = 1, 99 2450 WRITE(cl2,'(i2.2)') ji 2450 WRITE(cl2,'(i2.2)') ji 2451 2451 CALL iom_update_file_name('file'//cl2) 2452 2452 END DO 2453 2453 DO ji = 1, 999 2454 WRITE(cl3,'(i3.3)') ji 2454 WRITE(cl3,'(i3.3)') ji 2455 2455 CALL iom_update_file_name('file'//cl3) 2456 2456 END DO 2457 2457 2458 2458 ! Zooms... 2459 clgrd = (/ 'T', 'U', 'W' /) 2459 clgrd = (/ 'T', 'U', 'W' /) 2460 2460 DO jg = 1, SIZE(clgrd) ! grid type 2461 2461 cl1 = clgrd(jg) … … 2522 2522 IF( zlon == -10. .AND. zlat == 4. ) THEN ; zlon = 0. ; zlat = 0. ; ENDIF 2523 2523 CALL dom_ngb( zlon, zlat, ix, iy, cl1 ) 2524 IF( zlon >= 0. ) THEN 2524 IF( zlon >= 0. ) THEN 2525 2525 IF( zlon == REAL(NINT(zlon), wp) ) THEN ; WRITE(clon, '(i3, a)') NINT( zlon), 'e' 2526 2526 ELSE ; WRITE(clon, '(f5.1,a)') zlon , 'e' 2527 2527 ENDIF 2528 ELSE 2528 ELSE 2529 2529 IF( zlon == REAL(NINT(zlon), wp) ) THEN ; WRITE(clon, '(i3, a)') NINT(-zlon), 'w' 2530 2530 ELSE ; WRITE(clon, '(f5.1,a)') -zlon , 'w' 2531 2531 ENDIF 2532 2532 ENDIF 2533 IF( zlat >= 0. ) THEN 2533 IF( zlat >= 0. ) THEN 2534 2534 IF( zlat == REAL(NINT(zlat), wp) ) THEN ; WRITE(clat, '(i2, a)') NINT( zlat), 'n' 2535 2535 ELSE ; WRITE(clat, '(f4.1,a)') zlat , 'n' 2536 2536 ENDIF 2537 ELSE 2537 ELSE 2538 2538 IF( zlat == REAL(NINT(zlat), wp) ) THEN ; WRITE(clat, '(i2, a)') NINT(-zlat), 's' 2539 2539 ELSE ; WRITE(clat, '(f4.1,a)') -zlat , 's' … … 2549 2549 END DO 2550 2550 END DO 2551 2551 2552 2552 END SUBROUTINE set_mooring 2553 2553 2554 2554 2555 2555 SUBROUTINE iom_update_file_name( cdid ) 2556 2556 !!---------------------------------------------------------------------- 2557 2557 !! *** ROUTINE iom_update_file_name *** 2558 2558 !! 2559 !! ** Purpose : 2559 !! ** Purpose : 2560 2560 !! 2561 2561 !!---------------------------------------------------------------------- … … 2571 2571 REAL(wp) :: zsec 2572 2572 LOGICAL :: llexist 2573 TYPE(xios_duration) :: output_freq 2573 TYPE(xios_duration) :: output_freq 2574 2574 !!---------------------------------------------------------------------- 2575 2575 ! … … 2580 2580 IF( jn == 2 ) CALL iom_get_file_attr( cdid, name_suffix = clname ) 2581 2581 ! 2582 IF ( TRIM(clname) /= '' ) THEN 2582 IF ( TRIM(clname) /= '' ) THEN 2583 2583 ! 2584 2584 idx = INDEX(clname,'@expname@') + INDEX(clname,'@EXPNAME@') 2585 DO WHILE ( idx /= 0 ) 2585 DO WHILE ( idx /= 0 ) 2586 2586 clname = clname(1:idx-1)//TRIM(cexper)//clname(idx+9:LEN_TRIM(clname)) 2587 2587 idx = INDEX(clname,'@expname@') + INDEX(clname,'@EXPNAME@') … … 2589 2589 ! 2590 2590 idx = INDEX(clname,'@freq@') + INDEX(clname,'@FREQ@') 2591 DO WHILE ( idx /= 0 ) 2591 DO WHILE ( idx /= 0 ) 2592 2592 IF ( output_freq%timestep /= 0) THEN 2593 WRITE(clfreq,'(I18,A2)')INT(output_freq%timestep),'ts' 2593 WRITE(clfreq,'(I18,A2)')INT(output_freq%timestep),'ts' 2594 2594 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2595 2595 ELSE IF ( output_freq%second /= 0 ) THEN 2596 WRITE(clfreq,'(I19,A1)')INT(output_freq%second),'s' 2596 WRITE(clfreq,'(I19,A1)')INT(output_freq%second),'s' 2597 2597 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2598 2598 ELSE IF ( output_freq%minute /= 0 ) THEN 2599 WRITE(clfreq,'(I18,A2)')INT(output_freq%minute),'mi' 2599 WRITE(clfreq,'(I18,A2)')INT(output_freq%minute),'mi' 2600 2600 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2601 2601 ELSE IF ( output_freq%hour /= 0 ) THEN 2602 WRITE(clfreq,'(I19,A1)')INT(output_freq%hour),'h' 2602 WRITE(clfreq,'(I19,A1)')INT(output_freq%hour),'h' 2603 2603 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2604 2604 ELSE IF ( output_freq%day /= 0 ) THEN 2605 WRITE(clfreq,'(I19,A1)')INT(output_freq%day),'d' 2605 WRITE(clfreq,'(I19,A1)')INT(output_freq%day),'d' 2606 2606 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2607 ELSE IF ( output_freq%month /= 0 ) THEN 2608 WRITE(clfreq,'(I19,A1)')INT(output_freq%month),'m' 2607 ELSE IF ( output_freq%month /= 0 ) THEN 2608 WRITE(clfreq,'(I19,A1)')INT(output_freq%month),'m' 2609 2609 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2610 ELSE IF ( output_freq%year /= 0 ) THEN 2611 WRITE(clfreq,'(I19,A1)')INT(output_freq%year),'y' 2610 ELSE IF ( output_freq%year /= 0 ) THEN 2611 WRITE(clfreq,'(I19,A1)')INT(output_freq%year),'y' 2612 2612 itrlen = LEN_TRIM(ADJUSTL(clfreq)) 2613 2613 ELSE … … 2620 2620 ! 2621 2621 idx = INDEX(clname,'@startdate@') + INDEX(clname,'@STARTDATE@') 2622 DO WHILE ( idx /= 0 ) 2622 DO WHILE ( idx /= 0 ) 2623 2623 cldate = iom_sdate( fjulday - rn_Dt / rday ) 2624 2624 clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+11:LEN_TRIM(clname)) … … 2627 2627 ! 2628 2628 idx = INDEX(clname,'@startdatefull@') + INDEX(clname,'@STARTDATEFULL@') 2629 DO WHILE ( idx /= 0 ) 2629 DO WHILE ( idx /= 0 ) 2630 2630 cldate = iom_sdate( fjulday - rn_Dt / rday, ldfull = .TRUE. ) 2631 2631 clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+15:LEN_TRIM(clname)) … … 2634 2634 ! 2635 2635 idx = INDEX(clname,'@enddate@') + INDEX(clname,'@ENDDATE@') 2636 DO WHILE ( idx /= 0 ) 2636 DO WHILE ( idx /= 0 ) 2637 2637 cldate = iom_sdate( fjulday + rn_Dt / rday * REAL( nitend - nit000, wp ), ld24 = .TRUE. ) 2638 2638 clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+9:LEN_TRIM(clname)) … … 2641 2641 ! 2642 2642 idx = INDEX(clname,'@enddatefull@') + INDEX(clname,'@ENDDATEFULL@') 2643 DO WHILE ( idx /= 0 ) 2643 DO WHILE ( idx /= 0 ) 2644 2644 cldate = iom_sdate( fjulday + rn_Dt / rday * REAL( nitend - nit000, wp ), ld24 = .TRUE., ldfull = .TRUE. ) 2645 2645 clname = clname(1:idx-1)//TRIM(cldate)//clname(idx+13:LEN_TRIM(clname)) … … 2669 2669 ! 2670 2670 CHARACTER(LEN=20) :: iom_sdate 2671 CHARACTER(LEN=50) :: clfmt ! format used to write the date 2671 CHARACTER(LEN=50) :: clfmt ! format used to write the date 2672 2672 INTEGER :: iyear, imonth, iday, ihour, iminute, isec 2673 2673 REAL(wp) :: zsec … … 2691 2691 ENDIF 2692 2692 ! 2693 IF( iyear < 10000 ) THEN ; clfmt = "i4.4,2i2.2" ! format used to write the date 2693 IF( iyear < 10000 ) THEN ; clfmt = "i4.4,2i2.2" ! format used to write the date 2694 2694 ELSE ; WRITE(clfmt, "('i',i1,',2i2.2')") INT(LOG10(REAL(iyear,wp))) + 1 2695 2695 ENDIF 2696 2696 ! 2697 !$AGRIF_DO_NOT_TREAT 2697 !$AGRIF_DO_NOT_TREAT 2698 2698 ! needed in the conv 2699 IF( llfull ) THEN 2699 IF( llfull ) THEN 2700 2700 clfmt = TRIM(clfmt)//",'_',i2.2,':',i2.2,':',i2.2" 2701 2701 ihour = isec / 3600 … … 2707 2707 WRITE(iom_sdate, '('//TRIM(clfmt)//')') iyear, imonth, iday ! date of the end of run 2708 2708 ENDIF 2709 !$AGRIF_END_DO_NOT_TREAT 2709 !$AGRIF_END_DO_NOT_TREAT 2710 2710 ! 2711 2711 END FUNCTION iom_sdate … … 2716 2716 !!---------------------------------------------------------------------- 2717 2717 SUBROUTINE iom_setkt( kt, cdname ) 2718 INTEGER , INTENT(in):: kt 2718 INTEGER , INTENT(in):: kt 2719 2719 CHARACTER(LEN=*), INTENT(in) :: cdname 2720 2720 IF( .FALSE. ) WRITE(numout,*) kt, cdname ! useless test to avoid compilation warnings … … 2744 2744 SUBROUTINE iom_miss_val( cdname, pmiss_val ) 2745 2745 CHARACTER(LEN=*), INTENT(in ) :: cdname 2746 REAL(wp) , INTENT(out) :: pmiss_val 2747 REAL(dp) :: ztmp_pmiss_val 2746 REAL(wp) , INTENT(out) :: pmiss_val 2747 REAL(dp) :: ztmp_pmiss_val 2748 2748 #if defined key_iomput 2749 2749 ! get missing value … … 2755 2755 #endif 2756 2756 END SUBROUTINE iom_miss_val 2757 2757 2758 2758 !!====================================================================== 2759 2759 END MODULE iom -
NEMO/trunk/src/OCE/IOM/iom_def.F90
r13970 r14072 17 17 INTEGER, PARAMETER, PUBLIC :: jpdom_local = 2 !: (Nis0: Nie0 ,Njs0: Nje0 ) 18 18 INTEGER, PARAMETER, PUBLIC :: jpdom_unknown = 3 !: No dimension checking 19 INTEGER, PARAMETER, PUBLIC :: jpdom_auto = 4 !: 19 INTEGER, PARAMETER, PUBLIC :: jpdom_auto = 4 !: 20 20 INTEGER, PARAMETER, PUBLIC :: jpdom_auto_xy = 5 !: Automatically set horizontal dimensions only 21 21 … … 33 33 !$AGRIF_DO_NOT_TREAT 34 34 INTEGER, PUBLIC :: iom_open_init = 0 !: used to initialize iom_file(:)%nfid to 0 35 !XIOS write restart 35 !XIOS write restart 36 36 LOGICAL, PUBLIC :: lwxios = .FALSE. !: write single file restart using XIOS 37 37 INTEGER, PUBLIC :: nxioso = 0 !: type of restart file when writing using XIOS 1 - single, 2 - multiple 38 !XIOS read restart 38 !XIOS read restart 39 39 LOGICAL, PUBLIC :: lrxios = .FALSE. !: read single file restart using XIOS main switch 40 40 LOGICAL, PUBLIC :: lxios_sini = .FALSE. ! is restart in a single file … … 50 50 INTEGER :: iduld !: id of the unlimited dimension 51 51 INTEGER :: lenuld !: length of the unlimited dimension (number of records in file) 52 INTEGER :: irec !: writing record position 52 INTEGER :: irec !: writing record position 53 53 CHARACTER(LEN=32) :: uldname !: name of the unlimited dimension 54 54 CHARACTER(LEN=32), DIMENSION(jpmax_vars) :: cn_var !: names of the variables … … 56 56 INTEGER, DIMENSION(jpmax_vars) :: ndims !: number of dimensions of the variables 57 57 LOGICAL, DIMENSION(jpmax_vars) :: luld !: variable using the unlimited dimension 58 INTEGER, DIMENSION(jpmax_dims,jpmax_vars) :: dimsz !: size of variables dimensions 58 INTEGER, DIMENSION(jpmax_dims,jpmax_vars) :: dimsz !: size of variables dimensions 59 59 REAL(kind=wp), DIMENSION(jpmax_vars) :: scf !: scale_factor of the variables 60 60 REAL(kind=wp), DIMENSION(jpmax_vars) :: ofs !: add_offset of the variables -
NEMO/trunk/src/OCE/IOM/iom_nf90.F90
r13970 r14072 34 34 35 35 INTERFACE iom_nf90_get 36 MODULE PROCEDURE iom_nf90_g0d_sp 36 MODULE PROCEDURE iom_nf90_g0d_sp 37 37 MODULE PROCEDURE iom_nf90_g0d_dp, iom_nf90_g123d_dp 38 38 END INTERFACE … … 57 57 INTEGER , INTENT( out) :: kiomid ! nf90 identifier of the opened file 58 58 LOGICAL , INTENT(in ) :: ldwrt ! read or write the file? 59 LOGICAL , INTENT(in ) :: ldok ! check the existence 59 LOGICAL , INTENT(in ) :: ldok ! check the existence 60 60 INTEGER , INTENT(in ), OPTIONAL :: kdlev ! size of the ice/abl third dimension 61 61 CHARACTER(len=3) , INTENT(in ), OPTIONAL :: cdcomp ! name of component calling iom_nf90_open … … 85 85 clcomp = cdcomp ! use input value 86 86 ELSE 87 clcomp = 'OCE' ! by default 87 clcomp = 'OCE' ! by default 88 88 ENDIF 89 89 ! … … 120 120 121 121 IF( llclobber ) THEN ; imode = IOR( NF90_64BIT_OFFSET, NF90_CLOBBER ) 122 ELSE ; imode = IOR( NF90_64BIT_OFFSET, NF90_NOCLOBBER ) 122 ELSE ; imode = IOR( NF90_64BIT_OFFSET, NF90_NOCLOBBER ) 123 123 ENDIF 124 124 IF( snc4set%luse ) THEN … … 172 172 iom_file(kiomid)%nfid = if90id 173 173 iom_file(kiomid)%nvars = 0 174 iom_file(kiomid)%irec = -1 ! useless for NetCDF files, used to know if the file is in define mode 174 iom_file(kiomid)%irec = -1 ! useless for NetCDF files, used to know if the file is in define mode 175 175 CALL iom_nf90_check(NF90_Inquire(if90id, unlimitedDimId = iom_file(kiomid)%iduld), clinfo) 176 176 IF( iom_file(kiomid)%iduld .GE. 0 ) THEN 177 CALL iom_nf90_check(NF90_Inquire_Dimension(if90id, iom_file(kiomid)%iduld, & 177 CALL iom_nf90_check(NF90_Inquire_Dimension(if90id, iom_file(kiomid)%iduld, & 178 178 & name = iom_file(kiomid)%uldname, & 179 179 & len = iom_file(kiomid)%lenuld ), clinfo ) … … 201 201 202 202 203 FUNCTION iom_nf90_varid ( kiomid, cdvar, kiv, kdimsz, kndims, lduld ) 203 FUNCTION iom_nf90_varid ( kiomid, cdvar, kiv, kdimsz, kndims, lduld ) 204 204 !!----------------------------------------------------------------------- 205 205 !! *** FUNCTION iom_varid *** … … 209 209 INTEGER , INTENT(in ) :: kiomid ! file Identifier 210 210 CHARACTER(len=*) , INTENT(in ) :: cdvar ! name of the variable 211 INTEGER , INTENT(in ) :: kiv ! 211 INTEGER , INTENT(in ) :: kiv ! 212 212 INTEGER, DIMENSION(:), INTENT( out), OPTIONAL :: kdimsz ! size of each dimension 213 213 INTEGER , INTENT( out), OPTIONAL :: kndims ! number of dimensions … … 240 240 iom_file(kiomid)%dimsz(:,kiv) = 0 ! reset dimsz in case previously used 241 241 DO ji = 1, i_nvd ! dimensions size 242 CALL iom_nf90_check(NF90_Inquire_Dimension(if90id, idimid(ji), len = iom_file(kiomid)%dimsz(ji,kiv)), clinfo) 243 IF( idimid(ji) == iom_file(kiomid)%iduld ) iom_file(kiomid)%luld(kiv) = .TRUE. ! unlimited dimension? 242 CALL iom_nf90_check(NF90_Inquire_Dimension(if90id, idimid(ji), len = iom_file(kiomid)%dimsz(ji,kiv)), clinfo) 243 IF( idimid(ji) == iom_file(kiomid)%iduld ) iom_file(kiomid)%luld(kiv) = .TRUE. ! unlimited dimension? 244 244 END DO 245 245 !---------- Deal with scale_factor and add_offset … … 257 257 END IF 258 258 ! return the simension size 259 IF( PRESENT(kdimsz) ) THEN 259 IF( PRESENT(kdimsz) ) THEN 260 260 IF( i_nvd <= SIZE(kdimsz) ) THEN 261 261 kdimsz(1:i_nvd) = iom_file(kiomid)%dimsz(1:i_nvd,kiv) … … 267 267 IF( PRESENT(kndims) ) kndims = iom_file(kiomid)%ndims(kiv) 268 268 IF( PRESENT( lduld) ) lduld = iom_file(kiomid)%luld(kiv) 269 ELSE 269 ELSE 270 270 iom_nf90_varid = -1 ! variable not found, return error code: -1 271 271 ENDIF … … 323 323 INTEGER , INTENT(in ) :: kvid ! Name of the variable 324 324 INTEGER , INTENT(in ) :: knbdim ! number of dimensions of the variable 325 INTEGER , DIMENSION(:) , INTENT(in ) :: kstart ! start position of the reading in each axis 325 INTEGER , DIMENSION(:) , INTENT(in ) :: kstart ! start position of the reading in each axis 326 326 INTEGER , DIMENSION(:) , INTENT(in ) :: kcount ! number of points to be read in each axis 327 327 INTEGER , INTENT(in ) :: kx1, kx2, ky1, ky2 ! subdomain indexes … … 529 529 !! *** SUBROUTINE iom_nf90_rstput *** 530 530 !! 531 !! ** Purpose : read the time axis cdvar in the file 531 !! ** Purpose : read the time axis cdvar in the file 532 532 !!-------------------------------------------------------------------- 533 533 INTEGER , INTENT(in) :: kt ! ocean time-step 534 534 INTEGER , INTENT(in) :: kwrite ! writing time-step 535 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 535 INTEGER , INTENT(in) :: kiomid ! Identifier of the file 536 536 CHARACTER(len=*) , INTENT(in) :: cdvar ! variable name 537 537 INTEGER , INTENT(in) :: kvid ! variable id … … 544 544 INTEGER :: idims ! number of dimension 545 545 INTEGER :: idvar ! variable id 546 INTEGER :: jd ! dimension loop counter 547 INTEGER :: ix1, ix2, iy1, iy2 ! subdomain indexes 548 INTEGER, DIMENSION(4) :: idimsz ! dimensions size 546 INTEGER :: jd ! dimension loop counter 547 INTEGER :: ix1, ix2, iy1, iy2 ! subdomain indexes 548 INTEGER, DIMENSION(4) :: idimsz ! dimensions size 549 549 INTEGER, DIMENSION(4) :: idimid ! dimensions id 550 550 CHARACTER(LEN=256) :: clinfo ! info character … … 678 678 ELSEIF( idimsz(1) == jpi .AND. idimsz(2) == jpj ) THEN 679 679 ix1 = 1 ; ix2 = jpi ; iy1 = 1 ; iy2 = jpj 680 ELSE 680 ELSE 681 681 CALL ctl_stop( 'iom_nf90_rp0123d: should have been an impossible case...' ) 682 682 ENDIF … … 689 689 CALL iom_nf90_check( NF90_PUT_VAR( if90id, 2, gphit(ix1:ix2, iy1:iy2) ), clinfo ) 690 690 SELECT CASE (iom_file(kiomid)%comp) 691 CASE ('OCE') 691 CASE ('OCE') 692 692 CALL iom_nf90_check( NF90_PUT_VAR( if90id, 3, gdept_1d ), clinfo ) 693 693 CASE ('ABL') … … 697 697 END SELECT 698 698 ! "wrong" value: to be improved but not really useful... 699 CALL iom_nf90_check( NF90_PUT_VAR( if90id, 4, kt ), clinfo ) 699 CALL iom_nf90_check( NF90_PUT_VAR( if90id, 4, kt ), clinfo ) 700 700 ! update the size of the variable corresponding to the unlimited dimension 701 701 iom_file(kiomid)%dimsz(1, 4) = 1 ! so we don't enter this IF case any more... … … 720 720 IF(lwp) WRITE(numout,*) TRIM(clinfo)//' written ok' 721 721 ENDIF 722 ! 722 ! 723 723 END SUBROUTINE iom_nf90_rp0123d_dp 724 724 -
NEMO/trunk/src/OCE/IOM/prtctl.F90
r13982 r14072 15 15 IMPLICIT NONE 16 16 PRIVATE 17 17 18 18 INTEGER , DIMENSION( :), ALLOCATABLE :: numprt_oce, numprt_top 19 19 INTEGER , DIMENSION( :), ALLOCATABLE :: nall_ictls, nall_ictle ! first, last indoor index for each i-domain … … 22 22 REAL(wp), DIMENSION( :), ALLOCATABLE :: u_ctl , v_ctl ! previous velocity trend values 23 23 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: tra_ctl ! previous top trend values 24 ! 24 ! 25 25 PUBLIC prt_ctl ! called by all subroutines 26 26 PUBLIC prt_ctl_info ! called by all subroutines … … 31 31 !!---------------------------------------------------------------------- 32 32 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 33 !! $Id$ 33 !! $Id$ 34 34 !! Software governed by the CeCILL license (see ./LICENSE) 35 35 !!---------------------------------------------------------------------- … … 70 70 !! *** ROUTINE prt_ctl *** 71 71 !! 72 !! ** Purpose : - print sum control of 2D or 3D arrays over the same area 72 !! ** Purpose : - print sum control of 2D or 3D arrays over the same area 73 73 !! in mono and mpp case. This way can be usefull when 74 !! debugging a new parametrization in mono or mpp. 74 !! debugging a new parametrization in mono or mpp. 75 75 !! 76 76 !! ** Method : 2 possibilities exist when setting the sn_cfctl%prtctl parameter to 77 77 !! .true. in the ocean namelist: 78 !! - to debug a MPI run .vs. a mono-processor one; 78 !! - to debug a MPI run .vs. a mono-processor one; 79 79 !! the control print will be done over each sub-domain. 80 !! The nictl[se] and njctl[se] parameters in the namelist must 80 !! The nictl[se] and njctl[se] parameters in the namelist must 81 81 !! be set to zero and [ij]splt to the corresponding splitted 82 82 !! domain in MPI along respectively i-, j- directions. 83 !! - to debug a mono-processor run over the whole domain/a specific area; 83 !! - to debug a mono-processor run over the whole domain/a specific area; 84 84 !! in the first case the nictl[se] and njctl[se] parameters must be set 85 85 !! to zero else to the indices of the area to be controled. In both cases … … 87 87 !! - All arguments of the above calling sequence are optional so their 88 88 !! name must be explicitly typed if used. For instance if the 3D 89 !! array tn(:,:,:) must be passed through the prt_ctl subroutine, 89 !! array tn(:,:,:) must be passed through the prt_ctl subroutine, 90 90 !! it must look like: CALL prt_ctl(tab3d_1=tn). 91 91 !! … … 99 99 !! mask2 : mask (3D) to apply to the tab[23]d_2 array 100 100 !! clinfo2 : information about the tab[23]d_2 array 101 !! kdim : k- direction for 3D arrays 102 !! clinfo3 : additional information 101 !! kdim : k- direction for 3D arrays 102 !! clinfo3 : additional information 103 103 !!---------------------------------------------------------------------- 104 104 INTEGER , INTENT(in) :: ktab2d_1, ktab3d_1, ktab4d_1, ktab2d_2, ktab3d_2 … … 123 123 !!---------------------------------------------------------------------- 124 124 ! 125 ! Arrays, scalars initialization 125 ! Arrays, scalars initialization 126 126 cl1 = '' 127 127 cl2 = '' … … 310 310 WRITE(numout,*) '~~~~~~~~~~~~~' 311 311 ENDIF 312 IF( nn_ictls+nn_ictle+nn_jctls+nn_jctle == 0 ) THEN ! print control done over the default area 312 IF( nn_ictls+nn_ictle+nn_jctls+nn_jctle == 0 ) THEN ! print control done over the default area 313 313 nn_isplt = MAX(1, nn_isplt) ! number of processors following i-direction 314 314 nn_jsplt = MAX(1, nn_jsplt) ! number of processors following j-direction … … 391 391 ENDIF 392 392 393 ! Initialization 393 ! Initialization 394 394 IF( clcomp == 'oce' ) THEN 395 395 ALLOCATE( t_ctl(ijsplt), s_ctl(ijsplt), u_ctl(ijsplt), v_ctl(ijsplt), numprt_oce(ijsplt) ) … … 424 424 WRITE(inum,*) 425 425 WRITE(inum,'(19x,a20)') cl_run 426 WRITE(inum,*) 426 WRITE(inum,*) 427 427 WRITE(inum,*) 'prt_ctl : Sum control indices' 428 428 WRITE(inum,*) '~~~~~~~' -
NEMO/trunk/src/OCE/IOM/restart.F90
r14053 r14072 19 19 !! rst_read : read the ocean restart file 20 20 !!---------------------------------------------------------------------- 21 USE oce ! ocean dynamics and tracers 21 USE oce ! ocean dynamics and tracers 22 22 USE dom_oce ! ocean space and time domain 23 USE sbc_ice ! only lk_si3 23 USE sbc_ice ! only lk_si3 24 24 USE phycst ! physical constants 25 25 USE eosbn2 ! equation of state (eos bn2 routine) … … 49 49 !!--------------------------------------------------------------------- 50 50 !! *** ROUTINE rst_opn *** 51 !! 52 !! ** Purpose : + initialization (should be read in the namelist) of nitrst 51 !! 52 !! ** Purpose : + initialization (should be read in the namelist) of nitrst 53 53 !! + open the restart when we are one time step before nitrst 54 54 !! - restart header is defined when kt = nitrst-1 … … 66 66 ! 67 67 IF( kt == nit000 ) THEN ! default definitions 68 lrst_oce = .FALSE. 68 lrst_oce = .FALSE. 69 69 IF( ln_rst_list ) THEN 70 70 nrst_lst = 1 … … 74 74 ENDIF 75 75 ENDIF 76 76 77 77 IF( .NOT. ln_rst_list .AND. nn_stock == -1 ) RETURN ! we will never do any restart 78 78 79 79 ! frequency-based restart dumping (nn_stock) 80 IF( .NOT. ln_rst_list .AND. MOD( kt - 1, nn_stock ) == 0 ) THEN 80 IF( .NOT. ln_rst_list .AND. MOD( kt - 1, nn_stock ) == 0 ) THEN 81 81 ! we use kt - 1 and not kt - nit000 to keep the same periodicity from the beginning of the experiment 82 82 nitrst = kt + nn_stock - 1 ! define the next value of nitrst for restart writing … … 87 87 ! except if we write ocean restart files every time step or if an ocean restart file was writen at nitend - 1 88 88 IF( kt == nitrst - 1 .OR. nn_stock == 1 .OR. ( kt == nitend .AND. .NOT. lrst_oce ) ) THEN 89 IF( nitrst <= nitend .AND. nitrst > 0 ) THEN 89 IF( nitrst <= nitend .AND. nitrst > 0 ) THEN 90 90 ! beware of the format used to write kt (default is i8.8, that should be large enough...) 91 91 IF( nitrst > 999999999 ) THEN ; WRITE(clkt, * ) nitrst … … 115 115 clpname = clname 116 116 ELSE 117 clpname = TRIM(Agrif_CFixed())//"_"//clname 117 clpname = TRIM(Agrif_CFixed())//"_"//clname 118 118 ENDIF 119 119 numrow = iom_xios_setid(TRIM(clpath)//TRIM(clpname)) … … 135 135 !!--------------------------------------------------------------------- 136 136 !! *** ROUTINE rstwrite *** 137 !! 137 !! 138 138 !! ** Purpose : Write restart fields in NetCDF format 139 139 !! … … 164 164 CALL iom_rstput( kt, nitrst, numrow, 'rhop' , rhop ) 165 165 ENDIF 166 167 IF (ln_diurnal) CALL iom_rstput( kt, nitrst, numrow, 'Dsst', x_dsst ) 166 167 IF (ln_diurnal) CALL iom_rstput( kt, nitrst, numrow, 'Dsst', x_dsst ) 168 168 IF( kt == nitrst ) THEN 169 169 IF(.NOT.lwxios) THEN … … 187 187 188 188 SUBROUTINE rst_read_open 189 !!---------------------------------------------------------------------- 189 !!---------------------------------------------------------------------- 190 190 !! *** ROUTINE rst_read_open *** 191 !! 191 !! 192 192 !! ** Purpose : Open read files for NetCDF restart 193 !! 193 !! 194 194 !! ** Method : Use a non-zero, positive value of numror to assess whether or not 195 195 !! the file has already been opened … … 222 222 ! clpname = cn_ocerst_in 223 223 ! ELSE 224 ! clpname = TRIM(Agrif_CFixed())//"_"//cn_ocerst_in 224 ! clpname = TRIM(Agrif_CFixed())//"_"//cn_ocerst_in 225 225 ! ENDIF 226 226 CALL iom_init( cr_ocerst_cxt, kdid = numror, ld_closedef = .TRUE. ) … … 234 234 235 235 SUBROUTINE rst_read( Kbb, Kmm ) 236 !!---------------------------------------------------------------------- 236 !!---------------------------------------------------------------------- 237 237 !! *** ROUTINE rst_read *** 238 !! 238 !! 239 239 !! ** Purpose : Read velocity and T-S fields in the restart file 240 !! 240 !! 241 241 !! ** Method : Read in restart.nc fields which are necessary for restart 242 242 !! … … 255 255 IF(.NOT.lrxios ) CALL iom_delay_rst( 'READ', 'OCE', numror ) ! read only ocean delayed global communication variables 256 256 ! 257 ! !* Diurnal DSST 258 IF( ln_diurnal ) CALL iom_get( numror, jpdom_auto, 'Dsst' , x_dsst ) 259 IF ( ln_diurnal_only ) THEN 257 ! !* Diurnal DSST 258 IF( ln_diurnal ) CALL iom_get( numror, jpdom_auto, 'Dsst' , x_dsst ) 259 IF ( ln_diurnal_only ) THEN 260 260 IF(lwp) WRITE( numout, * ) & 261 & "rst_read:- ln_diurnal_only set, setting rhop=rho0" 261 & "rst_read:- ln_diurnal_only set, setting rhop=rho0" 262 262 rhop = rho0 263 CALL iom_get( numror, jpdom_auto, 'tn' , w3d ) 263 CALL iom_get( numror, jpdom_auto, 'tn' , w3d ) 264 264 ts(:,:,1,jp_tem,Kmm) = w3d(:,:,1) 265 RETURN 266 ENDIF 265 RETURN 266 ENDIF 267 267 ! 268 268 ! !* Read Kmm fields … … 289 289 CALL iom_get( numror, jpdom_auto, 'rhop' , rhop ) ! now potential density 290 290 ELSE 291 CALL eos( ts(:,:,:,:,Kmm), rhd, rhop, gdept(:,:,:,Kmm) ) 291 CALL eos( ts(:,:,:,:,Kmm), rhd, rhop, gdept(:,:,:,Kmm) ) 292 292 ENDIF 293 293 ! -
NEMO/trunk/src/OCE/ISF/isfcav.F90
r13970 r14072 79 79 CALL isf_tbl(Kmm, ts(:,:,:,jp_tem,Kmm), zttbl(:,:),'T', misfkt_cav, rhisf_tbl_cav, misfkb_cav, rfrac_tbl_cav ) 80 80 CALL isf_tbl(Kmm, ts(:,:,:,jp_sal,Kmm), zstbl(:,:),'T', misfkt_cav, rhisf_tbl_cav, misfkb_cav, rfrac_tbl_cav ) 81 ! 81 ! 82 82 ! output T/S/U/V for the top boundary layer 83 83 CALL iom_put('ttbl_cav',zttbl(:,:) * mskisf_cav(:,:)) … … 97 97 & zgammat, zgammas ) 98 98 END IF 99 ! 99 ! 100 100 ! compute tfrz, latent heat and melt (2d) 101 101 CALL isfcav_mlt(kt, zgammat, zgammas, zttbl, zstbl, & -
NEMO/trunk/src/OCE/ISF/isfcpl.F90
r14053 r14072 30 30 PRIVATE 31 31 32 PUBLIC isfcpl_rst_write, isfcpl_init ! iceshelf restart read and write 33 PUBLIC isfcpl_ssh, isfcpl_tra, isfcpl_vol, isfcpl_cons ! iceshelf correction for ssh, tra, dyn and conservation 32 PUBLIC isfcpl_rst_write, isfcpl_init ! iceshelf restart read and write 33 PUBLIC isfcpl_ssh, isfcpl_tra, isfcpl_vol, isfcpl_cons ! iceshelf correction for ssh, tra, dyn and conservation 34 34 35 35 TYPE isfcons … … 57 57 !!--------------------------------------------------------------------- 58 58 !! *** ROUTINE iscpl_init *** 59 !! 60 !! ** Purpose : correct ocean state for new wet cell and horizontal divergence 59 !! 60 !! ** Purpose : correct ocean state for new wet cell and horizontal divergence 61 61 !! correction for the dynamical adjustement 62 62 !! … … 74 74 ! start on an euler time step 75 75 l_1st_euler = .TRUE. 76 ! 76 ! 77 77 ! allocation and initialisation to 0 78 78 CALL isf_alloc_cpl() … … 88 88 IF(lwp) WRITE(numout,*) ' isfcpl_init:', id 89 89 IF (id == 0) THEN 90 IF(lwp) WRITE(numout,*) ' isfcpl_init: restart variables for ice sheet coupling are missing, skip coupling for this leg ' 90 IF(lwp) WRITE(numout,*) ' isfcpl_init: restart variables for ice sheet coupling are missing, skip coupling for this leg ' 91 91 IF(lwp) WRITE(numout,*) ' ~~~~~~~~~~~' 92 92 IF(lwp) WRITE(numout,*) '' … … 119 119 #if ! defined key_qco 120 120 e3t(:,:,:,Kbb) = e3t(:,:,:,Kmm) 121 #endif 121 #endif 122 122 END SUBROUTINE isfcpl_init 123 123 124 124 125 125 SUBROUTINE isfcpl_rst_write( kt, Kmm ) 126 126 !!--------------------------------------------------------------------- 127 127 !! *** ROUTINE iscpl_rst_write *** 128 !! 128 !! 129 129 !! ** Purpose : write icesheet coupling variables in restart 130 130 !! … … 143 143 ! 144 144 zgdepw(:,:,jk) = gdepw(:,:,jk,Kmm) 145 END DO 145 END DO 146 146 ! 147 147 CALL iom_rstput( kt, nitrst, numrow, 'tmask' , tmask ) … … 154 154 END SUBROUTINE isfcpl_rst_write 155 155 156 156 157 157 SUBROUTINE isfcpl_ssh(Kbb, Kmm, Kaa) 158 !!---------------------------------------------------------------------- 158 !!---------------------------------------------------------------------- 159 159 !! *** ROUTINE iscpl_ssh *** 160 !! 160 !! 161 161 !! ** Purpose : basic guess of ssh in new wet cell 162 !! 162 !! 163 163 !! ** Method : basic extrapolation from neigbourg cells 164 164 !! … … 176 176 CALL iom_get( numror, jpdom_auto, 'ssmask' , zssmask_b ) ! need to extrapolate T/S 177 177 178 ! compute new ssh if we open a full water column 178 ! compute new ssh if we open a full water column 179 179 ! rude average of the closest neigbourgs (e1e2t not taking into account) 180 180 ! … … 229 229 END SUBROUTINE isfcpl_ssh 230 230 231 231 232 232 SUBROUTINE isfcpl_tra(Kmm) 233 !!---------------------------------------------------------------------- 233 !!---------------------------------------------------------------------- 234 234 !! *** ROUTINE iscpl_tra *** 235 !! 236 !! ** Purpose : compute new tn, sn in case of evolving geometry of ice shelves 237 !! 235 !! 236 !! ** Purpose : compute new tn, sn in case of evolving geometry of ice shelves 237 !! 238 238 !! ** Method : tn, sn : basic extrapolation from neigbourg cells 239 239 !! … … 250 250 REAL(wp):: zdz, zdzm1, zdzp1 251 251 !! 252 REAL(wp), DIMENSION(jpi,jpj) :: zdmask 252 REAL(wp), DIMENSION(jpi,jpj) :: zdmask 253 253 REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztmask0, zwmaskn 254 254 REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztmask1, zwmaskb, ztmp3d 255 255 REAL(wp), DIMENSION(jpi,jpj,jpk,jpts) :: zts0 256 256 !!---------------------------------------------------------------------- 257 ! 257 ! 258 258 CALL iom_get( numror, jpdom_auto, 'tmask' , ztmask_b ) ! need to extrapolate T/S 259 259 !CALL iom_get( numror, jpdom_auto, 'wmask' , zwmask_b ) ! need to extrapolate T/S 260 260 !CALL iom_get( numror, jpdom_auto, 'gdepw_n', zdepw_b(:,:,:) ) ! need to interpol vertical profile (vvl) 261 261 ! 262 ! 262 ! 263 263 ! compute new T/S (interpolation) if vvl only for common wet cell in before and after wmask 264 264 !PM: Is this IF needed since change to VVL by default … … 376 376 & in your domain cfg computation' ) 377 377 END_3D 378 ! 378 ! 379 379 END SUBROUTINE isfcpl_tra 380 380 381 381 382 382 SUBROUTINE isfcpl_vol(Kmm) 383 !!---------------------------------------------------------------------- 383 !!---------------------------------------------------------------------- 384 384 !! *** ROUTINE iscpl_vol *** 385 !! 386 !! ** Purpose : compute the correction of the local divergence to apply 385 !! 386 !! ** Purpose : compute the correction of the local divergence to apply 387 387 !! during the first time step after the coupling. 388 388 !! … … 390 390 !! - compute vertical input 391 391 !! - compute correction 392 !! 392 !! 393 393 !!---------------------------------------------------------------------- 394 394 !! 395 395 INTEGER, INTENT(in) :: Kmm ! ocean time level index 396 396 !!---------------------------------------------------------------------- 397 INTEGER :: ji, jj, jk 397 INTEGER :: ji, jj, jk 398 398 INTEGER :: ikb, ikt 399 399 !! … … 421 421 ! 422 422 ! 1.2: get volume flux after coupling (>0 out) 423 ! properly mask velocity 423 ! properly mask velocity 424 424 ! (velocity are still mask with old mask at this stage) 425 425 uu(:,:,jk,Kmm) = uu(:,:,jk,Kmm) * umask(:,:,jk) … … 459 459 ! 460 460 ! 3.2: get 3d tr(:,:,:,:,Krhs) increment to apply at the first time step 461 ! temperature and salt content flux computed using local ts(:,:,:,:,Kmm) 461 ! temperature and salt content flux computed using local ts(:,:,:,:,Kmm) 462 462 ! (very simple advection scheme) 463 463 ! (>0 out) … … 473 473 END SUBROUTINE isfcpl_vol 474 474 475 475 476 476 SUBROUTINE isfcpl_cons(Kmm) 477 !!---------------------------------------------------------------------- 477 !!---------------------------------------------------------------------- 478 478 !! *** ROUTINE iscpl_cons *** 479 !! 479 !! 480 480 !! ** Purpose : compute the corrective increment in volume/salt/heat to put back the vol/heat/salt 481 481 !! removed or added during the coupling processes (wet or dry new cell) 482 !! 482 !! 483 483 !! ** Method : - compare volume/heat/salt before and after 484 484 !! - look for the closest wet cells (share amoung neigbourgs if there are) 485 485 !! - build the correction increment to applied at each time step 486 !! 486 !! 487 487 !!---------------------------------------------------------------------- 488 488 ! … … 496 496 INTEGER :: iig , ijg, ik ! dummy indices 497 497 INTEGER :: jisf ! start, end and current position in the increment array 498 INTEGER :: ingb, ifind ! 0/1 target found or need to be found 499 INTEGER :: nisfl_area ! global number of cell concerned by the wet->dry case 498 INTEGER :: ingb, ifind ! 0/1 target found or need to be found 499 INTEGER :: nisfl_area ! global number of cell concerned by the wet->dry case 500 500 INTEGER, DIMENSION(jpnij) :: nisfl ! local number of cell concerned by the wet->dry case 501 501 ! 502 502 REAL(wp) :: z1_sum, z1_rdtiscpl 503 503 REAL(wp) :: zdtem, zdsal, zdvol, zratio ! tem, sal, vol increment 504 REAL(wp) :: zlon , zlat ! target location 504 REAL(wp) :: zlon , zlat ! target location 505 505 REAL(wp), DIMENSION(jpi,jpj,jpk) :: ztmask_b ! mask before 506 506 REAL(wp), DIMENSION(jpi,jpj,jpk) :: ze3t_b ! scale factor before … … 522 522 nstp_iscpl = nitend - nit000 + 1 523 523 rdt_iscpl = nstp_iscpl * rn_Dt 524 z1_rdtiscpl = 1._wp / rdt_iscpl 524 z1_rdtiscpl = 1._wp / rdt_iscpl 525 525 526 526 IF (lwp) WRITE(numout,*) ' nb of stp for cons = ', nstp_iscpl … … 552 552 zdsal = ts(ji,jj,jk,jp_sal,Kmm) * e3t(ji,jj,jk,Kmm) * tmask (ji,jj,jk) & 553 553 - zs_b(ji,jj,jk) * ze3t_b(ji,jj,jk) * ztmask_b(ji,jj,jk) 554 554 555 555 ! volume, heat and salt differences in each cell (>0 means correction is an outward flux) 556 556 ! in addition to the geometry change unconservation, need to add the divergence correction as it is flux across the boundary … … 575 575 DO ji = Nis0,Nie0 576 576 jip1=MIN(ji+1,jpi) ; jim1=MAX(ji-1,1) ; jjp1=MIN(jj+1,jpj) ; jjm1=MAX(jj-1,1) ; 577 IF ( tmask(ji,jj,jk) == 0._wp .AND. ztmask_b(ji,jj,jk) == 1._wp ) THEN 577 IF ( tmask(ji,jj,jk) == 0._wp .AND. ztmask_b(ji,jj,jk) == 1._wp ) THEN 578 578 nisfl(narea) = nisfl(narea) + MAX(SUM(tmask(jim1:jip1,jjm1:jjp1,jk)),1._wp) 579 579 ENDIF … … 582 582 ENDDO 583 583 ! 584 ! global 584 ! global 585 585 CALL mpp_sum('isfcpl',nisfl ) 586 586 ! … … 636 636 ! share data among all processes because for some point we need to find the closest wet point (could be on other process) 637 637 DO jproc=1,jpnij 638 ! 638 ! 639 639 ! share total number of isf point treated for proc jproc 640 640 IF (jproc==narea) THEN … … 660 660 ingb = zisfpts(jisf)%ngb 661 661 ELSE 662 iig =0 ; ijg =0 ; ik =0 662 iig =0 ; ijg =0 ; ik =0 663 663 zdvol=-HUGE(1.0) ; zdsal=-HUGE(1.0) ; zdtem=-HUGE(1.0) 664 zlat =-HUGE(1.0) ; zlon =-HUGE(1.0) 664 zlat =-HUGE(1.0) ; zlon =-HUGE(1.0) 665 665 ingb = 0 666 666 END IF … … 711 711 INTEGER, INTENT(inout) :: kpts 712 712 !!---------------------------------------------------------------------- 713 INTEGER, INTENT(in ) :: ki, kj, kk ! target location (kfind=0) 713 INTEGER, INTENT(in ) :: ki, kj, kk ! target location (kfind=0) 714 714 ! ! or source location (kfind=1) 715 715 INTEGER, INTENT(in ), OPTIONAL :: kfind ! 0 target cell already found 716 716 ! ! 1 target to be determined 717 REAL(wp), INTENT(in ) :: pdvol, pdsal, pdtem, pratio ! vol/sal/tem increment 717 REAL(wp), INTENT(in ) :: pdvol, pdsal, pdtem, pratio ! vol/sal/tem increment 718 718 ! ! and ratio in case increment span over multiple cells. 719 719 !!---------------------------------------------------------------------- 720 720 INTEGER :: ifind 721 721 !!---------------------------------------------------------------------- 722 ! 722 ! 723 723 ! increment position 724 724 kpts = kpts + 1 -
NEMO/trunk/src/OCE/ISF/isfrst.F90
r14053 r14072 20 20 PRIVATE 21 21 22 PUBLIC isfrst_read, isfrst_write ! iceshelf restart read and write 22 PUBLIC isfrst_read, isfrst_write ! iceshelf restart read and write 23 23 24 24 !!---------------------------------------------------------------------- … … 28 28 !!---------------------------------------------------------------------- 29 29 CONTAINS 30 30 31 31 SUBROUTINE isfrst_read( cdisf, ptsc, pfwf, ptsc_b, pfwf_b ) 32 32 !!--------------------------------------------------------------------- … … 63 63 END SUBROUTINE isfrst_read 64 64 65 65 66 66 SUBROUTINE isfrst_write( kt, cdisf, ptsc, pfwf ) 67 67 !!--------------------------------------------------------------------- … … 95 95 ! 96 96 END SUBROUTINE isfrst_write 97 97 98 98 !!====================================================================== 99 99 END MODULE isfrst -
NEMO/trunk/src/OCE/LBC/lbclnk.F90
r13982 r14072 6 6 !! History : OPA ! 1997-06 (G. Madec) Original code 7 7 !! NEMO 1.0 ! 2002-09 (G. Madec) F90: Free form and module 8 !! 3.2 ! 2009-03 (R. Benshila) External north fold treatment 8 !! 3.2 ! 2009-03 (R. Benshila) External north fold treatment 9 9 !! 3.5 ! 2012 (S.Mocavero, I. Epicoco) optimization of BDY comm. via lbc_bdy_lnk and lbc_obc_lnk 10 !! 3.4 ! 2012-12 (R. Bourdalle-Badie, G. Reffray) add a C1D case 11 !! 3.6 ! 2015-06 (O. Tintó and M. Castrillo) add lbc_lnk_multi 10 !! 3.4 ! 2012-12 (R. Bourdalle-Badie, G. Reffray) add a C1D case 11 !! 3.6 ! 2015-06 (O. Tintó and M. Castrillo) add lbc_lnk_multi 12 12 !! 4.0 ! 2017-03 (G. Madec) automatique allocation of array size (use with any 3rd dim size) 13 13 !! - ! 2017-04 (G. Madec) remove duplicated routines (lbc_lnk_2d_9, lbc_lnk_2d_multiple, lbc_lnk_3d_gather) … … 57 57 MODULE PROCEDURE mpp_nfd_2d_ptr_sp, mpp_nfd_3d_ptr_sp, mpp_nfd_4d_ptr_sp 58 58 MODULE PROCEDURE mpp_nfd_2d_ptr_dp, mpp_nfd_3d_ptr_dp, mpp_nfd_4d_ptr_dp 59 59 60 60 END INTERFACE 61 61 … … 527 527 # include "mpp_lbc_north_icb_generic.h90" 528 528 # undef ROUTINE_LNK 529 529 530 530 531 531 !!---------------------------------------------------------------------- … … 559 559 # include "mpp_lnk_icb_generic.h90" 560 560 # undef ROUTINE_LNK 561 561 562 562 END MODULE lbclnk 563 -
NEMO/trunk/src/OCE/LBC/lib_mpp.F90
r13982 r14072 20 20 !! 4.0 ! 2011 (G. Madec) move ctl_ routines from in_out_manager 21 21 !! 3.5 ! 2012 (S.Mocavero, I. Epicoco) Add mpp_lnk_bdy_3d/2d routines to optimize the BDY comm. 22 !! 3.5 ! 2013 (C. Ethe, G. Madec) message passing arrays as local variables 22 !! 3.5 ! 2013 (C. Ethe, G. Madec) message passing arrays as local variables 23 23 !! 3.5 ! 2013 (S.Mocavero, I.Epicoco - CMCC) north fold optimizations 24 24 !! 3.6 ! 2015 (O. Tintó and M. Castrillo - BSC) Added '_multiple' case for 2D lbc and max … … 77 77 PUBLIC MPI_Wtime 78 78 #endif 79 79 80 80 !! * Interfaces 81 81 !! define generic interface for these routine as they are called sometimes … … 115 115 !$AGRIF_END_DO_NOT_TREAT 116 116 LOGICAL, PUBLIC, PARAMETER :: lk_mpp = .TRUE. !: mpp flag 117 #else 117 #else 118 118 INTEGER, PUBLIC, PARAMETER :: MPI_STATUS_SIZE = 1 119 119 INTEGER, PUBLIC, PARAMETER :: MPI_REAL = 4 … … 183 183 REAL(dp), DIMENSION(2), PUBLIC :: waiting_time = 0._dp 184 184 REAL(dp) , PUBLIC :: compute_time = 0._dp, elapsed_time = 0._dp 185 185 186 186 REAL(wp), DIMENSION(:), ALLOCATABLE, SAVE :: tampon ! buffer in case of bsend 187 187 188 188 LOGICAL, PUBLIC :: ln_nnogather !: namelist control of northfold comms 189 189 LOGICAL, PUBLIC :: l_north_nogather = .FALSE. !: internal control of northfold comms 190 190 191 191 !! * Substitutions 192 192 # include "do_loop_substitute.h90" … … 223 223 IF( ierr /= MPI_SUCCESS ) CALL ctl_stop( 'STOP', ' lib_mpp: Error in routine mpi_init' ) 224 224 ENDIF 225 225 226 226 IF( PRESENT(localComm) ) THEN 227 227 IF( Agrif_Root() ) THEN … … 473 473 END SUBROUTINE mppscatter 474 474 475 475 476 476 SUBROUTINE mpp_delay_sum( cdname, cdelay, y_in, pout, ldlast, kcom ) 477 477 !!---------------------------------------------------------------------- … … 498 498 499 499 isz = SIZE(y_in) 500 500 501 501 IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ld_dlg = .TRUE. ) 502 502 … … 519 519 END IF 520 520 ENDIF 521 521 522 522 IF( ndelayid(idvar) == -1 ) THEN ! first call without restart: define %y1d and %z1d from y_in with blocking allreduce 523 523 ! -------------------------- … … 547 547 END SUBROUTINE mpp_delay_sum 548 548 549 549 550 550 SUBROUTINE mpp_delay_max( cdname, cdelay, p_in, pout, ldlast, kcom ) 551 551 !!---------------------------------------------------------------------- … … 557 557 CHARACTER(len=*), INTENT(in ) :: cdname ! name of the calling subroutine 558 558 CHARACTER(len=*), INTENT(in ) :: cdelay ! name (used as id) of the delayed operation 559 REAL(wp), INTENT(in ), DIMENSION(:) :: p_in ! 560 REAL(wp), INTENT( out), DIMENSION(:) :: pout ! 559 REAL(wp), INTENT(in ), DIMENSION(:) :: p_in ! 560 REAL(wp), INTENT( out), DIMENSION(:) :: pout ! 561 561 LOGICAL, INTENT(in ) :: ldlast ! true if this is the last time we call this routine 562 562 INTEGER, INTENT(in ), OPTIONAL :: kcom … … 567 567 INTEGER :: MPI_TYPE 568 568 !!---------------------------------------------------------------------- 569 569 570 570 #if defined key_mpp_mpi 571 571 if( wp == dp ) then … … 575 575 else 576 576 CALL ctl_stop( "Error defining type, wp is neither dp nor sp" ) 577 577 578 578 end if 579 579 … … 629 629 END SUBROUTINE mpp_delay_max 630 630 631 631 632 632 SUBROUTINE mpp_delay_rcv( kid ) 633 633 !!---------------------------------------------------------------------- 634 634 !! *** routine mpp_delay_rcv *** 635 635 !! 636 !! ** Purpose : force barrier for delayed mpp (needed for restart) 637 !! 638 !!---------------------------------------------------------------------- 639 INTEGER,INTENT(in ) :: kid 636 !! ** Purpose : force barrier for delayed mpp (needed for restart) 637 !! 638 !!---------------------------------------------------------------------- 639 INTEGER,INTENT(in ) :: kid 640 640 INTEGER :: ierr 641 641 !!---------------------------------------------------------------------- … … 674 674 END SUBROUTINE mpp_bcast_nml 675 675 676 676 677 677 !!---------------------------------------------------------------------- 678 678 !! *** mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real *** 679 !! 679 !! 680 680 !!---------------------------------------------------------------------- 681 681 !! … … 729 729 !!---------------------------------------------------------------------- 730 730 !! *** mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real *** 731 !! 731 !! 732 732 !!---------------------------------------------------------------------- 733 733 !! … … 781 781 !!---------------------------------------------------------------------- 782 782 !! *** mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real *** 783 !! 783 !! 784 784 !! Global sum of 1D array or a variable (integer, real or complex) 785 785 !!---------------------------------------------------------------------- … … 855 855 !!---------------------------------------------------------------------- 856 856 !! *** mpp_minloc2d, mpp_minloc3d, mpp_maxloc2d, mpp_maxloc3d 857 !! 857 !! 858 858 !!---------------------------------------------------------------------- 859 859 !! … … 935 935 936 936 937 SUBROUTINE mppstop( ld_abort ) 937 SUBROUTINE mppstop( ld_abort ) 938 938 !!---------------------------------------------------------------------- 939 939 !! *** routine mppstop *** … … 1080 1080 !! collectives 1081 1081 !! 1082 !! ** Method : - Create graph communicators starting from the processes 1082 !! ** Method : - Create graph communicators starting from the processes 1083 1083 !! distribution along i and j directions 1084 1084 ! … … 1411 1411 jj = 0 1412 1412 END IF 1413 jj = jj + 1 1413 jj = jj + 1 1414 1414 END DO 1415 1415 WRITE(numcom,'(A, I4, A, A)') ' - ', jj,' times by subroutine ', TRIM(crname_glb(n_sequence_glb)) … … 1427 1427 jj = 0 1428 1428 END IF 1429 jj = jj + 1 1429 jj = jj + 1 1430 1430 END DO 1431 1431 WRITE(numcom,'(A, I4, A, A)') ' - ', jj,' times by subroutine ', TRIM(crname_dlg(n_sequence_dlg)) … … 1443 1443 END SUBROUTINE mpp_report 1444 1444 1445 1445 1446 1446 SUBROUTINE tic_tac (ld_tic, ld_global) 1447 1447 … … 1459 1459 IF( ld_global ) ii = 2 1460 1460 END IF 1461 1461 1462 1462 IF ( ld_tic ) THEN 1463 1463 tic_wt(ii) = MPI_Wtime() ! start count tic->tac (waiting time) … … 1468 1468 ENDIF 1469 1469 #endif 1470 1470 1471 1471 END SUBROUTINE tic_tac 1472 1472 … … 1478 1478 END SUBROUTINE mpi_wait 1479 1479 1480 1480 1481 1481 FUNCTION MPI_Wtime() 1482 1482 REAL(wp) :: MPI_Wtime … … 1540 1540 ! 1541 1541 IF( cd1 == 'STOP' ) THEN 1542 WRITE(numout,*) 1542 WRITE(numout,*) 1543 1543 WRITE(numout,*) 'huge E-R-R-O-R : immediate stop' 1544 WRITE(numout,*) 1544 WRITE(numout,*) 1545 1545 CALL FLUSH(numout) 1546 1546 CALL SLEEP(60) ! make sure that all output and abort files are written by all cores. 60s should be enough... … … 1639 1639 ENDIF 1640 1640 IF( iost /= 0 .AND. TRIM(clfile) == '/dev/null' ) & ! for windows 1641 & OPEN(UNIT=knum,FILE='NUL', FORM=cdform, ACCESS=cdacce, STATUS=cdstat , ERR=100, IOSTAT=iost ) 1641 & OPEN(UNIT=knum,FILE='NUL', FORM=cdform, ACCESS=cdacce, STATUS=cdstat , ERR=100, IOSTAT=iost ) 1642 1642 IF( iost == 0 ) THEN 1643 1643 IF(ldwp .AND. kout > 0) THEN … … 1681 1681 ! 1682 1682 WRITE (clios, '(I5.0)') kios 1683 IF( kios < 0 ) THEN 1683 IF( kios < 0 ) THEN 1684 1684 CALL ctl_warn( 'end of record or file while reading namelist ' & 1685 1685 & // TRIM(cdnam) // ' iostat = ' // TRIM(clios) ) … … 1727 1727 !csp = NEW_LINE('A') 1728 1728 ! a new line character is the best seperator but some systems (e.g.Cray) 1729 ! seem to terminate namelist reads from internal files early if they 1729 ! seem to terminate namelist reads from internal files early if they 1730 1730 ! encounter new-lines. Use a single space for safety. 1731 1731 csp = ' ' … … 1746 1746 iltc = LEN_TRIM(chline) 1747 1747 IF ( iltc.GT.0 ) THEN 1748 inl = INDEX(chline, '!') 1748 inl = INDEX(chline, '!') 1749 1749 IF( inl.eq.0 ) THEN 1750 1750 itot = itot + iltc + 1 ! +1 for the newline character -
NEMO/trunk/src/OCE/LBC/mpp_lnk_generic.h90
r13982 r14072 1 1 #if defined MULTI 2 # define NAT_IN(k) cd_nat(k) 2 # define NAT_IN(k) cd_nat(k) 3 3 # define SGN_IN(k) psgn(k) 4 4 # define F_SIZE(ptab) kfld … … 43 43 # define SGN_IN(k) psgn 44 44 # define F_SIZE(ptab) 1 45 # define OPT_K(k) 45 # define OPT_K(k) 46 46 # if defined DIM_2d 47 47 # define ARRAY_IN(i,j,k,l,f) ptab(i,j) … … 97 97 REAL(PRECISION), DIMENSION(:,:,:,:,:), ALLOCATABLE :: zsnd_so, zrcv_so, zsnd_no, zrcv_no ! north-south & south-north halos 98 98 LOGICAL :: llsend_we, llsend_ea, llsend_no, llsend_so ! communication send 99 LOGICAL :: llrecv_we, llrecv_ea, llrecv_no, llrecv_so ! communication receive 99 LOGICAL :: llrecv_we, llrecv_ea, llrecv_no, llrecv_so ! communication receive 100 100 LOGICAL :: lldo_nfd ! do north pole folding 101 101 !!---------------------------------------------------------------------- … … 133 133 llrecv_we = llsend_we ; llrecv_ea = llsend_ea ; llrecv_so = llsend_so ; llrecv_no = llsend_no 134 134 END IF 135 136 135 136 137 137 lldo_nfd = npolj /= 0 ! keep for compatibility, should be defined in mppini 138 138 … … 178 178 ! 179 179 ! Must exchange the whole column (from 1 to jpj) to get the corners if we have no south/north neighbourg 180 isize = nn_hls * jpj * ipk * ipl * ipf 180 isize = nn_hls * jpj * ipk * ipl * ipf 181 181 ! 182 182 ! Allocate local temporary arrays to be sent/received. Fill arrays to be sent … … 220 220 ! ishift = 0 ! fill halo from ji = 1 to nn_hls 221 221 SELECT CASE ( ifill_we ) 222 CASE ( jpfillnothing ) ! no filling 223 CASE ( jpfillmpi ) ! use data received by MPI 222 CASE ( jpfillnothing ) ! no filling 223 CASE ( jpfillmpi ) ! use data received by MPI 224 224 DO jf = 1, ipf ; DO jl = 1, ipl ; DO jk = 1, ipk ; DO jj = 1, jpj ; DO ji = 1, nn_hls 225 225 ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_we(ji,jj,jk,jl,jf) ! 1 -> nn_hls … … 242 242 ! 2.2 fill eastern halo 243 243 ! --------------------- 244 ishift = jpi - nn_hls ! fill halo from ji = jpi-nn_hls+1 to jpi 244 ishift = jpi - nn_hls ! fill halo from ji = jpi-nn_hls+1 to jpi 245 245 SELECT CASE ( ifill_ea ) 246 CASE ( jpfillnothing ) ! no filling 247 CASE ( jpfillmpi ) ! use data received by MPI 246 CASE ( jpfillnothing ) ! no filling 247 CASE ( jpfillmpi ) ! use data received by MPI 248 248 DO jf = 1, ipf ; DO jl = 1, ipl ; DO jk = 1, ipk ; DO jj = 1, jpj ; DO ji = 1, nn_hls 249 249 ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv_ea(ji,jj,jk,jl,jf) ! jpi - nn_hls + 1 -> jpi … … 290 290 IF( llrecv_no ) ALLOCATE( zrcv_no(jpi,nn_hls,ipk,ipl,ipf) ) 291 291 ! 292 isize = jpi * nn_hls * ipk * ipl * ipf 292 isize = jpi * nn_hls * ipk * ipl * ipf 293 293 294 294 ! allocate local temporary arrays to be sent/received. Fill arrays to be sent … … 326 326 ! ishift = 0 ! fill halo from jj = 1 to nn_hls 327 327 SELECT CASE ( ifill_so ) 328 CASE ( jpfillnothing ) ! no filling 329 CASE ( jpfillmpi ) ! use data received by MPI 328 CASE ( jpfillnothing ) ! no filling 329 CASE ( jpfillmpi ) ! use data received by MPI 330 330 DO jf = 1, ipf ; DO jl = 1, ipl ; DO jk = 1, ipk ; DO jj = 1, nn_hls ; DO ji = 1, jpi 331 331 ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_so(ji,jj,jk,jl,jf) ! 1 -> nn_hls … … 341 341 END DO ; END DO ; END DO ; END DO ; END DO 342 342 CASE ( jpfillcst ) ! filling with constant value 343 DO jf = 1, ipf ; DO jl = 1, ipl ; DO jk = 1, ipk ; DO jj = 1, nn_hls ; DO ji = 1, jpi 343 DO jf = 1, ipf ; DO jl = 1, ipl ; DO jk = 1, ipk ; DO jj = 1, nn_hls ; DO ji = 1, jpi 344 344 ARRAY_IN(ji,jj,jk,jl,jf) = zland 345 345 END DO ; END DO ; END DO ; END DO ; END DO … … 348 348 ! 5.2 fill northern halo 349 349 ! ---------------------- 350 ishift = jpj - nn_hls ! fill halo from jj = jpj-nn_hls+1 to jpj 350 ishift = jpj - nn_hls ! fill halo from jj = jpj-nn_hls+1 to jpj 351 351 SELECT CASE ( ifill_no ) 352 CASE ( jpfillnothing ) ! no filling 353 CASE ( jpfillmpi ) ! use data received by MPI 352 CASE ( jpfillnothing ) ! no filling 353 CASE ( jpfillmpi ) ! use data received by MPI 354 354 DO jf = 1, ipf ; DO jl = 1, ipl ; DO jk = 1, ipk ; DO jj = 1, nn_hls ; DO ji = 1, jpi 355 355 ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv_no(ji,jj,jk,jl,jf) ! jpj-nn_hls+1 -> jpj -
NEMO/trunk/src/OCE/LBC/mppini.F90
r14053 r14072 9 9 !! NEMO 1.0 ! 2004-01 (G. Madec, J.M Molines) F90 : free form , north fold jpni > 1 10 10 !! 3.4 ! 2011-10 (A. C. Coward, NOCS & J. Donners, PRACE) add init_nfdcom 11 !! 3. ! 2013-06 (I. Epicoco, S. Mocavero, CMCC) init_nfdcom: setup avoiding MPI communication 11 !! 3. ! 2013-06 (I. Epicoco, S. Mocavero, CMCC) init_nfdcom: setup avoiding MPI communication 12 12 !! 4.0 ! 2016-06 (G. Madec) use domain configuration file instead of bathymetry file 13 13 !! 4.0 ! 2017-06 (J.M. Molines, T. Lovato) merge of mppini and mppini_2 … … 16 16 !!---------------------------------------------------------------------- 17 17 !! mpp_init : Lay out the global domain over processors with/without land processor elimination 18 !! init_ioipsl: IOIPSL initialization in mpp 18 !! init_ioipsl: IOIPSL initialization in mpp 19 19 !! init_nfdcom: Setup for north fold exchanges with explicit point-to-point messaging 20 !! init_doloop: set the starting/ending indices of DO-loop used in do_loop_substitute 20 !! init_doloop: set the starting/ending indices of DO-loop used in do_loop_substitute 21 21 !!---------------------------------------------------------------------- 22 22 USE dom_oce ! ocean space and time domain 23 USE bdy_oce ! open BounDarY 23 USE bdy_oce ! open BounDarY 24 24 ! 25 USE lbcnfd , ONLY : isendto, nsndto ! Setup of north fold exchanges 25 USE lbcnfd , ONLY : isendto, nsndto ! Setup of north fold exchanges 26 26 USE lib_mpp ! distribued memory computing library 27 USE iom ! nemo I/O library 27 USE iom ! nemo I/O library 28 28 USE ioipsl ! I/O IPSL library 29 29 USE in_out_manager ! I/O Manager … … 36 36 PUBLIC mpp_basesplit ! called by prtctl 37 37 PUBLIC mpp_is_ocean ! called by prtctl 38 38 39 39 INTEGER :: numbot = -1 ! 'bottom_level' local logical unit 40 40 INTEGER :: numbdy = -1 ! 'bdy_msk' local logical unit 41 41 42 42 !!---------------------------------------------------------------------- 43 43 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 44 !! $Id$ 44 !! $Id$ 45 45 !! Software governed by the CeCILL license (see ./LICENSE) 46 46 !!---------------------------------------------------------------------- … … 88 88 l_Jperio = jpnj == 1 .AND. (jperio == 2 .OR. jperio == 7) 89 89 ! 90 CALL init_doloop ! set start/end indices or do-loop depending on the halo width value (nn_hls) 90 CALL init_doloop ! set start/end indices or do-loop depending on the halo width value (nn_hls) 91 91 ! 92 92 IF(lwp) THEN … … 94 94 WRITE(numout,*) 'mpp_init : NO massively parallel processing' 95 95 WRITE(numout,*) '~~~~~~~~ ' 96 WRITE(numout,*) ' l_Iperio = ', l_Iperio, ' l_Jperio = ', l_Jperio 96 WRITE(numout,*) ' l_Iperio = ', l_Iperio, ' l_Jperio = ', l_Jperio 97 97 WRITE(numout,*) ' npolj = ', npolj , ' njmpp = ', njmpp 98 98 ENDIF … … 114 114 !!---------------------------------------------------------------------- 115 115 !! *** ROUTINE mpp_init *** 116 !! 116 !! 117 117 !! ** Purpose : Lay out the global domain over processors. 118 118 !! If land processors are to be eliminated, this program requires the … … 128 128 !! 129 129 !! ** Action : - set domain parameters 130 !! nimpp : longitudinal index 130 !! nimpp : longitudinal index 131 131 !! njmpp : latitudinal index 132 132 !! narea : number for local area … … 148 148 INTEGER :: iiea, ijea, iiwe, ijwe ! - - 149 149 INTEGER :: iarea0 ! - - 150 INTEGER :: ierr, ios ! 150 INTEGER :: ierr, ios ! 151 151 INTEGER :: inbi, inbj, iimax, ijmax, icnt1, icnt2 152 152 LOGICAL :: llbest, llauto … … 162 162 NAMELIST/nambdy/ ln_bdy, nb_bdy, ln_coords_file, cn_coords_file, & 163 163 & ln_mask_file, cn_mask_file, cn_dyn2d, nn_dyn2d_dta, & 164 & cn_dyn3d, nn_dyn3d_dta, cn_tra, nn_tra_dta, & 164 & cn_dyn3d, nn_dyn3d_dta, cn_tra, nn_tra_dta, & 165 165 & ln_tra_dmp, ln_dyn3d_dmp, rn_time_dmp, rn_time_dmp_out, & 166 166 & cn_ice, nn_ice_dta, & … … 177 177 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nammpp in reference namelist' ) 178 178 READ ( numnam_cfg, nammpp, IOSTAT = ios, ERR = 902 ) 179 902 IF( ios > 0 ) CALL ctl_nam ( ios , 'nammpp in configuration namelist' ) 179 902 IF( ios > 0 ) CALL ctl_nam ( ios , 'nammpp in configuration namelist' ) 180 180 ! 181 181 nn_hls = MAX(1, nn_hls) ! nn_hls must be > 0 … … 259 259 ENDIF 260 260 ENDIF 261 261 262 262 ! look for land mpi subdomains... 263 263 ALLOCATE( llisoce(jpni,jpnj) ) … … 333 333 CALL mpp_sum( 'mppini', ierr ) 334 334 IF( ierr /= 0 ) CALL ctl_stop( 'STOP', 'mpp_init: unable to allocate standard ocean arrays' ) 335 335 336 336 #if defined key_agrif 337 337 IF( .NOT. Agrif_Root() ) THEN ! AGRIF children: specific setting (cf. agrif_user.F90) … … 354 354 ! nfjpi (jn) = ijpi(ii,ij) 355 355 !END DO 356 nfproc(:) = ipproc(:,jpnj) 357 nfimpp(:) = iimppt(:,jpnj) 356 nfproc(:) = ipproc(:,jpnj) 357 nfimpp(:) = iimppt(:,jpnj) 358 358 nfjpi (:) = ijpi(:,jpnj) 359 359 ! … … 363 363 WRITE(numout,*) 364 364 WRITE(numout,*) ' defines mpp subdomains' 365 WRITE(numout,*) ' jpni = ', jpni 365 WRITE(numout,*) ' jpni = ', jpni 366 366 WRITE(numout,*) ' jpnj = ', jpnj 367 367 WRITE(numout,*) ' jpnij = ', jpnij … … 370 370 WRITE(numout,*) ' sum ijpj(1,j) = ', sum(ijpj(1,:)), ' jpjglo = ', jpjglo 371 371 ENDIF 372 372 373 373 ! 3. Subdomain description in the Regular Case 374 374 ! -------------------------------------------- 375 375 ! specific cases where there is no communication -> must do the periodicity by itself 376 ! Warning: because of potential land-area suppression, do not use nbond[ij] == 2 376 ! Warning: because of potential land-area suppression, do not use nbond[ij] == 2 377 377 l_Iperio = jpni == 1 .AND. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6 .OR. jperio == 7) 378 378 l_Jperio = jpnj == 1 .AND. (jperio == 2 .OR. jperio == 7) 379 379 380 380 DO jarea = 1, jpni*jpnj 381 381 ! … … 450 450 ! In case of north fold exchange: I am the n neigbour of my n neigbour!! (#1057) 451 451 ! --> for northern neighbours of northern row processors (in case of north-fold) 452 ! need to reverse the LOGICAL direction of communication 452 ! need to reverse the LOGICAL direction of communication 453 453 idir = 1 ! we are indeed the s neigbour of this n neigbour 454 454 IF( ij == jpnj .AND. ijno == jpnj ) idir = -1 ! both are on the last row, we are in fact the n neigbour … … 478 478 ENDIF 479 479 END DO 480 480 481 481 ! 5. Subdomain print 482 482 ! ------------------ … … 504 504 9404 FORMAT(' * ' ,20(' ' ,i4,' * ') ) 505 505 ENDIF 506 506 507 507 ! just to save nono etc for all proc 508 508 ! warning ii*ij (zone) /= nproc (processors)! … … 511 511 ii_nono(:) = -1 512 512 ii_noea(:) = -1 513 ii_nowe(:) = -1 513 ii_nowe(:) = -1 514 514 DO jproc = 1, jpnij 515 515 ii = iin(jproc) … … 536 536 ENDIF 537 537 END DO 538 538 539 539 ! 6. Change processor name 540 540 ! ------------------------ … … 542 542 ij = ijn(narea) 543 543 ! 544 jpi = ijpi(ii,ij) 544 jpi = ijpi(ii,ij) 545 545 !!$ Nis0 = iis0(ii,ij) 546 546 !!$ Nie0 = iie0(ii,ij) 547 jpj = ijpj(ii,ij) 547 jpj = ijpj(ii,ij) 548 548 !!$ Njs0 = ijs0(ii,ij) 549 549 !!$ Nje0 = ije0(ii,ij) 550 550 nbondi = ibondi(ii,ij) 551 551 nbondj = ibondj(ii,ij) 552 nimpp = iimppt(ii,ij) 552 nimpp = iimppt(ii,ij) 553 553 njmpp = ijmppt(ii,ij) 554 554 jpk = jpkglo ! third dim … … 564 564 noses = -1 565 565 nosws = -1 566 566 567 567 noner = -1 568 568 nonwr = -1 … … 613 613 614 614 ! 615 CALL init_doloop ! set start/end indices of do-loop, depending on the halo width value (nn_hls) 615 CALL init_doloop ! set start/end indices of do-loop, depending on the halo width value (nn_hls) 616 616 ! 617 617 jpim1 = jpi-1 ! inner domain indices … … 630 630 ibonit(jproc) = ibondi(ii,ij) 631 631 ibonjt(jproc) = ibondj(ii,ij) 632 nimppt(jproc) = iimppt(ii,ij) 633 njmppt(jproc) = ijmppt(ii,ij) 632 nimppt(jproc) = iimppt(ii,ij) 633 njmppt(jproc) = ijmppt(ii,ij) 634 634 END DO 635 635 … … 647 647 & nis0all(jproc), njs0all(jproc), & 648 648 & nie0all(jproc), nje0all(jproc), & 649 & nimppt (jproc), njmppt (jproc), & 649 & nimppt (jproc), njmppt (jproc), & 650 650 & ii_nono(jproc), ii_noso(jproc), & 651 651 & ii_nowe(jproc), ii_noea(jproc), & 652 & ibonit (jproc), ibonjt (jproc) 652 & ibonit (jproc), ibonjt (jproc) 653 653 END DO 654 654 END IF … … 707 707 ! 708 708 CALL init_ioipsl ! Prepare NetCDF output file (if necessary) 709 ! 709 ! 710 710 IF (( jperio >= 3 .AND. jperio <= 6 .AND. jpni > 1 ).AND.( ln_nnogather )) THEN 711 711 CALL init_nfdcom ! northfold neighbour lists … … 719 719 ENDIF 720 720 ! 721 IF (llwrtlay) CLOSE(inum) 721 IF (llwrtlay) CLOSE(inum) 722 722 ! 723 723 DEALLOCATE(iin, ijn, ii_nono, ii_noea, ii_noso, ii_nowe, & … … 733 733 !!---------------------------------------------------------------------- 734 734 !! *** ROUTINE mpp_basesplit *** 735 !! 735 !! 736 736 !! ** Purpose : Lay out the global domain over processors. 737 737 !! … … 752 752 ! 753 753 INTEGER :: ji, jj 754 INTEGER :: i2hls 754 INTEGER :: i2hls 755 755 INTEGER :: iresti, irestj, irm, ijpjmin 756 756 !!---------------------------------------------------------------------- … … 759 759 #if defined key_nemocice_decomp 760 760 kimax = ( nx_global+2-i2hls + (knbi-1) ) / knbi + i2hls ! first dim. 761 kjmax = ( ny_global+2-i2hls + (knbj-1) ) / knbj + i2hls ! second dim. 761 kjmax = ( ny_global+2-i2hls + (knbj-1) ) / knbj + i2hls ! second dim. 762 762 #else 763 763 kimax = ( kiglo - i2hls + (knbi-1) ) / knbi + i2hls ! first dim. … … 797 797 irm = knbj - irestj ! total number of lines to be removed 798 798 klcj(:,knbj) = MAX( ijpjmin, kjmax-irm ) ! we must have jpj >= ijpjmin in the last row 799 irm = irm - ( kjmax - klcj(1,knbj) ) ! remaining number of lines to remove 799 irm = irm - ( kjmax - klcj(1,knbj) ) ! remaining number of lines to remove 800 800 irestj = knbj - 1 - irm 801 801 klcj(:, irestj+1:knbj-1) = kjmax-1 … … 831 831 END DO 832 832 ENDIF 833 833 834 834 END SUBROUTINE mpp_basesplit 835 835 … … 890 890 ! get the list of knbi that gives a smaller jpimax than knbi-1 891 891 ! get the list of knbj that gives a smaller jpjmax than knbj-1 892 DO ji = 1, inbijmax 892 DO ji = 1, inbijmax 893 893 #if defined key_nemocice_decomp 894 894 iszitst = ( nx_global+2-2*nn_hls + (ji-1) ) / ji + 2*nn_hls ! first dim. … … 958 958 ! extract only the partitions which reduce the subdomain size in comparison with smaller partitions 959 959 ALLOCATE( indexok(isz1) ) ! to store indices of the best partitions 960 isz0 = 0 ! number of best partitions 960 isz0 = 0 ! number of best partitions 961 961 inbij = 1 ! start with the min value of inbij1 => 1 962 962 iszij = jpiglo*jpjglo+1 ! default: larger than global domain … … 1018 1018 CALL mppstop( ld_abort = .TRUE. ) 1019 1019 ENDIF 1020 1020 1021 1021 DEALLOCATE( iszi0, iszj0 ) 1022 1022 inbij = inbijmax + 1 ! default: larger than possible 1023 1023 ii = isz0+1 ! start from the end of the list (smaller subdomains) 1024 1024 DO WHILE( inbij > knbij ) ! while the number of ocean subdomains exceed the number of procs 1025 ii = ii -1 1025 ii = ii -1 1026 1026 ALLOCATE( llisoce(inbi0(ii), inbj0(ii)) ) 1027 1027 CALL mpp_is_ocean( llisoce ) ! must be done by all core … … 1035 1035 ! 1036 1036 END SUBROUTINE bestpartition 1037 1038 1037 1038 1039 1039 SUBROUTINE mpp_init_landprop( propland ) 1040 1040 !!---------------------------------------------------------------------- … … 1059 1059 ENDIF 1060 1060 1061 ! number of processes reading the bathymetry file 1061 ! number of processes reading the bathymetry file 1062 1062 iproc = MINVAL( (/mppsize, Nj0glo/2, 100/) ) ! read a least 2 lines, no more that 100 processes reading at the same time 1063 1063 1064 1064 ! we want to read iproc strips of the land-sea mask. -> pick up iproc processes every idiv processes starting at 1 1065 1065 IF( iproc == 1 ) THEN ; idiv = mppsize … … 1084 1084 CALL mpp_sum( 'mppini', inboce ) ! total number of ocean points over the global domain 1085 1085 ! 1086 propland = REAL( Ni0glo*Nj0glo - inboce, wp ) / REAL( Ni0glo*Nj0glo, wp ) 1086 propland = REAL( Ni0glo*Nj0glo - inboce, wp ) / REAL( Ni0glo*Nj0glo, wp ) 1087 1087 ! 1088 1088 END SUBROUTINE mpp_init_landprop 1089 1090 1089 1090 1091 1091 SUBROUTINE mpp_is_ocean( ldisoce ) 1092 1092 !!---------------------------------------------------------------------- … … 1104 1104 !! ** Method : read inbj strips (of length Ni0glo) of the land-sea mask 1105 1105 !!---------------------------------------------------------------------- 1106 LOGICAL, DIMENSION(:,:), INTENT( out) :: ldisoce ! .true. if a sub domain constains 1 ocean point 1106 LOGICAL, DIMENSION(:,:), INTENT( out) :: ldisoce ! .true. if a sub domain constains 1 ocean point 1107 1107 ! 1108 1108 INTEGER :: idiv, iimax, ijmax, iarea … … 1113 1113 INTEGER, ALLOCATABLE, DIMENSION(:,:) :: iimppt, ijpi 1114 1114 INTEGER, ALLOCATABLE, DIMENSION(:,:) :: ijmppt, ijpj 1115 LOGICAL, ALLOCATABLE, DIMENSION(:,:) :: lloce ! lloce(i,j) = .true. if the point (i,j) is ocean 1115 LOGICAL, ALLOCATABLE, DIMENSION(:,:) :: lloce ! lloce(i,j) = .true. if the point (i,j) is ocean 1116 1116 !!---------------------------------------------------------------------- 1117 1117 ! do nothing if there is no land-sea mask … … 1146 1146 isty = 1 + COUNT( (/ iarea == 1 /) ) ! read from the first or the second line? 1147 1147 CALL readbot_strip( ijmppt(1,iarea) - 2 + isty, inry, lloce(2:inx-1, isty:inry+isty-1) ) ! read the strip 1148 ! 1148 ! 1149 1149 IF( iarea == 1 ) THEN ! the first line was not read 1150 1150 IF( jperio == 2 .OR. jperio == 7 ) THEN ! north-south periodocity … … 1157 1157 IF( jperio == 2 .OR. jperio == 7 ) THEN ! north-south periodocity 1158 1158 CALL readbot_strip( 1, 1, lloce(2:inx-1,iny) ) ! read the first line -> last line of lloce 1159 ELSEIF( jperio == 3 .OR. jperio == 4 ) THEN ! north-pole folding T-pivot, T-point 1159 ELSEIF( jperio == 3 .OR. jperio == 4 ) THEN ! north-pole folding T-pivot, T-point 1160 1160 lloce(2,iny) = lloce(2,iny-2) ! here we have 1 halo (even if nn_hls>1) 1161 1161 DO ji = 3,inx-1 … … 1191 1191 ENDIF 1192 1192 END DO 1193 1193 1194 1194 inboce_1d = RESHAPE(inboce, (/ inbi*inbj /)) 1195 1195 CALL mpp_sum( 'mppini', inboce_1d ) … … 1199 1199 ! 1200 1200 END SUBROUTINE mpp_is_ocean 1201 1202 1201 1202 1203 1203 SUBROUTINE readbot_strip( kjstr, kjcnt, ldoce ) 1204 1204 !!---------------------------------------------------------------------- … … 1213 1213 INTEGER , INTENT(in ) :: kjstr ! starting j position of the reading 1214 1214 INTEGER , INTENT(in ) :: kjcnt ! number of lines to read 1215 LOGICAL, DIMENSION(Ni0glo,kjcnt), INTENT( out) :: ldoce ! ldoce(i,j) = .true. if the point (i,j) is ocean 1215 LOGICAL, DIMENSION(Ni0glo,kjcnt), INTENT( out) :: ldoce ! ldoce(i,j) = .true. if the point (i,j) is ocean 1216 1216 ! 1217 1217 INTEGER :: inumsave ! local logical unit 1218 REAL(wp), DIMENSION(Ni0glo,kjcnt) :: zbot, zbdy 1218 REAL(wp), DIMENSION(Ni0glo,kjcnt) :: zbot, zbdy 1219 1219 !!---------------------------------------------------------------------- 1220 1220 ! 1221 1221 inumsave = numout ; numout = numnul ! redirect all print to /dev/null 1222 1222 ! 1223 IF( numbot /= -1 ) THEN 1223 IF( numbot /= -1 ) THEN 1224 1224 CALL iom_get( numbot, jpdom_unknown, 'bottom_level', zbot, kstart = (/1,kjstr/), kcount = (/Ni0glo, kjcnt/) ) 1225 1225 ELSE … … 1227 1227 ENDIF 1228 1228 ! 1229 IF( numbdy /= -1 ) THEN ! Adjust with bdy_msk if it exists 1229 IF( numbdy /= -1 ) THEN ! Adjust with bdy_msk if it exists 1230 1230 CALL iom_get ( numbdy, jpdom_unknown, 'bdy_msk', zbdy, kstart = (/1,kjstr/), kcount = (/Ni0glo, kjcnt/) ) 1231 1231 zbot(:,:) = zbot(:,:) * zbdy(:,:) … … 1295 1295 !! *** ROUTINE init_ioipsl *** 1296 1296 !! 1297 !! ** Purpose : 1298 !! 1299 !! ** Method : 1297 !! ** Purpose : 1298 !! 1299 !! ** Method : 1300 1300 !! 1301 1301 !! History : 1302 !! 9.0 ! 04-03 (G. Madec ) MPP-IOIPSL 1302 !! 9.0 ! 04-03 (G. Madec ) MPP-IOIPSL 1303 1303 !! " " ! 08-12 (A. Coward) addition in case of jpni*jpnj < jpnij 1304 1304 !!---------------------------------------------------------------------- … … 1328 1328 CALL flio_dom_set ( jpnij, nproc, idid, iglo, iloc, iabsf, iabsl, ihals, ihale, 'BOX', nidom) 1329 1329 ! 1330 END SUBROUTINE init_ioipsl 1330 END SUBROUTINE init_ioipsl 1331 1331 1332 1332 … … 1334 1334 !!---------------------------------------------------------------------- 1335 1335 !! *** ROUTINE init_nfdcom *** 1336 !! ** Purpose : Setup for north fold exchanges with explicit 1336 !! ** Purpose : Setup for north fold exchanges with explicit 1337 1337 !! point-to-point messaging 1338 1338 !! … … 1340 1340 !!---------------------------------------------------------------------- 1341 1341 !! 1.0 ! 2011-10 (A. C. Coward, NOCS & J. Donners, PRACE) 1342 !! 2.0 ! 2013-06 Setup avoiding MPI communication (I. Epicoco, S. Mocavero, CMCC) 1342 !! 2.0 ! 2013-06 Setup avoiding MPI communication (I. Epicoco, S. Mocavero, CMCC) 1343 1343 !!---------------------------------------------------------------------- 1344 1344 INTEGER :: sxM, dxM, sxT, dxT, jn … … 1392 1392 ! 1393 1393 Nis0 = 1+nn_hls ; Nis1 = Nis0-1 ; Nis2 = MAX( 1, Nis0-2) 1394 Njs0 = 1+nn_hls ; Njs1 = Njs0-1 ; Njs2 = MAX( 1, Njs0-2) 1395 ! 1394 Njs0 = 1+nn_hls ; Njs1 = Njs0-1 ; Njs2 = MAX( 1, Njs0-2) 1395 ! 1396 1396 Nie0 = jpi-nn_hls ; Nie1 = Nie0+1 ; Nie2 = MIN(jpi, Nie0+2) 1397 1397 Nje0 = jpj-nn_hls ; Nje1 = Nje0+1 ; Nje2 = MIN(jpj, Nje0+2) … … 1402 1402 Nie1nxt2 = Nie0 ; Nje1nxt2 = Nje0 1403 1403 ! 1404 ELSE !* larger halo size... 1404 ELSE !* larger halo size... 1405 1405 ! 1406 1406 Nis1nxt2 = Nis1 ; Njs1nxt2 = Njs1 … … 1417 1417 ! 1418 1418 END SUBROUTINE init_doloop 1419 1419 1420 1420 !!====================================================================== 1421 1421 END MODULE mppini -
NEMO/trunk/src/OCE/LDF/ldfc1d_c2d.F90
r13982 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE ldfc1d_c2d *** 4 !! Ocean physics: profile and horizontal shape of lateral eddy coefficients 4 !! Ocean physics: profile and horizontal shape of lateral eddy coefficients 5 5 !!===================================================================== 6 6 !! History : 3.7 ! 2013-12 (G. Madec) restructuration/simplification of aht/aeiv specification, … … 9 9 10 10 !!---------------------------------------------------------------------- 11 !! ldf_c1d : ah reduced by 1/4 on the vertical (tanh profile, inflection at 300m) 11 !! ldf_c1d : ah reduced by 1/4 on the vertical (tanh profile, inflection at 300m) 12 12 !! ldf_c2d : ah = F(e1,e2) (laplacian or = F(e1^3,e2^3) (bilaplacian) 13 13 !!---------------------------------------------------------------------- … … 29 29 REAL(wp) :: r1_4 = 0.25_wp ! =1/4 30 30 REAL(wp) :: r1_12 = 1._wp / 12._wp ! =1/12 31 31 32 32 !! * Substitutions 33 33 # include "do_loop_substitute.h90" … … 42 42 !!---------------------------------------------------------------------- 43 43 !! *** ROUTINE ldf_c1d *** 44 !! 44 !! 45 45 !! ** Purpose : 1D eddy diffusivity/viscosity coefficients 46 46 !! 47 47 !! ** Method : 1D eddy diffusivity coefficients F( depth ) 48 !! Reduction by zratio from surface to bottom 49 !! hyperbolic tangent profile with inflection point 48 !! Reduction by zratio from surface to bottom 49 !! hyperbolic tangent profile with inflection point 50 50 !! at zh=500m and a width of zw=200m 51 51 !! … … 95 95 END_3D 96 96 ! Lateral boundary conditions 97 CALL lbc_lnk_multi( 'ldfc1d_c2d', pah1, 'U', 1.0_wp , pah2, 'V', 1.0_wp ) 97 CALL lbc_lnk_multi( 'ldfc1d_c2d', pah1, 'U', 1.0_wp , pah2, 'V', 1.0_wp ) 98 98 ! 99 99 CASE DEFAULT ! error … … 107 107 !!---------------------------------------------------------------------- 108 108 !! *** ROUTINE ldf_c2d *** 109 !! 109 !! 110 110 !! ** Purpose : 2D eddy diffusivity/viscosity coefficients 111 111 !! … … 113 113 !! laplacian operator : ah proportional to the scale factor [m2/s] 114 114 !! bilaplacian operator : ah proportional to the (scale factor)^3 [m4/s] 115 !! In both cases, pah0 is the maximum value reached by the coefficient 115 !! In both cases, pah0 is the maximum value reached by the coefficient 116 116 !! at the Equator in case of e1=ra*rad= ~111km, not over the whole domain. 117 117 !! -
NEMO/trunk/src/OCE/LDF/ldftra.F90
r13982 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE ldftra *** 4 !! Ocean physics: lateral diffusivity coefficients 4 !! Ocean physics: lateral diffusivity coefficients 5 5 !!===================================================================== 6 6 !! History : ! 1997-07 (G. Madec) from inimix.F split in 2 routines 7 7 !! NEMO 1.0 ! 2002-09 (G. Madec) F90: Free form and module 8 !! 2.0 ! 2005-11 (G. Madec) 8 !! 2.0 ! 2005-11 (G. Madec) 9 9 !! 3.7 ! 2013-12 (F. Lemarie, G. Madec) restructuration/simplification of aht/aeiv specification, 10 10 !! ! add velocity dependent coefficient and optional read in file … … 13 13 !!---------------------------------------------------------------------- 14 14 !! ldf_tra_init : initialization, namelist read, and parameters control 15 !! ldf_tra : update lateral eddy diffusivity coefficients at each time step 16 !! ldf_eiv_init : initialization of the eiv coeff. from namelist choices 15 !! ldf_tra : update lateral eddy diffusivity coefficients at each time step 16 !! ldf_eiv_init : initialization of the eiv coeff. from namelist choices 17 17 !! ldf_eiv : time evolution of the eiv coefficients (function of the growth rate of baroclinic instability) 18 18 !! ldf_eiv_trp : add to the input ocean transport the contribution of the EIV parametrization … … 23 23 USE phycst ! physical constants 24 24 USE ldfslp ! lateral diffusion: slope of iso-neutral surfaces 25 USE ldfc1d_c2d ! lateral diffusion: 1D & 2D cases 25 USE ldfc1d_c2d ! lateral diffusion: 1D & 2D cases 26 26 USE diaptr 27 27 ! … … 40 40 PUBLIC ldf_eiv_trp ! called by traadv.F90 41 41 PUBLIC ldf_eiv_dia ! called by traldf_iso and traldf_iso_triad.F90 42 43 ! !!* Namelist namtra_ldf : lateral mixing on tracers * 42 43 ! !!* Namelist namtra_ldf : lateral mixing on tracers * 44 44 ! != Operator type =! 45 45 LOGICAL , PUBLIC :: ln_traldf_OFF !: no operator: No explicit diffusion … … 52 52 ! != iso-neutral options =! 53 53 ! LOGICAL , PUBLIC :: ln_traldf_triad !: griffies triad scheme (see ldfslp) 54 LOGICAL , PUBLIC :: ln_traldf_msc !: Method of Stabilizing Correction 54 LOGICAL , PUBLIC :: ln_traldf_msc !: Method of Stabilizing Correction 55 55 ! LOGICAL , PUBLIC :: ln_triad_iso !: pure horizontal mixing in ML (see ldfslp) 56 56 ! LOGICAL , PUBLIC :: ln_botmix_triad !: mixing on bottom (see ldfslp) … … 59 59 ! != Coefficients =! 60 60 INTEGER , PUBLIC :: nn_aht_ijk_t !: choice of time & space variations of the lateral eddy diffusivity coef. 61 ! ! time invariant coefficients: aht_0 = 1/2 Ud*Ld (lap case) 61 ! ! time invariant coefficients: aht_0 = 1/2 Ud*Ld (lap case) 62 62 ! ! bht_0 = 1/12 Ud*Ld^3 (blp case) 63 63 REAL(wp), PUBLIC :: rn_Ud !: lateral diffusive velocity [m/s] … … 72 72 REAL(wp), PUBLIC :: rn_Ue !: lateral diffusive velocity [m/s] 73 73 REAL(wp), PUBLIC :: rn_Le !: lateral diffusive length [m] 74 74 75 75 ! ! Flag to control the type of lateral diffusive operator 76 76 INTEGER, PARAMETER, PUBLIC :: np_ERROR =-10 ! error in specification of lateral diffusion … … 106 106 !!---------------------------------------------------------------------- 107 107 !! *** ROUTINE ldf_tra_init *** 108 !! 108 !! 109 109 !! ** Purpose : initializations of the tracer lateral mixing coeff. 110 110 !! … … 116 116 !! nn_aht_ijk_t = 0 => = constant 117 117 !! ! 118 !! = 10 => = F(z) : constant with a reduction of 1/4 with depth 118 !! = 10 => = F(z) : constant with a reduction of 1/4 with depth 119 119 !! ! 120 120 !! =-20 => = F(i,j) = shape read in 'eddy_diffusivity.nc' file … … 126 126 !! = 31 = F(i,j,k,t) = F(local velocity) ( 1/2 |u|e laplacian operator 127 127 !! or 1/12 |u|e^3 bilaplacian operator ) 128 !! * initialisation of the eddy induced velocity coefficient by a call to ldf_eiv_init 129 !! 128 !! * initialisation of the eddy induced velocity coefficient by a call to ldf_eiv_init 129 !! 130 130 !! ** action : ahtu, ahtv initialized one for all or l_ldftra_time set to true 131 131 !! aeiu, aeiv initialized one for all or l_ldfeiv_time set to true … … 148 148 WRITE(numout,*) '~~~~~~~~~~~~ ' 149 149 ENDIF 150 150 151 151 ! 152 152 ! Choice of lateral tracer physics … … 182 182 ! 183 183 ! 184 ! Operator and its acting direction (set nldf_tra) 184 ! Operator and its acting direction (set nldf_tra) 185 185 ! ================================= 186 186 ! … … 210 210 ENDIF 211 211 IF ( ln_zps ) THEN ! z-coordinate with partial step 212 IF ( ln_traldf_lev ) ierr = 1 ! iso-level not allowed 212 IF ( ln_traldf_lev ) ierr = 1 ! iso-level not allowed 213 213 IF ( ln_traldf_hor ) nldf_tra = np_lap ! horizontal (no rotation) 214 214 IF ( ln_traldf_iso ) nldf_tra = np_lap_i ! iso-neutral: standard (rotation) … … 231 231 ENDIF 232 232 IF ( ln_zps ) THEN ! z-coordinate with partial step 233 IF ( ln_traldf_lev ) ierr = 1 ! iso-level not allowed 233 IF ( ln_traldf_lev ) ierr = 1 ! iso-level not allowed 234 234 IF ( ln_traldf_hor ) nldf_tra = np_blp ! horizontal (no rotation) 235 235 IF ( ln_traldf_iso ) nldf_tra = np_blp_i ! iso-neutral: standard ( rotation) … … 249 249 ! 250 250 IF( nldf_tra == np_lap_i .OR. nldf_tra == np_lap_it .OR. & 251 & nldf_tra == np_blp_i .OR. nldf_tra == np_blp_it ) l_ldfslp = .TRUE. ! slope of neutral surfaces required 251 & nldf_tra == np_blp_i .OR. nldf_tra == np_blp_it ) l_ldfslp = .TRUE. ! slope of neutral surfaces required 252 252 ! 253 253 IF( ln_traldf_blp .AND. ( ln_traldf_iso .OR. ln_traldf_triad) ) THEN ! iso-neutral bilaplacian need MSC … … 270 270 271 271 ! 272 ! Space/time variation of eddy coefficients 272 ! Space/time variation of eddy coefficients 273 273 ! =========================================== 274 274 ! … … 286 286 IF( ierr /= 0 ) CALL ctl_stop( 'STOP', 'ldf_tra_init: failed to allocate arrays') 287 287 ! 288 ahtu(:,:,jpk) = 0._wp ! last level always 0 288 ahtu(:,:,jpk) = 0._wp ! last level always 0 289 289 ahtv(:,:,jpk) = 0._wp 290 290 !. … … 363 363 END SELECT 364 364 ! 365 IF( .NOT.l_ldftra_time ) THEN !* No time variation 365 IF( .NOT.l_ldftra_time ) THEN !* No time variation 366 366 IF( ln_traldf_lap ) THEN ! laplacian operator (mask only) 367 367 ahtu(:,:,1:jpkm1) = ahtu(:,:,1:jpkm1) * umask(:,:,1:jpkm1) … … 381 381 !!---------------------------------------------------------------------- 382 382 !! *** ROUTINE ldf_tra *** 383 !! 383 !! 384 384 !! ** Purpose : update at kt the tracer lateral mixing coeff. (aht and aeiv) 385 385 !! … … 395 395 !! * time varying EIV coefficients: call to ldf_eiv routine 396 396 !! 397 !! ** action : ahtu, ahtv update at each time step 398 !! aeiu, aeiv - - - - (if ln_ldfeiv=T) 397 !! ** action : ahtu, ahtv update at each time step 398 !! aeiu, aeiv - - - - (if ln_ldfeiv=T) 399 399 !!---------------------------------------------------------------------- 400 400 INTEGER, INTENT(in) :: kt ! time step … … 420 420 ahtu(:,:,1) = aeiu(:,:,1) 421 421 ahtv(:,:,1) = aeiv(:,:,1) 422 ELSE ! compute aht. 422 ELSE ! compute aht. 423 423 CALL ldf_eiv( kt, aht0, ahtu, ahtv, Kmm ) 424 424 ENDIF 425 425 ! 426 z1_f20 = 1._wp / ( 2._wp * omega * SIN( rad * 20._wp ) ) ! 1 / ff(20 degrees) 426 z1_f20 = 1._wp / ( 2._wp * omega * SIN( rad * 20._wp ) ) ! 1 / ff(20 degrees) 427 427 zaht_min = 0.2_wp * aht0 ! minimum value for aht 428 zDaht = aht0 - zaht_min 428 zDaht = aht0 - zaht_min 429 429 ! NOTE: [tiling-comms-merge] Change needed to preserve results with respect to the trunk 430 430 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) … … 480 480 !! nn_aei_ijk_t = 0 => = constant 481 481 !! ! 482 !! = 10 => = F(z) : constant with a reduction of 1/4 with depth 482 !! = 10 => = F(z) : constant with a reduction of 1/4 with depth 483 483 !! ! 484 484 !! =-20 => = F(i,j) = shape read in 'eddy_diffusivity.nc' file … … 547 547 ! != Specification of space-time variations of eaiu, aeiv 548 548 ! 549 aeiu(:,:,jpk) = 0._wp ! last level always 0 549 aeiu(:,:,jpk) = 0._wp ! last level always 0 550 550 aeiv(:,:,jpk) = 0._wp 551 551 ! ! value of EIV coef. (laplacian operator) … … 609 609 END SELECT 610 610 ! 611 IF( .NOT.l_ldfeiv_time ) THEN !* mask if No time variation 611 IF( .NOT.l_ldfeiv_time ) THEN !* mask if No time variation 612 612 DO jk = 1, jpkm1 613 613 aeiu(:,:,jk) = aeiu(:,:,jk) * umask(:,:,jk) … … 617 617 ! 618 618 ENDIF 619 ! 619 ! 620 620 END SUBROUTINE ldf_eiv_init 621 621 … … 649 649 IF( ln_traldf_triad ) THEN 650 650 DO_3D( 0, 0, 0, 0, 1, jpk ) 651 ! Take the max of N^2 and zero then take the vertical sum 652 ! of the square root of the resulting N^2 ( required to compute 653 ! internal Rossby radius Ro = .5 * sum_jpk(N) / f 651 ! Take the max of N^2 and zero then take the vertical sum 652 ! of the square root of the resulting N^2 ( required to compute 653 ! internal Rossby radius Ro = .5 * sum_jpk(N) / f 654 654 zn2 = MAX( rn2b(ji,jj,jk), 0._wp ) 655 655 zn(ji,jj) = zn(ji,jj) + SQRT( zn2 ) * e3w(ji,jj,jk,Kmm) 656 656 ! Compute elements required for the inverse time scale of baroclinic 657 ! eddies using the isopycnal slopes calculated in ldfslp.F : 657 ! eddies using the isopycnal slopes calculated in ldfslp.F : 658 658 ! T^-1 = sqrt(m_jpk(N^2*(r1^2+r2^2)*e3w)) 659 659 ze3w = e3w(ji,jj,jk,Kmm) * wmask(ji,jj,jk) … … 663 663 ELSE 664 664 DO_3D( 0, 0, 0, 0, 1, jpk ) 665 ! Take the max of N^2 and zero then take the vertical sum 666 ! of the square root of the resulting N^2 ( required to compute 667 ! internal Rossby radius Ro = .5 * sum_jpk(N) / f 665 ! Take the max of N^2 and zero then take the vertical sum 666 ! of the square root of the resulting N^2 ( required to compute 667 ! internal Rossby radius Ro = .5 * sum_jpk(N) / f 668 668 zn2 = MAX( rn2b(ji,jj,jk), 0._wp ) 669 669 zn(ji,jj) = zn(ji,jj) + SQRT( zn2 ) * e3w(ji,jj,jk,Kmm) 670 670 ! Compute elements required for the inverse time scale of baroclinic 671 ! eddies using the isopycnal slopes calculated in ldfslp.F : 671 ! eddies using the isopycnal slopes calculated in ldfslp.F : 672 672 ! T^-1 = sqrt(m_jpk(N^2*(r1^2+r2^2)*e3w)) 673 673 ze3w = e3w(ji,jj,jk,Kmm) * wmask(ji,jj,jk) … … 693 693 END_2D 694 694 CALL lbc_lnk( 'ldftra', zaeiw(:,:), 'W', 1.0_wp ) ! lateral boundary condition 695 ! 695 ! 696 696 DO_2D( 0, 0, 0, 0 ) !== aei at u- and v-points ==! 697 697 paeiu(ji,jj,1) = 0.5_wp * ( zaeiw(ji,jj) + zaeiw(ji+1,jj ) ) * umask(ji,jj,1) … … 704 704 paeiv(:,:,jk) = paeiv(:,:,1) * vmask(:,:,jk) 705 705 END DO 706 ! 706 ! 707 707 END SUBROUTINE ldf_eiv 708 708 … … 711 711 !!---------------------------------------------------------------------- 712 712 !! *** ROUTINE ldf_eiv_trp *** 713 !! 714 !! ** Purpose : add to the input ocean transport the contribution of 713 !! 714 !! ** Purpose : add to the input ocean transport the contribution of 715 715 !! the eddy induced velocity parametrization. 716 716 !! 717 717 !! ** Method : The eddy induced transport is computed from a flux stream- 718 718 !! function which depends on the slope of iso-neutral surfaces 719 !! (see ldf_slp). For example, in the i-k plan : 719 !! (see ldf_slp). For example, in the i-k plan : 720 720 !! psi_uw = mk(aeiu) e2u mi(wslpi) [in m3/s] 721 721 !! Utr_eiv = - dk[psi_uw] … … 748 748 ENDIF 749 749 750 750 751 751 zpsi_uw(:,:, 1 ) = 0._wp ; zpsi_vw(:,:, 1 ) = 0._wp 752 752 zpsi_uw(:,:,jpk) = 0._wp ; zpsi_vw(:,:,jpk) = 0._wp … … 794 794 ! 795 795 !!gm I don't like this routine.... Crazy way of doing things, not optimal at all... 796 !!gm to be redesigned.... 796 !!gm to be redesigned.... 797 797 ! !== eiv stream function: output ==! 798 798 !!gm CALL iom_put( "psi_eiv_uw", psi_uw ) ! output … … 826 826 zw3d(:,:,jk) = zw3d(:,:,jk) * zw2d(:,:) 827 827 END DO 828 CALL iom_put( "weiv_masstr" , zw3d ) 828 CALL iom_put( "weiv_masstr" , zw3d ) 829 829 ENDIF 830 830 ! … … 832 832 zw3d(:,:,:) = 0.e0 833 833 DO jk = 1, jpkm1 834 zw3d(:,:,jk) = rho0 * ( psi_uw(:,:,jk+1) - psi_uw(:,:,jk) ) 834 zw3d(:,:,jk) = rho0 * ( psi_uw(:,:,jk+1) - psi_uw(:,:,jk) ) 835 835 END DO 836 836 CALL iom_put( "ueiv_masstr", zw3d ) ! mass transport in i-direction 837 837 ENDIF 838 838 ! 839 zztmp = 0.5_wp * rho0 * rcp 839 zztmp = 0.5_wp * rho0 * rcp 840 840 IF( iom_use('ueiv_heattr') .OR. iom_use('ueiv_heattr3d') ) THEN 841 zw2d(:,:) = 0._wp 842 zw3d(:,:,:) = 0._wp 841 zw2d(:,:) = 0._wp 842 zw3d(:,:,:) = 0._wp 843 843 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) 844 844 zw3d(ji,jj,jk) = zw3d(ji,jj,jk) + ( psi_uw(ji,jj,jk+1) - psi_uw(ji ,jj,jk) ) & 845 & * ( ts (ji,jj,jk,jp_tem,Kmm) + ts (ji+1,jj,jk,jp_tem,Kmm) ) 845 & * ( ts (ji,jj,jk,jp_tem,Kmm) + ts (ji+1,jj,jk,jp_tem,Kmm) ) 846 846 zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk) 847 847 END_3D … … 853 853 zw3d(:,:,:) = 0.e0 854 854 DO jk = 1, jpkm1 855 zw3d(:,:,jk) = rho0 * ( psi_vw(:,:,jk+1) - psi_vw(:,:,jk) ) 855 zw3d(:,:,jk) = rho0 * ( psi_vw(:,:,jk+1) - psi_vw(:,:,jk) ) 856 856 END DO 857 857 CALL iom_put( "veiv_masstr", zw3d ) ! mass transport in i-direction 858 858 ENDIF 859 859 ! 860 zw2d(:,:) = 0._wp 861 zw3d(:,:,:) = 0._wp 860 zw2d(:,:) = 0._wp 861 zw3d(:,:,:) = 0._wp 862 862 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) 863 863 zw3d(ji,jj,jk) = zw3d(ji,jj,jk) + ( psi_vw(ji,jj,jk+1) - psi_vw(ji,jj ,jk) ) & 864 & * ( ts (ji,jj,jk,jp_tem,Kmm) + ts (ji,jj+1,jk,jp_tem,Kmm) ) 864 & * ( ts (ji,jj,jk,jp_tem,Kmm) + ts (ji,jj+1,jk,jp_tem,Kmm) ) 865 865 zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk) 866 866 END_3D … … 872 872 zztmp = 0.5_wp * 0.5 873 873 IF( iom_use('ueiv_salttr') .OR. iom_use('ueiv_salttr3d')) THEN 874 zw2d(:,:) = 0._wp 875 zw3d(:,:,:) = 0._wp 874 zw2d(:,:) = 0._wp 875 zw3d(:,:,:) = 0._wp 876 876 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) 877 877 zw3d(ji,jj,jk) = zw3d(ji,jj,jk) * ( psi_uw(ji,jj,jk+1) - psi_uw(ji ,jj,jk) ) & 878 & * ( ts (ji,jj,jk,jp_sal,Kmm) + ts (ji+1,jj,jk,jp_sal,Kmm) ) 878 & * ( ts (ji,jj,jk,jp_sal,Kmm) + ts (ji+1,jj,jk,jp_sal,Kmm) ) 879 879 zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk) 880 880 END_3D … … 882 882 CALL iom_put( "ueiv_salttr3d", zztmp * zw3d ) ! salt transport in i-direction 883 883 ENDIF 884 zw2d(:,:) = 0._wp 885 zw3d(:,:,:) = 0._wp 884 zw2d(:,:) = 0._wp 885 zw3d(:,:,:) = 0._wp 886 886 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) 887 887 zw3d(ji,jj,jk) = zw3d(ji,jj,jk) + ( psi_vw(ji,jj,jk+1) - psi_vw(ji,jj ,jk) ) & 888 & * ( ts (ji,jj,jk,jp_sal,Kmm) + ts (ji,jj+1,jk,jp_sal,Kmm) ) 888 & * ( ts (ji,jj,jk,jp_sal,Kmm) + ts (ji,jj+1,jk,jp_sal,Kmm) ) 889 889 zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk) 890 890 END_3D -
NEMO/trunk/src/OCE/SBC/cpl_oasis3.F90
r14007 r14072 14 14 !! 3.6 ! 2014-11 (S. Masson) OASIS3-MCT 15 15 !!---------------------------------------------------------------------- 16 16 17 17 !!---------------------------------------------------------------------- 18 18 !! 'key_oasis3' coupled Ocean/Atmosphere via OASIS3-MCT … … 63 63 #endif 64 64 65 INTEGER :: nrcv ! total number of fields received 66 INTEGER :: nsnd ! total number of fields sent 65 INTEGER :: nrcv ! total number of fields received 66 INTEGER :: nsnd ! total number of fields sent 67 67 INTEGER :: ncplmodel ! Maximum number of models to/from which NEMO is potentialy sending/receiving data 68 68 INTEGER, PUBLIC, PARAMETER :: nmaxfld=62 ! Maximum number of coupling fields 69 69 INTEGER, PUBLIC, PARAMETER :: nmaxcat=5 ! Maximum number of coupling fields 70 70 INTEGER, PUBLIC, PARAMETER :: nmaxcpl=5 ! Maximum number of coupling fields 71 71 72 72 TYPE, PUBLIC :: FLD_CPL !: Type for coupling field information 73 73 LOGICAL :: laction ! To be coupled or not 74 CHARACTER(len = 8) :: clname ! Name of the coupling field 75 CHARACTER(len = 1) :: clgrid ! Grid type 74 CHARACTER(len = 8) :: clname ! Name of the coupling field 75 CHARACTER(len = 1) :: clgrid ! Grid type 76 76 REAL(wp) :: nsgn ! Control of the sign change 77 77 INTEGER, DIMENSION(nmaxcat,nmaxcpl) :: nid ! Id of the field (no more than 9 categories and 9 extrena models) … … 98 98 !! exchange between AGCM, OGCM and COUPLER. (OASIS3 software) 99 99 !! 100 !! ** Method : OASIS3 MPI communication 100 !! ** Method : OASIS3 MPI communication 101 101 !!-------------------------------------------------------------------- 102 102 CHARACTER(len = *), INTENT(in ) :: cd_modname ! model name as set in namcouple file … … 132 132 !! exchange between AGCM, OGCM and COUPLER. (OASIS3 software) 133 133 !! 134 !! ** Method : OASIS3 MPI communication 134 !! ** Method : OASIS3 MPI communication 135 135 !!-------------------------------------------------------------------- 136 136 INTEGER, INTENT(in) :: krcv, ksnd ! Number of received and sent coupling fields … … 180 180 ! 181 181 ! ----------------------------------------------------------------- 182 ! ... Define the partition, excluding halos as we don't want them to be "seen" by oasis 182 ! ... Define the partition, excluding halos as we don't want them to be "seen" by oasis 183 183 ! ----------------------------------------------------------------- 184 184 185 185 paral(1) = 2 ! box partitioning 186 paral(2) = Ni0glo * mjg0(nn_hls) + mig0(nn_hls) ! NEMO lower left corner global offset, without halos 186 paral(2) = Ni0glo * mjg0(nn_hls) + mig0(nn_hls) ! NEMO lower left corner global offset, without halos 187 187 paral(3) = Ni_0 ! local extent in i, excluding halos 188 188 paral(4) = Nj_0 ! local extent in j, excluding halos 189 189 paral(5) = Ni0glo ! global extent in x, excluding halos 190 190 191 191 IF( sn_cfctl%l_oasout ) THEN 192 192 WRITE(numout,*) ' multiexchg: paral (1:5)', paral … … 195 195 WRITE(numout,*) ' multiexchg: Njs0, Nje0, njmpp =', Njs0, Nje0, njmpp 196 196 ENDIF 197 197 198 198 CALL oasis_def_partition ( id_part, paral, nerror, Ni0glo*Nj0glo ) ! global number of points, excluding halos 199 199 ! 200 ! ... Announce send variables. 200 ! ... Announce send variables. 201 201 ! 202 202 ssnd(:)%ncplmodel = kcplmodel … … 210 210 RETURN 211 211 ENDIF 212 212 213 213 DO jc = 1, ssnd(ji)%nct 214 214 DO jm = 1, kcplmodel … … 225 225 ENDIF 226 226 #if defined key_agrif 227 IF( agrif_fixed() /= 0 ) THEN 227 IF( agrif_fixed() /= 0 ) THEN 228 228 zclname=TRIM(Agrif_CFixed())//'_'//TRIM(zclname) 229 229 ENDIF … … 243 243 END DO 244 244 ! 245 ! ... Announce received variables. 245 ! ... Announce received variables. 246 246 ! 247 247 srcv(:)%ncplmodel = kcplmodel 248 248 ! 249 249 DO ji = 1, krcv 250 IF( srcv(ji)%laction ) THEN 251 250 IF( srcv(ji)%laction ) THEN 251 252 252 IF( srcv(ji)%nct > nmaxcat ) THEN 253 253 CALL oasis_abort ( ncomp_id, 'cpl_define', 'Number of categories of '// & … … 255 255 RETURN 256 256 ENDIF 257 257 258 258 DO jc = 1, srcv(ji)%nct 259 259 DO jm = 1, kcplmodel 260 260 261 261 IF( srcv(ji)%nct .GT. 1 ) THEN 262 262 WRITE(cli2,'(i2.2)') jc … … 270 270 ENDIF 271 271 #if defined key_agrif 272 IF( agrif_fixed() /= 0 ) THEN 272 IF( agrif_fixed() /= 0 ) THEN 273 273 zclname=TRIM(Agrif_CFixed())//'_'//TRIM(zclname) 274 274 ENDIF … … 288 288 ENDIF 289 289 END DO 290 290 291 291 !------------------------------------------------------------------ 292 292 ! End of definition phase 293 293 !------------------------------------------------------------------ 294 ! 294 ! 295 295 #if defined key_agrif 296 296 IF( agrif_fixed() == Agrif_Nb_Fine_Grids() ) THEN … … 303 303 ! 304 304 END SUBROUTINE cpl_define 305 306 305 306 307 307 SUBROUTINE cpl_snd( kid, kstep, pdata, kinfo ) 308 308 !!--------------------------------------------------------------------- … … 324 324 DO jc = 1, ssnd(kid)%nct 325 325 DO jm = 1, ssnd(kid)%ncplmodel 326 326 327 327 IF( ssnd(kid)%nid(jc,jm) /= -1 ) THEN ! exclude halos from data sent to oasis 328 328 CALL oasis_put ( ssnd(kid)%nid(jc,jm), kstep, pdata(Nis0:Nie0, Njs0:Nje0,jc), kinfo ) 329 330 IF ( sn_cfctl%l_oasout ) THEN 329 330 IF ( sn_cfctl%l_oasout ) THEN 331 331 IF ( kinfo == OASIS_Sent .OR. kinfo == OASIS_ToRest .OR. & 332 332 & kinfo == OASIS_SentOut .OR. kinfo == OASIS_ToRestOut ) THEN … … 342 342 ENDIF 343 343 ENDIF 344 344 345 345 ENDIF 346 346 347 347 ENDDO 348 348 ENDDO … … 379 379 IF( srcv(kid)%nid(jc,jm) /= -1 ) THEN 380 380 381 CALL oasis_get ( srcv(kid)%nid(jc,jm), kstep, exfld, kinfo ) 382 381 CALL oasis_get ( srcv(kid)%nid(jc,jm), kstep, exfld, kinfo ) 382 383 383 llaction = kinfo == OASIS_Recvd .OR. kinfo == OASIS_FromRest .OR. & 384 384 & kinfo == OASIS_RecvOut .OR. kinfo == OASIS_FromRestOut 385 385 386 386 IF ( sn_cfctl%l_oasout ) & 387 387 & WRITE(numout,*) "llaction, kinfo, kstep, ivarid: " , llaction, kinfo, kstep, srcv(kid)%nid(jc,jm) 388 388 389 389 IF( llaction ) THEN ! data received from oasis do not include halos 390 390 391 391 kinfo = OASIS_Rcv 392 IF( ll_1st ) THEN 392 IF( ll_1st ) THEN 393 393 pdata(Nis0:Nie0,Njs0:Nje0,jc) = exfld(:,:) * pmask(Nis0:Nie0,Njs0:Nje0,jm) 394 394 ll_1st = .FALSE. … … 397 397 & + exfld(:,:) * pmask(Nis0:Nie0,Njs0:Nje0,jm) 398 398 ENDIF 399 400 IF ( sn_cfctl%l_oasout ) THEN 399 400 IF ( sn_cfctl%l_oasout ) THEN 401 401 WRITE(numout,*) '****************' 402 402 WRITE(numout,*) 'oasis_get: Incoming ', srcv(kid)%clname … … 409 409 WRITE(numout,*) '****************' 410 410 ENDIF 411 411 412 412 ENDIF 413 413 414 414 ENDIF 415 415 416 416 ENDDO 417 417 418 418 !--- we must call lbc_lnk to fill the halos that where not received. 419 419 IF( .NOT. ll_1st ) THEN 420 CALL lbc_lnk( 'cpl_oasis3', pdata(:,:,jc), srcv(kid)%clgrid, srcv(kid)%nsgn ) 420 CALL lbc_lnk( 'cpl_oasis3', pdata(:,:,jc), srcv(kid)%clgrid, srcv(kid)%nsgn ) 421 421 ENDIF 422 422 423 423 ENDDO 424 424 ! … … 426 426 427 427 428 INTEGER FUNCTION cpl_freq( cdfieldname ) 428 INTEGER FUNCTION cpl_freq( cdfieldname ) 429 429 !!--------------------------------------------------------------------- 430 430 !! *** ROUTINE cpl_freq *** … … 491 491 DEALLOCATE( exfld ) 492 492 IF(nstop == 0) THEN 493 CALL oasis_terminate( nerror ) 493 CALL oasis_terminate( nerror ) 494 494 ELSE 495 495 CALL oasis_abort( ncomp_id, "cpl_finalize", "NEMO ABORT STOP" ) 496 ENDIF 496 ENDIF 497 497 ! 498 498 END SUBROUTINE cpl_finalize … … 544 544 WRITE(numout,*) 'oasis_enddef: Error you sould not be there...' 545 545 END SUBROUTINE oasis_enddef 546 546 547 547 SUBROUTINE oasis_put(k1,k2,p1,k3) 548 548 REAL(wp), DIMENSION(:,:), INTENT(in ) :: p1 … … 574 574 WRITE(numout,*) 'oasis_terminate: Error you sould not be there...' 575 575 END SUBROUTINE oasis_terminate 576 576 577 577 #endif 578 578 -
NEMO/trunk/src/OCE/SBC/sbc_ice.F90
r13472 r14072 20 20 # endif 21 21 # if defined key_cice 22 USE ice_domain_size, only: ncat 22 USE ice_domain_size, only: ncat 23 23 #endif 24 24 USE lib_mpp ! MPP library … … 32 32 # if defined key_si3 33 33 LOGICAL , PUBLIC, PARAMETER :: lk_si3 = .TRUE. !: SI3 ice model 34 LOGICAL , PUBLIC, PARAMETER :: lk_cice = .FALSE. !: no CICE 34 LOGICAL , PUBLIC, PARAMETER :: lk_cice = .FALSE. !: no CICE 35 35 # endif 36 36 # if defined key_cice … … 47 47 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: alb_ice !: ice albedo [-] 48 48 49 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qml_ice !: heat available for snow / ice surface melting [W/m2] 50 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qcn_ice !: heat conduction flux in the layer below surface [W/m2] 49 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qml_ice !: heat available for snow / ice surface melting [W/m2] 50 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qcn_ice !: heat conduction flux in the layer below surface [W/m2] 51 51 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qtr_ice_top !: solar flux transmitted below the ice surface [W/m2] 52 52 … … 87 87 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: fr_iu !: ice fraction at NEMO U point 88 88 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: fr_iv !: ice fraction at NEMO V point 89 89 90 90 ! variables used in the coupled interface 91 91 INTEGER , PUBLIC, PARAMETER :: jpl = ncat 92 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: u_ice, v_ice 93 92 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: u_ice, v_ice 93 94 94 ! already defined in ice.F90 for SI3 95 95 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: a_i … … 98 98 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: tatm_ice !: air temperature [K] 99 99 #endif 100 101 REAL(wp), PUBLIC, SAVE :: pp_cldf = 0.81 !: cloud fraction over sea ice, summer CLIO value [-]102 100 103 101 !! arrays relating to embedding ice in the ocean … … 108 106 !!---------------------------------------------------------------------- 109 107 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 110 !! $Id$ 108 !! $Id$ 111 109 !! Software governed by the CeCILL license (see ./LICENSE) 112 110 !!---------------------------------------------------------------------- … … 145 143 & v_ice(jpi,jpj) , alb_ice(jpi,jpj,1) , & 146 144 & emp_ice(jpi,jpj) , qns_ice(jpi,jpj,1) , dqns_ice(jpi,jpj,1) , & 147 & STAT= ierr(3) ) 145 & STAT= ierr(3) ) 148 146 IF( ln_cpl ) ALLOCATE( h_i(jpi,jpj,jpl) , h_s(jpi,jpj,jpl) , STAT=ierr(4) ) 149 147 #endif … … 168 166 LOGICAL , PUBLIC, PARAMETER :: lk_si3 = .FALSE. !: no SI3 ice model 169 167 LOGICAL , PUBLIC, PARAMETER :: lk_cice = .FALSE. !: no CICE ice model 170 REAL(wp) , PUBLIC, PARAMETER :: pp_cldf = 0.81 !: cloud fraction over sea ice, summer CLIO value [-] 171 INTEGER , PUBLIC, PARAMETER :: jpl = 1 168 169 INTEGER , PUBLIC, PARAMETER :: jpl = 1 172 170 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: u_ice, v_ice ! jpi, jpj 173 171 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: tn_ice, alb_ice, qns_ice, dqns_ice ! (jpi,jpj,jpl) … … 178 176 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: topmelt, botmelt 179 177 ! 180 !! arrays related to embedding ice in the ocean. 181 !! These arrays need to be declared even if no ice model is required. 178 !! arrays related to embedding ice in the ocean. 179 !! These arrays need to be declared even if no ice model is required. 182 180 !! In the no ice model or traditional levitating ice cases they contain only zeros 183 181 !! --------------------- -
NEMO/trunk/src/OCE/SBC/sbc_oce.F90
r14007 r14072 73 73 LOGICAL , PUBLIC :: ln_charn !: =T Chranock coefficient from wave model 74 74 LOGICAL , PUBLIC :: ln_taw !: =T wind stress corrected by wave intake 75 LOGICAL , PUBLIC :: ln_phioc !: =T TKE surface BC from wave model 75 LOGICAL , PUBLIC :: ln_phioc !: =T TKE surface BC from wave model 76 76 LOGICAL , PUBLIC :: ln_bern_srfc !: Bernoulli head, waves' inuced pressure 77 77 LOGICAL , PUBLIC :: ln_breivikFV_2016 !: Breivik 2016 profile … … 153 153 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: frq_m !: mean (nn_fsbc time-step) fraction of solar net radiation absorbed in the 1st T level [-] 154 154 155 !!---------------------------------------------------------------------- 156 !! Surface atmospheric fields 157 !!---------------------------------------------------------------------- 158 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: q_air_zt !: specific humidity of air at z=zt [kg/kg]ww 159 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: theta_air_zt !: potential temperature of air at z=zt [K] 160 161 155 162 !! * Substitutions 156 163 # include "do_loop_substitute.h90" … … 166 173 !! *** FUNCTION sbc_oce_alloc *** 167 174 !!--------------------------------------------------------------------- 168 INTEGER :: ierr( 5)175 INTEGER :: ierr(6) 169 176 !!--------------------------------------------------------------------- 170 177 ierr(:) = 0 … … 188 195 ! 189 196 ALLOCATE( e3t_m(jpi,jpj) , STAT=ierr(5) ) 197 ! 198 ALLOCATE( q_air_zt(jpi,jpj) , theta_air_zt(jpi,jpj) , STAT=ierr(6) ) !#LB 190 199 ! 191 200 sbc_oce_alloc = MAXVAL( ierr ) -
NEMO/trunk/src/OCE/SBC/sbcapr.F90
r14053 r14072 6 6 !! History : 3.3 ! 2010-09 (J. Chanut, C. Bricaud, G. Madec) Original code 7 7 !!---------------------------------------------------------------------- 8 8 9 9 !!---------------------------------------------------------------------- 10 !! sbc_apr : read atmospheric pressure in netcdf files 10 !! sbc_apr : read atmospheric pressure in netcdf files 11 11 !!---------------------------------------------------------------------- 12 12 USE dom_oce ! ocean space and time domain … … 25 25 PUBLIC sbc_apr ! routine called in sbcmod 26 26 PUBLIC sbc_apr_init ! routine called in sbcmod 27 27 28 28 ! !!* namsbc_apr namelist (Atmospheric PRessure) * 29 LOGICAL, PUBLIC :: ln_apr_obc = .false. !: inverse barometer added to OBC ssh data 29 LOGICAL, PUBLIC :: ln_apr_obc = .false. !: inverse barometer added to OBC ssh data 30 30 LOGICAL, PUBLIC :: ln_ref_apr !: ref. pressure: global mean Patm (F) or a constant (F) 31 31 REAL(wp) :: rn_pref ! reference atmospheric pressure [N/m2] … … 34 34 REAL(wp), ALLOCATABLE, SAVE, PUBLIC, DIMENSION(:,:) :: ssh_ibb ! Inverse barometer before sea surface height [m] 35 35 REAL(wp), ALLOCATABLE, SAVE, PUBLIC, DIMENSION(:,:) :: apr ! atmospheric pressure at kt [N/m2] 36 36 37 37 REAL(wp) :: tarea ! whole domain mean masked ocean surface 38 38 REAL(wp) :: r1_grau ! = 1.e0 / (grav * rho0) 39 39 40 40 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_apr ! structure of input fields (file informations, fields read) 41 41 … … 54 54 !! 55 55 !! ** Method : - Read namelist namsbc_apr 56 !! - Read Patm fields in netcdf files 56 !! - Read Patm fields in netcdf files 57 57 !! - Compute reference atmospheric pressure 58 58 !! - Compute inverse barometer ssh … … 60 60 !! ssh_ib : inverse barometer ssh at kt 61 61 !!--------------------------------------------------------------------- 62 INTEGER :: ierror ! local integer 62 INTEGER :: ierror ! local integer 63 63 INTEGER :: ios ! Local integer output status for namelist read 64 64 !! … … 103 103 IF(lwp) WRITE(numout,*) ' Inverse barometer added to OBC ssh data' 104 104 ENDIF 105 !jc: stop below should rather be a warning 105 !jc: stop below should rather be a warning 106 106 IF( ln_apr_obc .AND. .NOT.ln_apr_dyn ) & 107 107 CALL ctl_warn( 'sbc_apr: use inverse barometer ssh at open boundary ONLY requires ln_apr_dyn=T' ) … … 116 116 !! 117 117 !! ** Method : - Read namelist namsbc_apr 118 !! - Read Patm fields in netcdf files 118 !! - Read Patm fields in netcdf files 119 119 !! - Compute reference atmospheric pressure 120 120 !! - Compute inverse barometer ssh … … 148 148 ! ! ---------------------------------------- ! 149 149 ! !* Restart: read in restart file 150 IF( ln_rstart .AND. .NOT.l_1st_euler ) THEN 150 IF( ln_rstart .AND. .NOT.l_1st_euler ) THEN 151 151 IF(lwp) WRITE(numout,*) 'sbc_apr: ssh_ibb read in the restart file' 152 152 CALL iom_get( numror, jpdom_auto, 'ssh_ibb', ssh_ibb ) ! before inv. barometer ssh … … 167 167 ! 168 168 END SUBROUTINE sbc_apr 169 169 170 170 !!====================================================================== 171 171 END MODULE sbcapr -
NEMO/trunk/src/OCE/SBC/sbcblk.F90
r14007 r14072 19 19 !! 4.0 ! 2016-10 (M. Vancoppenolle) Introduce conduction flux emulator (M. Vancoppenolle) 20 20 !! 4.0 ! 2019-03 (F. Lemarié & G. Samson) add ABL compatibility (ln_abl=TRUE) 21 !! 4.2 ! 2020-12 (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 21 22 !!---------------------------------------------------------------------- 22 23 … … 30 31 !! blk_ice_2 : provide the heat and mass fluxes at air-ice interface 31 32 !! blk_ice_qcn : provide ice surface temperature and snow/ice conduction flux (emulating conduction flux) 32 !! Cdn10_Lupkes2012 : Lupkes et al. (2012) air-ice drag33 !! Cdn10_Lupkes2015 : Lupkes et al. (2015) air-ice drag34 33 !!---------------------------------------------------------------------- 35 34 USE oce ! ocean dynamics and tracers … … 41 40 USE sbcdcy ! surface boundary condition: diurnal cycle 42 41 USE sbcwave , ONLY : cdn_wave ! wave module 43 USE sbc_ice ! Surface boundary condition: ice fields44 42 USE lib_fortran ! to use key_nosignedzero 43 ! 45 44 #if defined key_si3 45 USE sbc_ice ! Surface boundary condition: ice fields #LB? ok to be in 'key_si3' ??? 46 46 USE ice , ONLY : u_ice, v_ice, jpl, a_i_b, at_i_b, t_su, rn_cnd_s, hfx_err_dif, nn_qtrice 47 47 USE icevar ! for CALL ice_var_snwblow 48 #endif 49 USE sbcblk_algo_ncar ! => turb_ncar : NCAR - CORE (Large & Yeager, 2009) 48 USE sbcblk_algo_ice_an05 49 USE sbcblk_algo_ice_lu12 50 USE sbcblk_algo_ice_lg15 51 #endif 52 USE sbcblk_algo_ncar ! => turb_ncar : NCAR - (formerly known as CORE, Large & Yeager, 2009) 50 53 USE sbcblk_algo_coare3p0 ! => turb_coare3p0 : COAREv3.0 (Fairall et al. 2003) 51 54 USE sbcblk_algo_coare3p6 ! => turb_coare3p6 : COAREv3.6 (Fairall et al. 2018 + Edson et al. 2013) 52 55 USE sbcblk_algo_ecmwf ! => turb_ecmwf : ECMWF (IFS cycle 45r1) 56 USE sbcblk_algo_andreas ! => turb_andreas : Andreas et al. 2015 53 57 ! 54 58 USE iom ! I/O manager library … … 58 62 USE prtctl ! Print control 59 63 60 USE sbcblk_phy ! a catalog of functions for physical/meteorological parameters in the marine boundary layer, rho_air, q_sat, etc... 61 64 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 62 65 63 66 IMPLICIT NONE … … 100 103 LOGICAL :: ln_COARE_3p6 ! "COARE 3.6" algorithm (Edson et al. 2013) 101 104 LOGICAL :: ln_ECMWF ! "ECMWF" algorithm (IFS cycle 45r1) 105 LOGICAL :: ln_ANDREAS ! "ANDREAS" algorithm (Andreas et al. 2015) 102 106 ! 103 LOGICAL :: ln_Cd_L12 ! ice-atm drag = F( ice concentration ) (Lupkes et al. JGR2012) 104 LOGICAL :: ln_Cd_L15 ! ice-atm drag = F( ice concentration, atmospheric stability ) (Lupkes et al. JGR2015) 107 !#LB: 108 LOGICAL :: ln_Cx_ice_cst ! use constant air-ice bulk transfer coefficients (value given in namelist's rn_Cd_i, rn_Ce_i & rn_Ch_i) 109 REAL(wp) :: rn_Cd_i, rn_Ce_i, rn_Ch_i ! values for " " 110 LOGICAL :: ln_Cx_ice_AN05 ! air-ice bulk transfer coefficients based on Andreas et al., 2005 111 LOGICAL :: ln_Cx_ice_LU12 ! air-ice bulk transfer coefficients based on Lupkes et al., 2012 112 LOGICAL :: ln_Cx_ice_LG15 ! air-ice bulk transfer coefficients based on Lupkes & Gryanik, 2015 113 !#LB. 105 114 ! 106 115 LOGICAL :: ln_crt_fbk ! Add surface current feedback to the wind stress computation (Renault et al. 2020) 107 116 REAL(wp) :: rn_stau_a ! Alpha and Beta coefficients of Renault et al. 2020, eq. 10: Stau = Alpha * Wnd + Beta 108 REAL(wp) :: rn_stau_b ! 117 REAL(wp) :: rn_stau_b ! 109 118 ! 110 119 REAL(wp) :: rn_pfac ! multiplication factor for precipitation … … 113 122 REAL(wp) :: rn_zu ! z(u) : height of wind measurements 114 123 ! 115 REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:) :: Cdn_oce, Chn_oce, Cen_oce ! neutral coeffs over ocean (L15 bulk scheme and ABL) 116 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: Cd_ice , Ch_ice , Ce_ice ! transfert coefficients over ice 117 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: t_zu, q_zu ! air temp. and spec. hum. at wind speed height (L15 bulk scheme) 124 INTEGER :: nn_iter_algo ! Number of iterations in bulk param. algo ("stable ABL + weak wind" requires more) 125 126 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: theta_zu, q_zu ! air temp. and spec. hum. at wind speed height (L15 bulk scheme) 127 128 #if defined key_si3 129 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: Cd_ice , Ch_ice , Ce_ice !#LB transfert coefficients over ice 130 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: theta_zu_i, q_zu_i !#LB fixme ! air temp. and spec. hum. over ice at wind speed height (L15 bulk scheme) 131 #endif 132 118 133 119 134 LOGICAL :: ln_skin_cs ! use the cool-skin (only available in ECMWF and COARE algorithms) !LB … … 122 137 LOGICAL :: ln_humi_dpt ! humidity read in files ("sn_humi") is dew-point temperature [K] if .true. !LB 123 138 LOGICAL :: ln_humi_rlh ! humidity read in files ("sn_humi") is relative humidity [%] if .true. !LB 124 LOGICAL :: ln_t pot !!GS: flag to compute or not potential temperature139 LOGICAL :: ln_tair_pot ! temperature read in files ("sn_tair") is already potential temperature (not absolute) 125 140 ! 126 141 INTEGER :: nhumi ! choice of the bulk algorithm … … 136 151 INTEGER, PARAMETER :: np_COARE_3p6 = 3 ! "COARE 3.6" algorithm (Edson et al. 2013) 137 152 INTEGER, PARAMETER :: np_ECMWF = 4 ! "ECMWF" algorithm (IFS cycle 45r1) 153 INTEGER, PARAMETER :: np_ANDREAS = 5 ! "ANDREAS" algorithm (Andreas et al. 2015) 154 155 !#LB: 156 #if defined key_si3 157 ! Same, over sea-ice: 158 INTEGER :: nblk_ice ! choice of the bulk algorithm 159 ! ! associated indices: 160 INTEGER, PARAMETER :: np_ice_cst = 1 ! constant transfer coefficients 161 INTEGER, PARAMETER :: np_ice_an05 = 2 ! Andreas et al., 2005 162 INTEGER, PARAMETER :: np_ice_lu12 = 3 ! Lupkes el al., 2012 163 INTEGER, PARAMETER :: np_ice_lg15 = 4 ! Lupkes & Gryanik, 2015 164 #endif 165 !LB. 166 167 138 168 139 169 !! * Substitutions … … 150 180 !! *** ROUTINE sbc_blk_alloc *** 151 181 !!------------------------------------------------------------------- 152 ALLOCATE( t_zu(jpi,jpj) , q_zu(jpi,jpj) , & 153 & Cdn_oce(jpi,jpj), Chn_oce(jpi,jpj), Cen_oce(jpi,jpj), & 154 & Cd_ice (jpi,jpj), Ch_ice (jpi,jpj), Ce_ice (jpi,jpj), STAT=sbc_blk_alloc ) 155 ! 182 ALLOCATE( theta_zu(jpi,jpj), q_zu(jpi,jpj), STAT=sbc_blk_alloc ) 156 183 CALL mpp_sum ( 'sbcblk', sbc_blk_alloc ) 157 184 IF( sbc_blk_alloc /= 0 ) CALL ctl_stop( 'STOP', 'sbc_blk_alloc: failed to allocate arrays' ) 158 185 END FUNCTION sbc_blk_alloc 186 187 #if defined key_si3 188 INTEGER FUNCTION sbc_blk_ice_alloc() 189 !!------------------------------------------------------------------- 190 !! *** ROUTINE sbc_blk_ice_alloc *** 191 !!------------------------------------------------------------------- 192 ALLOCATE( Cd_ice (jpi,jpj), Ch_ice (jpi,jpj), Ce_ice (jpi,jpj), & 193 & theta_zu_i(jpi,jpj), q_zu_i(jpi,jpj), STAT=sbc_blk_ice_alloc ) 194 CALL mpp_sum ( 'sbcblk', sbc_blk_ice_alloc ) 195 IF( sbc_blk_ice_alloc /= 0 ) CALL ctl_stop( 'STOP', 'sbc_blk_ice_alloc: failed to allocate arrays' ) 196 END FUNCTION sbc_blk_ice_alloc 197 #endif 159 198 160 199 … … 178 217 TYPE(FLD_N) :: sn_cc, sn_hpgi, sn_hpgj ! " " 179 218 INTEGER :: ipka ! number of levels in the atmospheric variable 180 NAMELIST/namsbc_blk/ sn_wndi, sn_wndj, sn_humi, sn_qsr, sn_qlw , & ! input fields 181 & sn_tair, sn_prec, sn_snow, sn_slp, sn_uoatm, sn_voatm, & 182 & sn_cc, sn_hpgi, sn_hpgj, & 183 & ln_NCAR, ln_COARE_3p0, ln_COARE_3p6, ln_ECMWF, & ! bulk algorithm 184 & cn_dir , rn_zqt, rn_zu, & 185 & rn_pfac, rn_efac, ln_Cd_L12, ln_Cd_L15, ln_tpot, & 219 NAMELIST/namsbc_blk/ ln_NCAR, ln_COARE_3p0, ln_COARE_3p6, ln_ECMWF, ln_ANDREAS, & ! bulk algorithm 220 & rn_zqt, rn_zu, nn_iter_algo, ln_skin_cs, ln_skin_wl, & 221 & rn_pfac, rn_efac, & 186 222 & ln_crt_fbk, rn_stau_a, rn_stau_b, & ! current feedback 187 & ln_skin_cs, ln_skin_wl, ln_humi_sph, ln_humi_dpt, ln_humi_rlh ! cool-skin / warm-layer !LB 223 & ln_humi_sph, ln_humi_dpt, ln_humi_rlh, ln_tair_pot, & 224 & ln_Cx_ice_cst, rn_Cd_i, rn_Ce_i, rn_Ch_i, & 225 & ln_Cx_ice_AN05, ln_Cx_ice_LU12, ln_Cx_ice_LG15, & 226 & cn_dir, & 227 & sn_wndi, sn_wndj, sn_qsr, sn_qlw , & ! input fields 228 & sn_tair, sn_humi, sn_prec, sn_snow, sn_slp, & 229 & sn_uoatm, sn_voatm, sn_cc, sn_hpgi, sn_hpgj 230 231 ! cool-skin / warm-layer !LB 188 232 !!--------------------------------------------------------------------- 189 233 ! 190 234 ! ! allocate sbc_blk_core array 191 IF( sbc_blk_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_blk : unable to allocate standard arrays' ) 235 IF( sbc_blk_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_blk : unable to allocate standard arrays' ) 236 ! 237 #if defined key_si3 238 IF( sbc_blk_ice_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_blk : unable to allocate standard ice arrays' ) 239 #endif 192 240 ! 193 241 ! !** read bulk namelist … … 215 263 nblk = np_ECMWF ; ioptio = ioptio + 1 216 264 ENDIF 265 IF( ln_ANDREAS ) THEN 266 nblk = np_ANDREAS ; ioptio = ioptio + 1 267 ENDIF 217 268 IF( ioptio /= 1 ) CALL ctl_stop( 'sbc_blk_init: Choose one and only one bulk algorithm' ) 218 269 … … 222 273 IF( ln_NCAR ) & 223 274 & CALL ctl_stop( 'sbc_blk_init: Cool-skin/warm-layer param. not compatible with NCAR algorithm' ) 275 IF( ln_ANDREAS ) & 276 & CALL ctl_stop( 'sbc_blk_init: Cool-skin/warm-layer param. not compatible with ANDREAS algorithm' ) 224 277 IF( nn_fsbc /= 1 ) & 225 278 & CALL ctl_stop( 'sbc_blk_init: Please set "nn_fsbc" to 1 when using cool-skin/warm-layer param.') … … 254 307 ENDIF 255 308 ENDIF 309 310 #if defined key_si3 311 ioptio = 0 312 IF( ln_Cx_ice_cst ) THEN 313 nblk_ice = np_ice_cst ; ioptio = ioptio + 1 314 ENDIF 315 IF( ln_Cx_ice_AN05 ) THEN 316 nblk_ice = np_ice_an05 ; ioptio = ioptio + 1 317 ENDIF 318 IF( ln_Cx_ice_LU12 ) THEN 319 nblk_ice = np_ice_lu12 ; ioptio = ioptio + 1 320 ENDIF 321 IF( ln_Cx_ice_LG15 ) THEN 322 nblk_ice = np_ice_lg15 ; ioptio = ioptio + 1 323 ENDIF 324 IF( ioptio /= 1 ) CALL ctl_stop( 'sbc_blk_init: Choose one and only one ice-atm bulk algorithm' ) 325 #endif 326 327 256 328 ! !* set the bulk structure 257 329 ! !- store namelist information in an array … … 322 394 ENDIF 323 395 ! 324 ! set transfer coefficients to default sea-ice values325 Cd_ice(:,:) = rCd_ice326 Ch_ice(:,:) = rCd_ice327 Ce_ice(:,:) = rCd_ice328 396 ! 329 397 IF(lwp) THEN !** Control print … … 331 399 WRITE(numout,*) !* namelist 332 400 WRITE(numout,*) ' Namelist namsbc_blk (other than data information):' 333 WRITE(numout,*) ' "NCAR" algorithm (Large and Yeager 2008) ln_NCAR = ', ln_NCAR401 WRITE(numout,*) ' "NCAR" algorithm (Large and Yeager 2008) ln_NCAR = ', ln_NCAR 334 402 WRITE(numout,*) ' "COARE 3.0" algorithm (Fairall et al. 2003) ln_COARE_3p0 = ', ln_COARE_3p0 335 WRITE(numout,*) ' "COARE 3.6" algorithm (Fairall 2018 + Edson al 2013)ln_COARE_3p6 = ', ln_COARE_3p6 336 WRITE(numout,*) ' "ECMWF" algorithm (IFS cycle 45r1) ln_ECMWF = ', ln_ECMWF 403 WRITE(numout,*) ' "COARE 3.6" algorithm (Fairall 2018 + Edson al 2013) ln_COARE_3p6 = ', ln_COARE_3p6 404 WRITE(numout,*) ' "ECMWF" algorithm (IFS cycle 45r1) ln_ECMWF = ', ln_ECMWF 405 WRITE(numout,*) ' "ANDREAS" algorithm (Andreas et al. 2015) ln_ANDREAS = ', ln_ANDREAS 337 406 WRITE(numout,*) ' Air temperature and humidity reference height (m) rn_zqt = ', rn_zqt 338 407 WRITE(numout,*) ' Wind vector reference height (m) rn_zu = ', rn_zu … … 340 409 WRITE(numout,*) ' factor applied on evaporation rn_efac = ', rn_efac 341 410 WRITE(numout,*) ' (form absolute (=0) to relative winds(=1))' 342 WRITE(numout,*) ' use ice-atm drag from Lupkes2012 ln_Cd_L12 = ', ln_Cd_L12343 WRITE(numout,*) ' use ice-atm drag from Lupkes2015 ln_Cd_L15 = ', ln_Cd_L15344 411 WRITE(numout,*) ' use surface current feedback on wind stress ln_crt_fbk = ', ln_crt_fbk 345 412 IF(ln_crt_fbk) THEN … … 355 422 CASE( np_COARE_3p6 ) ; WRITE(numout,*) ' ==>>> "COARE 3.6" algorithm (Fairall 2018+Edson et al. 2013)' 356 423 CASE( np_ECMWF ) ; WRITE(numout,*) ' ==>>> "ECMWF" algorithm (IFS cycle 45r1)' 424 CASE( np_ANDREAS ) ; WRITE(numout,*) ' ==>>> "ANDREAS" algorithm (Andreas et al. 2015)' 357 425 END SELECT 358 426 ! … … 367 435 CASE( np_humi_rlh ) ; WRITE(numout,*) ' ==>>> air humidity is RELATIVE HUMIDITY [%]' 368 436 END SELECT 437 ! 438 !#LB: 439 #if defined key_si3 440 IF( nn_ice > 0 ) THEN 441 WRITE(numout,*) 442 WRITE(numout,*) ' use constant ice-atm bulk transfer coeff. ln_Cx_ice_cst = ', ln_Cx_ice_cst 443 WRITE(numout,*) ' use ice-atm bulk coeff. from Andreas et al., 2005 ln_Cx_ice_AN05 = ', ln_Cx_ice_AN05 444 WRITE(numout,*) ' use ice-atm bulk coeff. from Lupkes et al., 2012 ln_Cx_ice_LU12 = ', ln_Cx_ice_LU12 445 WRITE(numout,*) ' use ice-atm bulk coeff. from Lupkes & Gryanik, 2015 ln_Cx_ice_LG15 = ', ln_Cx_ice_LG15 446 ENDIF 447 WRITE(numout,*) 448 SELECT CASE( nblk_ice ) !* Print the choice of bulk algorithm 449 CASE( np_ice_cst ) 450 WRITE(numout,*) ' ==>>> Constant bulk transfer coefficients over sea-ice:' 451 WRITE(numout,*) ' => Cd_ice, Ce_ice, Ch_ice =', REAL(rn_Cd_i,4), REAL(rn_Ce_i,4), REAL(rn_Ch_i,4) 452 IF( (rn_Cd_i<0._wp).OR.(rn_Cd_i>1.E-2_wp).OR.(rn_Ce_i<0._wp).OR.(rn_Ce_i>1.E-2_wp).OR.(rn_Ch_i<0._wp).OR.(rn_Ch_i>1.E-2_wp) ) & 453 & CALL ctl_stop( 'Be realistic in your pick of Cd_ice, Ce_ice & Ch_ice ! (0 < Cx < 1.E-2)') 454 CASE( np_ice_an05 ) ; WRITE(numout,*) ' ==>>> bulk algo over ice: Andreas et al, 2005' 455 CASE( np_ice_lu12 ) ; WRITE(numout,*) ' ==>>> bulk algo over ice: Lupkes et al, 2012' 456 CASE( np_ice_lg15 ) ; WRITE(numout,*) ' ==>>> bulk algo over ice: Lupkes & Gryanik, 2015' 457 END SELECT 458 #endif 459 !#LB. 369 460 ! 370 461 ENDIF … … 409 500 INTEGER, INTENT(in) :: kt ! ocean time step 410 501 !!---------------------------------------------------------------------- 411 REAL(wp), DIMENSION(jpi,jpj) :: zssq, zcd_du, zsen, z evp502 REAL(wp), DIMENSION(jpi,jpj) :: zssq, zcd_du, zsen, zlat, zevp 412 503 REAL(wp) :: ztmp 413 504 !!---------------------------------------------------------------------- … … 446 537 ! ! compute the surface ocean fluxes using bulk formulea 447 538 IF( MOD( kt - 1, nn_fsbc ) == 0 ) THEN 539 540 ! Specific humidity of air at z=rn_zqt ! 541 SELECT CASE( nhumi ) 542 CASE( np_humi_sph ) 543 q_air_zt(:,:) = sf(jp_humi )%fnow(:,:,1) ! what we read in file is already a spec. humidity! 544 CASE( np_humi_dpt ) 545 IF((kt==nit000).AND.lwp) WRITE(numout,*) ' *** sbc_blk() => computing q_air out of dew-point and P !' 546 q_air_zt(:,:) = q_sat( sf(jp_humi )%fnow(:,:,1), sf(jp_slp )%fnow(:,:,1) ) 547 CASE( np_humi_rlh ) 548 IF((kt==nit000).AND.lwp) WRITE(numout,*) ' *** sbc_blk() => computing q_air out of RH, t_air and slp !' !LBrm 549 q_air_zt(:,:) = q_air_rh( 0.01_wp*sf(jp_humi )%fnow(:,:,1), & 550 & sf(jp_tair )%fnow(:,:,1), sf(jp_slp )%fnow(:,:,1) ) !#LB: 0.01 => RH is % percent in file 551 END SELECT 552 553 ! POTENTIAL temperature of air at z=rn_zqt 554 ! based on adiabatic lapse-rate (see Josey, Gulev & Yu, 2013) / doi=10.1016/B978-0-12-391851-2.00005-2 555 ! (most reanalysis products provide absolute temp., not potential temp.) 556 IF( ln_tair_pot ) THEN 557 ! temperature read into file is already potential temperature, do nothing... 558 theta_air_zt(:,:) = sf(jp_tair )%fnow(:,:,1) 559 ELSE 560 ! temperature read into file is ABSOLUTE temperature (that's the case for ECMWF products for example...) 561 IF((kt==nit000).AND.lwp) WRITE(numout,*) ' *** sbc_blk() => air temperature converted from ABSOLUTE to POTENTIAL!' 562 theta_air_zt(:,:) = sf(jp_tair )%fnow(:,:,1) + gamma_moist( sf(jp_tair )%fnow(:,:,1), q_air_zt(:,:) ) * rn_zqt 563 ENDIF 564 ! 448 565 CALL blk_oce_1( kt, sf(jp_wndi )%fnow(:,:,1), sf(jp_wndj )%fnow(:,:,1), & ! <<= in 449 & sf(jp_tair )%fnow(:,:,1), sf(jp_humi )%fnow(:,:,1),& ! <<= in566 & theta_air_zt(:,:), q_air_zt(:,:), & ! <<= in 450 567 & sf(jp_slp )%fnow(:,:,1), sst_m, ssu_m, ssv_m, & ! <<= in 451 568 & sf(jp_uoatm)%fnow(:,:,1), sf(jp_voatm)%fnow(:,:,1), & ! <<= in 452 569 & sf(jp_qsr )%fnow(:,:,1), sf(jp_qlw )%fnow(:,:,1), & ! <<= in (wl/cs) 453 & tsk_m, zssq, zcd_du, zsen, z evp )! =>> out454 455 CALL blk_oce_2( sf(jp_tair )%fnow(:,:,1), sf(jp_qsr )%fnow(:,:,1),& ! <<= in570 & tsk_m, zssq, zcd_du, zsen, zlat, zevp ) ! =>> out 571 572 CALL blk_oce_2( theta_air_zt(:,:), & ! <<= in 456 573 & sf(jp_qlw )%fnow(:,:,1), sf(jp_prec )%fnow(:,:,1), & ! <<= in 457 574 & sf(jp_snow )%fnow(:,:,1), tsk_m, & ! <<= in 458 & zsen, z evp )! <=> in out575 & zsen, zlat, zevp ) ! <=> in out 459 576 ENDIF 460 577 ! … … 467 584 qsr_ice(:,:,1) = sf(jp_qsr)%fnow(:,:,1) 468 585 ENDIF 469 tatm_ice(:,:) = sf(jp_tair)%fnow(:,:,1) 470 471 SELECT CASE( nhumi ) 472 CASE( np_humi_sph ) 473 qatm_ice(:,:) = sf(jp_humi)%fnow(:,:,1) 474 CASE( np_humi_dpt ) 475 qatm_ice(:,:) = q_sat( sf(jp_humi)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1) ) 476 CASE( np_humi_rlh ) 477 qatm_ice(:,:) = q_air_rh( 0.01_wp*sf(jp_humi)%fnow(:,:,1), sf(jp_tair)%fnow(:,:,1), sf(jp_slp)%fnow(:,:,1)) !LB: 0.01 => RH is % percent in file 478 END SELECT 586 tatm_ice(:,:) = sf(jp_tair)%fnow(:,:,1) !#LB: should it be POTENTIAL temperature instead ???? 587 !tatm_ice(:,:) = theta_air_zt(:,:) !#LB: THIS! ? 588 589 qatm_ice(:,:) = q_air_zt(:,:) !#LB: 479 590 480 591 tprecip(:,:) = sf(jp_prec)%fnow(:,:,1) * rn_pfac … … 488 599 489 600 490 SUBROUTINE blk_oce_1( kt, pwndi, pwndj, ptair, p humi, & ! inp601 SUBROUTINE blk_oce_1( kt, pwndi, pwndj, ptair, pqair, & ! inp 491 602 & pslp , pst , pu , pv, & ! inp 492 & puatm, pvatm, p qsr , pqlw ,& ! inp493 & ptsk , pssq , pcd_du, psen, p evp )! out603 & puatm, pvatm, pdqsr , pdqlw , & ! inp 604 & ptsk , pssq , pcd_du, psen, plat, pevp ) ! out 494 605 !!--------------------------------------------------------------------- 495 606 !! *** ROUTINE blk_oce_1 *** … … 504 615 !! ** Outputs : - pssq : surface humidity used to compute latent heat flux (kg/kg) 505 616 !! - pcd_du : Cd x |dU| at T-points (m/s) 506 !! - psen : Ch x |dU| at T-points (m/s) 507 !! - pevp : Ce x |dU| at T-points (m/s) 617 !! - psen : sensible heat flux (W/m^2) 618 !! - plat : latent heat flux (W/m^2) 619 !! - pevp : evaporation (mm/s) #lolo 508 620 !!--------------------------------------------------------------------- 509 621 INTEGER , INTENT(in ) :: kt ! time step index 510 622 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pwndi ! atmospheric wind at U-point [m/s] 511 623 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pwndj ! atmospheric wind at V-point [m/s] 512 REAL(wp), INTENT(in ), DIMENSION(:,:) :: p humi! specific humidity at T-points [kg/kg]624 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pqair ! specific humidity at T-points [kg/kg] 513 625 REAL(wp), INTENT(in ), DIMENSION(:,:) :: ptair ! potential temperature at T-points [Kelvin] 514 626 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pslp ! sea-level pressure [Pa] … … 518 630 REAL(wp), INTENT(in ), DIMENSION(:,:) :: puatm ! surface current seen by the atm at T-point (i-component) [m/s] 519 631 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pvatm ! surface current seen by the atm at T-point (j-component) [m/s] 520 REAL(wp), INTENT(in ), DIMENSION(:,:) :: p qsr !521 REAL(wp), INTENT(in ), DIMENSION(:,:) :: p qlw !632 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pdqsr ! downwelling solar (shortwave) radiation at surface [W/m^2] 633 REAL(wp), INTENT(in ), DIMENSION(:,:) :: pdqlw ! downwelling longwave radiation at surface [W/m^2] 522 634 REAL(wp), INTENT( out), DIMENSION(:,:) :: ptsk ! skin temp. (or SST if CS & WL not used) [Celsius] 523 635 REAL(wp), INTENT( out), DIMENSION(:,:) :: pssq ! specific humidity at pst [kg/kg] 524 REAL(wp), INTENT( out), DIMENSION(:,:) :: pcd_du ! Cd x |dU| at T-points [m/s] 525 REAL(wp), INTENT( out), DIMENSION(:,:) :: psen ! Ch x |dU| at T-points [m/s] 526 REAL(wp), INTENT( out), DIMENSION(:,:) :: pevp ! Ce x |dU| at T-points [m/s] 636 REAL(wp), INTENT( out), DIMENSION(:,:) :: pcd_du 637 REAL(wp), INTENT( out), DIMENSION(:,:) :: psen 638 REAL(wp), INTENT( out), DIMENSION(:,:) :: plat 639 REAL(wp), INTENT( out), DIMENSION(:,:) :: pevp 527 640 ! 528 641 INTEGER :: ji, jj ! dummy loop indices … … 534 647 REAL(wp), DIMENSION(jpi,jpj) :: ztau_i, ztau_j ! wind stress components at T-point 535 648 REAL(wp), DIMENSION(jpi,jpj) :: zU_zu ! bulk wind speed at height zu [m/s] 536 REAL(wp), DIMENSION(jpi,jpj) :: ztpot ! potential temperature of air at z=rn_zqt [K]537 REAL(wp), DIMENSION(jpi,jpj) :: zqair ! specific humidity of air at z=rn_zqt [kg/kg]538 649 REAL(wp), DIMENSION(jpi,jpj) :: zcd_oce ! momentum transfert coefficient over ocean 539 650 REAL(wp), DIMENSION(jpi,jpj) :: zch_oce ! sensible heat transfert coefficient over ocean 540 651 REAL(wp), DIMENSION(jpi,jpj) :: zce_oce ! latent heat transfert coefficient over ocean 541 REAL(wp), DIMENSION(jpi,jpj) :: zqla ! latent heat flux542 652 REAL(wp), DIMENSION(jpi,jpj) :: zztmp1, zztmp2 543 653 !!--------------------------------------------------------------------- … … 578 688 zztmp = 1. - albo 579 689 IF( ln_dm2dc ) THEN 580 qsr(:,:) = zztmp * sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) * tmask(:,:,1)690 qsr(:,:) = zztmp * sbc_dcy( pdqsr(:,:) ) * tmask(:,:,1) 581 691 ELSE 582 qsr(:,:) = zztmp * sf(jp_qsr)%fnow(:,:,1) * tmask(:,:,1)692 qsr(:,:) = zztmp * pdqsr(:,:) * tmask(:,:,1) 583 693 ENDIF 584 694 … … 597 707 ENDIF 598 708 599 ! specific humidity of air at "rn_zqt" m above the sea600 SELECT CASE( nhumi )601 CASE( np_humi_sph )602 zqair(:,:) = phumi(:,:) ! what we read in file is already a spec. humidity!603 CASE( np_humi_dpt )604 !IF(lwp) WRITE(numout,*) ' *** blk_oce => computing q_air out of d_air and slp !' !LBrm605 zqair(:,:) = q_sat( phumi(:,:), pslp(:,:) )606 CASE( np_humi_rlh )607 !IF(lwp) WRITE(numout,*) ' *** blk_oce => computing q_air out of RH, t_air and slp !' !LBrm608 zqair(:,:) = q_air_rh( 0.01_wp*phumi(:,:), ptair(:,:), pslp(:,:) ) !LB: 0.01 => RH is % percent in file609 END SELECT610 !611 ! potential temperature of air at "rn_zqt" m above the sea612 IF( ln_abl ) THEN613 ztpot = ptair(:,:)614 ELSE615 ! Estimate of potential temperature at z=rn_zqt, based on adiabatic lapse-rate616 ! (see Josey, Gulev & Yu, 2013) / doi=10.1016/B978-0-12-391851-2.00005-2617 ! (since reanalysis products provide T at z, not theta !)618 !#LB: because AGRIF hates functions that return something else than a scalar, need to619 ! use scalar version of gamma_moist() ...620 IF( ln_tpot ) THEN621 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )622 ztpot(ji,jj) = ptair(ji,jj) + gamma_moist( ptair(ji,jj), zqair(ji,jj) ) * rn_zqt623 END_2D624 ELSE625 ztpot = ptair(:,:)626 ENDIF627 ENDIF628 629 709 !! Time to call the user-selected bulk parameterization for 630 710 !! == transfer coefficients ==! Cd, Ch, Ce at T-point, and more... … … 632 712 633 713 CASE( np_NCAR ) 634 CALL turb_ncar ( rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, & 635 & zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce ) 636 714 CALL turb_ncar ( rn_zqt, rn_zu, ptsk, ptair, pssq, pqair, wndm, & 715 & zcd_oce, zch_oce, zce_oce, theta_zu, q_zu, zU_zu , & 716 & nb_iter=nn_iter_algo ) 717 ! 637 718 CASE( np_COARE_3p0 ) 638 CALL turb_coare3p0 ( kt, rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, ln_skin_cs, ln_skin_wl, & 639 & zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce, & 640 & Qsw=qsr(:,:), rad_lw=pqlw(:,:), slp=pslp(:,:) ) 641 719 CALL turb_coare3p0( kt, rn_zqt, rn_zu, ptsk, ptair, pssq, pqair, wndm, & 720 & ln_skin_cs, ln_skin_wl, & 721 & zcd_oce, zch_oce, zce_oce, theta_zu, q_zu, zU_zu, & 722 & nb_iter=nn_iter_algo, & 723 & Qsw=qsr(:,:), rad_lw=pdqlw(:,:), slp=pslp(:,:) ) 724 ! 642 725 CASE( np_COARE_3p6 ) 643 CALL turb_coare3p6 ( kt, rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, ln_skin_cs, ln_skin_wl, & 644 & zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce, & 645 & Qsw=qsr(:,:), rad_lw=pqlw(:,:), slp=pslp(:,:) ) 646 726 CALL turb_coare3p6( kt, rn_zqt, rn_zu, ptsk, ptair, pssq, pqair, wndm, & 727 & ln_skin_cs, ln_skin_wl, & 728 & zcd_oce, zch_oce, zce_oce, theta_zu, q_zu, zU_zu, & 729 & nb_iter=nn_iter_algo, & 730 & Qsw=qsr(:,:), rad_lw=pdqlw(:,:), slp=pslp(:,:) ) 731 ! 647 732 CASE( np_ECMWF ) 648 CALL turb_ecmwf ( kt, rn_zqt, rn_zu, ptsk, ztpot, pssq, zqair, wndm, ln_skin_cs, ln_skin_wl, & 649 & zcd_oce, zch_oce, zce_oce, t_zu, q_zu, zU_zu, cdn_oce, chn_oce, cen_oce, & 650 & Qsw=qsr(:,:), rad_lw=pqlw(:,:), slp=pslp(:,:) ) 651 733 CALL turb_ecmwf ( kt, rn_zqt, rn_zu, ptsk, ptair, pssq, pqair, wndm, & 734 & ln_skin_cs, ln_skin_wl, & 735 & zcd_oce, zch_oce, zce_oce, theta_zu, q_zu, zU_zu, & 736 & nb_iter=nn_iter_algo, & 737 & Qsw=qsr(:,:), rad_lw=pdqlw(:,:), slp=pslp(:,:) ) 738 ! 739 CASE( np_ANDREAS ) 740 CALL turb_andreas ( rn_zqt, rn_zu, ptsk, ptair, pssq, pqair, wndm, & 741 & zcd_oce, zch_oce, zce_oce, theta_zu, q_zu, zU_zu , & 742 & nb_iter=nn_iter_algo ) 743 ! 652 744 CASE DEFAULT 653 CALL ctl_stop( 'STOP', 'sbc_oce: non-existing bulk formulaselected' )654 745 CALL ctl_stop( 'STOP', 'sbc_oce: non-existing bulk parameterizaton selected' ) 746 ! 655 747 END SELECT 656 748 657 749 IF( iom_use('Cd_oce') ) CALL iom_put("Cd_oce", zcd_oce * tmask(:,:,1)) 658 750 IF( iom_use('Ce_oce') ) CALL iom_put("Ce_oce", zce_oce * tmask(:,:,1)) 659 751 IF( iom_use('Ch_oce') ) CALL iom_put("Ch_oce", zch_oce * tmask(:,:,1)) 660 752 !! LB: mainly here for debugging purpose: 661 IF( iom_use('theta_zt') ) CALL iom_put("theta_zt", ( ztpot-rt0) * tmask(:,:,1)) ! potential temperature at z=zt662 IF( iom_use('q_zt') ) CALL iom_put("q_zt", zqair * tmask(:,:,1)) ! specific humidity "663 IF( iom_use('theta_zu') ) CALL iom_put("theta_zu", (t _zu -rt0) * tmask(:,:,1)) ! potential temperature at z=zu753 IF( iom_use('theta_zt') ) CALL iom_put("theta_zt", (ptair-rt0) * tmask(:,:,1)) ! potential temperature at z=zt 754 IF( iom_use('q_zt') ) CALL iom_put("q_zt", pqair * tmask(:,:,1)) ! specific humidity " 755 IF( iom_use('theta_zu') ) CALL iom_put("theta_zu", (theta_zu -rt0) * tmask(:,:,1)) ! potential temperature at z=zu 664 756 IF( iom_use('q_zu') ) CALL iom_put("q_zu", q_zu * tmask(:,:,1)) ! specific humidity " 665 757 IF( iom_use('ssq') ) CALL iom_put("ssq", pssq * tmask(:,:,1)) ! saturation specific humidity at z=0 666 758 IF( iom_use('wspd_blk') ) CALL iom_put("wspd_blk", zU_zu * tmask(:,:,1)) ! bulk wind speed at z=zu 667 759 668 760 IF( ln_skin_cs .OR. ln_skin_wl ) THEN 669 761 !! ptsk and pssq have been updated!!! … … 677 769 END IF 678 770 679 ! Turbulent fluxes over ocean => BULK_FORMULA @ sbc blk_phy.F90771 ! Turbulent fluxes over ocean => BULK_FORMULA @ sbc_phy.F90 680 772 ! ------------------------------------------------------------- 681 773 … … 687 779 psen(ji,jj) = zztmp * zch_oce(ji,jj) 688 780 pevp(ji,jj) = zztmp * zce_oce(ji,jj) 689 rhoa(ji,jj) = rho_air( ptair(ji,jj), p humi(ji,jj), pslp(ji,jj) )781 rhoa(ji,jj) = rho_air( ptair(ji,jj), pqair(ji,jj), pslp(ji,jj) ) 690 782 END_2D 691 783 ELSE !== BLK formulation ==! turbulent fluxes computation 692 CALL BULK_FORMULA( rn_zu, ptsk(:,:), pssq(:,:), t _zu(:,:), q_zu(:,:), &784 CALL BULK_FORMULA( rn_zu, ptsk(:,:), pssq(:,:), theta_zu(:,:), q_zu(:,:), & 693 785 & zcd_oce(:,:), zch_oce(:,:), zce_oce(:,:), & 694 786 & wndm(:,:), zU_zu(:,:), pslp(:,:), & 695 & taum(:,:), psen(:,:), zqla(:,:), &787 & taum(:,:), psen(:,:), plat(:,:), & 696 788 & pEvap=pevp(:,:), prhoa=rhoa(:,:), pfact_evap=rn_efac ) 697 789 698 zqla(:,:) = zqla(:,:) * tmask(:,:,1)699 790 psen(:,:) = psen(:,:) * tmask(:,:,1) 791 plat(:,:) = plat(:,:) * tmask(:,:,1) 700 792 taum(:,:) = taum(:,:) * tmask(:,:,1) 701 793 pevp(:,:) = pevp(:,:) * tmask(:,:,1) 702 794 703 795 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 704 705 796 IF( wndm(ji,jj) > 0._wp ) THEN 797 zztmp = taum(ji,jj) / wndm(ji,jj) 706 798 #if defined key_cyclone 707 708 799 ztau_i(ji,jj) = zztmp * zwnd_i(ji,jj) 800 ztau_j(ji,jj) = zztmp * zwnd_j(ji,jj) 709 801 #else 710 711 712 #endif 713 714 715 ztau_j(ji,jj) = 0._wp716 802 ztau_i(ji,jj) = zztmp * pwndi(ji,jj) 803 ztau_j(ji,jj) = zztmp * pwndj(ji,jj) 804 #endif 805 ELSE 806 ztau_i(ji,jj) = 0._wp 807 ztau_j(ji,jj) = 0._wp 808 ENDIF 717 809 END_2D 718 810 … … 743 835 ENDIF 744 836 745 CALL iom_put( "taum_oce", taum ) ! output wind stress module 837 ! Saving open-ocean wind-stress (module and components) on T-points: 838 CALL iom_put( "taum_oce", taum(:,:)*tmask(:,:,1) ) ! output wind stress module 839 !#LB: These 2 lines below mostly here for 'STATION_ASF' test-case, otherwize "utau" (U-grid) and vtau" (V-grid) does the job in: [DYN/dynatf.F90]) 840 CALL iom_put( "utau_oce", ztau_i(:,:)*tmask(:,:,1) ) ! utau at T-points! 841 CALL iom_put( "vtau_oce", ztau_j(:,:)*tmask(:,:,1) ) ! vtau at T-points! 746 842 747 843 IF(sn_cfctl%l_prtctl) THEN 748 CALL prt_ctl( tab2d_1=wndm , clinfo1=' blk_oce_1: wndm : ') 749 CALL prt_ctl( tab2d_1=utau , clinfo1=' blk_oce_1: utau : ', mask1=umask, & 750 & tab2d_2=vtau , clinfo2=' vtau : ', mask2=vmask ) 844 CALL prt_ctl( tab2d_1=pssq , clinfo1=' blk_oce_1: pssq : ') 845 CALL prt_ctl( tab2d_1=wndm , clinfo1=' blk_oce_1: wndm : ') 846 CALL prt_ctl( tab2d_1=utau , clinfo1=' blk_oce_1: utau : ', mask1=umask, & 847 & tab2d_2=vtau , clinfo2=' vtau : ', mask2=vmask ) 848 CALL prt_ctl( tab2d_1=zcd_oce, clinfo1=' blk_oce_1: Cd : ') 751 849 ENDIF 752 850 ! 753 851 ENDIF !IF( ln_abl ) 754 852 755 853 ptsk(:,:) = ( ptsk(:,:) - rt0 ) * tmask(:,:,1) ! Back to Celsius 756 854 757 855 IF( ln_skin_cs .OR. ln_skin_wl ) THEN 758 856 CALL iom_put( "t_skin" , ptsk ) ! T_skin in Celsius 759 857 CALL iom_put( "dt_skin" , ptsk - pst ) ! T_skin - SST temperature difference... 760 858 ENDIF 761 762 IF(sn_cfctl%l_prtctl) THEN763 CALL prt_ctl( tab2d_1=pevp , clinfo1=' blk_oce_1: pevp : ' )764 CALL prt_ctl( tab2d_1=psen , clinfo1=' blk_oce_1: psen : ' )765 CALL prt_ctl( tab2d_1=pssq , clinfo1=' blk_oce_1: pssq : ' )766 ENDIF767 859 ! 768 860 END SUBROUTINE blk_oce_1 769 861 770 862 771 SUBROUTINE blk_oce_2( ptair, p qsr, pqlw, pprec,& ! <<= in772 & psnow, ptsk, psen, pevp ) ! <<= in863 SUBROUTINE blk_oce_2( ptair, pdqlw, pprec, psnow, & ! <<= in 864 & ptsk, psen, plat, pevp ) ! <<= in 773 865 !!--------------------------------------------------------------------- 774 866 !! *** ROUTINE blk_oce_2 *** … … 786 878 !! - emp : evaporation minus precipitation (kg/m2/s) 787 879 !!--------------------------------------------------------------------- 788 REAL(wp), INTENT(in), DIMENSION(:,:) :: ptair 789 REAL(wp), INTENT(in), DIMENSION(:,:) :: pqsr 790 REAL(wp), INTENT(in), DIMENSION(:,:) :: pqlw 880 REAL(wp), INTENT(in), DIMENSION(:,:) :: ptair ! potential temperature of air #LB: confirm! 881 REAL(wp), INTENT(in), DIMENSION(:,:) :: pdqlw ! downwelling longwave radiation at surface [W/m^2] 791 882 REAL(wp), INTENT(in), DIMENSION(:,:) :: pprec 792 883 REAL(wp), INTENT(in), DIMENSION(:,:) :: psnow 793 884 REAL(wp), INTENT(in), DIMENSION(:,:) :: ptsk ! SKIN surface temperature [Celsius] 794 885 REAL(wp), INTENT(in), DIMENSION(:,:) :: psen 886 REAL(wp), INTENT(in), DIMENSION(:,:) :: plat 795 887 REAL(wp), INTENT(in), DIMENSION(:,:) :: pevp 796 888 ! 797 889 INTEGER :: ji, jj ! dummy loop indices 798 890 REAL(wp) :: zztmp,zz1,zz2,zz3 ! local variable 799 REAL(wp), DIMENSION(jpi,jpj) :: ztskk ! skin temp. in Kelvin 800 REAL(wp), DIMENSION(jpi,jpj) :: zqlw ! long wave and sensible heat fluxes 801 REAL(wp), DIMENSION(jpi,jpj) :: zqla ! latent heat fluxes and evaporation 891 REAL(wp), DIMENSION(jpi,jpj) :: zqlw ! net long wave radiative heat flux 802 892 !!--------------------------------------------------------------------- 803 893 ! 804 894 ! local scalars ( place there for vector optimisation purposes) 805 895 806 807 ztskk(:,:) = ptsk(:,:) + rt0 ! => ptsk in Kelvin rather than Celsius808 809 896 ! ----------------------------------------------------------------------------- ! 810 897 ! III Net longwave radiative FLUX ! 811 898 ! ----------------------------------------------------------------------------- ! 812 813 !! LB: now moved after Turbulent fluxes because must use the skin temperature rather that the SST 814 !! (ztskk is skin temperature if ln_skin_cs==.TRUE. .OR. ln_skin_wl==.TRUE.) 815 zqlw(:,:) = emiss_w * ( pqlw(:,:) - stefan*ztskk(:,:)*ztskk(:,:)*ztskk(:,:)*ztskk(:,:) ) * tmask(:,:,1) ! Net radiative longwave flux 816 817 ! Latent flux over ocean 818 ! ----------------------- 819 820 ! use scalar version of L_vap() for AGRIF compatibility 821 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 822 zqla(ji,jj) = - L_vap( ztskk(ji,jj) ) * pevp(ji,jj) ! Latent Heat flux !!GS: possibility to add a global qla to avoid recomputation after abl update 823 END_2D 824 825 IF(sn_cfctl%l_prtctl) THEN 826 CALL prt_ctl( tab2d_1=zqla , clinfo1=' blk_oce_2: zqla : ' ) 827 CALL prt_ctl( tab2d_1=zqlw , clinfo1=' blk_oce_2: zqlw : ', tab2d_2=qsr, clinfo2=' qsr : ' ) 828 829 ENDIF 899 !! #LB: now moved after Turbulent fluxes because must use the skin temperature rather than bulk SST 900 !! (ptsk is skin temperature if ln_skin_cs==.TRUE. .OR. ln_skin_wl==.TRUE.) 901 zqlw(:,:) = qlw_net( pdqlw(:,:), ptsk(:,:)+rt0 ) 830 902 831 903 ! ----------------------------------------------------------------------------- ! … … 836 908 & - pprec(:,:) * rn_pfac ) * tmask(:,:,1) 837 909 ! 838 qns(:,:) = zqlw(:,:) + psen(:,:) + zqla(:,:) & ! Downward Non Solar910 qns(:,:) = zqlw(:,:) + psen(:,:) + plat(:,:) & ! Downward Non Solar 839 911 & - psnow(:,:) * rn_pfac * rLfus & ! remove latent melting heat for solid precip 840 912 & - pevp(:,:) * ptsk(:,:) * rcp & ! remove evap heat content at SST … … 846 918 ! 847 919 #if defined key_si3 848 qns_oce(:,:) = zqlw(:,:) + psen(:,:) + zqla(:,:) ! non solar without emp (only needed by SI3)920 qns_oce(:,:) = zqlw(:,:) + psen(:,:) + plat(:,:) ! non solar without emp (only needed by SI3) 849 921 qsr_oce(:,:) = qsr(:,:) 850 922 #endif … … 854 926 CALL iom_put( "qlw_oce" , zqlw ) ! output downward longwave heat over the ocean 855 927 CALL iom_put( "qsb_oce" , psen ) ! output downward sensible heat over the ocean 856 CALL iom_put( "qla_oce" , zqla) ! output downward latent heat over the ocean928 CALL iom_put( "qla_oce" , plat ) ! output downward latent heat over the ocean 857 929 tprecip(:,:) = pprec(:,:) * rn_pfac * tmask(:,:,1) ! output total precipitation [kg/m2/s] 858 930 sprecip(:,:) = psnow(:,:) * rn_pfac * tmask(:,:,1) ! output solid precipitation [kg/m2/s] … … 861 933 ! 862 934 IF ( nn_ice == 0 ) THEN 863 CALL iom_put( "qemp_oce" , qns-zqlw-psen- zqla) ! output downward heat content of E-P over the ocean935 CALL iom_put( "qemp_oce" , qns-zqlw-psen-plat ) ! output downward heat content of E-P over the ocean 864 936 CALL iom_put( "qns_oce" , qns ) ! output downward non solar heat over the ocean 865 937 CALL iom_put( "qsr_oce" , qsr ) ! output downward solar heat over the ocean … … 869 941 IF(sn_cfctl%l_prtctl) THEN 870 942 CALL prt_ctl(tab2d_1=zqlw , clinfo1=' blk_oce_2: zqlw : ') 871 CALL prt_ctl(tab2d_1=zqla , clinfo1=' blk_oce_2: zqla : ', tab2d_2=qsr , clinfo2=' qsr : ') 943 CALL prt_ctl(tab2d_1=psen , clinfo1=' blk_oce_2: psen : ' ) 944 CALL prt_ctl(tab2d_1=plat , clinfo1=' blk_oce_2: plat : ' ) 945 CALL prt_ctl(tab2d_1=qns , clinfo1=' blk_oce_2: qns : ' ) 872 946 CALL prt_ctl(tab2d_1=emp , clinfo1=' blk_oce_2: emp : ') 873 947 ENDIF … … 883 957 !! blk_ice_2 : provide the heat and mass fluxes at air-ice interface 884 958 !! blk_ice_qcn : provide ice surface temperature and snow/ice conduction flux (emulating conduction flux) 885 !! Cdn10_Lupkes2012 : Lupkes et al. (2012) air-ice drag886 !! Cdn10_Lupkes2015 : Lupkes et al. (2015) air-ice drag887 959 !!---------------------------------------------------------------------- 888 960 889 SUBROUTINE blk_ice_1( pwndi, pwndj, ptair, p humi, pslp , puice, pvice, ptsui, & ! inputs961 SUBROUTINE blk_ice_1( pwndi, pwndj, ptair, pqair, pslp , puice, pvice, ptsui, & ! inputs 890 962 & putaui, pvtaui, pseni, pevpi, pssqi, pcd_dui ) ! optional outputs 891 963 !!--------------------------------------------------------------------- … … 902 974 REAL(wp) , INTENT(in ), DIMENSION(:,: ) :: pwndj ! atmospheric wind at T-point [m/s] 903 975 REAL(wp) , INTENT(in ), DIMENSION(:,: ) :: ptair ! atmospheric wind at T-point [m/s] 904 REAL(wp) , INTENT(in ), DIMENSION(:,: ) :: p humi! atmospheric wind at T-point [m/s]976 REAL(wp) , INTENT(in ), DIMENSION(:,: ) :: pqair ! atmospheric wind at T-point [m/s] 905 977 REAL(wp) , INTENT(in ), DIMENSION(:,: ) :: puice ! sea-ice velocity on I or C grid [m/s] 906 978 REAL(wp) , INTENT(in ), DIMENSION(:,: ) :: pvice ! " … … 915 987 INTEGER :: ji, jj ! dummy loop indices 916 988 REAL(wp) :: zootm_su ! sea-ice surface mean temperature 917 REAL(wp) :: zztmp1, zztmp2 ! temporary arrays 918 REAL(wp), DIMENSION(jpi,jpj) :: zcd_dui ! transfer coefficient for momentum (tau) 919 !!--------------------------------------------------------------------- 920 ! 921 989 REAL(wp) :: zztmp1, zztmp2 ! temporary scalars 990 REAL(wp), DIMENSION(jpi,jpj) :: ztmp ! temporary array 991 !!--------------------------------------------------------------------- 992 ! 993 ! LB: ptsui is in K !!! 994 ! 922 995 ! ------------------------------------------------------------ ! 923 996 ! Wind module relative to the moving ice ( U10m - U_ice ) ! … … 925 998 ! C-grid ice dynamics : U & V-points (same as ocean) 926 999 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 927 1000 wndm_ice(ji,jj) = SQRT( pwndi(ji,jj) * pwndi(ji,jj) + pwndj(ji,jj) * pwndj(ji,jj) ) 928 1001 END_2D 929 1002 ! 930 1003 ! Make ice-atm. drag dependent on ice concentration 931 IF ( ln_Cd_L12 ) THEN ! calculate new drag from Lupkes(2012) equations 932 CALL Cdn10_Lupkes2012( Cd_ice ) 933 Ch_ice(:,:) = Cd_ice(:,:) ! momentum and heat transfer coef. are considered identical 934 Ce_ice(:,:) = Cd_ice(:,:) 935 ELSEIF( ln_Cd_L15 ) THEN ! calculate new drag from Lupkes(2015) equations 936 CALL Cdn10_Lupkes2015( ptsui, pslp, Cd_ice, Ch_ice ) 937 Ce_ice(:,:) = Ch_ice(:,:) ! sensible and latent heat transfer coef. are considered identical 938 ENDIF 939 940 IF( iom_use('Cd_ice') ) CALL iom_put("Cd_ice", Cd_ice) 941 IF( iom_use('Ce_ice') ) CALL iom_put("Ce_ice", Ce_ice) 942 IF( iom_use('Ch_ice') ) CALL iom_put("Ch_ice", Ch_ice) 943 944 ! local scalars ( place there for vector optimisation purposes) 945 zcd_dui(:,:) = wndm_ice(:,:) * Cd_ice(:,:) 1004 1005 1006 SELECT CASE( nblk_ice ) 1007 1008 CASE( np_ice_cst ) 1009 ! Constant bulk transfer coefficients over sea-ice: 1010 Cd_ice(:,:) = rn_Cd_i 1011 Ch_ice(:,:) = rn_Ch_i 1012 Ce_ice(:,:) = rn_Ce_i 1013 ! no height adjustment, keeping zt values: 1014 theta_zu_i(:,:) = ptair(:,:) 1015 q_zu_i(:,:) = pqair(:,:) 1016 1017 CASE( np_ice_an05 ) ! calculate new drag from Lupkes(2015) equations 1018 ztmp(:,:) = q_sat( ptsui(:,:), pslp(:,:), l_ice=.TRUE. ) ! temporary array for SSQ 1019 CALL turb_ice_an05( rn_zqt, rn_zu, ptsui, ptair, ztmp, pqair, wndm_ice, & 1020 & Cd_ice, Ch_ice, Ce_ice, theta_zu_i, q_zu_i ) 1021 !! 1022 CASE( np_ice_lu12 ) 1023 ztmp(:,:) = q_sat( ptsui(:,:), pslp(:,:), l_ice=.TRUE. ) ! temporary array for SSQ 1024 CALL turb_ice_lu12( rn_zqt, rn_zu, ptsui, ptair, ztmp, pqair, wndm_ice, fr_i, & 1025 & Cd_ice, Ch_ice, Ce_ice, theta_zu_i, q_zu_i ) 1026 !! 1027 CASE( np_ice_lg15 ) ! calculate new drag from Lupkes(2015) equations 1028 ztmp(:,:) = q_sat( ptsui(:,:), pslp(:,:), l_ice=.TRUE. ) ! temporary array for SSQ 1029 CALL turb_ice_lg15( rn_zqt, rn_zu, ptsui, ptair, ztmp, pqair, wndm_ice, fr_i, & 1030 & Cd_ice, Ch_ice, Ce_ice, theta_zu_i, q_zu_i ) 1031 !! 1032 END SELECT 1033 1034 IF( iom_use('Cd_ice').OR.iom_use('Ce_ice').OR.iom_use('Ch_ice').OR.iom_use('taum_ice').OR.iom_use('utau_ice').OR.iom_use('vtau_ice') ) & 1035 & ztmp(:,:) = ( 1._wp - MAX(0._wp, SIGN( 1._wp, 1.E-6_wp - fr_i )) )*tmask(:,:,1) ! mask for presence of ice ! 1036 1037 IF( iom_use('Cd_ice') ) CALL iom_put("Cd_ice", Cd_ice*ztmp) 1038 IF( iom_use('Ce_ice') ) CALL iom_put("Ce_ice", Ce_ice*ztmp) 1039 IF( iom_use('Ch_ice') ) CALL iom_put("Ch_ice", Ch_ice*ztmp) 1040 946 1041 947 1042 IF( ln_blk ) THEN … … 950 1045 ! ---------------------------------------------------- ! 951 1046 ! supress moving ice in wind stress computation as we don't know how to do it properly... 952 DO_2D( 0, 1, 0, 1 ) ! at T point 953 putaui(ji,jj) = rhoa(ji,jj) * zcd_dui(ji,jj) * pwndi(ji,jj) 954 pvtaui(ji,jj) = rhoa(ji,jj) * zcd_dui(ji,jj) * pwndj(ji,jj) 1047 DO_2D( 0, 1, 0, 1 ) ! at T point 1048 zztmp1 = rhoa(ji,jj) * Cd_ice(ji,jj) * wndm_ice(ji,jj) 1049 putaui(ji,jj) = zztmp1 * pwndi(ji,jj) 1050 pvtaui(ji,jj) = zztmp1 * pwndj(ji,jj) 955 1051 END_2D 1052 1053 !#LB: saving the module, and x-y components, of the ai wind-stress at T-points: NOT weighted by the ice concentration !!! 1054 IF(iom_use('taum_ice')) CALL iom_put('taum_ice', SQRT( putaui*putaui + pvtaui*pvtaui )*ztmp ) 1055 !#LB: These 2 lines below mostly here for 'STATION_ASF' test-case, otherwize "utau_oi" (U-grid) and vtau_oi" (V-grid) does the job in: [ICE/icedyn_rhg_evp.F90]) 1056 IF(iom_use('utau_ice')) CALL iom_put("utau_ice", putaui*ztmp) ! utau at T-points! 1057 IF(iom_use('vtau_ice')) CALL iom_put("vtau_ice", pvtaui*ztmp) ! vtau at T-points! 1058 956 1059 ! 957 1060 DO_2D( 0, 0, 0, 0 ) ! U & V-points (same as ocean). 958 ! take care of the land-sea mask to avoid "pollution" of coastal stress. p[uv]taui used in frazil and rheology 1061 !#LB: QUESTION?? so SI3 expects wind stress vector to be provided at U & V points? Not at T-points ? 1062 ! take care of the land-sea mask to avoid "pollution" of coastal stress. p[uv]taui used in frazil and rheology 959 1063 zztmp1 = 0.5_wp * ( 2. - umask(ji,jj,1) ) * MAX( tmask(ji,jj,1),tmask(ji+1,jj ,1) ) 960 1064 zztmp2 = 0.5_wp * ( 2. - vmask(ji,jj,1) ) * MAX( tmask(ji,jj,1),tmask(ji ,jj+1,1) ) … … 967 1071 & , tab2d_2=pvtaui , clinfo2=' pvtaui : ' ) 968 1072 ELSE ! ln_abl 969 zztmp1 = 11637800.0_wp970 zztmp2 = -5897.8_wp971 1073 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 972 pcd_dui(ji,jj) = zcd_dui (ji,jj) 973 pseni (ji,jj) = wndm_ice(ji,jj) * Ch_ice(ji,jj) 974 pevpi (ji,jj) = wndm_ice(ji,jj) * Ce_ice(ji,jj) 975 zootm_su = zztmp2 / ptsui(ji,jj) ! ptsui is in K (it can't be zero ??) 976 pssqi (ji,jj) = zztmp1 * EXP( zootm_su ) / rhoa(ji,jj) 1074 pcd_dui(ji,jj) = wndm_ice(ji,jj) * Cd_ice(ji,jj) 1075 pseni (ji,jj) = wndm_ice(ji,jj) * Ch_ice(ji,jj) 1076 pevpi (ji,jj) = wndm_ice(ji,jj) * Ce_ice(ji,jj) 977 1077 END_2D 978 ENDIF 1078 !#LB: 1079 pssqi(:,:) = q_sat( ptsui(:,:), pslp(:,:), l_ice=.TRUE. ) ; ! more accurate way to obtain ssq ! 1080 !#LB. 1081 ENDIF !IF( ln_blk ) 979 1082 ! 980 1083 IF(sn_cfctl%l_prtctl) CALL prt_ctl(tab2d_1=wndm_ice , clinfo1=' blk_ice: wndm_ice : ') … … 983 1086 984 1087 985 SUBROUTINE blk_ice_2( ptsu, phs, phi, palb, ptair, p humi, pslp, pqlw, pprec, psnow )1088 SUBROUTINE blk_ice_2( ptsu, phs, phi, palb, ptair, pqair, pslp, pdqlw, pprec, psnow ) 986 1089 !!--------------------------------------------------------------------- 987 1090 !! *** ROUTINE blk_ice_2 *** … … 999 1102 REAL(wp), DIMENSION(:,:,:), INTENT(in) :: phi ! ice thickness 1000 1103 REAL(wp), DIMENSION(:,:,:), INTENT(in) :: palb ! ice albedo (all skies) 1001 REAL(wp), DIMENSION(:,: ), INTENT(in) :: ptair 1002 REAL(wp), DIMENSION(:,: ), INTENT(in) :: p humi1104 REAL(wp), DIMENSION(:,: ), INTENT(in) :: ptair ! potential temperature of air #LB: okay ??? 1105 REAL(wp), DIMENSION(:,: ), INTENT(in) :: pqair ! specific humidity of air 1003 1106 REAL(wp), DIMENSION(:,: ), INTENT(in) :: pslp 1004 REAL(wp), DIMENSION(:,: ), INTENT(in) :: p qlw1107 REAL(wp), DIMENSION(:,: ), INTENT(in) :: pdqlw 1005 1108 REAL(wp), DIMENSION(:,: ), INTENT(in) :: pprec 1006 1109 REAL(wp), DIMENSION(:,: ), INTENT(in) :: psnow 1007 1110 !! 1008 1111 INTEGER :: ji, jj, jl ! dummy loop indices 1009 REAL(wp) :: zst 3! local variable1112 REAL(wp) :: zst, zst3, zsq ! local variable 1010 1113 REAL(wp) :: zcoef_dqlw, zcoef_dqla ! - - 1011 REAL(wp) :: zztmp, zztmp2, z1_rLsub ! - - 1012 REAL(wp), DIMENSION(jpi,jpj,jpl) :: z1_st ! inverse of surface temperature 1114 REAL(wp) :: zztmp, zzblk, zztmp1, z1_rLsub ! - - 1013 1115 REAL(wp), DIMENSION(jpi,jpj,jpl) :: z_qlw ! long wave heat flux over ice 1014 1116 REAL(wp), DIMENSION(jpi,jpj,jpl) :: z_qsb ! sensible heat flux over ice … … 1016 1118 REAL(wp), DIMENSION(jpi,jpj,jpl) :: z_dqsb ! sensible heat sensitivity over ice 1017 1119 REAL(wp), DIMENSION(jpi,jpj) :: zevap, zsnw ! evaporation and snw distribution after wind blowing (SI3) 1018 REAL(wp), DIMENSION(jpi,jpj) :: zqair ! specific humidity of air at z=rn_zqt [kg/kg] !LB1019 1120 REAL(wp), DIMENSION(jpi,jpj) :: ztmp, ztmp2 1020 1121 REAL(wp), DIMENSION(jpi,jpj) :: ztri 1021 1122 !!--------------------------------------------------------------------- 1022 1123 ! 1023 zcoef_dqlw = 4._wp * 0.95_wp * stefan ! local scalars 1024 zcoef_dqla = -rLsub * 11637800._wp * (-5897.8_wp) !LB: BAD! 1025 ! 1026 SELECT CASE( nhumi ) 1027 CASE( np_humi_sph ) 1028 zqair(:,:) = phumi(:,:) ! what we read in file is already a spec. humidity! 1029 CASE( np_humi_dpt ) 1030 zqair(:,:) = q_sat( phumi(:,:), pslp ) 1031 CASE( np_humi_rlh ) 1032 zqair(:,:) = q_air_rh( 0.01_wp*phumi(:,:), ptair(:,:), pslp(:,:) ) !LB: 0.01 => RH is % percent in file 1033 END SELECT 1034 ! 1124 zcoef_dqlw = 4._wp * emiss_i * stefan ! local scalars 1125 ! 1126 1035 1127 zztmp = 1. / ( 1. - albo ) 1036 WHERE( ptsu(:,:,:) /= 0._wp ) 1037 z1_st(:,:,:) = 1._wp / ptsu(:,:,:) 1038 ELSEWHERE 1039 z1_st(:,:,:) = 0._wp 1040 END WHERE 1128 dqla_ice(:,:,:) = 0._wp 1129 1041 1130 ! ! ========================== ! 1042 1131 DO jl = 1, jpl ! Loop over ice categories ! 1043 1132 ! ! ========================== ! 1044 DO jj = 1 , jpj 1045 DO ji = 1, jpi 1133 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 1134 1135 zst = ptsu(ji,jj,jl) ! surface temperature of sea-ice [K] 1136 zsq = q_sat( zst, pslp(ji,jj), l_ice=.TRUE. ) ! surface saturation specific humidity when ice present 1137 1046 1138 ! ----------------------------! 1047 1139 ! I Radiative FLUXES ! 1048 1140 ! ----------------------------! 1049 zst3 = ptsu(ji,jj,jl) * ptsu(ji,jj,jl) * ptsu(ji,jj,jl)1050 1141 ! Short Wave (sw) 1051 1142 qsr_ice(ji,jj,jl) = zztmp * ( 1. - palb(ji,jj,jl) ) * qsr(ji,jj) 1143 1052 1144 ! Long Wave (lw) 1053 z_qlw(ji,jj,jl) = 0.95 * ( pqlw(ji,jj) - stefan * ptsu(ji,jj,jl) * zst3 ) * tmask(ji,jj,1) 1145 zst3 = zst * zst * zst 1146 z_qlw(ji,jj,jl) = emiss_i * ( pdqlw(ji,jj) - stefan * zst * zst3 ) * tmask(ji,jj,1) 1054 1147 ! lw sensitivity 1055 z_dqlw(ji,jj,jl) = zcoef_dqlw * zst31148 z_dqlw(ji,jj,jl) = zcoef_dqlw * zst3 1056 1149 1057 1150 ! ----------------------------! … … 1060 1153 1061 1154 ! ... turbulent heat fluxes with Ch_ice recalculated in blk_ice_1 1155 1156 ! Common term in bulk F. equations... 1157 zzblk = rhoa(ji,jj) * wndm_ice(ji,jj) 1158 1062 1159 ! Sensible Heat 1063 z_qsb(ji,jj,jl) = rhoa(ji,jj) * rCp_air * Ch_ice(ji,jj) * wndm_ice(ji,jj) * (ptsu(ji,jj,jl) - ptair(ji,jj)) 1160 zztmp1 = zzblk * rCp_air * Ch_ice(ji,jj) 1161 z_qsb (ji,jj,jl) = zztmp1 * (zst - theta_zu_i(ji,jj)) 1162 z_dqsb(ji,jj,jl) = zztmp1 ! ==> Qsens sensitivity (Dqsb_ice/Dtn_ice) 1163 1064 1164 ! Latent Heat 1065 zztmp2 = EXP( -5897.8 * z1_st(ji,jj,jl) ) 1066 qla_ice(ji,jj,jl) = rn_efac * MAX( 0.e0, rhoa(ji,jj) * rLsub * Ce_ice(ji,jj) * wndm_ice(ji,jj) * & 1067 & ( 11637800. * zztmp2 / rhoa(ji,jj) - zqair(ji,jj) ) ) 1068 ! Latent heat sensitivity for ice (Dqla/Dt) 1069 IF( qla_ice(ji,jj,jl) > 0._wp ) THEN 1070 dqla_ice(ji,jj,jl) = rn_efac * zcoef_dqla * Ce_ice(ji,jj) * wndm_ice(ji,jj) * & 1071 & z1_st(ji,jj,jl) * z1_st(ji,jj,jl) * zztmp2 1072 ELSE 1073 dqla_ice(ji,jj,jl) = 0._wp 1074 ENDIF 1075 1076 ! Sensible heat sensitivity (Dqsb_ice/Dtn_ice) 1077 z_dqsb(ji,jj,jl) = rhoa(ji,jj) * rCp_air * Ch_ice(ji,jj) * wndm_ice(ji,jj) 1165 zztmp1 = zzblk * rLsub * Ce_ice(ji,jj) 1166 qla_ice(ji,jj,jl) = MAX( zztmp1 * (zsq - q_zu_i(ji,jj)) , 0._wp ) ! #LB: only sublimation (and not condensation) ??? 1167 IF(qla_ice(ji,jj,jl)>0._wp) dqla_ice(ji,jj,jl) = zztmp1*dq_sat_dt_ice(zst, pslp(ji,jj)) ! ==> Qlat sensitivity (dQlat/dT) 1168 ! !#LB: dq_sat_dt_ice() in "sbc_phy.F90" 1169 !#LB: without this unjustified "condensation sensure": 1170 !qla_ice( ji,jj,jl) = zztmp1 * (zsq - q_zu_i(ji,jj)) 1171 !dqla_ice(ji,jj,jl) = zztmp1 * dq_sat_dt_ice(zst, pslp(ji,jj)) ! ==> Qlat sensitivity (dQlat/dT) 1172 1078 1173 1079 1174 ! ----------------------------! … … 1083 1178 qns_ice (ji,jj,jl) = z_qlw (ji,jj,jl) - z_qsb (ji,jj,jl) - qla_ice (ji,jj,jl) 1084 1179 ! Total non solar heat flux sensitivity for ice 1085 dqns_ice(ji,jj,jl) = - ( z_dqlw(ji,jj,jl) + z_dqsb(ji,jj,jl) + dqla_ice(ji,jj,jl) ) 1086 END DO 1087 ! 1088 END DO 1180 dqns_ice(ji,jj,jl) = - ( z_dqlw(ji,jj,jl) + z_dqsb(ji,jj,jl) + dqla_ice(ji,jj,jl) ) !#LB: correct signs ???? 1181 1182 END_2D 1089 1183 ! 1090 1184 END DO … … 1138 1232 ztri(:,:) = 0.18 * ( 1.0 - cloud_fra(:,:) ) + 0.35 * cloud_fra(:,:) ! surface transmission when hi>10cm 1139 1233 DO jl = 1, jpl 1140 WHERE ( phs(:,:,jl) <= 0._wp .AND. phi(:,:,jl) < 0.1_wp ) ! linear decrease from hi=0 to 10cm 1234 WHERE ( phs(:,:,jl) <= 0._wp .AND. phi(:,:,jl) < 0.1_wp ) ! linear decrease from hi=0 to 10cm 1141 1235 qtr_ice_top(:,:,jl) = qsr_ice(:,:,jl) * ( ztri(:,:) + ( 1._wp - ztri(:,:) ) * ( 1._wp - phi(:,:,jl) * 10._wp ) ) 1142 1236 ELSEWHERE( phs(:,:,jl) <= 0._wp .AND. phi(:,:,jl) >= 0.1_wp ) ! constant (ztri) when hi>10cm 1143 1237 qtr_ice_top(:,:,jl) = qsr_ice(:,:,jl) * ztri(:,:) 1144 1238 ELSEWHERE ! zero when hs>0 1145 qtr_ice_top(:,:,jl) = 0._wp 1239 qtr_ice_top(:,:,jl) = 0._wp 1146 1240 END WHERE 1147 1241 ENDDO … … 1182 1276 CALL prt_ctl(tab2d_1=tprecip , clinfo1=' blk_ice: tprecip : ', tab2d_2=sprecip , clinfo2=' sprecip : ') 1183 1277 ENDIF 1184 ! 1278 1279 !#LB: 1280 ! air-ice heat flux components that are not written from ice_stp()@icestp.F90: 1281 IF( iom_use('qla_ice') ) CALL iom_put( 'qla_ice', SUM( - qla_ice * a_i_b, dim=3 ) ) !#LB: sign consistent with what's done for ocean 1282 IF( iom_use('qsb_ice') ) CALL iom_put( 'qsb_ice', SUM( - z_qsb * a_i_b, dim=3 ) ) !#LB: ==> negative => loss of heat for sea-ice 1283 IF( iom_use('qlw_ice') ) CALL iom_put( 'qlw_ice', SUM( z_qlw * a_i_b, dim=3 ) ) 1284 !#LB. 1285 1185 1286 END SUBROUTINE blk_ice_2 1186 1287 … … 1278 1379 END SUBROUTINE blk_ice_qcn 1279 1380 1280 1281 SUBROUTINE Cdn10_Lupkes2012( pcd )1282 !!----------------------------------------------------------------------1283 !! *** ROUTINE Cdn10_Lupkes2012 ***1284 !!1285 !! ** Purpose : Recompute the neutral air-ice drag referenced at 10m1286 !! to make it dependent on edges at leads, melt ponds and flows.1287 !! After some approximations, this can be resumed to a dependency1288 !! on ice concentration.1289 !!1290 !! ** Method : The parameterization is taken from Lupkes et al. (2012) eq.(50)1291 !! with the highest level of approximation: level4, eq.(59)1292 !! The generic drag over a cell partly covered by ice can be re-written as follows:1293 !!1294 !! Cd = Cdw * (1-A) + Cdi * A + Ce * (1-A)**(nu+1/(10*beta)) * A**mu1295 !!1296 !! Ce = 2.23e-3 , as suggested by Lupkes (eq. 59)1297 !! nu = mu = beta = 1 , as suggested by Lupkes (eq. 59)1298 !! A is the concentration of ice minus melt ponds (if any)1299 !!1300 !! This new drag has a parabolic shape (as a function of A) starting at1301 !! Cdw(say 1.5e-3) for A=0, reaching 1.97e-3 for A~0.51302 !! and going down to Cdi(say 1.4e-3) for A=11303 !!1304 !! It is theoretically applicable to all ice conditions (not only MIZ)1305 !! => see Lupkes et al (2013)1306 !!1307 !! ** References : Lupkes et al. JGR 2012 (theory)1308 !! Lupkes et al. GRL 2013 (application to GCM)1309 !!1310 !!----------------------------------------------------------------------1311 REAL(wp), DIMENSION(:,:), INTENT(inout) :: pcd1312 REAL(wp), PARAMETER :: zCe = 2.23e-03_wp1313 REAL(wp), PARAMETER :: znu = 1._wp1314 REAL(wp), PARAMETER :: zmu = 1._wp1315 REAL(wp), PARAMETER :: zbeta = 1._wp1316 REAL(wp) :: zcoef1317 !!----------------------------------------------------------------------1318 zcoef = znu + 1._wp / ( 10._wp * zbeta )1319 1320 ! generic drag over a cell partly covered by ice1321 !!Cd(:,:) = Cd_oce(:,:) * ( 1._wp - at_i_b(:,:) ) + & ! pure ocean drag1322 !! & Cd_ice * at_i_b(:,:) + & ! pure ice drag1323 !! & zCe * ( 1._wp - at_i_b(:,:) )**zcoef * at_i_b(:,:)**zmu ! change due to sea-ice morphology1324 1325 ! ice-atm drag1326 pcd(:,:) = rCd_ice + & ! pure ice drag1327 & zCe * ( 1._wp - at_i_b(:,:) )**zcoef * at_i_b(:,:)**(zmu-1._wp) ! change due to sea-ice morphology1328 1329 END SUBROUTINE Cdn10_Lupkes20121330 1331 1332 SUBROUTINE Cdn10_Lupkes2015( ptm_su, pslp, pcd, pch )1333 !!----------------------------------------------------------------------1334 !! *** ROUTINE Cdn10_Lupkes2015 ***1335 !!1336 !! ** pUrpose : Alternative turbulent transfert coefficients formulation1337 !! between sea-ice and atmosphere with distinct momentum1338 !! and heat coefficients depending on sea-ice concentration1339 !! and atmospheric stability (no meltponds effect for now).1340 !!1341 !! ** Method : The parameterization is adapted from Lupkes et al. (2015)1342 !! and ECHAM6 atmospheric model. Compared to Lupkes2012 scheme,1343 !! it considers specific skin and form drags (Andreas et al. 2010)1344 !! to compute neutral transfert coefficients for both heat and1345 !! momemtum fluxes. Atmospheric stability effect on transfert1346 !! coefficient is also taken into account following Louis (1979).1347 !!1348 !! ** References : Lupkes et al. JGR 2015 (theory)1349 !! Lupkes et al. ECHAM6 documentation 2015 (implementation)1350 !!1351 !!----------------------------------------------------------------------1352 !1353 REAL(wp), DIMENSION(:,:), INTENT(in ) :: ptm_su ! sea-ice surface temperature [K]1354 REAL(wp), DIMENSION(:,:), INTENT(in ) :: pslp ! sea-level pressure [Pa]1355 REAL(wp), DIMENSION(:,:), INTENT(inout) :: pcd ! momentum transfert coefficient1356 REAL(wp), DIMENSION(:,:), INTENT(inout) :: pch ! heat transfert coefficient1357 REAL(wp), DIMENSION(jpi,jpj) :: zst, zqo_sat, zqi_sat1358 !1359 ! ECHAM6 constants1360 REAL(wp), PARAMETER :: z0_skin_ice = 0.69e-3_wp ! Eq. 43 [m]1361 REAL(wp), PARAMETER :: z0_form_ice = 0.57e-3_wp ! Eq. 42 [m]1362 REAL(wp), PARAMETER :: z0_ice = 1.00e-3_wp ! Eq. 15 [m]1363 REAL(wp), PARAMETER :: zce10 = 2.80e-3_wp ! Eq. 411364 REAL(wp), PARAMETER :: zbeta = 1.1_wp ! Eq. 411365 REAL(wp), PARAMETER :: zc = 5._wp ! Eq. 131366 REAL(wp), PARAMETER :: zc2 = zc * zc1367 REAL(wp), PARAMETER :: zam = 2. * zc ! Eq. 141368 REAL(wp), PARAMETER :: zah = 3. * zc ! Eq. 301369 REAL(wp), PARAMETER :: z1_alpha = 1._wp / 0.2_wp ! Eq. 511370 REAL(wp), PARAMETER :: z1_alphaf = z1_alpha ! Eq. 561371 REAL(wp), PARAMETER :: zbetah = 1.e-3_wp ! Eq. 261372 REAL(wp), PARAMETER :: zgamma = 1.25_wp ! Eq. 261373 REAL(wp), PARAMETER :: z1_gamma = 1._wp / zgamma1374 REAL(wp), PARAMETER :: r1_3 = 1._wp / 3._wp1375 !1376 INTEGER :: ji, jj ! dummy loop indices1377 REAL(wp) :: zthetav_os, zthetav_is, zthetav_zu1378 REAL(wp) :: zrib_o, zrib_i1379 REAL(wp) :: zCdn_skin_ice, zCdn_form_ice, zCdn_ice1380 REAL(wp) :: zChn_skin_ice, zChn_form_ice1381 REAL(wp) :: z0w, z0i, zfmi, zfmw, zfhi, zfhw1382 REAL(wp) :: zCdn_form_tmp1383 !!----------------------------------------------------------------------1384 1385 ! Momentum Neutral Transfert Coefficients (should be a constant)1386 zCdn_form_tmp = zce10 * ( LOG( 10._wp / z0_form_ice + 1._wp ) / LOG( rn_zu / z0_form_ice + 1._wp ) )**2 ! Eq. 401387 zCdn_skin_ice = ( vkarmn / LOG( rn_zu / z0_skin_ice + 1._wp ) )**2 ! Eq. 71388 zCdn_ice = zCdn_skin_ice ! Eq. 71389 !zCdn_ice = 1.89e-3 ! old ECHAM5 value (cf Eq. 32)1390 1391 ! Heat Neutral Transfert Coefficients1392 zChn_skin_ice = vkarmn**2 / ( LOG( rn_zu / z0_ice + 1._wp ) * LOG( rn_zu * z1_alpha / z0_skin_ice + 1._wp ) ) ! Eq. 50 + Eq. 521393 1394 ! Atmospheric and Surface Variables1395 zst(:,:) = sst_m(:,:) + rt0 ! convert SST from Celcius to Kelvin1396 zqo_sat(:,:) = rdct_qsat_salt * q_sat( zst(:,:) , pslp(:,:) ) ! saturation humidity over ocean [kg/kg]1397 zqi_sat(:,:) = q_sat( ptm_su(:,:), pslp(:,:) ) ! saturation humidity over ice [kg/kg]1398 !1399 DO_2D( 0, 0, 0, 0 )1400 ! Virtual potential temperature [K]1401 zthetav_os = zst(ji,jj) * ( 1._wp + rctv0 * zqo_sat(ji,jj) ) ! over ocean1402 zthetav_is = ptm_su(ji,jj) * ( 1._wp + rctv0 * zqi_sat(ji,jj) ) ! ocean ice1403 zthetav_zu = t_zu (ji,jj) * ( 1._wp + rctv0 * q_zu(ji,jj) ) ! at zu1404 1405 ! Bulk Richardson Number (could use Ri_bulk function from aerobulk instead)1406 zrib_o = grav / zthetav_os * ( zthetav_zu - zthetav_os ) * rn_zu / MAX( 0.5, wndm(ji,jj) )**2 ! over ocean1407 zrib_i = grav / zthetav_is * ( zthetav_zu - zthetav_is ) * rn_zu / MAX( 0.5, wndm_ice(ji,jj) )**2 ! over ice1408 1409 ! Momentum and Heat Neutral Transfert Coefficients1410 zCdn_form_ice = zCdn_form_tmp * at_i_b(ji,jj) * ( 1._wp - at_i_b(ji,jj) )**zbeta ! Eq. 401411 zChn_form_ice = zCdn_form_ice / ( 1._wp + ( LOG( z1_alphaf ) / vkarmn ) * SQRT( zCdn_form_ice ) ) ! Eq. 531412 1413 ! Momentum and Heat Stability functions (possibility to use psi_m_ecmwf instead ?)1414 z0w = rn_zu * EXP( -1._wp * vkarmn / SQRT( Cdn_oce(ji,jj) ) ) ! over water1415 z0i = z0_skin_ice ! over ice1416 IF( zrib_o <= 0._wp ) THEN1417 zfmw = 1._wp - zam * zrib_o / ( 1._wp + 3._wp * zc2 * Cdn_oce(ji,jj) * SQRT( -zrib_o * ( rn_zu / z0w + 1._wp ) ) ) ! Eq. 101418 zfhw = ( 1._wp + ( zbetah * ( zthetav_os - zthetav_zu )**r1_3 / ( Chn_oce(ji,jj) * MAX(0.01, wndm(ji,jj)) ) & ! Eq. 261419 & )**zgamma )**z1_gamma1420 ELSE1421 zfmw = 1._wp / ( 1._wp + zam * zrib_o / SQRT( 1._wp + zrib_o ) ) ! Eq. 121422 zfhw = 1._wp / ( 1._wp + zah * zrib_o / SQRT( 1._wp + zrib_o ) ) ! Eq. 281423 ENDIF1424 1425 IF( zrib_i <= 0._wp ) THEN1426 zfmi = 1._wp - zam * zrib_i / (1._wp + 3._wp * zc2 * zCdn_ice * SQRT( -zrib_i * ( rn_zu / z0i + 1._wp))) ! Eq. 91427 zfhi = 1._wp - zah * zrib_i / (1._wp + 3._wp * zc2 * zCdn_ice * SQRT( -zrib_i * ( rn_zu / z0i + 1._wp))) ! Eq. 251428 ELSE1429 zfmi = 1._wp / ( 1._wp + zam * zrib_i / SQRT( 1._wp + zrib_i ) ) ! Eq. 111430 zfhi = 1._wp / ( 1._wp + zah * zrib_i / SQRT( 1._wp + zrib_i ) ) ! Eq. 271431 ENDIF1432 1433 ! Momentum Transfert Coefficients (Eq. 38)1434 pcd(ji,jj) = zCdn_skin_ice * zfmi + &1435 & zCdn_form_ice * ( zfmi * at_i_b(ji,jj) + zfmw * ( 1._wp - at_i_b(ji,jj) ) ) / MAX( 1.e-06, at_i_b(ji,jj) )1436 1437 ! Heat Transfert Coefficients (Eq. 49)1438 pch(ji,jj) = zChn_skin_ice * zfhi + &1439 & zChn_form_ice * ( zfhi * at_i_b(ji,jj) + zfhw * ( 1._wp - at_i_b(ji,jj) ) ) / MAX( 1.e-06, at_i_b(ji,jj) )1440 !1441 END_2D1442 CALL lbc_lnk_multi( 'sbcblk', pcd, 'T', 1.0_wp, pch, 'T', 1.0_wp )1443 !1444 END SUBROUTINE Cdn10_Lupkes20151445 1446 1381 #endif 1447 1382 -
NEMO/trunk/src/OCE/SBC/sbcblk_algo_coare3p0.F90
r13460 r14072 7 7 !! * bulk transfer coefficients C_D, C_E and C_H 8 8 !! * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed 9 !! * the effective bulk wind speed at 10m U _blk9 !! * the effective bulk wind speed at 10m Ubzu 10 10 !! => all these are used in bulk formulas in sbcblk.F90 11 11 !! … … 15 15 !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk) 16 16 !!---------------------------------------------------------------------- 17 !! History : 4.0 ! 2016-02 (L.Brodeau) Original code 17 !! History : 4.0 ! 2016-02 (L.Brodeau) Original code 18 !! 4.2 ! 2020-12 (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 18 19 !!---------------------------------------------------------------------- 19 20 … … 37 38 38 39 USE sbc_oce ! Surface boundary condition: ocean fields 39 USE sbc blk_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB40 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 40 41 USE sbcblk_skin_coare ! cool-skin/warm layer scheme (CSWL_ECMWF) !LB 41 42 … … 50 51 REAL(wp), PARAMETER :: zi0 = 600._wp ! scale height of the atmospheric boundary layer... 51 52 REAL(wp), PARAMETER :: Beta0 = 1.25_wp ! gustiness parameter 52 53 INTEGER , PARAMETER :: nb_itt = 10 ! number of itterations 53 REAL(wp), PARAMETER :: zeta_abs_max = 50._wp 54 54 55 55 !!---------------------------------------------------------------------- … … 90 90 91 91 SUBROUTINE turb_coare3p0( kt, zt, zu, T_s, t_zt, q_s, q_zt, U_zu, l_use_cs, l_use_wl, & 92 & Cd, Ch, Ce, t_zu, q_zu, U _blk,&93 & Cdn, Chn, Cen, &92 & Cd, Ch, Ce, t_zu, q_zu, Ubzu, & 93 & nb_iter, Cdn, Chn, Cen, & ! optional output 94 94 & Qsw, rad_lw, slp, pdT_cs, & ! optionals for cool-skin (and warm-layer) 95 & pdT_wl, pHz_wl ) 95 & pdT_wl, pHz_wl ) ! optionals for warm-layer only 96 96 !!---------------------------------------------------------------------- 97 97 !! *** ROUTINE turb_coare3p0 *** … … 147 147 !! * t_zu : pot. air temperature adjusted at wind height zu [K] 148 148 !! * q_zu : specific humidity of air // [kg/kg] 149 !! * U _blk: bulk wind speed at zu [m/s]149 !! * Ubzu : bulk wind speed at zu [m/s] 150 150 !! 151 151 !! … … 167 167 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: t_zu ! pot. air temp. adjusted at zu [K] 168 168 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: q_zu ! spec. humidity adjusted at zu [kg/kg] 169 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: U_blk ! bulk wind speed at zu [m/s] 170 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Cdn, Chn, Cen ! neutral transfer coefficients 171 ! 169 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Ubzu ! bulk wind speed at zu [m/s] 170 ! 171 INTEGER , INTENT(in ), OPTIONAL :: nb_iter ! number of iterations 172 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CdN 173 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: ChN 174 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CeN 172 175 REAL(wp), INTENT(in ), OPTIONAL, DIMENSION(jpi,jpj) :: Qsw ! [W/m^2] 173 176 REAL(wp), INTENT(in ), OPTIONAL, DIMENSION(jpi,jpj) :: rad_lw ! [W/m^2] … … 177 180 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: pHz_wl ! [m] 178 181 ! 179 INTEGER :: j_itt182 INTEGER :: nbit, jit 180 183 LOGICAL :: l_zt_equal_zu = .FALSE. ! if q and t are given at same height as U 181 184 ! … … 194 197 IF( kt == nit000 ) CALL SBCBLK_ALGO_COARE3P0_INIT(l_use_cs, l_use_wl) 195 198 199 nbit = nb_iter0 200 IF( PRESENT(nb_iter) ) nbit = nb_iter 201 196 202 l_zt_equal_zu = ( ABS(zu - zt) < 0.01_wp ) ! testing "zu == zt" is risky with double precision 197 203 IF( .NOT. l_zt_equal_zu ) ALLOCATE( zeta_t(jpi,jpj) ) … … 211 217 ENDIF 212 218 213 214 219 !! First guess of temperature and humidity at height zu: 215 220 t_zu = MAX( t_zt , 180._wp ) ! who knows what's given on masked-continental regions... … … 222 227 znu_a = visc_air(t_zu) ! Air viscosity (m^2/s) at zt given from temperature in (K) 223 228 224 U _blk= SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution229 Ubzu = SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution 225 230 226 231 ztmp0 = LOG( zu*10000._wp) ! optimization: 10000. == 1/z0 (with z0 first guess == 0.0001) 227 232 ztmp1 = LOG(10._wp*10000._wp) ! " " " 228 u_star = 0.035_wp*U _blk*ztmp1/ztmp0 ! (u* = 0.035*Un10)229 230 z0 = alfa_charn_3p0(U_zu)*u_star*u_star/grav + 0.11_wp*znu_a/u_star233 u_star = 0.035_wp*Ubzu*ztmp1/ztmp0 ! (u* = 0.035*Un10) 234 235 z0 = charn_coare3p0(U_zu)*u_star*u_star/grav + 0.11_wp*znu_a/u_star 231 236 z0 = MIN( MAX(ABS(z0), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 232 237 … … 234 239 z0t = MIN( MAX(ABS(z0t), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 235 240 236 Cd = (vkarmn/ztmp0)**2! first guess of Cd237 238 ztmp0 = vkarmn *vkarmn/LOG(zt/z0t)/Cd239 240 ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U _blk) ! Bulk Richardson Number (BRN)241 Cd = MAX( (vkarmn/ztmp0)**2 , Cx_min ) ! first guess of Cd 242 243 ztmp0 = vkarmn2/LOG(zt/z0t)/Cd 244 245 ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, Ubzu ) ! Bulk Richardson Number (BRN) 241 246 242 247 !! First estimate of zeta_u, depending on the stability, ie sign of BRN (ztmp2): 243 248 ztmp1 = 0.5 + SIGN( 0.5_wp , ztmp2 ) 244 ztmp0 = ztmp0*ztmp2 245 zeta_u = (1._wp-ztmp1) * (ztmp0/(1._wp+ztmp2/(-zu/(zi0*0.004_wp*Beta0**3)))) & ! BRN < 0 246 & + ztmp1 * (ztmp0*(1._wp + 27._wp/9._wp*ztmp2/ztmp0)) ! BRN > 0 247 !#LB: should make sure that the "ztmp0" of "27./9.*ztmp2/ztmp0" is "ztmp0*ztmp2" and not "ztmp0==vkarmn*vkarmn/LOG(zt/z0t)/Cd" ! 249 zeta_u = (1._wp - ztmp1) * ztmp0*ztmp2 / (1._wp - ztmp2*zi0*0.004_wp*Beta0**3/zu) & ! BRN < 0 250 & + ztmp1 * ( ztmp0*ztmp2 + 27._wp/9._wp*ztmp2*ztmp2 ) ! BRN > 0 248 251 249 252 !! First guess M-O stability dependent scaling params.(u*,t*,q*) to estimate z0 and z/L 250 253 ztmp0 = vkarmn/(LOG(zu/z0t) - psi_h_coare(zeta_u)) 251 254 252 u_star = MAX ( U _blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on)255 u_star = MAX ( Ubzu*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on) 253 256 t_star = dt_zu*ztmp0 254 257 q_star = dq_zu*ztmp0 … … 269 272 270 273 !! ITERATION BLOCK 271 DO j _itt = 1, nb_itt272 273 !!Inverse of Monin-Obukov length (1/L) :274 ztmp0 = One_on_L(t_zu, q_zu, u_star, t_star, q_star) ! 1/L == 1/[ Monin-Obukhov length]275 ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! (prevents FPE from stupid values from masked region later on...)274 DO jit = 1, nbit 275 276 !!Inverse of Obukov length (1/L) : 277 ztmp0 = One_on_L(t_zu, q_zu, u_star, t_star, q_star) ! 1/L == 1/[Obukhov length] 278 ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! 1/L (prevents FPE from stupid values from masked region later on...) 276 279 277 280 ztmp1 = u_star*u_star ! u*^2 … … 280 283 ztmp2 = Beta0*Beta0*ztmp1*(MAX(-zi0*ztmp0/vkarmn,0._wp))**(2._wp/3._wp) ! square of wind gustiness contribution, ztmp2 == Ug^2 281 284 !! ! Only true when unstable (L<0) => when ztmp0 < 0 => explains "-" before zi0 282 U _blk= MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp) ! include gustiness in bulk wind speed283 ! => 0.2 prevents U _blkto be 0 in stable case when U_zu=0.285 Ubzu = MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp) ! include gustiness in bulk wind speed 286 ! => 0.2 prevents Ubzu to be 0 in stable case when U_zu=0. 284 287 285 288 !! Stability parameters: 286 289 zeta_u = zu*ztmp0 287 zeta_u = SIGN( MIN(ABS(zeta_u), 50.0_wp), zeta_u )290 zeta_u = SIGN( MIN(ABS(zeta_u),zeta_abs_max), zeta_u ) 288 291 IF( .NOT. l_zt_equal_zu ) THEN 289 292 zeta_t = zt*ztmp0 290 zeta_t = SIGN( MIN(ABS(zeta_t), 50.0_wp), zeta_t )293 zeta_t = SIGN( MIN(ABS(zeta_t),zeta_abs_max), zeta_t ) 291 294 ENDIF 292 295 … … 296 299 !! Roughness lengthes z0, z0t (z0q = z0t) : 297 300 ztmp2 = u_star/vkarmn*LOG(10./z0) ! Neutral wind speed at 10m 298 z0 = alfa_charn_3p0(ztmp2)*ztmp1/grav + 0.11_wp*znu_a/u_star ! Roughness length (eq.6) [ ztmp1==u*^2 ]301 z0 = charn_coare3p0(ztmp2)*ztmp1/grav + 0.11_wp*znu_a/u_star ! Roughness length (eq.6) [ ztmp1==u*^2 ] 299 302 z0 = MIN( MAX(ABS(z0), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 300 303 … … 309 312 t_star = dt_zu*ztmp1 310 313 q_star = dq_zu*ztmp1 311 u_star = MAX( U _blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on)314 u_star = MAX( Ubzu*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on) 312 315 313 316 IF( .NOT. l_zt_equal_zu ) THEN … … 318 321 ENDIF 319 322 320 321 323 IF( l_use_cs ) THEN 322 324 !! Cool-skin contribution 323 325 324 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U _blk, slp, rad_lw, &326 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, Ubzu, slp, rad_lw, & 325 327 & ztmp1, zeta_u, Qlat=ztmp2) ! Qnsol -> ztmp1 / Tau -> zeta_u 326 328 … … 330 332 IF( l_use_wl ) T_s(:,:) = T_s(:,:) + dT_wl(:,:)*tmask(:,:,1) 331 333 q_s(:,:) = rdct_qsat_salt*q_sat(MAX(T_s(:,:), 200._wp), slp(:,:)) 332 333 334 ENDIF 334 335 335 336 IF( l_use_wl ) THEN 336 337 !! Warm-layer contribution 337 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U _blk, slp, rad_lw, &338 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, Ubzu, slp, rad_lw, & 338 339 & ztmp1, zeta_u) ! Qnsol -> ztmp1 / Tau -> zeta_u 339 340 !! In WL_COARE or , Tau_ac and Qnt_ac must be updated at the final itteration step => add a flag to do this! 340 CALL WL_COARE( Qsw, ztmp1, zeta_u, zsst, MOD(nb _itt,j_itt) )341 CALL WL_COARE( Qsw, ztmp1, zeta_u, zsst, MOD(nbit,jit) ) 341 342 342 343 !! Updating T_s and q_s !!! … … 351 352 ENDIF 352 353 353 END DO !DO j _itt = 1, nb_itt354 END DO !DO jit = 1, nbit 354 355 355 356 ! compute transfer coefficients at zu : 356 ztmp0 = u_star/U_blk 357 Cd = ztmp0*ztmp0 358 Ch = ztmp0*t_star/dt_zu 359 Ce = ztmp0*q_star/dq_zu 360 361 ztmp1 = zu + z0 362 Cdn = vkarmn*vkarmn / (log(ztmp1/z0 )*log(ztmp1/z0 )) 363 Chn = vkarmn*vkarmn / (log(ztmp1/z0t)*log(ztmp1/z0t)) 364 Cen = Chn 357 ztmp0 = u_star/Ubzu 358 Cd = MAX( ztmp0*ztmp0 , Cx_min ) 359 Ch = MAX( ztmp0*t_star/dt_zu , Cx_min ) 360 Ce = MAX( ztmp0*q_star/dq_zu , Cx_min ) 365 361 366 362 IF( .NOT. l_zt_equal_zu ) DEALLOCATE( zeta_t ) 363 364 IF(PRESENT(Cdn)) Cdn = MAX( vkarmn2 / (LOG(zu/z0 )*LOG(zu/z0 )) , Cx_min ) 365 IF(PRESENT(Chn)) Chn = MAX( vkarmn2 / (LOG(zu/z0t)*LOG(zu/z0t)) , Cx_min ) 366 IF(PRESENT(Cen)) Cen = MAX( vkarmn2 / (LOG(zu/z0t)*LOG(zu/z0t)) , Cx_min ) 367 367 368 368 IF( l_use_cs .AND. PRESENT(pdT_cs) ) pdT_cs = dT_cs … … 375 375 376 376 377 FUNCTION alfa_charn_3p0( pwnd )377 FUNCTION charn_coare3p0( pwnd ) 378 378 !!------------------------------------------------------------------- 379 379 !! Compute the Charnock parameter as a function of the wind speed … … 387 387 !! Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 388 388 !!------------------------------------------------------------------- 389 REAL(wp), DIMENSION(jpi,jpj) :: alfa_charn_3p0389 REAL(wp), DIMENSION(jpi,jpj) :: charn_coare3p0 390 390 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pwnd ! wind speed 391 391 ! … … 393 393 REAL(wp) :: zw, zgt10, zgt18 394 394 !!------------------------------------------------------------------- 395 !396 395 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 397 !398 zw = pwnd(ji,jj) ! wind speed399 !400 ! Charnock's constant, increases with the wind :401 zgt10 = 0.5 + SIGN(0.5_wp,(zw - 10)) ! If zw<10. --> 0, else --> 1402 zgt18 = 0.5 + SIGN(0.5_wp,(zw - 18.)) ! If zw<18. --> 0, else --> 1403 !404 alfa_charn_3p0(ji,jj) = (1. - zgt10)*0.011 & ! wind is lower than 10 m/s405 & + zgt10*((1. - zgt18)*(0.011 + (0.018 - 0.011) &406 & *(zw - 10.)/(18. - 10.)) + zgt18*( 0.018 ) ) ! Hare et al. (1999)407 !396 ! 397 zw = pwnd(ji,jj) ! wind speed 398 ! 399 ! Charnock's constant, increases with the wind : 400 zgt10 = 0.5 + SIGN(0.5_wp,(zw - 10)) ! If zw<10. --> 0, else --> 1 401 zgt18 = 0.5 + SIGN(0.5_wp,(zw - 18.)) ! If zw<18. --> 0, else --> 1 402 ! 403 charn_coare3p0(ji,jj) = (1. - zgt10)*0.011 & ! wind is lower than 10 m/s 404 & + zgt10*((1. - zgt18)*(0.011 + (0.018 - 0.011) & 405 & *(zw - 10.)/(18. - 10.)) + zgt18*( 0.018 ) ) ! Hare et al. (1999) 406 ! 408 407 END_2D 409 ! 410 END FUNCTION alfa_charn_3p0 408 END FUNCTION charn_coare3p0 411 409 412 410 FUNCTION psi_m_coare( pzeta ) … … 429 427 REAL(wp) :: zta, zphi_m, zphi_c, zpsi_k, zpsi_c, zf, zc, zstab 430 428 !!---------------------------------------------------------------------------------- 431 !432 429 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 433 ! 434 zta = pzeta(ji,jj) 435 ! 436 zphi_m = ABS(1. - 15.*zta)**.25 !!Kansas unstable 437 ! 438 zpsi_k = 2.*LOG((1. + zphi_m)/2.) + LOG((1. + zphi_m*zphi_m)/2.) & 439 & - 2.*ATAN(zphi_m) + 0.5*rpi 440 ! 441 zphi_c = ABS(1. - 10.15*zta)**.3333 !!Convective 442 ! 443 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 444 & - 1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 445 ! 446 zf = zta*zta 447 zf = zf/(1. + zf) 448 zc = MIN(50._wp, 0.35_wp*zta) 449 zstab = 0.5 + SIGN(0.5_wp, zta) 450 ! 451 psi_m_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & ! (zta < 0) 452 & - zstab * ( 1. + 1.*zta & ! (zta > 0) 453 & + 0.6667*(zta - 14.28)/EXP(zc) + 8.525 ) ! " 454 ! 430 ! 431 zta = pzeta(ji,jj) 432 ! 433 zphi_m = ABS(1. - 15.*zta)**.25 !!Kansas unstable 434 ! 435 zpsi_k = 2.*LOG((1. + zphi_m)/2.) + LOG((1. + zphi_m*zphi_m)/2.) & 436 & - 2.*ATAN(zphi_m) + 0.5*rpi 437 ! 438 zphi_c = ABS(1. - 10.15*zta)**.3333 !!Convective 439 ! 440 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 441 & - 1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 442 ! 443 zf = zta*zta 444 zf = zf/(1. + zf) 445 zc = MIN(50._wp, 0.35_wp*zta) 446 zstab = 0.5 + SIGN(0.5_wp, zta) 447 ! 448 psi_m_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & ! (zta < 0) 449 & - zstab * ( 1. + 1.*zta & ! (zta > 0) 450 & + 0.6667*(zta - 14.28)/EXP(zc) + 8.525 ) ! " 455 451 END_2D 456 !457 452 END FUNCTION psi_m_coare 458 453 … … 474 469 !! (https://github.com/brodeau/aerobulk/) 475 470 !!---------------------------------------------------------------- 476 !!477 471 REAL(wp), DIMENSION(jpi,jpj) :: psi_h_coare 478 472 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta … … 480 474 INTEGER :: ji, jj ! dummy loop indices 481 475 REAL(wp) :: zta, zphi_h, zphi_c, zpsi_k, zpsi_c, zf, zc, zstab 482 ! 476 !!---------------------------------------------------------------- 483 477 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 484 ! 485 zta = pzeta(ji,jj) 486 ! 487 zphi_h = (ABS(1. - 15.*zta))**.5 !! Kansas unstable (zphi_h = zphi_m**2 when unstable, zphi_m when stable) 488 ! 489 zpsi_k = 2.*LOG((1. + zphi_h)/2.) 490 ! 491 zphi_c = (ABS(1. - 34.15*zta))**.3333 !! Convective 492 ! 493 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 494 & -1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 495 ! 496 zf = zta*zta 497 zf = zf/(1. + zf) 498 zc = MIN(50._wp,0.35_wp*zta) 499 zstab = 0.5 + SIGN(0.5_wp, zta) 500 ! 501 psi_h_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & 502 & - zstab * ( (ABS(1. + 2.*zta/3.))**1.5 & 503 & + .6667*(zta - 14.28)/EXP(zc) + 8.525 ) 504 ! 478 ! 479 zta = pzeta(ji,jj) 480 ! 481 zphi_h = (ABS(1. - 15.*zta))**.5 !! Kansas unstable (zphi_h = zphi_m**2 when unstable, zphi_m when stable) 482 ! 483 zpsi_k = 2.*LOG((1. + zphi_h)/2.) 484 ! 485 zphi_c = (ABS(1. - 34.15*zta))**.3333 !! Convective 486 ! 487 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 488 & -1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 489 ! 490 zf = zta*zta 491 zf = zf/(1. + zf) 492 zc = MIN(50._wp,0.35_wp*zta) 493 zstab = 0.5 + SIGN(0.5_wp, zta) 494 ! 495 psi_h_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & 496 & - zstab * ( (ABS(1. + 2.*zta/3.))**1.5 & 497 & + .6667*(zta - 14.28)/EXP(zc) + 8.525 ) 505 498 END_2D 506 !507 499 END FUNCTION psi_h_coare 508 500 -
NEMO/trunk/src/OCE/SBC/sbcblk_algo_coare3p6.F90
r13460 r14072 7 7 !! * bulk transfer coefficients C_D, C_E and C_H 8 8 !! * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed 9 !! * the effective bulk wind speed at 10m U _blk9 !! * the effective bulk wind speed at 10m Ubzu 10 10 !! => all these are used in bulk formulas in sbcblk.F90 11 11 !! … … 16 16 !!---------------------------------------------------------------------- 17 17 !! History : 4.0 ! 2016-02 (L.Brodeau) Original code 18 !! 4.2 ! 2020-12 (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 18 19 !!---------------------------------------------------------------------- 19 20 … … 23 24 !! returns the effective bulk wind speed at 10m 24 25 !!---------------------------------------------------------------------- 25 USE oce ! ocean dynamics and tracers26 26 USE dom_oce ! ocean space and time domain 27 27 USE phycst ! physical constants 28 USE iom ! I/O manager library 29 USE lib_mpp ! distribued memory computing library 30 USE in_out_manager ! I/O manager 31 USE prtctl ! Print control 32 USE sbcwave, ONLY : cdn_wave ! wave module 33 #if defined key_si3 || defined key_cice 34 USE sbc_ice ! Surface boundary condition: ice fields 35 #endif 36 USE lib_fortran ! to use key_nosignedzero 37 38 USE sbc_oce ! Surface boundary condition: ocean fields 39 USE sbcblk_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB 28 USE lib_mpp, ONLY: ctl_stop ! distribued memory computing library 29 USE in_out_manager, ONLY: nit000 ! I/O manager 30 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 40 31 USE sbcblk_skin_coare ! cool-skin/warm layer scheme (CSWL_ECMWF) !LB 41 32 … … 50 41 REAL(wp), PARAMETER :: zi0 = 600._wp ! scale height of the atmospheric boundary layer... 51 42 REAL(wp), PARAMETER :: Beta0 = 1.2_wp ! gustiness parameter 52 53 INTEGER , PARAMETER :: nb_itt = 10 ! number of itterations 43 REAL(wp), PARAMETER :: zeta_abs_max = 50._wp 54 44 55 45 !!---------------------------------------------------------------------- … … 90 80 91 81 SUBROUTINE turb_coare3p6( kt, zt, zu, T_s, t_zt, q_s, q_zt, U_zu, l_use_cs, l_use_wl, & 92 & Cd, Ch, Ce, t_zu, q_zu, U _blk,&93 & Cdn, Chn, Cen, &82 & Cd, Ch, Ce, t_zu, q_zu, Ubzu, & 83 & nb_iter, Cdn, Chn, Cen, & ! optional output 94 84 & Qsw, rad_lw, slp, pdT_cs, & ! optionals for cool-skin (and warm-layer) 95 & pdT_wl, pHz_wl ) 85 & pdT_wl, pHz_wl ) ! optionals for warm-layer only 96 86 !!---------------------------------------------------------------------- 97 87 !! *** ROUTINE turb_coare3p6 *** … … 147 137 !! * t_zu : pot. air temperature adjusted at wind height zu [K] 148 138 !! * q_zu : specific humidity of air // [kg/kg] 149 !! * U _blk: bulk wind speed at zu [m/s]139 !! * Ubzu : bulk wind speed at zu [m/s] 150 140 !! 151 141 !! … … 167 157 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: t_zu ! pot. air temp. adjusted at zu [K] 168 158 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: q_zu ! spec. humidity adjusted at zu [kg/kg] 169 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: U_blk ! bulk wind speed at zu [m/s] 170 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Cdn, Chn, Cen ! neutral transfer coefficients 171 ! 159 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Ubzu ! bulk wind speed at zu [m/s] 160 ! 161 INTEGER , INTENT(in ), OPTIONAL :: nb_iter ! number of iterations 162 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CdN 163 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: ChN 164 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CeN 172 165 REAL(wp), INTENT(in ), OPTIONAL, DIMENSION(jpi,jpj) :: Qsw ! [W/m^2] 173 166 REAL(wp), INTENT(in ), OPTIONAL, DIMENSION(jpi,jpj) :: rad_lw ! [W/m^2] … … 177 170 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: pHz_wl ! [m] 178 171 ! 179 INTEGER :: j_itt172 INTEGER :: nbit, jit 180 173 LOGICAL :: l_zt_equal_zu = .FALSE. ! if q and t are given at same height as U 181 174 ! … … 194 187 IF( kt == nit000 ) CALL SBCBLK_ALGO_COARE3P6_INIT(l_use_cs, l_use_wl) 195 188 189 nbit = nb_iter0 190 IF( PRESENT(nb_iter) ) nbit = nb_iter 191 196 192 l_zt_equal_zu = ( ABS(zu - zt) < 0.01_wp ) ! testing "zu == zt" is risky with double precision 197 193 IF( .NOT. l_zt_equal_zu ) ALLOCATE( zeta_t(jpi,jpj) ) … … 211 207 ENDIF 212 208 213 214 209 !! First guess of temperature and humidity at height zu: 215 210 t_zu = MAX( t_zt , 180._wp ) ! who knows what's given on masked-continental regions... … … 222 217 znu_a = visc_air(t_zu) ! Air viscosity (m^2/s) at zt given from temperature in (K) 223 218 224 U _blk= SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution219 Ubzu = SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution 225 220 226 221 ztmp0 = LOG( zu*10000._wp) ! optimization: 10000. == 1/z0 (with z0 first guess == 0.0001) 227 222 ztmp1 = LOG(10._wp*10000._wp) ! " " " 228 u_star = 0.035_wp*U _blk*ztmp1/ztmp0 ! (u* = 0.035*Un10)229 230 z0 = alfa_charn_3p6(U_zu)*u_star*u_star/grav + 0.11_wp*znu_a/u_star223 u_star = 0.035_wp*Ubzu*ztmp1/ztmp0 ! (u* = 0.035*Un10) 224 225 z0 = charn_coare3p6(U_zu)*u_star*u_star/grav + 0.11_wp*znu_a/u_star 231 226 z0 = MIN( MAX(ABS(z0), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 232 227 … … 234 229 z0t = MIN( MAX(ABS(z0t), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 235 230 236 Cd = (vkarmn/ztmp0)**2! first guess of Cd237 238 ztmp0 = vkarmn *vkarmn/LOG(zt/z0t)/Cd239 240 ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U _blk) ! Bulk Richardson Number (BRN)231 Cd = MAX( (vkarmn/ztmp0)**2 , Cx_min ) ! first guess of Cd 232 233 ztmp0 = vkarmn2/LOG(zt/z0t)/Cd 234 235 ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, Ubzu ) ! Bulk Richardson Number (BRN) 241 236 242 237 !! First estimate of zeta_u, depending on the stability, ie sign of BRN (ztmp2): 243 238 ztmp1 = 0.5 + SIGN( 0.5_wp , ztmp2 ) 244 ztmp0 = ztmp0*ztmp2 245 zeta_u = (1._wp-ztmp1) * (ztmp0/(1._wp+ztmp2/(-zu/(zi0*0.004_wp*Beta0**3)))) & ! BRN < 0 246 & + ztmp1 * (ztmp0*(1._wp + 27._wp/9._wp*ztmp2/ztmp0)) ! BRN > 0 247 !#LB: should make sure that the "ztmp0" of "27./9.*ztmp2/ztmp0" is "ztmp0*ztmp2" and not "ztmp0==vkarmn*vkarmn/LOG(zt/z0t)/Cd" ! 239 zeta_u = (1._wp - ztmp1) * ztmp0*ztmp2 / (1._wp - ztmp2*zi0*0.004_wp*Beta0**3/zu) & ! BRN < 0 240 & + ztmp1 * ( ztmp0*ztmp2 + 27._wp/9._wp*ztmp2*ztmp2 ) ! BRN > 0 248 241 249 242 !! First guess M-O stability dependent scaling params.(u*,t*,q*) to estimate z0 and z/L 250 243 ztmp0 = vkarmn/(LOG(zu/z0t) - psi_h_coare(zeta_u)) 251 244 252 u_star = MAX ( U _blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on)245 u_star = MAX ( Ubzu*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on) 253 246 t_star = dt_zu*ztmp0 254 247 q_star = dq_zu*ztmp0 … … 269 262 270 263 !! ITERATION BLOCK 271 DO j _itt = 1, nb_itt272 273 !!Inverse of Monin-Obukov length (1/L) :274 ztmp0 = One_on_L(t_zu, q_zu, u_star, t_star, q_star) ! 1/L == 1/[ Monin-Obukhov length]275 ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! (prevents FPE from stupid values from masked region later on...)264 DO jit = 1, nbit 265 266 !!Inverse of Obukov length (1/L) : 267 ztmp0 = One_on_L(t_zu, q_zu, u_star, t_star, q_star) ! 1/L == 1/[Obukhov length] 268 ztmp0 = SIGN( MIN(ABS(ztmp0),200._wp), ztmp0 ) ! 1/L (prevents FPE from stupid values from masked region later on...) 276 269 277 270 ztmp1 = u_star*u_star ! u*^2 … … 280 273 ztmp2 = Beta0*Beta0*ztmp1*(MAX(-zi0*ztmp0/vkarmn,0._wp))**(2._wp/3._wp) ! square of wind gustiness contribution, ztmp2 == Ug^2 281 274 !! ! Only true when unstable (L<0) => when ztmp0 < 0 => explains "-" before zi0 282 U _blk= MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp) ! include gustiness in bulk wind speed283 ! => 0.2 prevents U _blkto be 0 in stable case when U_zu=0.275 Ubzu = MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp) ! include gustiness in bulk wind speed 276 ! => 0.2 prevents Ubzu to be 0 in stable case when U_zu=0. 284 277 285 278 !! Stability parameters: 286 279 zeta_u = zu*ztmp0 287 zeta_u = SIGN( MIN(ABS(zeta_u), 50.0_wp), zeta_u )280 zeta_u = SIGN( MIN(ABS(zeta_u),zeta_abs_max), zeta_u ) 288 281 IF( .NOT. l_zt_equal_zu ) THEN 289 282 zeta_t = zt*ztmp0 290 zeta_t = SIGN( MIN(ABS(zeta_t), 50.0_wp), zeta_t )283 zeta_t = SIGN( MIN(ABS(zeta_t),zeta_abs_max), zeta_t ) 291 284 ENDIF 292 285 … … 296 289 !! Roughness lengthes z0, z0t (z0q = z0t) : 297 290 ztmp2 = u_star/vkarmn*LOG(10./z0) ! Neutral wind speed at 10m 298 z0 = alfa_charn_3p6(ztmp2)*ztmp1/grav + 0.11_wp*znu_a/u_star ! Roughness length (eq.6) [ ztmp1==u*^2 ]291 z0 = charn_coare3p6(ztmp2)*ztmp1/grav + 0.11_wp*znu_a/u_star ! Roughness length (eq.6) [ ztmp1==u*^2 ] 299 292 z0 = MIN( MAX(ABS(z0), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 300 293 … … 309 302 t_star = dt_zu*ztmp1 310 303 q_star = dq_zu*ztmp1 311 u_star = MAX( U _blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on)304 u_star = MAX( Ubzu*vkarmn/(LOG(zu) - LOG(z0) - psi_m_coare(zeta_u)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on) 312 305 313 306 IF( .NOT. l_zt_equal_zu ) THEN … … 318 311 ENDIF 319 312 320 321 313 IF( l_use_cs ) THEN 322 314 !! Cool-skin contribution 323 315 324 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U _blk, slp, rad_lw, &316 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, Ubzu, slp, rad_lw, & 325 317 & ztmp1, zeta_u, Qlat=ztmp2) ! Qnsol -> ztmp1 / Tau -> zeta_u 326 318 … … 330 322 IF( l_use_wl ) T_s(:,:) = T_s(:,:) + dT_wl(:,:)*tmask(:,:,1) 331 323 q_s(:,:) = rdct_qsat_salt*q_sat(MAX(T_s(:,:), 200._wp), slp(:,:)) 332 333 324 ENDIF 334 325 335 326 IF( l_use_wl ) THEN 336 327 !! Warm-layer contribution 337 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U _blk, slp, rad_lw, &328 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, Ubzu, slp, rad_lw, & 338 329 & ztmp1, zeta_u) ! Qnsol -> ztmp1 / Tau -> zeta_u 339 330 !! In WL_COARE or , Tau_ac and Qnt_ac must be updated at the final itteration step => add a flag to do this! 340 CALL WL_COARE( Qsw, ztmp1, zeta_u, zsst, MOD(nb _itt,j_itt) )331 CALL WL_COARE( Qsw, ztmp1, zeta_u, zsst, MOD(nbit,jit) ) 341 332 342 333 !! Updating T_s and q_s !!! … … 351 342 ENDIF 352 343 353 END DO !DO j _itt = 1, nb_itt344 END DO !DO jit = 1, nbit 354 345 355 346 ! compute transfer coefficients at zu : 356 ztmp0 = u_star/U_blk 357 Cd = ztmp0*ztmp0 358 Ch = ztmp0*t_star/dt_zu 359 Ce = ztmp0*q_star/dq_zu 360 361 ztmp1 = zu + z0 362 Cdn = vkarmn*vkarmn / (log(ztmp1/z0 )*log(ztmp1/z0 )) 363 Chn = vkarmn*vkarmn / (log(ztmp1/z0t)*log(ztmp1/z0t)) 364 Cen = Chn 347 ztmp0 = u_star/Ubzu 348 Cd = MAX( ztmp0*ztmp0 , Cx_min ) 349 Ch = MAX( ztmp0*t_star/dt_zu , Cx_min ) 350 Ce = MAX( ztmp0*q_star/dq_zu , Cx_min ) 365 351 366 352 IF( .NOT. l_zt_equal_zu ) DEALLOCATE( zeta_t ) 353 354 IF(PRESENT(Cdn)) Cdn = MAX( vkarmn2 / (LOG(zu/z0 )*LOG(zu/z0 )) , Cx_min ) 355 IF(PRESENT(Chn)) Chn = MAX( vkarmn2 / (LOG(zu/z0t)*LOG(zu/z0t)) , Cx_min ) 356 IF(PRESENT(Cen)) Cen = MAX( vkarmn2 / (LOG(zu/z0t)*LOG(zu/z0t)) , Cx_min ) 367 357 368 358 IF( l_use_cs .AND. PRESENT(pdT_cs) ) pdT_cs = dT_cs … … 375 365 376 366 377 FUNCTION alfa_charn_3p6( pwnd )367 FUNCTION charn_coare3p6( pwnd ) 378 368 !!------------------------------------------------------------------- 379 369 !! Computes the Charnock parameter as a function of the Neutral wind speed at 10m … … 383 373 !! Author: L. Brodeau, July 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) 384 374 !!------------------------------------------------------------------- 385 REAL(wp), DIMENSION(jpi,jpj) :: alfa_charn_3p6375 REAL(wp), DIMENSION(jpi,jpj) :: charn_coare3p6 386 376 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pwnd ! neutral wind speed at 10m 387 377 ! 388 378 REAL(wp), PARAMETER :: charn0_max = 0.028 !: value above which the Charnock parameter levels off for winds > 18 m/s 389 379 !!------------------------------------------------------------------- 390 alfa_charn_3p6 = MAX( MIN( 0.0017_wp*pwnd - 0.005_wp , charn0_max) , 0._wp )391 !! 392 END FUNCTION alfa_charn_3p6393 394 FUNCTION alfa_charn_3p6_wave( pus, pwsh, pwps )380 charn_coare3p6 = MAX( MIN( 0.0017_wp*pwnd - 0.005_wp , charn0_max) , 0._wp ) 381 !! 382 END FUNCTION charn_coare3p6 383 384 FUNCTION charn_coare3p6_wave( pus, pwsh, pwps ) 395 385 !!------------------------------------------------------------------- 396 386 !! Computes the Charnock parameter as a function of wave information and u* … … 400 390 !! Author: L. Brodeau, October 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) 401 391 !!------------------------------------------------------------------- 402 REAL(wp), DIMENSION(jpi,jpj) :: alfa_charn_3p6_wave392 REAL(wp), DIMENSION(jpi,jpj) :: charn_coare3p6_wave 403 393 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pus ! friction velocity [m/s] 404 394 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pwsh ! significant wave height [m] 405 395 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pwps ! phase speed of dominant waves [m/s] 406 396 !!------------------------------------------------------------------- 407 alfa_charn_3p6_wave = ( pwsh*0.2_wp*(pus/pwps)**2.2_wp ) * grav/(pus*pus)408 !! 409 END FUNCTION alfa_charn_3p6_wave397 charn_coare3p6_wave = ( pwsh*0.2_wp*(pus/pwps)**2.2_wp ) * grav/(pus*pus) 398 !! 399 END FUNCTION charn_coare3p6_wave 410 400 411 401 … … 429 419 REAL(wp) :: zta, zphi_m, zphi_c, zpsi_k, zpsi_c, zf, zc, zstab 430 420 !!---------------------------------------------------------------------------------- 431 !432 421 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 433 ! 434 zta = pzeta(ji,jj) 435 ! 436 zphi_m = ABS(1. - 15.*zta)**.25 !!Kansas unstable 437 ! 438 zpsi_k = 2.*LOG((1. + zphi_m)/2.) + LOG((1. + zphi_m*zphi_m)/2.) & 439 & - 2.*ATAN(zphi_m) + 0.5*rpi 440 ! 441 zphi_c = ABS(1. - 10.15*zta)**.3333 !!Convective 442 ! 443 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 444 & - 1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 445 ! 446 zf = zta*zta 447 zf = zf/(1. + zf) 448 zc = MIN(50._wp, 0.35_wp*zta) 449 zstab = 0.5 + SIGN(0.5_wp, zta) 450 ! 451 psi_m_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & ! (zta < 0) 452 & - zstab * ( 1. + 1.*zta & ! (zta > 0) 453 & + 0.6667*(zta - 14.28)/EXP(zc) + 8.525 ) ! " 454 ! 422 ! 423 zta = pzeta(ji,jj) 424 ! 425 zphi_m = ABS(1. - 15.*zta)**.25 !!Kansas unstable 426 ! 427 zpsi_k = 2.*LOG((1. + zphi_m)/2.) + LOG((1. + zphi_m*zphi_m)/2.) & 428 & - 2.*ATAN(zphi_m) + 0.5*rpi 429 ! 430 zphi_c = ABS(1. - 10.15*zta)**.3333 !!Convective 431 ! 432 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 433 & - 1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 434 ! 435 zf = zta*zta 436 zf = zf/(1. + zf) 437 zc = MIN(50._wp, 0.35_wp*zta) 438 zstab = 0.5 + SIGN(0.5_wp, zta) 439 ! 440 psi_m_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & ! (zta < 0) 441 & - zstab * ( 1. + 1.*zta & ! (zta > 0) 442 & + 0.6667*(zta - 14.28)/EXP(zc) + 8.525 ) ! " 455 443 END_2D 456 !457 444 END FUNCTION psi_m_coare 458 445 … … 474 461 !! (https://github.com/brodeau/aerobulk/) 475 462 !!---------------------------------------------------------------- 476 !!477 463 REAL(wp), DIMENSION(jpi,jpj) :: psi_h_coare 478 464 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta … … 480 466 INTEGER :: ji, jj ! dummy loop indices 481 467 REAL(wp) :: zta, zphi_h, zphi_c, zpsi_k, zpsi_c, zf, zc, zstab 482 ! 468 !!---------------------------------------------------------------- 483 469 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 484 ! 485 zta = pzeta(ji,jj) 486 ! 487 zphi_h = (ABS(1. - 15.*zta))**.5 !! Kansas unstable (zphi_h = zphi_m**2 when unstable, zphi_m when stable) 488 ! 489 zpsi_k = 2.*LOG((1. + zphi_h)/2.) 490 ! 491 zphi_c = (ABS(1. - 34.15*zta))**.3333 !! Convective 492 ! 493 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 494 & -1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 495 ! 496 zf = zta*zta 497 zf = zf/(1. + zf) 498 zc = MIN(50._wp,0.35_wp*zta) 499 zstab = 0.5 + SIGN(0.5_wp, zta) 500 ! 501 psi_h_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & 502 & - zstab * ( (ABS(1. + 2.*zta/3.))**1.5 & 503 & + .6667*(zta - 14.28)/EXP(zc) + 8.525 ) 504 ! 470 ! 471 zta = pzeta(ji,jj) 472 ! 473 zphi_h = (ABS(1. - 15.*zta))**.5 !! Kansas unstable (zphi_h = zphi_m**2 when unstable, zphi_m when stable) 474 ! 475 zpsi_k = 2.*LOG((1. + zphi_h)/2.) 476 ! 477 zphi_c = (ABS(1. - 34.15*zta))**.3333 !! Convective 478 ! 479 zpsi_c = 1.5*LOG((1. + zphi_c + zphi_c*zphi_c)/3.) & 480 & -1.7320508*ATAN((1. + 2.*zphi_c)/1.7320508) + 1.813799447 481 ! 482 zf = zta*zta 483 zf = zf/(1. + zf) 484 zc = MIN(50._wp,0.35_wp*zta) 485 zstab = 0.5 + SIGN(0.5_wp, zta) 486 ! 487 psi_h_coare(ji,jj) = (1. - zstab) * ( (1. - zf)*zpsi_k + zf*zpsi_c ) & 488 & - zstab * ( (ABS(1. + 2.*zta/3.))**1.5 & 489 & + .6667*(zta - 14.28)/EXP(zc) + 8.525 ) 505 490 END_2D 506 !507 491 END FUNCTION psi_h_coare 508 492 -
NEMO/trunk/src/OCE/SBC/sbcblk_algo_ecmwf.F90
r14007 r14072 5 5 !! * bulk transfer coefficients C_D, C_E and C_H 6 6 !! * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed 7 !! * the effective bulk wind speed at 10m U _blk7 !! * the effective bulk wind speed at 10m Ubzu 8 8 !! => all these are used in bulk formulas in sbcblk.F90 9 9 !! … … 17 17 !!---------------------------------------------------------------------- 18 18 !! History : 4.0 ! 2016-02 (L.Brodeau) Original code 19 !! 4.2 ! 2020-12 ( G. Madec, E. Clementi) Charnock coeff from wave model19 !! 4.2 ! 2020-12 (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 20 20 !!---------------------------------------------------------------------- 21 21 … … 25 25 !! returns the effective bulk wind speed at 10m 26 26 !!---------------------------------------------------------------------- 27 USE oce ! ocean dynamics and tracers28 27 USE dom_oce ! ocean space and time domain 29 28 USE phycst ! physical constants 30 USE iom ! I/O manager library 31 USE lib_mpp ! distribued memory computing library 32 USE in_out_manager ! I/O manager 33 USE prtctl ! Print control 34 USE sbcwave, ONLY : charn ! wave module 35 #if defined key_si3 || defined key_cice 36 USE sbc_ice ! Surface boundary condition: ice fields 37 #endif 38 USE lib_fortran ! to use key_nosignedzero 39 40 USE sbc_oce ! Surface boundary condition: ocean fields 41 USE sbcblk_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB 29 USE lib_mpp, ONLY: ctl_stop ! distribued memory computing library 30 USE in_out_manager, ONLY: nit000 ! I/O manager 31 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 42 32 USE sbcblk_skin_ecmwf ! cool-skin/warm layer scheme !LB 43 33 … … 46 36 47 37 PUBLIC :: SBCBLK_ALGO_ECMWF_INIT, TURB_ECMWF 48 !! * Substitutions49 # include "do_loop_substitute.h90"50 38 51 39 !! ECMWF own values for given constants, taken form IFS documentation... 52 REAL(wp), PARAMETER :: charn0 = 0.018! Charnock constant (pretty high value here !!!40 REAL(wp), PARAMETER, PUBLIC :: charn0_ecmwf = 0.018_wp ! Charnock constant (pretty high value here !!! 53 41 ! ! => Usually 0.011 for moderate winds) 54 42 REAL(wp), PARAMETER :: zi0 = 1000. ! scale height of the atmospheric boundary layer...1 … … 58 46 REAL(wp), PARAMETER :: alpha_Q = 0.62 ! 59 47 60 INTEGER , PARAMETER :: nb_itt = 10 ! number of itterations 48 !! * Substitutions 49 # include "do_loop_substitute.h90" 61 50 62 51 !!---------------------------------------------------------------------- … … 95 84 96 85 SUBROUTINE turb_ecmwf( kt, zt, zu, T_s, t_zt, q_s, q_zt, U_zu, l_use_cs, l_use_wl, & 97 & Cd, Ch, Ce, t_zu, q_zu, U _blk,&98 & Cdn, Chn, Cen, &86 & Cd, Ch, Ce, t_zu, q_zu, Ubzu, & 87 & nb_iter, Cdn, Chn, Cen, & ! optional output 99 88 & Qsw, rad_lw, slp, pdT_cs, & ! optionals for cool-skin (and warm-layer) 100 89 & pdT_wl, pHz_wl ) ! optionals for warm-layer only … … 152 141 !! * t_zu : pot. air temperature adjusted at wind height zu [K] 153 142 !! * q_zu : specific humidity of air // [kg/kg] 154 !! * U _blk: bulk wind speed at zu [m/s]143 !! * Ubzu : bulk wind speed at zu [m/s] 155 144 !! 156 145 !! … … 172 161 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: t_zu ! pot. air temp. adjusted at zu [K] 173 162 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: q_zu ! spec. humidity adjusted at zu [kg/kg] 174 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: U_blk ! bulk wind speed at zu [m/s] 175 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Cdn, Chn, Cen ! neutral transfer coefficients 176 ! 163 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Ubzu ! bulk wind speed at zu [m/s] 164 ! 165 INTEGER , INTENT(in ), OPTIONAL :: nb_iter ! number of iterations 166 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CdN 167 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: ChN 168 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CeN 177 169 REAL(wp), INTENT(in ), OPTIONAL, DIMENSION(jpi,jpj) :: Qsw ! [W/m^2] 178 170 REAL(wp), INTENT(in ), OPTIONAL, DIMENSION(jpi,jpj) :: rad_lw ! [W/m^2] … … 182 174 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: pHz_wl ! [m] 183 175 ! 184 INTEGER :: j_itt176 INTEGER :: nbit, jit 185 177 LOGICAL :: l_zt_equal_zu = .FALSE. ! if q and t are given at same height as U 186 178 ! … … 198 190 !!---------------------------------------------------------------------------------- 199 191 IF( kt == nit000 ) CALL SBCBLK_ALGO_ECMWF_INIT(l_use_cs, l_use_wl) 192 193 nbit = nb_iter0 194 IF( PRESENT(nb_iter) ) nbit = nb_iter 200 195 201 196 l_zt_equal_zu = ( ABS(zu - zt) < 0.01_wp ) ! testing "zu == zt" is risky with double precision … … 228 223 znu_a = visc_air(t_zu) ! Air viscosity (m^2/s) at zt given from temperature in (K) 229 224 230 U _blk= SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution225 Ubzu = SQRT(U_zu*U_zu + 0.5_wp*0.5_wp) ! initial guess for wind gustiness contribution 231 226 232 227 ztmp0 = LOG( zu*10000._wp) ! optimization: 10000. == 1/z0 (with z0 first guess == 0.0001) 233 228 ztmp1 = LOG(10._wp*10000._wp) ! " " " 234 u_star = 0.035_wp*U_blk*ztmp1/ztmp0 ! (u* = 0.035*Un10) 235 236 IF (ln_charn) THEN ! Charnock value if wave coupling 237 z0 = charn*u_star*u_star/grav + 0.11_wp*znu_a/u_star 238 ELSE 239 z0 = charn0*u_star*u_star/grav + 0.11_wp*znu_a/u_star 240 ENDIF 241 229 u_star = 0.035_wp*Ubzu*ztmp1/ztmp0 ! (u* = 0.035*Un10) 230 231 z0 = charn0_ecmwf*u_star*u_star/grav + 0.11_wp*znu_a/u_star 242 232 z0 = MIN( MAX(ABS(z0), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 243 233 … … 245 235 z0t = MIN( MAX(ABS(z0t), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 246 236 247 Cd = (vkarmn/ztmp0)**2! first guess of Cd248 249 ztmp0 = vkarmn *vkarmn/LOG(zt/z0t)/Cd250 251 ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U _blk) ! Bulk Richardson Number (BRN)237 Cd = MAX( (vkarmn/ztmp0)**2 , Cx_min ) ! first guess of Cd 238 239 ztmp0 = vkarmn2/LOG(zt/z0t)/Cd 240 241 ztmp2 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, Ubzu ) ! Bulk Richardson Number (BRN) 252 242 253 243 !! First estimate of zeta_u, depending on the stability, ie sign of BRN (ztmp2): 254 244 ztmp1 = 0.5 + SIGN( 0.5_wp , ztmp2 ) 255 func_m = ztmp0*ztmp2 ! temporary array !! 256 func_h = (1._wp-ztmp1) * (func_m/(1._wp+ztmp2/(-zu/(zi0*0.004_wp*Beta0**3)))) & ! BRN < 0 ! temporary array !!! func_h == zeta_u 257 & + ztmp1 * (func_m*(1._wp + 27._wp/9._wp*ztmp2/func_m)) ! BRN > 0 258 !#LB: should make sure that the "func_m" of "27./9.*ztmp2/func_m" is "ztmp0*ztmp2" and not "ztmp0==vkarmn*vkarmn/LOG(zt/z0t)/Cd" ! 245 func_h = (1._wp - ztmp1) * ztmp0*ztmp2 / (1._wp - ztmp2*zi0*0.004_wp*Beta0**3/zu) & ! BRN < 0 246 & + ztmp1 * ( ztmp0*ztmp2 + 27._wp/9._wp*ztmp2*ztmp2 ) ! BRN > 0 259 247 260 248 !! First guess M-O stability dependent scaling params.(u*,t*,q*) to estimate z0 and z/L 261 249 ztmp0 = vkarmn/(LOG(zu/z0t) - psi_h_ecmwf(func_h)) 262 250 263 u_star = MAX ( U _blk*vkarmn/(LOG(zu) - LOG(z0) - psi_m_ecmwf(func_h)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on)251 u_star = MAX ( Ubzu*vkarmn/(LOG(zu) - LOG(z0) - psi_m_ecmwf(func_h)) , 1.E-9 ) ! (MAX => prevents FPE from stupid values from masked region later on) 264 252 t_star = dt_zu*ztmp0 265 253 q_star = dq_zu*ztmp0 … … 282 270 283 271 284 !! First guess of inverse of Monin-Obukov length (1/L) :272 !! First guess of inverse of Obukov length (1/L) : 285 273 Linv = One_on_L( t_zu, q_zu, u_star, t_star, q_star ) 286 274 287 !! Functions such as u* = U _blk*vkarmn/func_m275 !! Functions such as u* = Ubzu*vkarmn/func_m 288 276 ztmp0 = zu*Linv 289 277 func_m = LOG(zu) - LOG(z0) - psi_m_ecmwf(ztmp0) + psi_m_ecmwf( z0*Linv) … … 291 279 292 280 !! ITERATION BLOCK 293 DO j _itt = 1, nb_itt281 DO jit = 1, nbit 294 282 295 283 !! Bulk Richardson Number at z=zu (Eq. 3.25) 296 ztmp0 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, U _blk) ! Bulk Richardson Number (BRN)297 298 !! New estimate of the inverse of the Monin-Obukhon length (Linv == zeta/zu) :284 ztmp0 = Ri_bulk( zu, T_s, t_zu, q_s, q_zu, Ubzu ) ! Bulk Richardson Number (BRN) 285 286 !! New estimate of the inverse of the Obukhon length (Linv == zeta/zu) : 299 287 Linv = ztmp0*func_m*func_m/func_h / zu ! From Eq. 3.23, Chap.3.2.3, IFS doc - Cy40r1 300 288 !! Note: it is slightly different that the L we would get with the usual … … 305 293 306 294 !! Need to update roughness lengthes: 307 u_star = U _blk*vkarmn/func_m295 u_star = Ubzu*vkarmn/func_m 308 296 ztmp2 = u_star*u_star 309 297 ztmp1 = znu_a/u_star 310 IF (ln_charn) THEN ! Charnock value if wave coupling 311 z0 = MIN( ABS( alpha_M*ztmp1 + charn*ztmp2/grav ) , 0.001_wp) 312 ELSE 313 z0 = MIN( ABS( alpha_M*ztmp1 + charn0*ztmp2/grav ) , 0.001_wp) 314 ENDIF 315 z0t = MIN( ABS( alpha_H*ztmp1 ) , 0.001_wp) ! eq.3.26, Chap.3, p.34, IFS doc - Cy31r1 316 z0q = MIN( ABS( alpha_Q*ztmp1 ) , 0.001_wp) 298 z0 = MIN( ABS( alpha_M*ztmp1 + charn0_ecmwf*ztmp2/grav ) , 0.001_wp) 299 z0t = MIN( ABS( alpha_H*ztmp1 ) , 0.001_wp) ! eq.3.26, Chap.3, p.34, IFS doc - Cy31r1 300 z0q = MIN( ABS( alpha_Q*ztmp1 ) , 0.001_wp) 317 301 318 302 !! Update wind at zu with convection-related wind gustiness in unstable conditions (Chap. 3.2, IFS doc - Cy40r1, Eq.3.17 and Eq.3.18 + Eq.3.8) 319 303 ztmp2 = Beta0*Beta0*ztmp2*(MAX(-zi0*Linv/vkarmn,0._wp))**(2._wp/3._wp) ! square of wind gustiness contribution (combining Eq. 3.8 and 3.18, hap.3, IFS doc - Cy31r1) 320 304 !! ! Only true when unstable (L<0) => when ztmp0 < 0 => explains "-" before zi0 321 U _blk= MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp) ! include gustiness in bulk wind speed322 ! => 0.2 prevents U _blkto be 0 in stable case when U_zu=0.305 Ubzu = MAX(SQRT(U_zu*U_zu + ztmp2), 0.2_wp) ! include gustiness in bulk wind speed 306 ! => 0.2 prevents Ubzu to be 0 in stable case when U_zu=0. 323 307 324 308 … … 356 340 !! Cool-skin contribution 357 341 358 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U _blk, slp, rad_lw, &342 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, Ubzu, slp, rad_lw, & 359 343 & ztmp1, ztmp0, Qlat=ztmp2) ! Qnsol -> ztmp1 / Tau -> ztmp0 360 344 … … 369 353 IF( l_use_wl ) THEN 370 354 !! Warm-layer contribution 371 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, U _blk, slp, rad_lw, &355 CALL UPDATE_QNSOL_TAU( zu, T_s, q_s, t_zu, q_zu, u_star, t_star, q_star, U_zu, Ubzu, slp, rad_lw, & 372 356 & ztmp1, ztmp2) ! Qnsol -> ztmp1 / Tau -> ztmp2 373 357 CALL WL_ECMWF( Qsw, ztmp1, u_star, zsst ) … … 383 367 ENDIF 384 368 385 END DO !DO j _itt = 1, nb_itt386 387 Cd = vkarmn*vkarmn/(func_m*func_m)388 Ch = vkarmn*vkarmn/(func_m*func_h)389 ztmp2 = log(zu/z0q) - psi_h_ecmwf(zu*Linv) + psi_h_ecmwf(z0q*Linv) ! func_q390 Ce = vkarmn*vkarmn/(func_m*ztmp2)391 392 Cdn = vkarmn*vkarmn / (log(zu/z0 )*log(zu/z0 ))393 Chn = vkarmn*vkarmn / (log(zu/z0t)*log(zu/z0t))394 Cen = vkarmn*vkarmn / (log(zu/z0q)*log(zu/z0q))369 END DO !DO jit = 1, nbit 370 371 Cd = MAX( vkarmn2/(func_m*func_m) , Cx_min ) 372 Ch = MAX( vkarmn2/(func_m*func_h) , Cx_min ) 373 ztmp2 = LOG(zu/z0q) - psi_h_ecmwf(zu*Linv) + psi_h_ecmwf(z0q*Linv) ! func_q 374 Ce = MAX( vkarmn2/(func_m*ztmp2) , Cx_min ) 375 376 IF(PRESENT(Cdn)) Cdn = MAX( vkarmn2 / (LOG(zu/z0 )*LOG(zu/z0 )) , Cx_min ) 377 IF(PRESENT(Chn)) Chn = MAX( vkarmn2 / (LOG(zu/z0t)*LOG(zu/z0t)) , Cx_min ) 378 IF(PRESENT(Cen)) Cen = MAX( vkarmn2 / (LOG(zu/z0q)*LOG(zu/z0q)) , Cx_min ) 395 379 396 380 IF( l_use_cs .AND. PRESENT(pdT_cs) ) pdT_cs = dT_cs … … 418 402 ! 419 403 INTEGER :: ji, jj ! dummy loop indices 420 REAL(wp) :: zzeta, zx, ztmp, psi_unst, psi_stab, stab 421 !!---------------------------------------------------------------------------------- 404 REAL(wp) :: zta, zx2, zx, ztmp, zpsi_unst, zpsi_stab, zstab, zc 405 !!---------------------------------------------------------------------------------- 406 zc = 5._wp/0.35_wp 422 407 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 423 ! 424 zzeta = MIN( pzeta(ji,jj) , 5._wp ) !! Very stable conditions (L positif and big!): 425 ! 426 ! Unstable (Paulson 1970): 427 ! eq.3.20, Chap.3, p.33, IFS doc - Cy31r1 428 zx = SQRT(ABS(1._wp - 16._wp*zzeta)) 429 ztmp = 1._wp + SQRT(zx) 430 ztmp = ztmp*ztmp 431 psi_unst = LOG( 0.125_wp*ztmp*(1._wp + zx) ) & 432 & -2._wp*ATAN( SQRT(zx) ) + 0.5_wp*rpi 433 ! 434 ! Unstable: 435 ! eq.3.22, Chap.3, p.33, IFS doc - Cy31r1 436 psi_stab = -2._wp/3._wp*(zzeta - 5._wp/0.35_wp)*EXP(-0.35_wp*zzeta) & 437 & - zzeta - 2._wp/3._wp*5._wp/0.35_wp 438 ! 439 ! Combining: 440 stab = 0.5_wp + SIGN(0.5_wp, zzeta) ! zzeta > 0 => stab = 1 441 ! 442 psi_m_ecmwf(ji,jj) = (1._wp - stab) * psi_unst & ! (zzeta < 0) Unstable 443 & + stab * psi_stab ! (zzeta > 0) Stable 444 ! 408 ! 409 zta = MIN( pzeta(ji,jj) , 5._wp ) !! Very stable conditions (L positif and big!): 410 411 ! *** Unstable (Paulson 1970) [eq.3.20, Chap.3, p.33, IFS doc - Cy31r1] : 412 zx2 = SQRT( ABS(1._wp - 16._wp*zta) ) ! (1 - 16z)^0.5 413 zx = SQRT(zx2) ! (1 - 16z)^0.25 414 ztmp = 1._wp + zx 415 zpsi_unst = LOG( 0.125_wp*ztmp*ztmp*(1._wp + zx2) ) - 2._wp*ATAN( zx ) + 0.5_wp*rpi 416 417 ! *** Stable [eq.3.22, Chap.3, p.33, IFS doc - Cy31r1] : 418 zpsi_stab = -2._wp/3._wp*(zta - zc)*EXP(-0.35_wp*zta) & 419 & - zta - 2._wp/3._wp*zc 420 ! 421 zstab = 0.5_wp + SIGN(0.5_wp, zta) ! zta > 0 => zstab = 1 422 ! 423 psi_m_ecmwf(ji,jj) = zstab * zpsi_stab & ! (zta > 0) Stable 424 & + (1._wp - zstab) * zpsi_unst ! (zta < 0) Unstable 425 ! 445 426 END_2D 446 427 END FUNCTION psi_m_ecmwf … … 462 443 ! 463 444 INTEGER :: ji, jj ! dummy loop indices 464 REAL(wp) :: zzeta, zx, psi_unst, psi_stab, stab 465 !!---------------------------------------------------------------------------------- 445 REAL(wp) :: zta, zx2, zpsi_unst, zpsi_stab, zstab, zc 446 !!---------------------------------------------------------------------------------- 447 zc = 5._wp/0.35_wp 466 448 ! 467 449 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 468 ! 469 zzeta = MIN(pzeta(ji,jj) , 5._wp) ! Very stable conditions (L positif and big!): 470 ! 471 zx = ABS(1._wp - 16._wp*zzeta)**.25 ! this is actually (1/phi_m)**2 !!! 472 ! ! eq.3.19, Chap.3, p.33, IFS doc - Cy31r1 473 ! Unstable (Paulson 1970) : 474 psi_unst = 2._wp*LOG(0.5_wp*(1._wp + zx*zx)) ! eq.3.20, Chap.3, p.33, IFS doc - Cy31r1 475 ! 476 ! Stable: 477 psi_stab = -2._wp/3._wp*(zzeta - 5._wp/0.35_wp)*EXP(-0.35_wp*zzeta) & ! eq.3.22, Chap.3, p.33, IFS doc - Cy31r1 478 & - ABS(1._wp + 2._wp/3._wp*zzeta)**1.5_wp - 2._wp/3._wp*5._wp/0.35_wp + 1._wp 479 ! LB: added ABS() to avoid NaN values when unstable, which contaminates the unstable solution... 480 ! 481 stab = 0.5_wp + SIGN(0.5_wp, zzeta) ! zzeta > 0 => stab = 1 482 ! 483 ! 484 psi_h_ecmwf(ji,jj) = (1._wp - stab) * psi_unst & ! (zzeta < 0) Unstable 485 & + stab * psi_stab ! (zzeta > 0) Stable 486 ! 450 ! 451 zta = MIN(pzeta(ji,jj) , 5._wp) ! Very stable conditions (L positif and big!): 452 ! 453 ! *** Unstable (Paulson 1970) [eq.3.20, Chap.3, p.33, IFS doc - Cy31r1] : 454 zx2 = SQRT( ABS(1._wp - 16._wp*zta) ) ! (1 -16z)^0.5 455 zpsi_unst = 2._wp*LOG( 0.5_wp*(1._wp + zx2) ) 456 ! 457 ! *** Stable [eq.3.22, Chap.3, p.33, IFS doc - Cy31r1] : 458 zpsi_stab = -2._wp/3._wp*(zta - zc)*EXP(-0.35_wp*zta) & 459 & - ABS(1._wp + 2._wp/3._wp*zta)**1.5_wp - 2._wp/3._wp*zc + 1._wp 460 ! 461 ! LB: added ABS() to avoid NaN values when unstable, which contaminates the unstable solution... 462 ! 463 zstab = 0.5_wp + SIGN(0.5_wp, zta) ! zta > 0 => zstab = 1 464 ! 465 psi_h_ecmwf(ji,jj) = zstab * zpsi_stab & ! (zta > 0) Stable 466 & + (1._wp - zstab) * zpsi_unst ! (zta < 0) Unstable 467 ! 487 468 END_2D 488 469 END FUNCTION psi_h_ecmwf -
NEMO/trunk/src/OCE/SBC/sbcblk_algo_ncar.F90
r13460 r14072 5 5 !! * bulk transfer coefficients C_D, C_E and C_H 6 6 !! * air temp. and spec. hum. adjusted from zt (2m) to zu (10m) if needed 7 !! * the effective bulk wind speed at 10m U _blk7 !! * the effective bulk wind speed at 10m Ubzu 8 8 !! => all these are used in bulk formulas in sbcblk.F90 9 9 !! … … 16 16 !!===================================================================== 17 17 !! History : 3.6 ! 2016-02 (L.Brodeau) successor of old turb_ncar of former sbcblk_core.F90 18 !! 4.2 ! 2020-12 (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 18 19 !!---------------------------------------------------------------------- 19 20 … … 23 24 !! returns the effective bulk wind speed at 10m 24 25 !!---------------------------------------------------------------------- 25 USE oce ! ocean dynamics and tracers26 26 USE dom_oce ! ocean space and time domain 27 USE sbc_oce, ONLY: ln_cdgw 28 USE sbcwave, ONLY: cdn_wave ! wave module 27 29 USE phycst ! physical constants 28 USE sbc_oce ! Surface boundary condition: ocean fields 29 USE sbcwave, ONLY : cdn_wave ! wave module 30 #if defined key_si3 || defined key_cice 31 USE sbc_ice ! Surface boundary condition: ice fields 32 #endif 33 ! 34 USE iom ! I/O manager library 35 USE lib_mpp ! distribued memory computing library 36 USE in_out_manager ! I/O manager 37 USE prtctl ! Print control 38 USE lib_fortran ! to use key_nosignedzero 39 40 USE sbcblk_phy ! all thermodynamics functions, rho_air, q_sat, etc... !LB 30 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 41 31 42 32 IMPLICIT NONE … … 45 35 PUBLIC :: TURB_NCAR ! called by sbcblk.F90 46 36 47 INTEGER , PARAMETER :: nb_itt = 5 ! number of itterations48 37 !! * Substitutions 49 38 # include "do_loop_substitute.h90" … … 52 41 CONTAINS 53 42 54 SUBROUTINE turb_ncar( zt, zu, sst, t_zt, ssq, q_zt, U_zu, &55 & Cd, Ch, Ce, t_zu, q_zu, U_blk,&56 & Cdn, Chn, Cen)43 SUBROUTINE turb_ncar( zt, zu, sst, t_zt, ssq, q_zt, U_zu, & 44 & Cd, Ch, Ce, t_zu, q_zu, Ubzu, & 45 & nb_iter, CdN, ChN, CeN ) 57 46 !!---------------------------------------------------------------------------------- 58 47 !! *** ROUTINE turb_ncar *** … … 61 50 !! fluxes according to Large & Yeager (2004) and Large & Yeager (2008) 62 51 !! If relevant (zt /= zu), adjust temperature and humidity from height zt to zu 63 !! Returns the effective bulk wind speed at 10m to be used in the bulk formulas 64 !! 52 !! Returns the effective bulk wind speed at zu to be used in the bulk formulas 65 53 !! 66 54 !! INPUT : … … 82 70 !! * t_zu : pot. air temperature adjusted at wind height zu [K] 83 71 !! * q_zu : specific humidity of air // [kg/kg] 84 !! * U_blk : bulk wind speed at zu [m/s] 85 !! 72 !! * Ubzu : bulk wind speed at zu [m/s] 73 !! 74 !! OPTIONAL OUTPUT: 75 !! ---------------- 76 !! * CdN : neutral-stability drag coefficient 77 !! * ChN : neutral-stability sensible heat coefficient 78 !! * CeN : neutral-stability evaporation coefficient 86 79 !! 87 80 !! ** Author: L. Brodeau, June 2019 / AeroBulk (https://github.com/brodeau/aerobulk/) … … 99 92 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: t_zu ! pot. air temp. adjusted at zu [K] 100 93 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: q_zu ! spec. humidity adjusted at zu [kg/kg] 101 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: U_blk ! bulk wind speed at zu [m/s] 102 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Cdn, Chn, Cen ! neutral transfer coefficients 103 ! 104 INTEGER :: j_itt 94 REAL(wp), INTENT( out), DIMENSION(jpi,jpj) :: Ubzu ! bulk wind speed at zu [m/s] 95 ! 96 INTEGER , INTENT(in ), OPTIONAL :: nb_iter ! number of iterations 97 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CdN 98 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: ChN 99 REAL(wp), INTENT( out), OPTIONAL, DIMENSION(jpi,jpj) :: CeN 100 ! 101 INTEGER :: nbit, jit ! iterations... 105 102 LOGICAL :: l_zt_equal_zu = .FALSE. ! if q and t are given at same height as U 106 103 ! 107 REAL(wp), DIMENSION(jpi,jpj) :: Cx_n10! 10m neutral latent/sensible coefficient108 REAL(wp), DIMENSION(jpi,jpj) :: sqrt_Cd_n10 ! root square of Cd_n10104 REAL(wp), DIMENSION(jpi,jpj) :: zCdN, zCeN, zChN ! 10m neutral latent/sensible coefficient 105 REAL(wp), DIMENSION(jpi,jpj) :: zsqrt_Cd, zsqrt_CdN ! root square of Cd and Cd_neutral 109 106 REAL(wp), DIMENSION(jpi,jpj) :: zeta_u ! stability parameter at height zu 110 REAL(wp), DIMENSION(jpi,jpj) :: zpsi_h_u111 107 REAL(wp), DIMENSION(jpi,jpj) :: ztmp0, ztmp1, ztmp2 112 REAL(wp), DIMENSION(jpi,jpj) :: stab ! stability test integer 113 !!---------------------------------------------------------------------------------- 108 !!---------------------------------------------------------------------------------- 109 nbit = nb_iter0 110 IF( PRESENT(nb_iter) ) nbit = nb_iter 111 114 112 l_zt_equal_zu = ( ABS(zu - zt) < 0.01_wp ) ! testing "zu == zt" is risky with double precision 115 113 116 U _blk= MAX( 0.5_wp , U_zu ) ! relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s114 Ubzu = MAX( 0.5_wp , U_zu ) ! relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s 117 115 118 116 !! First guess of stability: 119 117 ztmp0 = virt_temp(t_zt, q_zt) - virt_temp(sst, ssq) ! air-sea difference of virtual pot. temp. at zt 120 stab = 0.5_wp + sign(0.5_wp,ztmp0) ! stab= 1 if dTv > 0 => STABLE, 0 if unstable118 ztmp1 = 0.5_wp + SIGN(0.5_wp,ztmp0) ! ztmp1 = 1 if dTv > 0 => STABLE, 0 if unstable 121 119 122 120 !! Neutral coefficients at 10m: 123 121 IF( ln_cdgw ) THEN ! wave drag case 124 122 cdn_wave(:,:) = cdn_wave(:,:) + rsmall * ( 1._wp - tmask(:,:,1) ) 125 z tmp0(:,:) = cdn_wave(:,:)123 zCdN (:,:) = cdn_wave(:,:) 126 124 ELSE 127 z tmp0 = cd_neutral_10m( U_blk)125 zCdN = cd_n10_ncar( Ubzu ) 128 126 ENDIF 129 127 130 sqrt_Cd_n10 = SQRT( ztmp0)128 zsqrt_CdN = SQRT( zCdN ) 131 129 132 130 !! Initializing transf. coeff. with their first guess neutral equivalents : 133 Cd = z tmp0134 Ce = 1.e-3_wp*( 34.6_wp * sqrt_Cd_n10)135 Ch = 1.e-3_wp*sqrt_Cd_n10*(18._wp*stab + 32.7_wp*(1._wp - stab))136 stab = sqrt_Cd_n10 ! Temporaty array !!! stab == SQRT(Cd)137 131 Cd = zCdN 132 Ce = ce_n10_ncar( zsqrt_CdN ) 133 Ch = ch_n10_ncar( zsqrt_CdN , ztmp1 ) ! ztmp1 is stability (1/0) 134 zsqrt_Cd = zsqrt_CdN 135 138 136 IF( ln_cdgw ) THEN 139 Cen= Ce140 Chn= Ch137 zCeN = Ce 138 zChN = Ch 141 139 ENDIF 142 140 143 !! First guess of temperature and humidity at height zu:141 !! Initializing values at z_u with z_t values: 144 142 t_zu = MAX( t_zt , 180._wp ) ! who knows what's given on masked-continental regions... 145 143 q_zu = MAX( q_zt , 1.e-6_wp ) ! " 146 144 145 147 146 !! ITERATION BLOCK 148 DO j _itt = 1, nb_itt147 DO jit = 1, nbit 149 148 ! 150 149 ztmp1 = t_zu - sst ! Updating air/sea differences 151 150 ztmp2 = q_zu - ssq 152 151 153 ! Updating turbulent scales : (L&Y 2004 eq. (7))154 ztmp0 = stab*U_blk ! u* (stab == SQRT(Cd))155 ztmp1 = Ch/ stab*ztmp1 ! theta* (stab == SQRT(Cd))156 ztmp2 = Ce/ stab*ztmp2 ! q* (stab == SQRT(Cd))157 158 ! Estimate the inverse of Monin-Obukov length (1/L) at height zu:152 ! Updating turbulent scales : (L&Y 2004 Eq. (7)) 153 ztmp0 = zsqrt_Cd*Ubzu ! u* 154 ztmp1 = Ch/zsqrt_Cd*ztmp1 ! theta* 155 ztmp2 = Ce/zsqrt_Cd*ztmp2 ! q* 156 157 ! Estimate the inverse of Obukov length (1/L) at height zu: 159 158 ztmp0 = One_on_L( t_zu, q_zu, ztmp0, ztmp1, ztmp2 ) 160 159 161 160 !! Stability parameters : 162 161 zeta_u = zu*ztmp0 163 zeta_u = sign( min(abs(zeta_u),10._wp), zeta_u ) 164 zpsi_h_u = psi_h( zeta_u ) 165 166 !! Shifting temperature and humidity at zu (L&Y 2004 eq. (9b-9c)) 162 zeta_u = sign( min(abs(zeta_u),10._wp), zeta_u ) 163 164 !! Shifting temperature and humidity at zu (L&Y 2004 Eq. (9b-9c)) 167 165 IF( .NOT. l_zt_equal_zu ) THEN 168 !! Array 'stab' is free for the moment so using it to store 'zeta_t'169 stab = zt*ztmp0170 stab = SIGN( MIN(ABS(stab),10._wp), stab ) ! Temporaty array stab == zeta_t !!!171 stab = LOG(zt/zu) + zpsi_h_u - psi_h(stab) ! stab just used as temp array again!172 t_zu = t_zt - ztmp1/vkarmn*stab ! ztmp1 is still theta* L&Y 2004 eq.(9b)173 q_zu = q_zt - ztmp2/vkarmn* stab ! ztmp2 is still q* L&Y 2004 eq.(9c)174 q_zu = max(0._wp, q_zu)175 END IF176 177 ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)...166 ztmp0 = zt*ztmp0 ! zeta_t ! 167 ztmp0 = SIGN( MIN(ABS(ztmp0),10._wp), ztmp0 ) ! Temporaty array ztmp0 == zeta_t !!! 168 ztmp0 = LOG(zt/zu) + psi_h_ncar(zeta_u) - psi_h_ncar(ztmp0) ! ztmp0 just used as temp array again! 169 t_zu = t_zt - ztmp1/vkarmn*ztmp0 ! ztmp1 is still theta* L&Y 2004 Eq. (9b) 170 !! 171 q_zu = q_zt - ztmp2/vkarmn*ztmp0 ! ztmp2 is still q* L&Y 2004 Eq. (9c) 172 q_zu = MAX(0._wp, q_zu) 173 END IF 174 175 ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 Eq. 9a)... 178 176 ! In very rare low-wind conditions, the old way of estimating the 179 177 ! neutral wind speed at 10m leads to a negative value that causes the code 180 178 ! to crash. To prevent this a threshold of 0.25m/s is imposed. 181 ztmp2 = psi_m (zeta_u)179 ztmp2 = psi_m_ncar(zeta_u) 182 180 IF( ln_cdgw ) THEN ! surface wave case 183 stab = vkarmn / ( vkarmn / sqrt_Cd_n10 - ztmp2 ) ! (stab == SQRT(Cd))184 Cd = stab * stab185 ztmp0 = (LOG(zu/10._wp) - zpsi_h_u) / vkarmn / sqrt_Cd_n10186 ztmp2 = stab / sqrt_Cd_n10 ! (stab == SQRT(Cd))187 ztmp1 = 1._wp + Chn * ztmp0188 Ch = Chn* ztmp2 / ztmp1 ! L&Y 2004 eq. (10b)189 ztmp1 = 1._wp + Cen* ztmp0190 Ce = Cen* ztmp2 / ztmp1 ! L&Y 2004 eq. (10c)181 zsqrt_Cd = vkarmn / ( vkarmn / zsqrt_CdN - ztmp2 ) 182 Cd = zsqrt_Cd * zsqrt_Cd 183 ztmp0 = (LOG(zu/10._wp) - psi_h_ncar(zeta_u)) / vkarmn / zsqrt_CdN 184 ztmp2 = zsqrt_Cd / zsqrt_CdN 185 ztmp1 = 1._wp + zChN * ztmp0 186 Ch = zChN * ztmp2 / ztmp1 ! L&Y 2004 eq. (10b) 187 ztmp1 = 1._wp + zCeN * ztmp0 188 Ce = zCeN * ztmp2 / ztmp1 ! L&Y 2004 eq. (10c) 191 189 192 190 ELSE 193 ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)... 194 ! In very rare low-wind conditions, the old way of estimating the 195 ! neutral wind speed at 10m leads to a negative value that causes the code 196 ! to crash. To prevent this a threshold of 0.25m/s is imposed. 197 ztmp0 = MAX( 0.25_wp , U_blk/(1._wp + sqrt_Cd_n10/vkarmn*(LOG(zu/10._wp) - ztmp2)) ) ! U_n10 (ztmp2 == psi_m(zeta_u)) 198 ztmp0 = cd_neutral_10m(ztmp0) ! Cd_n10 199 Cdn(:,:) = ztmp0 200 sqrt_Cd_n10 = sqrt(ztmp0) 201 202 stab = 0.5_wp + sign(0.5_wp,zeta_u) ! update stability 203 Cx_n10 = 1.e-3_wp*sqrt_Cd_n10*(18._wp*stab + 32.7_wp*(1._wp - stab)) ! L&Y 2004 eq. (6c-6d) (Cx_n10 == Ch_n10) 204 Chn(:,:) = Cx_n10 191 ztmp0 = MAX( 0.25_wp , UN10_from_CD(zu, Ubzu, Cd, ppsi=ztmp2) ) ! U_n10 (ztmp2 == psi_m_ncar(zeta_u)) 192 193 zCdN = cd_n10_ncar(ztmp0) 194 zsqrt_CdN = sqrt(zCdN) 205 195 206 196 !! Update of transfer coefficients: 207 ztmp1 = 1._wp + sqrt_Cd_n10/vkarmn*(LOG(zu/10._wp) - ztmp2) ! L&Y 2004 eq. (10a) (ztmp2 == psi_m(zeta_u)) 208 Cd = ztmp0 / ( ztmp1*ztmp1 ) 209 stab = SQRT( Cd ) ! Temporary array !!! (stab == SQRT(Cd)) 210 211 ztmp0 = (LOG(zu/10._wp) - zpsi_h_u) / vkarmn / sqrt_Cd_n10 212 ztmp2 = stab / sqrt_Cd_n10 ! (stab == SQRT(Cd)) 213 ztmp1 = 1._wp + Cx_n10*ztmp0 ! (Cx_n10 == Ch_n10) 214 Ch = Cx_n10*ztmp2 / ztmp1 ! L&Y 2004 eq. (10b) 215 216 Cx_n10 = 1.e-3_wp * (34.6_wp * sqrt_Cd_n10) ! L&Y 2004 eq. (6b) ! Cx_n10 == Ce_n10 217 Cen(:,:) = Cx_n10 218 ztmp1 = 1._wp + Cx_n10*ztmp0 219 Ce = Cx_n10*ztmp2 / ztmp1 ! L&Y 2004 eq. (10c) 197 198 !! C_D 199 ztmp1 = 1._wp + zsqrt_CdN/vkarmn*(LOG(zu/10._wp) - ztmp2) ! L&Y 2004 Eq. (10a) (ztmp2 == psi_m(zeta_u)) 200 Cd = MAX( zCdN / ( ztmp1*ztmp1 ), Cx_min ) 201 202 !! C_H and C_E 203 zsqrt_Cd = SQRT( Cd ) 204 ztmp0 = ( LOG(zu/10._wp) - psi_h_ncar(zeta_u) ) / vkarmn / zsqrt_CdN 205 ztmp2 = zsqrt_Cd / zsqrt_CdN 206 207 ztmp1 = 0.5_wp + SIGN(0.5_wp,zeta_u) ! update stability 208 zChN = 1.e-3_wp * zsqrt_CdN*(18._wp*ztmp1 + 32.7_wp*(1._wp - ztmp1)) ! L&Y 2004 eq. (6c-6d) 209 zCeN = 1.e-3_wp * (34.6_wp * zsqrt_CdN) ! L&Y 2004 eq. (6b) 210 211 Ch = MAX( zChN*ztmp2 / ( 1._wp + zChN*ztmp0 ) , Cx_min ) ! L&Y 2004 eq. (10b) 212 Ce = MAX( zCeN*ztmp2 / ( 1._wp + zCeN*ztmp0 ) , Cx_min ) ! L&Y 2004 eq. (10c) 213 220 214 ENDIF 221 215 222 END DO !DO j_itt = 1, nb_itt 216 END DO !DO jit = 1, nbit 217 218 IF(PRESENT(CdN)) CdN(:,:) = zCdN(:,:) 219 IF(PRESENT(CeN)) CeN(:,:) = zCeN(:,:) 220 IF(PRESENT(ChN)) ChN(:,:) = zChN(:,:) 223 221 224 222 END SUBROUTINE turb_ncar 225 223 226 224 227 FUNCTION cd_n eutral_10m( pw10 )228 !!---------------------------------------------------------------------------------- 225 FUNCTION cd_n10_ncar( pw10 ) 226 !!---------------------------------------------------------------------------------- 229 227 !! Estimate of the neutral drag coefficient at 10m as a function 230 228 !! of neutral wind speed at 10m 231 229 !! 232 !! Origin: Large & Yeager 2008 eq.(11a) and eq.(11b)230 !! Origin: Large & Yeager 2008, Eq. (11) 233 231 !! 234 232 !! ** Author: L. Brodeau, june 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 235 233 !!---------------------------------------------------------------------------------- 236 234 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pw10 ! scalar wind speed at 10m (m/s) 237 REAL(wp), DIMENSION(jpi,jpj) :: cd_n eutral_10m235 REAL(wp), DIMENSION(jpi,jpj) :: cd_n10_ncar 238 236 ! 239 237 INTEGER :: ji, jj ! dummy loop indices … … 242 240 ! 243 241 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 244 !245 zw = pw10(ji,jj)246 zw6 = zw*zw*zw247 zw6 = zw6*zw6248 !249 ! When wind speed > 33 m/s => Cyclone conditions => special treatment250 zgt33 = 0.5_wp + SIGN( 0.5_wp, (zw - 33._wp) ) ! If pw10 < 33. => 0, else => 1251 !252 cd_neutral_10m(ji,jj) = 1.e-3_wp * ( &253 & (1._wp - zgt33)*( 2.7_wp/zw + 0.142_wp + zw/13.09_wp - 3.14807E-10_wp*zw6) & ! wind < 33 m/s254 & + zgt33 * 2.34_wp ) ! wind >= 33 m/s255 !256 cd_neutral_10m(ji,jj) = MAX(cd_neutral_10m(ji,jj), 1.E-6_wp)257 !242 ! 243 zw = pw10(ji,jj) 244 zw6 = zw*zw*zw 245 zw6 = zw6*zw6 246 ! 247 ! When wind speed > 33 m/s => Cyclone conditions => special treatment 248 zgt33 = 0.5_wp + SIGN( 0.5_wp, (zw - 33._wp) ) ! If pw10 < 33. => 0, else => 1 249 ! 250 cd_n10_ncar(ji,jj) = 1.e-3_wp * ( & 251 & (1._wp - zgt33)*( 2.7_wp/zw + 0.142_wp + zw/13.09_wp - 3.14807E-10_wp*zw6) & ! wind < 33 m/s 252 & + zgt33 * 2.34_wp ) ! wind >= 33 m/s 253 ! 254 cd_n10_ncar(ji,jj) = MAX( cd_n10_ncar(ji,jj), Cx_min ) 255 ! 258 256 END_2D 259 257 ! 260 END FUNCTION cd_neutral_10m 261 262 263 FUNCTION psi_m( pzeta ) 258 END FUNCTION cd_n10_ncar 259 260 261 FUNCTION ch_n10_ncar( psqrtcdn10 , pstab ) 262 !!---------------------------------------------------------------------------------- 263 !! Estimate of the neutral heat transfer coefficient at 10m !! 264 !! Origin: Large & Yeager 2008, Eq. (9) and (12) 265 266 !!---------------------------------------------------------------------------------- 267 REAL(wp), DIMENSION(jpi,jpj) :: ch_n10_ncar 268 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psqrtcdn10 ! sqrt( CdN10 ) 269 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pstab ! stable ABL => 1 / unstable ABL => 0 270 !!---------------------------------------------------------------------------------- 271 IF( ANY(pstab < -0.00001) .OR. ANY(pstab > 1.00001) ) THEN 272 PRINT *, 'ERROR: ch_n10_ncar@mod_blk_ncar.f90: pstab =' 273 PRINT *, pstab 274 STOP 275 END IF 276 ! 277 ch_n10_ncar = MAX( 1.e-3_wp * psqrtcdn10*( 18._wp*pstab + 32.7_wp*(1._wp - pstab) ) , Cx_min ) ! Eq. (9) & (12) Large & Yeager, 2008 278 ! 279 END FUNCTION ch_n10_ncar 280 281 FUNCTION ce_n10_ncar( psqrtcdn10 ) 282 !!---------------------------------------------------------------------------------- 283 !! Estimate of the neutral heat transfer coefficient at 10m !! 284 !! Origin: Large & Yeager 2008, Eq. (9) and (13) 285 !!---------------------------------------------------------------------------------- 286 REAL(wp), DIMENSION(jpi,jpj) :: ce_n10_ncar 287 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: psqrtcdn10 ! sqrt( CdN10 ) 288 !!---------------------------------------------------------------------------------- 289 ce_n10_ncar = MAX( 1.e-3_wp * ( 34.6_wp * psqrtcdn10 ) , Cx_min ) 290 ! 291 END FUNCTION ce_n10_ncar 292 293 294 FUNCTION psi_m_ncar( pzeta ) 264 295 !!---------------------------------------------------------------------------------- 265 296 !! Universal profile stability function for momentum 266 !! !! Psis, L&Y 2004 eq. (8c), (8d), (8e)297 !! !! Psis, L&Y 2004, Eq. (8c), (8d), (8e) 267 298 !! 268 299 !! pzeta : stability paramenter, z/L where z is altitude measurement … … 271 302 !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 272 303 !!---------------------------------------------------------------------------------- 273 REAL(wp), DIMENSION(jpi,jpj) :: psi_m 304 REAL(wp), DIMENSION(jpi,jpj) :: psi_m_ncar 274 305 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta 275 306 ! 276 307 INTEGER :: ji, jj ! dummy loop indices 277 REAL(wp) :: z x2, zx,zstab ! local scalars308 REAL(wp) :: zta, zx2, zx, zpsi_unst, zpsi_stab, zstab ! local scalars 278 309 !!---------------------------------------------------------------------------------- 279 310 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 280 zx2 = SQRT( ABS( 1._wp - 16._wp*pzeta(ji,jj) ) ) 281 zx2 = MAX( zx2 , 1._wp ) 282 zx = SQRT( zx2 ) 283 zstab = 0.5_wp + SIGN( 0.5_wp , pzeta(ji,jj) ) 284 ! 285 psi_m(ji,jj) = zstab * (-5._wp*pzeta(ji,jj)) & ! Stable 286 & + (1._wp - zstab) * (2._wp*LOG((1._wp + zx)*0.5_wp) & ! Unstable 287 & + LOG((1._wp + zx2)*0.5_wp) - 2._wp*ATAN(zx) + rpi*0.5_wp) ! " 288 ! 311 zta = pzeta(ji,jj) 312 ! 313 zx2 = SQRT( ABS(1._wp - 16._wp*zta) ) ! (1 - 16z)^0.5 314 zx2 = MAX( zx2 , 1._wp ) 315 zx = SQRT(zx2) ! (1 - 16z)^0.25 316 zpsi_unst = 2._wp*LOG( (1._wp + zx )*0.5_wp ) & 317 & + LOG( (1._wp + zx2)*0.5_wp ) & 318 & - 2._wp*ATAN(zx) + rpi*0.5_wp 319 ! 320 zpsi_stab = -5._wp*zta 321 ! 322 zstab = 0.5_wp + SIGN(0.5_wp, zta) ! zta > 0 => zstab = 1 323 ! 324 psi_m_ncar(ji,jj) = zstab * zpsi_stab & ! (zta > 0) Stable 325 & + (1._wp - zstab) * zpsi_unst ! (zta < 0) Unstable 326 ! 327 ! 289 328 END_2D 290 END FUNCTION psi_m 291 292 293 FUNCTION psi_h ( pzeta )329 END FUNCTION psi_m_ncar 330 331 332 FUNCTION psi_h_ncar( pzeta ) 294 333 !!---------------------------------------------------------------------------------- 295 334 !! Universal profile stability function for temperature and humidity 296 !! !! Psis, L&Y 2004 eq. (8c), (8d), (8e)335 !! !! Psis, L&Y 2004, Eq. (8c), (8d), (8e) 297 336 !! 298 337 !! pzeta : stability paramenter, z/L where z is altitude measurement … … 301 340 !! ** Author: L. Brodeau, June 2016 / AeroBulk (https://github.com/brodeau/aerobulk/) 302 341 !!---------------------------------------------------------------------------------- 303 REAL(wp), DIMENSION(jpi,jpj) :: psi_h 342 REAL(wp), DIMENSION(jpi,jpj) :: psi_h_ncar 304 343 REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pzeta 305 344 ! 306 345 INTEGER :: ji, jj ! dummy loop indices 307 REAL(wp) :: z x2, zstab ! local scalars346 REAL(wp) :: zta, zx2, zpsi_unst, zpsi_stab, zstab ! local scalars 308 347 !!---------------------------------------------------------------------------------- 309 348 ! 310 349 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 311 zx2 = SQRT( ABS( 1._wp - 16._wp*pzeta(ji,jj) ) ) 312 zx2 = MAX( zx2 , 1._wp ) 313 zstab = 0.5_wp + SIGN( 0.5_wp , pzeta(ji,jj) ) 314 ! 315 psi_h(ji,jj) = zstab * (-5._wp*pzeta(ji,jj)) & ! Stable 316 & + (1._wp - zstab) * (2._wp*LOG( (1._wp + zx2)*0.5_wp )) ! Unstable 317 ! 350 ! 351 zta = pzeta(ji,jj) 352 ! 353 zx2 = SQRT( ABS(1._wp - 16._wp*zta) ) ! (1 -16z)^0.5 354 zx2 = MAX( zx2 , 1._wp ) 355 zpsi_unst = 2._wp*LOG( 0.5_wp*(1._wp + zx2) ) 356 ! 357 zpsi_stab = -5._wp*zta 358 ! 359 zstab = 0.5_wp + SIGN(0.5_wp, zta) ! zta > 0 => zstab = 1 360 ! 361 psi_h_ncar(ji,jj) = zstab * zpsi_stab & ! (zta > 0) Stable 362 & + (1._wp - zstab) * zpsi_unst ! (zta < 0) Unstable 363 ! 318 364 END_2D 319 END FUNCTION psi_h 365 END FUNCTION psi_h_ncar 320 366 321 367 !!====================================================================== -
NEMO/trunk/src/OCE/SBC/sbcblk_skin_coare.F90
r13460 r14072 13 13 !! ** Author: L. Brodeau, November 2019 / AeroBulk (https://github.com/brodeau/aerobulk) 14 14 !!---------------------------------------------------------------------- 15 !! History : 4. x! 2019-11 (L.Brodeau) Original code15 !! History : 4.0 ! 2019-11 (L.Brodeau) Original code 16 16 !!---------------------------------------------------------------------- 17 17 USE oce ! ocean dynamics and tracers … … 20 20 USE sbc_oce ! Surface boundary condition: ocean fields 21 21 22 USE sbc blk_phy ! misc. functions for marine ABL physics (rho_air, q_sat, bulk_formula, etc)22 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 23 23 24 24 USE sbcdcy !#LB: to know hour of dawn and dusk: rdawn_dcy and rdusk_dcy (needed in WL_COARE) -
NEMO/trunk/src/OCE/SBC/sbcblk_skin_ecmwf.F90
r13460 r14072 28 28 !! ** Author: L. Brodeau, November 2019 / AeroBulk (https://github.com/brodeau/aerobulk) 29 29 !!---------------------------------------------------------------------- 30 !! History : 4.x ! 2019-11 (L.Brodeau) Original code 30 !! History : 4.0 ! 2019-11 (L.Brodeau) Original code 31 !! 4.2 ! 2020-12 (L. Brodeau) Introduction of various air-ice bulk parameterizations + improvements 31 32 !!---------------------------------------------------------------------- 32 33 USE oce ! ocean dynamics and tracers … … 35 36 USE sbc_oce ! Surface boundary condition: ocean fields 36 37 37 USE sbc blk_phy ! misc. functions for marine ABL physics (rho_air, q_sat, bulk_formula, etc)38 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 38 39 39 40 USE lib_mpp ! distribued memory computing library … … 160 161 REAL(wp) :: zalfa !: thermal expansion coefficient of sea-water [1/K] 161 162 REAL(wp) :: zdTwl_b, zdTwl_n !: temp. diff. between "almost surface (right below viscous layer) and bottom of WL 162 REAL(wp) :: zfr, zeta 163 REAL(wp) :: zusw, zusw2 164 REAL(wp) :: zLa, zfLa 165 REAL(wp) :: flg, zwf, zQabs 163 REAL(wp) :: zfr, zeta 164 REAL(wp) :: zusw, zusw2 165 REAL(wp) :: zLa, zfLa 166 REAL(wp) :: flg, zwf, zQabs 166 167 REAL(wp) :: ZA, ZB, zL1, zL2 167 168 REAL(wp) :: zcst0, zcst1, zcst2, zcst3 -
NEMO/trunk/src/OCE/SBC/sbccpl.F90
r14007 r14072 33 33 #endif 34 34 USE cpl_oasis3 ! OASIS3 coupling 35 USE geo2ocean ! 35 USE geo2ocean ! 36 36 USE oce , ONLY : ts, uu, vv, ssh, fraqsr_1lev 37 USE ocealb ! 38 USE eosbn2 ! 37 USE ocealb ! 38 USE eosbn2 ! 39 39 USE sbcrnf , ONLY : l_rnfcpl 40 40 #if defined key_cice … … 50 50 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 51 51 52 #if defined key_oasis3 53 USE mod_oasis, ONLY : OASIS_Sent, OASIS_ToRest, OASIS_SentOut, OASIS_ToRestOut 54 #endif 52 #if defined key_oasis3 53 USE mod_oasis, ONLY : OASIS_Sent, OASIS_ToRest, OASIS_SentOut, OASIS_ToRestOut 54 #endif 55 56 USE sbc_phy, ONLY : pp_cldf 55 57 56 58 IMPLICIT NONE … … 65 67 66 68 INTEGER, PARAMETER :: jpr_otx1 = 1 ! 3 atmosphere-ocean stress components on grid 1 67 INTEGER, PARAMETER :: jpr_oty1 = 2 ! 68 INTEGER, PARAMETER :: jpr_otz1 = 3 ! 69 INTEGER, PARAMETER :: jpr_oty1 = 2 ! 70 INTEGER, PARAMETER :: jpr_otz1 = 3 ! 69 71 INTEGER, PARAMETER :: jpr_otx2 = 4 ! 3 atmosphere-ocean stress components on grid 2 70 INTEGER, PARAMETER :: jpr_oty2 = 5 ! 71 INTEGER, PARAMETER :: jpr_otz2 = 6 ! 72 INTEGER, PARAMETER :: jpr_oty2 = 5 ! 73 INTEGER, PARAMETER :: jpr_otz2 = 6 ! 72 74 INTEGER, PARAMETER :: jpr_itx1 = 7 ! 3 atmosphere-ice stress components on grid 1 73 INTEGER, PARAMETER :: jpr_ity1 = 8 ! 74 INTEGER, PARAMETER :: jpr_itz1 = 9 ! 75 INTEGER, PARAMETER :: jpr_ity1 = 8 ! 76 INTEGER, PARAMETER :: jpr_itz1 = 9 ! 75 77 INTEGER, PARAMETER :: jpr_itx2 = 10 ! 3 atmosphere-ice stress components on grid 2 76 INTEGER, PARAMETER :: jpr_ity2 = 11 ! 77 INTEGER, PARAMETER :: jpr_itz2 = 12 ! 78 INTEGER, PARAMETER :: jpr_ity2 = 11 ! 79 INTEGER, PARAMETER :: jpr_itz2 = 12 ! 78 80 INTEGER, PARAMETER :: jpr_qsroce = 13 ! Qsr above the ocean 79 81 INTEGER, PARAMETER :: jpr_qsrice = 14 ! Qsr above the ice 80 INTEGER, PARAMETER :: jpr_qsrmix = 15 82 INTEGER, PARAMETER :: jpr_qsrmix = 15 81 83 INTEGER, PARAMETER :: jpr_qnsoce = 16 ! Qns above the ocean 82 84 INTEGER, PARAMETER :: jpr_qnsice = 17 ! Qns above the ice … … 103 105 INTEGER, PARAMETER :: jpr_ocy1 = 38 ! 104 106 INTEGER, PARAMETER :: jpr_ssh = 39 ! sea surface height 105 INTEGER, PARAMETER :: jpr_fice = 40 ! ice fraction 106 INTEGER, PARAMETER :: jpr_e3t1st = 41 ! first T level thickness 107 INTEGER, PARAMETER :: jpr_fice = 40 ! ice fraction 108 INTEGER, PARAMETER :: jpr_e3t1st = 41 ! first T level thickness 107 109 INTEGER, PARAMETER :: jpr_fraqsr = 42 ! fraction of solar net radiation absorbed in the first ocean level 108 INTEGER, PARAMETER :: jpr_mslp = 43 ! mean sea level pressure 110 INTEGER, PARAMETER :: jpr_mslp = 43 ! mean sea level pressure 109 111 !** surface wave coupling ** 110 112 INTEGER, PARAMETER :: jpr_hsig = 44 ! Hsig … … 128 130 INTEGER, PARAMETER :: jpr_ts_ice = 62 ! Sea ice surface temp 129 131 130 INTEGER, PARAMETER :: jprcv = 62 ! total number of fields received 132 INTEGER, PARAMETER :: jprcv = 62 ! total number of fields received 131 133 132 134 INTEGER, PARAMETER :: jps_fice = 1 ! ice fraction sent to the atmosphere … … 152 154 INTEGER, PARAMETER :: jps_sflx = 21 ! salt flux 153 155 INTEGER, PARAMETER :: jps_otx1 = 22 ! 2 atmosphere-ocean stress components on grid 1 154 INTEGER, PARAMETER :: jps_oty1 = 23 ! 156 INTEGER, PARAMETER :: jps_oty1 = 23 ! 155 157 INTEGER, PARAMETER :: jps_rnf = 24 ! runoffs 156 158 INTEGER, PARAMETER :: jps_taum = 25 ! wind stress module … … 158 160 INTEGER, PARAMETER :: jps_e3t1st = 27 ! first level depth (vvl) 159 161 INTEGER, PARAMETER :: jps_fraqsr = 28 ! fraction of solar net radiation absorbed in the first ocean level 160 INTEGER, PARAMETER :: jps_ficet = 29 ! total ice fraction 161 INTEGER, PARAMETER :: jps_ocxw = 30 ! currents on grid 1 162 INTEGER, PARAMETER :: jps_ficet = 29 ! total ice fraction 163 INTEGER, PARAMETER :: jps_ocxw = 30 ! currents on grid 1 162 164 INTEGER, PARAMETER :: jps_ocyw = 31 ! currents on grid 2 163 INTEGER, PARAMETER :: jps_wlev = 32 ! water level 165 INTEGER, PARAMETER :: jps_wlev = 32 ! water level 164 166 INTEGER, PARAMETER :: jps_fice1 = 33 ! first-order ice concentration (for semi-implicit coupling of atmos-ice fluxes) 165 167 INTEGER, PARAMETER :: jps_a_p = 34 ! meltpond area fraction … … 169 171 INTEGER, PARAMETER :: jps_ttilyr = 38 ! sea ice top layer temp 170 172 171 INTEGER, PARAMETER :: jpsnd = 38 ! total number of fields sent 172 173 #if ! defined key_oasis3 174 ! Dummy variables to enable compilation when oasis3 is not being used 175 INTEGER :: OASIS_Sent = -1 176 INTEGER :: OASIS_SentOut = -1 177 INTEGER :: OASIS_ToRest = -1 178 INTEGER :: OASIS_ToRestOut = -1 179 #endif 173 INTEGER, PARAMETER :: jpsnd = 38 ! total number of fields sent 174 175 #if ! defined key_oasis3 176 ! Dummy variables to enable compilation when oasis3 is not being used 177 INTEGER :: OASIS_Sent = -1 178 INTEGER :: OASIS_SentOut = -1 179 INTEGER :: OASIS_ToRest = -1 180 INTEGER :: OASIS_ToRestOut = -1 181 #endif 180 182 181 183 ! !!** namelist namsbc_cpl ** 182 TYPE :: FLD_C ! 184 TYPE :: FLD_C ! 183 185 CHARACTER(len = 32) :: cldes ! desciption of the coupling strategy 184 186 CHARACTER(len = 32) :: clcat ! multiple ice categories strategy … … 187 189 CHARACTER(len = 32) :: clvgrd ! grids on which is located the vector fields 188 190 END TYPE FLD_C 189 ! ! Send to the atmosphere 191 ! ! Send to the atmosphere 190 192 TYPE(FLD_C) :: sn_snd_temp , sn_snd_alb , sn_snd_thick, sn_snd_crt , sn_snd_co2, & 191 193 & sn_snd_thick1, sn_snd_cond, sn_snd_mpnd , sn_snd_sstfrz, sn_snd_ttilyr … … 194 196 & sn_rcv_qns , sn_rcv_emp , sn_rcv_rnf, sn_rcv_ts_ice 195 197 TYPE(FLD_C) :: sn_rcv_cal, sn_rcv_iceflx, sn_rcv_co2, sn_rcv_mslp, sn_rcv_icb, sn_rcv_isf 196 ! ! Send to waves 197 TYPE(FLD_C) :: sn_snd_ifrac, sn_snd_crtw, sn_snd_wlev 198 ! ! Received from waves 198 ! ! Send to waves 199 TYPE(FLD_C) :: sn_snd_ifrac, sn_snd_crtw, sn_snd_wlev 200 ! ! Received from waves 199 201 TYPE(FLD_C) :: sn_rcv_hsig, sn_rcv_phioc, sn_rcv_sdrfx, sn_rcv_sdrfy, sn_rcv_wper, sn_rcv_wnum, & 200 202 & sn_rcv_wstrf, sn_rcv_wdrag, sn_rcv_charn, sn_rcv_taw, sn_rcv_bhd, sn_rcv_tusd, sn_rcv_tvsd … … 203 205 LOGICAL :: ln_usecplmask ! use a coupling mask file to merge data received from several models 204 206 ! -> file cplmask.nc with the float variable called cplmask (jpi,jpj,nn_cplmodel) 205 LOGICAL :: ln_scale_ice_flux ! use ice fluxes that are already "ice weighted" ( i.e. multiplied ice concentration) 206 207 TYPE :: DYNARR 208 REAL(wp), POINTER, DIMENSION(:,:,:) :: z3 207 LOGICAL :: ln_scale_ice_flux ! use ice fluxes that are already "ice weighted" ( i.e. multiplied ice concentration) 208 209 TYPE :: DYNARR 210 REAL(wp), POINTER, DIMENSION(:,:,:) :: z3 209 211 END TYPE DYNARR 210 212 … … 216 218 #endif 217 219 218 REAL(wp) :: rpref = 101000._wp ! reference atmospheric pressure[N/m2] 219 REAL(wp) :: r1_grau ! = 1.e0 / (grav * rho0) 220 REAL(wp) :: rpref = 101000._wp ! reference atmospheric pressure[N/m2] 221 REAL(wp) :: r1_grau ! = 1.e0 / (grav * rho0) 220 222 221 223 INTEGER , ALLOCATABLE, SAVE, DIMENSION(:) :: nrcvinfo ! OASIS info argument … … 230 232 !!---------------------------------------------------------------------- 231 233 CONTAINS 232 234 233 235 INTEGER FUNCTION sbc_cpl_alloc() 234 236 !!---------------------------------------------------------------------- … … 240 242 ! 241 243 ALLOCATE( alb_oce_mix(jpi,jpj), nrcvinfo(jprcv), STAT=ierr(1) ) 242 244 243 245 #if ! defined key_si3 && ! defined key_cice 244 246 ALLOCATE( a_i(jpi,jpj,1) , STAT=ierr(2) ) ! used in sbcice_if.F90 (done here as there is no sbc_ice_if_init) … … 258 260 259 261 260 SUBROUTINE sbc_cpl_init( k_ice ) 262 SUBROUTINE sbc_cpl_init( k_ice ) 261 263 !!---------------------------------------------------------------------- 262 264 !! *** ROUTINE sbc_cpl_init *** … … 265 267 !! the atmospheric component 266 268 !! 267 !! ** Method : * Read namsbc_cpl namelist 269 !! ** Method : * Read namsbc_cpl namelist 268 270 !! * define the receive interface 269 271 !! * define the send interface … … 277 279 !! 278 280 NAMELIST/namsbc_cpl/ nn_cplmodel , ln_usecplmask, nn_cats_cpl , ln_scale_ice_flux, & 279 & sn_snd_temp , sn_snd_alb , sn_snd_thick, sn_snd_crt , sn_snd_co2 , & 280 & sn_snd_ttilyr, sn_snd_cond , sn_snd_mpnd , sn_snd_sstfrz, sn_snd_thick1, & 281 & sn_snd_ifrac , sn_snd_crtw , sn_snd_wlev , sn_rcv_hsig , sn_rcv_phioc , & 282 & sn_rcv_w10m , sn_rcv_taumod, sn_rcv_tau , sn_rcv_dqnsdt, sn_rcv_qsr , & 281 & sn_snd_temp , sn_snd_alb , sn_snd_thick, sn_snd_crt , sn_snd_co2 , & 282 & sn_snd_ttilyr, sn_snd_cond , sn_snd_mpnd , sn_snd_sstfrz, sn_snd_thick1, & 283 & sn_snd_ifrac , sn_snd_crtw , sn_snd_wlev , sn_rcv_hsig , sn_rcv_phioc , & 284 & sn_rcv_w10m , sn_rcv_taumod, sn_rcv_tau , sn_rcv_dqnsdt, sn_rcv_qsr , & 283 285 & sn_rcv_sdrfx , sn_rcv_sdrfy , sn_rcv_wper , sn_rcv_wnum , sn_rcv_wstrf , & 284 286 & sn_rcv_charn , sn_rcv_taw , sn_rcv_bhd , sn_rcv_tusd , sn_rcv_tvsd, & 285 287 & sn_rcv_wdrag , sn_rcv_qns , sn_rcv_emp , sn_rcv_rnf , sn_rcv_cal , & 286 & sn_rcv_iceflx, sn_rcv_co2 , sn_rcv_icb , sn_rcv_isf , sn_rcv_ts_ice 288 & sn_rcv_iceflx, sn_rcv_co2 , sn_rcv_icb , sn_rcv_isf , sn_rcv_ts_ice 287 289 288 290 !!--------------------------------------------------------------------- … … 328 330 WRITE(numout,*)' Sea ice surface skin temperature= ', TRIM(sn_rcv_ts_ice%cldes), ' (', TRIM(sn_rcv_ts_ice%clcat), ')' 329 331 WRITE(numout,*)' surface waves:' 330 WRITE(numout,*)' significant wave heigth = ', TRIM(sn_rcv_hsig%cldes ), ' (', TRIM(sn_rcv_hsig%clcat ), ')' 331 WRITE(numout,*)' wave to oce energy flux = ', TRIM(sn_rcv_phioc%cldes ), ' (', TRIM(sn_rcv_phioc%clcat ), ')' 332 WRITE(numout,*)' Surface Stokes drift grid u = ', TRIM(sn_rcv_sdrfx%cldes ), ' (', TRIM(sn_rcv_sdrfx%clcat ), ')' 333 WRITE(numout,*)' Surface Stokes drift grid v = ', TRIM(sn_rcv_sdrfy%cldes ), ' (', TRIM(sn_rcv_sdrfy%clcat ), ')' 334 WRITE(numout,*)' Mean wave period = ', TRIM(sn_rcv_wper%cldes ), ' (', TRIM(sn_rcv_wper%clcat ), ')' 335 WRITE(numout,*)' Mean wave number = ', TRIM(sn_rcv_wnum%cldes ), ' (', TRIM(sn_rcv_wnum%clcat ), ')' 332 WRITE(numout,*)' significant wave heigth = ', TRIM(sn_rcv_hsig%cldes ), ' (', TRIM(sn_rcv_hsig%clcat ), ')' 333 WRITE(numout,*)' wave to oce energy flux = ', TRIM(sn_rcv_phioc%cldes ), ' (', TRIM(sn_rcv_phioc%clcat ), ')' 334 WRITE(numout,*)' Surface Stokes drift grid u = ', TRIM(sn_rcv_sdrfx%cldes ), ' (', TRIM(sn_rcv_sdrfx%clcat ), ')' 335 WRITE(numout,*)' Surface Stokes drift grid v = ', TRIM(sn_rcv_sdrfy%cldes ), ' (', TRIM(sn_rcv_sdrfy%clcat ), ')' 336 WRITE(numout,*)' Mean wave period = ', TRIM(sn_rcv_wper%cldes ), ' (', TRIM(sn_rcv_wper%clcat ), ')' 337 WRITE(numout,*)' Mean wave number = ', TRIM(sn_rcv_wnum%cldes ), ' (', TRIM(sn_rcv_wnum%clcat ), ')' 336 338 WRITE(numout,*)' Stress frac adsorbed by waves = ', TRIM(sn_rcv_wstrf%cldes ), ' (', TRIM(sn_rcv_wstrf%clcat ), ')' 337 WRITE(numout,*)' Neutral surf drag coefficient = ', TRIM(sn_rcv_wdrag%cldes ), ' (', TRIM(sn_rcv_wdrag%clcat ), ')' 339 WRITE(numout,*)' Neutral surf drag coefficient = ', TRIM(sn_rcv_wdrag%cldes ), ' (', TRIM(sn_rcv_wdrag%clcat ), ')' 338 340 WRITE(numout,*)' Charnock coefficient = ', TRIM(sn_rcv_charn%cldes ), ' (', TRIM(sn_rcv_charn%clcat ), ')' 339 341 WRITE(numout,*)' sent fields (multiple ice categories)' … … 342 344 WRITE(numout,*)' albedo = ', TRIM(sn_snd_alb%cldes ), ' (', TRIM(sn_snd_alb%clcat ), ')' 343 345 WRITE(numout,*)' ice/snow thickness = ', TRIM(sn_snd_thick%cldes ), ' (', TRIM(sn_snd_thick%clcat ), ')' 344 WRITE(numout,*)' total ice fraction = ', TRIM(sn_snd_ifrac%cldes ), ' (', TRIM(sn_snd_ifrac%clcat ), ')' 346 WRITE(numout,*)' total ice fraction = ', TRIM(sn_snd_ifrac%cldes ), ' (', TRIM(sn_snd_ifrac%clcat ), ')' 345 347 WRITE(numout,*)' surface current = ', TRIM(sn_snd_crt%cldes ), ' (', TRIM(sn_snd_crt%clcat ), ')' 346 WRITE(numout,*)' - referential = ', sn_snd_crt%clvref 348 WRITE(numout,*)' - referential = ', sn_snd_crt%clvref 347 349 WRITE(numout,*)' - orientation = ', sn_snd_crt%clvor 348 350 WRITE(numout,*)' - mesh = ', sn_snd_crt%clvgrd … … 351 353 WRITE(numout,*)' meltponds fraction and depth = ', TRIM(sn_snd_mpnd%cldes ), ' (', TRIM(sn_snd_mpnd%clcat ), ')' 352 354 WRITE(numout,*)' sea surface freezing temp = ', TRIM(sn_snd_sstfrz%cldes), ' (', TRIM(sn_snd_sstfrz%clcat), ')' 353 WRITE(numout,*)' water level = ', TRIM(sn_snd_wlev%cldes ), ' (', TRIM(sn_snd_wlev%clcat ), ')' 354 WRITE(numout,*)' mean sea level pressure = ', TRIM(sn_rcv_mslp%cldes ), ' (', TRIM(sn_rcv_mslp%clcat ), ')' 355 WRITE(numout,*)' surface current to waves = ', TRIM(sn_snd_crtw%cldes ), ' (', TRIM(sn_snd_crtw%clcat ), ')' 356 WRITE(numout,*)' - referential = ', sn_snd_crtw%clvref 357 WRITE(numout,*)' - orientation = ', sn_snd_crtw%clvor 358 WRITE(numout,*)' - mesh = ', sn_snd_crtw%clvgrd 355 WRITE(numout,*)' water level = ', TRIM(sn_snd_wlev%cldes ), ' (', TRIM(sn_snd_wlev%clcat ), ')' 356 WRITE(numout,*)' mean sea level pressure = ', TRIM(sn_rcv_mslp%cldes ), ' (', TRIM(sn_rcv_mslp%clcat ), ')' 357 WRITE(numout,*)' surface current to waves = ', TRIM(sn_snd_crtw%cldes ), ' (', TRIM(sn_snd_crtw%clcat ), ')' 358 WRITE(numout,*)' - referential = ', sn_snd_crtw%clvref 359 WRITE(numout,*)' - orientation = ', sn_snd_crtw%clvor 360 WRITE(numout,*)' - mesh = ', sn_snd_crtw%clvgrd 359 361 ENDIF 360 362 IF( lwp .AND. ln_wave) THEN ! control print … … 380 382 ! ! allocate sbccpl arrays 381 383 IF( sbc_cpl_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_cpl_alloc : unable to allocate arrays' ) 382 384 383 385 ! ================================ ! 384 386 ! Define the receive interface ! 385 387 ! ================================ ! 386 nrcvinfo(:) = OASIS_idle ! needed by nrcvinfo(jpr_otx1) if we do not receive ocean stress 388 nrcvinfo(:) = OASIS_idle ! needed by nrcvinfo(jpr_otx1) if we do not receive ocean stress 387 389 388 390 ! for each field: define the OASIS name (srcv(:)%clname) … … 394 396 395 397 ! ! ------------------------- ! 396 ! ! ice and ocean wind stress ! 397 ! ! ------------------------- ! 398 ! ! Name 398 ! ! ice and ocean wind stress ! 399 ! ! ------------------------- ! 400 ! ! Name 399 401 srcv(jpr_otx1)%clname = 'O_OTaux1' ! 1st ocean component on grid ONE (T or U) 400 srcv(jpr_oty1)%clname = 'O_OTauy1' ! 2nd - - - - 401 srcv(jpr_otz1)%clname = 'O_OTauz1' ! 3rd - - - - 402 srcv(jpr_oty1)%clname = 'O_OTauy1' ! 2nd - - - - 403 srcv(jpr_otz1)%clname = 'O_OTauz1' ! 3rd - - - - 402 404 srcv(jpr_otx2)%clname = 'O_OTaux2' ! 1st ocean component on grid TWO (V) 403 srcv(jpr_oty2)%clname = 'O_OTauy2' ! 2nd - - - - 404 srcv(jpr_otz2)%clname = 'O_OTauz2' ! 3rd - - - - 405 srcv(jpr_oty2)%clname = 'O_OTauy2' ! 2nd - - - - 406 srcv(jpr_otz2)%clname = 'O_OTauz2' ! 3rd - - - - 405 407 ! 406 408 srcv(jpr_itx1)%clname = 'O_ITaux1' ! 1st ice component on grid ONE (T, F, I or U) 407 srcv(jpr_ity1)%clname = 'O_ITauy1' ! 2nd - - - - 408 srcv(jpr_itz1)%clname = 'O_ITauz1' ! 3rd - - - - 409 srcv(jpr_ity1)%clname = 'O_ITauy1' ! 2nd - - - - 410 srcv(jpr_itz1)%clname = 'O_ITauz1' ! 3rd - - - - 409 411 srcv(jpr_itx2)%clname = 'O_ITaux2' ! 1st ice component on grid TWO (V) 410 srcv(jpr_ity2)%clname = 'O_ITauy2' ! 2nd - - - - 411 srcv(jpr_itz2)%clname = 'O_ITauz2' ! 3rd - - - - 412 ! 412 srcv(jpr_ity2)%clname = 'O_ITauy2' ! 2nd - - - - 413 srcv(jpr_itz2)%clname = 'O_ITauz2' ! 3rd - - - - 414 ! 413 415 ! Vectors: change of sign at north fold ONLY if on the local grid 414 416 IF( TRIM( sn_rcv_tau%cldes ) == 'oce only' .OR. TRIM( sn_rcv_tau%cldes ) == 'oce and ice' & … … 416 418 ! 417 419 IF( TRIM( sn_rcv_tau%clvor ) == 'local grid' ) srcv(jpr_otx1:jpr_itz2)%nsgn = -1. 418 420 419 421 ! ! Set grid and action 420 422 SELECT CASE( TRIM( sn_rcv_tau%clvgrd ) ) ! 'T', 'U,V', 'U,V,I', 'U,V,F', 'T,I', 'T,F', or 'T,U,V' 421 CASE( 'T' ) 423 CASE( 'T' ) 422 424 srcv(jpr_otx1:jpr_itz2)%clgrid = 'T' ! oce and ice components given at T-point 423 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 424 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 425 CASE( 'U,V' ) 425 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 426 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 427 CASE( 'U,V' ) 426 428 srcv(jpr_otx1:jpr_otz1)%clgrid = 'U' ! oce components given at U-point 427 429 srcv(jpr_otx2:jpr_otz2)%clgrid = 'V' ! and V-point … … 447 449 srcv(jpr_otx1:jpr_otz2)%laction = .TRUE. ! receive oce components on grid 1 & 2 448 450 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 only 449 CASE( 'T,I' ) 451 CASE( 'T,I' ) 450 452 srcv(jpr_otx1:jpr_itz2)%clgrid = 'T' ! oce and ice components given at T-point 451 453 srcv(jpr_itx1:jpr_itz1)%clgrid = 'I' ! ice components given at I-point 452 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 453 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 454 CASE( 'T,F' ) 454 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 455 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 456 CASE( 'T,F' ) 455 457 srcv(jpr_otx1:jpr_itz2)%clgrid = 'T' ! oce and ice components given at T-point 456 458 srcv(jpr_itx1:jpr_itz1)%clgrid = 'F' ! ice components given at F-point 457 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 458 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 459 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 460 srcv(jpr_itx1:jpr_itz1)%laction = .TRUE. ! receive ice components on grid 1 459 461 CASE( 'T,U,V' ) 460 462 srcv(jpr_otx1:jpr_otz1)%clgrid = 'T' ! oce components given at T-point … … 463 465 srcv(jpr_otx1:jpr_otz1)%laction = .TRUE. ! receive oce components on grid 1 only 464 466 srcv(jpr_itx1:jpr_itz2)%laction = .TRUE. ! receive ice components on grid 1 & 2 465 CASE default 467 CASE default 466 468 CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_rcv_tau%clvgrd' ) 467 469 END SELECT 468 470 ! 469 471 IF( TRIM( sn_rcv_tau%clvref ) == 'spherical' ) & ! spherical: 3rd component not received 470 & srcv( (/jpr_otz1, jpr_otz2, jpr_itz1, jpr_itz2/) )%laction = .FALSE. 472 & srcv( (/jpr_otz1, jpr_otz2, jpr_itz1, jpr_itz2/) )%laction = .FALSE. 471 473 ! 472 474 IF( TRIM( sn_rcv_tau%clvor ) == 'local grid' ) THEN ! already on local grid -> no need of the second grid 473 srcv(jpr_otx2:jpr_otz2)%laction = .FALSE. 474 srcv(jpr_itx2:jpr_itz2)%laction = .FALSE. 475 srcv(jpr_otx2:jpr_otz2)%laction = .FALSE. 476 srcv(jpr_itx2:jpr_itz2)%laction = .FALSE. 475 477 srcv(jpr_oty1)%clgrid = srcv(jpr_oty2)%clgrid ! not needed but cleaner... 476 478 srcv(jpr_ity1)%clgrid = srcv(jpr_ity2)%clgrid ! not needed but cleaner... … … 488 490 ! ! ------------------------- ! 489 491 ! we suppose that atmosphere modele do not make the difference between precipiration (liquide or solid) 490 ! over ice of free ocean within the same atmospheric cell.cd 492 ! over ice of free ocean within the same atmospheric cell.cd 491 493 srcv(jpr_rain)%clname = 'OTotRain' ! Rain = liquid precipitation 492 494 srcv(jpr_snow)%clname = 'OTotSnow' ! Snow = solid precipitation 493 495 srcv(jpr_tevp)%clname = 'OTotEvap' ! total evaporation (over oce + ice sublimation) 494 496 srcv(jpr_ievp)%clname = 'OIceEvap' ! evaporation over ice = sublimation 495 srcv(jpr_sbpr)%clname = 'OSubMPre' ! sublimation - liquid precipitation - solid precipitation 497 srcv(jpr_sbpr)%clname = 'OSubMPre' ! sublimation - liquid precipitation - solid precipitation 496 498 srcv(jpr_semp)%clname = 'OISubMSn' ! ice solid water budget = sublimation - solid precipitation 497 499 srcv(jpr_oemp)%clname = 'OOEvaMPr' ! ocean water budget = ocean Evap - ocean precip 498 500 SELECT CASE( TRIM( sn_rcv_emp%cldes ) ) 499 501 CASE( 'none' ) ! nothing to do 500 CASE( 'oce only' ) ; srcv(jpr_oemp)%laction = .TRUE. 502 CASE( 'oce only' ) ; srcv(jpr_oemp)%laction = .TRUE. 501 503 CASE( 'conservative' ) 502 504 srcv( (/jpr_rain, jpr_snow, jpr_ievp, jpr_tevp/) )%laction = .TRUE. … … 507 509 ! 508 510 ! ! ------------------------- ! 509 ! ! Runoffs & Calving ! 511 ! ! Runoffs & Calving ! 510 512 ! ! ------------------------- ! 511 513 srcv(jpr_rnf )%clname = 'O_Runoff' … … 540 542 CASE( 'conservative' ) ; srcv( (/jpr_qnsice, jpr_qnsmix/) )%laction = .TRUE. 541 543 CASE( 'oce and ice' ) ; srcv( (/jpr_qnsice, jpr_qnsoce/) )%laction = .TRUE. 542 CASE( 'mixed oce-ice' ) ; srcv( jpr_qnsmix )%laction = .TRUE. 544 CASE( 'mixed oce-ice' ) ; srcv( jpr_qnsmix )%laction = .TRUE. 543 545 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_rcv_qns%cldes' ) 544 546 END SELECT … … 557 559 CASE( 'conservative' ) ; srcv( (/jpr_qsrice, jpr_qsrmix/) )%laction = .TRUE. 558 560 CASE( 'oce and ice' ) ; srcv( (/jpr_qsrice, jpr_qsroce/) )%laction = .TRUE. 559 CASE( 'mixed oce-ice' ) ; srcv( jpr_qsrmix )%laction = .TRUE. 561 CASE( 'mixed oce-ice' ) ; srcv( jpr_qsrmix )%laction = .TRUE. 560 562 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_rcv_qsr%cldes' ) 561 563 END SELECT … … 566 568 ! ! non solar sensitivity ! d(Qns)/d(T) 567 569 ! ! ------------------------- ! 568 srcv(jpr_dqnsdt)%clname = 'O_dQnsdT' 570 srcv(jpr_dqnsdt)%clname = 'O_dQnsdT' 569 571 IF( TRIM( sn_rcv_dqnsdt%cldes ) == 'coupled' ) srcv(jpr_dqnsdt)%laction = .TRUE. 570 572 ! … … 574 576 ! 575 577 ! ! ------------------------- ! 576 ! ! 10m wind module ! 577 ! ! ------------------------- ! 578 srcv(jpr_w10m)%clname = 'O_Wind10' ; IF( TRIM(sn_rcv_w10m%cldes ) == 'coupled' ) srcv(jpr_w10m)%laction = .TRUE. 579 ! 580 ! ! ------------------------- ! 581 ! ! wind stress module ! 578 ! ! 10m wind module ! 579 ! ! ------------------------- ! 580 srcv(jpr_w10m)%clname = 'O_Wind10' ; IF( TRIM(sn_rcv_w10m%cldes ) == 'coupled' ) srcv(jpr_w10m)%laction = .TRUE. 581 ! 582 ! ! ------------------------- ! 583 ! ! wind stress module ! 582 584 ! ! ------------------------- ! 583 585 srcv(jpr_taum)%clname = 'O_TauMod' ; IF( TRIM(sn_rcv_taumod%cldes) == 'coupled' ) srcv(jpr_taum)%laction = .TRUE. … … 586 588 ! ! Atmospheric CO2 ! 587 589 ! ! ------------------------- ! 588 srcv(jpr_co2 )%clname = 'O_AtmCO2' 590 srcv(jpr_co2 )%clname = 'O_AtmCO2' 589 591 IF( TRIM(sn_rcv_co2%cldes ) == 'coupled' ) THEN 590 592 srcv(jpr_co2 )%laction = .TRUE. … … 595 597 ENDIF 596 598 ! 597 ! ! ------------------------- ! 598 ! ! Mean Sea Level Pressure ! 599 ! ! ------------------------- ! 600 srcv(jpr_mslp)%clname = 'O_MSLP' ; IF( TRIM(sn_rcv_mslp%cldes ) == 'coupled' ) srcv(jpr_mslp)%laction = .TRUE. 601 ! 602 ! ! ------------------------- ! 603 ! ! ice topmelt and botmelt ! 599 ! ! ------------------------- ! 600 ! ! Mean Sea Level Pressure ! 601 ! ! ------------------------- ! 602 srcv(jpr_mslp)%clname = 'O_MSLP' ; IF( TRIM(sn_rcv_mslp%cldes ) == 'coupled' ) srcv(jpr_mslp)%laction = .TRUE. 603 ! 604 ! ! ------------------------- ! 605 ! ! ice topmelt and botmelt ! 604 606 ! ! ------------------------- ! 605 607 srcv(jpr_topm )%clname = 'OTopMlt' … … 614 616 ENDIF 615 617 ! ! ------------------------- ! 616 ! ! ice skin temperature ! 618 ! ! ice skin temperature ! 617 619 ! ! ------------------------- ! 618 620 srcv(jpr_ts_ice)%clname = 'OTsfIce' ! needed by Met Office … … 622 624 623 625 #if defined key_si3 624 IF( ln_cndflx .AND. .NOT.ln_cndemulate ) THEN 626 IF( ln_cndflx .AND. .NOT.ln_cndemulate ) THEN 625 627 IF( .NOT.srcv(jpr_ts_ice)%laction ) & 626 & CALL ctl_stop( 'sbc_cpl_init: srcv(jpr_ts_ice)%laction should be set to true when ln_cndflx=T' ) 628 & CALL ctl_stop( 'sbc_cpl_init: srcv(jpr_ts_ice)%laction should be set to true when ln_cndflx=T' ) 627 629 ENDIF 628 630 #endif 629 631 ! ! ------------------------- ! 630 ! ! Wave breaking ! 631 ! ! ------------------------- ! 632 ! ! Wave breaking ! 633 ! ! ------------------------- ! 632 634 srcv(jpr_hsig)%clname = 'O_Hsigwa' ! significant wave height 633 635 IF( TRIM(sn_rcv_hsig%cldes ) == 'coupled' ) THEN … … 704 706 ! 705 707 ! ! ------------------------------- ! 706 ! ! OPA-SAS coupling - rcv by opa ! 708 ! ! OPA-SAS coupling - rcv by opa ! 707 709 ! ! ------------------------------- ! 708 710 srcv(jpr_sflx)%clname = 'O_SFLX' … … 740 742 ENDIF 741 743 ! ! -------------------------------- ! 742 ! ! OPA-SAS coupling - rcv by sas ! 744 ! ! OPA-SAS coupling - rcv by sas ! 743 745 ! ! -------------------------------- ! 744 746 srcv(jpr_toce )%clname = 'I_SSTSST' … … 747 749 srcv(jpr_ocy1 )%clname = 'I_OCury1' 748 750 srcv(jpr_ssh )%clname = 'I_SSHght' 749 srcv(jpr_e3t1st)%clname = 'I_E3T1st' 750 srcv(jpr_fraqsr)%clname = 'I_FraQsr' 751 srcv(jpr_e3t1st)%clname = 'I_E3T1st' 752 srcv(jpr_fraqsr)%clname = 'I_FraQsr' 751 753 ! 752 754 IF( nn_components == jp_iam_sas ) THEN … … 778 780 ENDIF 779 781 WRITE(numout,*)' sea surface temperature (Celsius) ' 780 WRITE(numout,*)' sea surface salinity ' 781 WRITE(numout,*)' surface currents ' 782 WRITE(numout,*)' sea surface height ' 783 WRITE(numout,*)' thickness of first ocean T level ' 782 WRITE(numout,*)' sea surface salinity ' 783 WRITE(numout,*)' surface currents ' 784 WRITE(numout,*)' sea surface height ' 785 WRITE(numout,*)' thickness of first ocean T level ' 784 786 WRITE(numout,*)' fraction of solar net radiation absorbed in the first ocean level' 785 787 WRITE(numout,*) 786 788 ENDIF 787 789 ENDIF 788 790 789 791 ! =================================================== ! 790 792 ! Allocate all parts of frcv used for received fields ! … … 812 814 ! define send or not from the namelist parameters (ssnd(:)%laction) 813 815 ! define the north fold type of lbc (ssnd(:)%nsgn) 814 816 815 817 ! default definitions of nsnd 816 818 ssnd(:)%laction = .FALSE. ; ssnd(:)%clgrid = 'T' ; ssnd(:)%nsgn = 1. ; ssnd(:)%nct = 1 817 819 818 820 ! ! ------------------------- ! 819 821 ! ! Surface temperature ! … … 832 834 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_temp%cldes' ) 833 835 END SELECT 834 836 835 837 ! ! ------------------------- ! 836 838 ! ! Albedo ! 837 839 ! ! ------------------------- ! 838 ssnd(jps_albice)%clname = 'O_AlbIce' 840 ssnd(jps_albice)%clname = 'O_AlbIce' 839 841 ssnd(jps_albmix)%clname = 'O_AlbMix' 840 842 SELECT CASE( TRIM( sn_snd_alb%cldes ) ) … … 847 849 ! Need to calculate oceanic albedo if 848 850 ! 1. sending mixed oce-ice albedo or 849 ! 2. receiving mixed oce-ice solar radiation 851 ! 2. receiving mixed oce-ice solar radiation 850 852 IF( TRIM ( sn_snd_alb%cldes ) == 'mixed oce-ice' .OR. TRIM ( sn_rcv_qsr%cldes ) == 'mixed oce-ice' ) THEN 851 853 CALL oce_alb( zaos, zacs ) … … 854 856 ENDIF 855 857 ! ! ------------------------- ! 856 ! ! Ice fraction & Thickness ! 858 ! ! Ice fraction & Thickness ! 857 859 ! ! ------------------------- ! 858 860 ssnd(jps_fice)%clname = 'OIceFrc' 859 ssnd(jps_ficet)%clname = 'OIceFrcT' 861 ssnd(jps_ficet)%clname = 'OIceFrcT' 860 862 ssnd(jps_hice)%clname = 'OIceTck' 861 863 ssnd(jps_a_p)%clname = 'OPndFrc' … … 870 872 IF( TRIM( sn_snd_thick1%clcat ) == 'yes' ) ssnd(jps_fice1)%nct = nn_cats_cpl 871 873 ENDIF 872 873 IF(TRIM( sn_snd_ifrac%cldes ) == 'coupled') ssnd(jps_ficet)%laction = .TRUE. 874 875 IF(TRIM( sn_snd_ifrac%cldes ) == 'coupled') ssnd(jps_ficet)%laction = .TRUE. 874 876 875 877 SELECT CASE ( TRIM( sn_snd_thick%cldes ) ) 876 878 CASE( 'none' ) ! nothing to do 877 CASE( 'ice and snow' ) 879 CASE( 'ice and snow' ) 878 880 ssnd(jps_hice:jps_hsnw)%laction = .TRUE. 879 881 IF( TRIM( sn_snd_thick%clcat ) == 'yes' ) THEN 880 882 ssnd(jps_hice:jps_hsnw)%nct = nn_cats_cpl 881 883 ENDIF 882 CASE ( 'weighted ice and snow' ) 884 CASE ( 'weighted ice and snow' ) 883 885 ssnd(jps_hice:jps_hsnw)%laction = .TRUE. 884 886 IF( TRIM( sn_snd_thick%clcat ) == 'yes' ) ssnd(jps_hice:jps_hsnw)%nct = nn_cats_cpl … … 890 892 a_i_last_couple(:,:,:) = 0._wp 891 893 #endif 892 ! ! ------------------------- ! 893 ! ! Ice Meltponds ! 894 ! ! ------------------------- ! 894 ! ! ------------------------- ! 895 ! ! Ice Meltponds ! 896 ! ! ------------------------- ! 895 897 ! Needed by Met Office 896 ssnd(jps_a_p)%clname = 'OPndFrc' 897 ssnd(jps_ht_p)%clname = 'OPndTck' 898 SELECT CASE ( TRIM( sn_snd_mpnd%cldes ) ) 899 CASE ( 'none' ) 900 ssnd(jps_a_p)%laction = .FALSE. 901 ssnd(jps_ht_p)%laction = .FALSE. 902 CASE ( 'ice only' ) 903 ssnd(jps_a_p)%laction = .TRUE. 904 ssnd(jps_ht_p)%laction = .TRUE. 905 IF( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN 906 ssnd(jps_a_p)%nct = nn_cats_cpl 907 ssnd(jps_ht_p)%nct = nn_cats_cpl 908 ELSE 909 IF( nn_cats_cpl > 1 ) THEN 910 CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_mpnd%cldes if not exchanging category fields' ) 911 ENDIF 912 ENDIF 913 CASE ( 'weighted ice' ) 914 ssnd(jps_a_p)%laction = .TRUE. 915 ssnd(jps_ht_p)%laction = .TRUE. 916 IF( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN 917 ssnd(jps_a_p)%nct = nn_cats_cpl 918 ssnd(jps_ht_p)%nct = nn_cats_cpl 919 ENDIF 920 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_mpnd%cldes; '//sn_snd_mpnd%cldes ) 921 END SELECT 922 898 ssnd(jps_a_p)%clname = 'OPndFrc' 899 ssnd(jps_ht_p)%clname = 'OPndTck' 900 SELECT CASE ( TRIM( sn_snd_mpnd%cldes ) ) 901 CASE ( 'none' ) 902 ssnd(jps_a_p)%laction = .FALSE. 903 ssnd(jps_ht_p)%laction = .FALSE. 904 CASE ( 'ice only' ) 905 ssnd(jps_a_p)%laction = .TRUE. 906 ssnd(jps_ht_p)%laction = .TRUE. 907 IF( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN 908 ssnd(jps_a_p)%nct = nn_cats_cpl 909 ssnd(jps_ht_p)%nct = nn_cats_cpl 910 ELSE 911 IF( nn_cats_cpl > 1 ) THEN 912 CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_mpnd%cldes if not exchanging category fields' ) 913 ENDIF 914 ENDIF 915 CASE ( 'weighted ice' ) 916 ssnd(jps_a_p)%laction = .TRUE. 917 ssnd(jps_ht_p)%laction = .TRUE. 918 IF( TRIM( sn_snd_mpnd%clcat ) == 'yes' ) THEN 919 ssnd(jps_a_p)%nct = nn_cats_cpl 920 ssnd(jps_ht_p)%nct = nn_cats_cpl 921 ENDIF 922 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_mpnd%cldes; '//sn_snd_mpnd%cldes ) 923 END SELECT 924 923 925 ! ! ------------------------- ! 924 926 ! ! Surface current ! … … 928 930 ssnd(jps_ocy1)%clname = 'O_OCury1' ; ssnd(jps_ivy1)%clname = 'O_IVely1' 929 931 ssnd(jps_ocz1)%clname = 'O_OCurz1' ; ssnd(jps_ivz1)%clname = 'O_IVelz1' 930 ssnd(jps_ocxw)%clname = 'O_OCurxw' 931 ssnd(jps_ocyw)%clname = 'O_OCuryw' 932 ssnd(jps_ocxw)%clname = 'O_OCurxw' 933 ssnd(jps_ocyw)%clname = 'O_OCuryw' 932 934 ! 933 935 ssnd(jps_ocx1:jps_ivz1)%nsgn = -1. ! vectors: change of the sign at the north fold … … 935 937 IF( sn_snd_crt%clvgrd == 'U,V' ) THEN 936 938 ssnd(jps_ocx1)%clgrid = 'U' ; ssnd(jps_ocy1)%clgrid = 'V' 937 ELSE IF( sn_snd_crt%clvgrd /= 'T' ) THEN 939 ELSE IF( sn_snd_crt%clvgrd /= 'T' ) THEN 938 940 CALL ctl_stop( 'sn_snd_crt%clvgrd must be equal to T' ) 939 941 ENDIF 940 942 ssnd(jps_ocx1:jps_ivz1)%laction = .TRUE. ! default: all are send 941 IF( TRIM( sn_snd_crt%clvref ) == 'spherical' ) ssnd( (/jps_ocz1, jps_ivz1/) )%laction = .FALSE. 943 IF( TRIM( sn_snd_crt%clvref ) == 'spherical' ) ssnd( (/jps_ocz1, jps_ivz1/) )%laction = .FALSE. 942 944 IF( TRIM( sn_snd_crt%clvor ) == 'eastward-northward' ) ssnd(jps_ocx1:jps_ivz1)%nsgn = 1. 943 945 SELECT CASE( TRIM( sn_snd_crt%cldes ) ) … … 949 951 END SELECT 950 952 951 ssnd(jps_ocxw:jps_ocyw)%nsgn = -1. ! vectors: change of the sign at the north fold 952 953 IF( sn_snd_crtw%clvgrd == 'U,V' ) THEN 954 ssnd(jps_ocxw)%clgrid = 'U' ; ssnd(jps_ocyw)%clgrid = 'V' 955 ELSE IF( sn_snd_crtw%clvgrd /= 'T' ) THEN 956 CALL ctl_stop( 'sn_snd_crtw%clvgrd must be equal to T' ) 957 ENDIF 958 IF( TRIM( sn_snd_crtw%clvor ) == 'eastward-northward' ) ssnd(jps_ocxw:jps_ocyw)%nsgn = 1. 959 SELECT CASE( TRIM( sn_snd_crtw%cldes ) ) 960 CASE( 'none' ) ; ssnd(jps_ocxw:jps_ocyw)%laction = .FALSE. 961 CASE( 'oce only' ) ; ssnd(jps_ocxw:jps_ocyw)%laction = .TRUE. 962 CASE( 'weighted oce and ice' ) ! nothing to do 963 CASE( 'mixed oce-ice' ) ; ssnd(jps_ivx1:jps_ivz1)%laction = .FALSE. 964 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_crtw%cldes' ) 965 END SELECT 953 ssnd(jps_ocxw:jps_ocyw)%nsgn = -1. ! vectors: change of the sign at the north fold 954 955 IF( sn_snd_crtw%clvgrd == 'U,V' ) THEN 956 ssnd(jps_ocxw)%clgrid = 'U' ; ssnd(jps_ocyw)%clgrid = 'V' 957 ELSE IF( sn_snd_crtw%clvgrd /= 'T' ) THEN 958 CALL ctl_stop( 'sn_snd_crtw%clvgrd must be equal to T' ) 959 ENDIF 960 IF( TRIM( sn_snd_crtw%clvor ) == 'eastward-northward' ) ssnd(jps_ocxw:jps_ocyw)%nsgn = 1. 961 SELECT CASE( TRIM( sn_snd_crtw%cldes ) ) 962 CASE( 'none' ) ; ssnd(jps_ocxw:jps_ocyw)%laction = .FALSE. 963 CASE( 'oce only' ) ; ssnd(jps_ocxw:jps_ocyw)%laction = .TRUE. 964 CASE( 'weighted oce and ice' ) ! nothing to do 965 CASE( 'mixed oce-ice' ) ; ssnd(jps_ivx1:jps_ivz1)%laction = .FALSE. 966 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_crtw%cldes' ) 967 END SELECT 966 968 967 969 ! ! ------------------------- ! … … 969 971 ! ! ------------------------- ! 970 972 ssnd(jps_co2)%clname = 'O_CO2FLX' ; IF( TRIM(sn_snd_co2%cldes) == 'coupled' ) ssnd(jps_co2 )%laction = .TRUE. 971 ! 972 ! ! ------------------------- ! 973 ! ! Sea surface freezing temp ! 974 ! ! ------------------------- ! 973 ! 974 ! ! ------------------------- ! 975 ! ! Sea surface freezing temp ! 976 ! ! ------------------------- ! 975 977 ! needed by Met Office 976 ssnd(jps_sstfrz)%clname = 'O_SSTFrz' ; IF( TRIM(sn_snd_sstfrz%cldes) == 'coupled' ) ssnd(jps_sstfrz)%laction = .TRUE. 977 ! 978 ! ! ------------------------- ! 979 ! ! Ice conductivity ! 980 ! ! ------------------------- ! 978 ssnd(jps_sstfrz)%clname = 'O_SSTFrz' ; IF( TRIM(sn_snd_sstfrz%cldes) == 'coupled' ) ssnd(jps_sstfrz)%laction = .TRUE. 979 ! 980 ! ! ------------------------- ! 981 ! ! Ice conductivity ! 982 ! ! ------------------------- ! 981 983 ! needed by Met Office 982 ! Note that ultimately we will move to passing an ocean effective conductivity as well so there 983 ! will be some changes to the parts of the code which currently relate only to ice conductivity 984 ssnd(jps_ttilyr )%clname = 'O_TtiLyr' 985 SELECT CASE ( TRIM( sn_snd_ttilyr%cldes ) ) 986 CASE ( 'none' ) 987 ssnd(jps_ttilyr)%laction = .FALSE. 988 CASE ( 'ice only' ) 989 ssnd(jps_ttilyr)%laction = .TRUE. 990 IF( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) THEN 991 ssnd(jps_ttilyr)%nct = nn_cats_cpl 992 ELSE 993 IF( nn_cats_cpl > 1 ) THEN 994 CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_ttilyr%cldes if not exchanging category fields' ) 995 ENDIF 996 ENDIF 997 CASE ( 'weighted ice' ) 998 ssnd(jps_ttilyr)%laction = .TRUE. 999 IF( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) ssnd(jps_ttilyr)%nct = nn_cats_cpl 1000 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_ttilyr%cldes;'//sn_snd_ttilyr%cldes ) 1001 END SELECT 1002 1003 ssnd(jps_kice )%clname = 'OIceKn' 1004 SELECT CASE ( TRIM( sn_snd_cond%cldes ) ) 1005 CASE ( 'none' ) 1006 ssnd(jps_kice)%laction = .FALSE. 1007 CASE ( 'ice only' ) 1008 ssnd(jps_kice)%laction = .TRUE. 1009 IF( TRIM( sn_snd_cond%clcat ) == 'yes' ) THEN 1010 ssnd(jps_kice)%nct = nn_cats_cpl 1011 ELSE 1012 IF( nn_cats_cpl > 1 ) THEN 1013 CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_cond%cldes if not exchanging category fields' ) 1014 ENDIF 1015 ENDIF 1016 CASE ( 'weighted ice' ) 1017 ssnd(jps_kice)%laction = .TRUE. 1018 IF( TRIM( sn_snd_cond%clcat ) == 'yes' ) ssnd(jps_kice)%nct = nn_cats_cpl 1019 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_cond%cldes;'//sn_snd_cond%cldes ) 1020 END SELECT 1021 ! 1022 ! ! ------------------------- ! 1023 ! ! Sea surface height ! 1024 ! ! ------------------------- ! 1025 ssnd(jps_wlev)%clname = 'O_Wlevel' ; IF( TRIM(sn_snd_wlev%cldes) == 'coupled' ) ssnd(jps_wlev)%laction = .TRUE. 984 ! Note that ultimately we will move to passing an ocean effective conductivity as well so there 985 ! will be some changes to the parts of the code which currently relate only to ice conductivity 986 ssnd(jps_ttilyr )%clname = 'O_TtiLyr' 987 SELECT CASE ( TRIM( sn_snd_ttilyr%cldes ) ) 988 CASE ( 'none' ) 989 ssnd(jps_ttilyr)%laction = .FALSE. 990 CASE ( 'ice only' ) 991 ssnd(jps_ttilyr)%laction = .TRUE. 992 IF( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) THEN 993 ssnd(jps_ttilyr)%nct = nn_cats_cpl 994 ELSE 995 IF( nn_cats_cpl > 1 ) THEN 996 CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_ttilyr%cldes if not exchanging category fields' ) 997 ENDIF 998 ENDIF 999 CASE ( 'weighted ice' ) 1000 ssnd(jps_ttilyr)%laction = .TRUE. 1001 IF( TRIM( sn_snd_ttilyr%clcat ) == 'yes' ) ssnd(jps_ttilyr)%nct = nn_cats_cpl 1002 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_ttilyr%cldes;'//sn_snd_ttilyr%cldes ) 1003 END SELECT 1004 1005 ssnd(jps_kice )%clname = 'OIceKn' 1006 SELECT CASE ( TRIM( sn_snd_cond%cldes ) ) 1007 CASE ( 'none' ) 1008 ssnd(jps_kice)%laction = .FALSE. 1009 CASE ( 'ice only' ) 1010 ssnd(jps_kice)%laction = .TRUE. 1011 IF( TRIM( sn_snd_cond%clcat ) == 'yes' ) THEN 1012 ssnd(jps_kice)%nct = nn_cats_cpl 1013 ELSE 1014 IF( nn_cats_cpl > 1 ) THEN 1015 CALL ctl_stop( 'sbc_cpl_init: use weighted ice option for sn_snd_cond%cldes if not exchanging category fields' ) 1016 ENDIF 1017 ENDIF 1018 CASE ( 'weighted ice' ) 1019 ssnd(jps_kice)%laction = .TRUE. 1020 IF( TRIM( sn_snd_cond%clcat ) == 'yes' ) ssnd(jps_kice)%nct = nn_cats_cpl 1021 CASE default ; CALL ctl_stop( 'sbc_cpl_init: wrong definition of sn_snd_cond%cldes;'//sn_snd_cond%cldes ) 1022 END SELECT 1023 ! 1024 ! ! ------------------------- ! 1025 ! ! Sea surface height ! 1026 ! ! ------------------------- ! 1027 ssnd(jps_wlev)%clname = 'O_Wlevel' ; IF( TRIM(sn_snd_wlev%cldes) == 'coupled' ) ssnd(jps_wlev)%laction = .TRUE. 1026 1028 1027 1029 ! ! ------------------------------- ! 1028 ! ! OPA-SAS coupling - snd by opa ! 1030 ! ! OPA-SAS coupling - snd by opa ! 1029 1031 ! ! ------------------------------- ! 1030 ssnd(jps_ssh )%clname = 'O_SSHght' 1031 ssnd(jps_soce )%clname = 'O_SSSal' 1032 ssnd(jps_e3t1st)%clname = 'O_E3T1st' 1032 ssnd(jps_ssh )%clname = 'O_SSHght' 1033 ssnd(jps_soce )%clname = 'O_SSSal' 1034 ssnd(jps_e3t1st)%clname = 'O_E3T1st' 1033 1035 ssnd(jps_fraqsr)%clname = 'O_FraQsr' 1034 1036 ! … … 1048 1050 WRITE(numout,*)' sent fields to SAS component ' 1049 1051 WRITE(numout,*)' sea surface temperature (T before, Celsius) ' 1050 WRITE(numout,*)' sea surface salinity ' 1051 WRITE(numout,*)' surface currents U,V on local grid and spherical coordinates' 1052 WRITE(numout,*)' sea surface height ' 1053 WRITE(numout,*)' thickness of first ocean T level ' 1052 WRITE(numout,*)' sea surface salinity ' 1053 WRITE(numout,*)' surface currents U,V on local grid and spherical coordinates' 1054 WRITE(numout,*)' sea surface height ' 1055 WRITE(numout,*)' thickness of first ocean T level ' 1054 1056 WRITE(numout,*)' fraction of solar net radiation absorbed in the first ocean level' 1055 1057 WRITE(numout,*) … … 1057 1059 ENDIF 1058 1060 ! ! ------------------------------- ! 1059 ! ! OPA-SAS coupling - snd by sas ! 1061 ! ! OPA-SAS coupling - snd by sas ! 1060 1062 ! ! ------------------------------- ! 1061 ssnd(jps_sflx )%clname = 'I_SFLX' 1063 ssnd(jps_sflx )%clname = 'I_SFLX' 1062 1064 ssnd(jps_fice2 )%clname = 'IIceFrc' 1063 ssnd(jps_qsroce)%clname = 'I_QsrOce' 1064 ssnd(jps_qnsoce)%clname = 'I_QnsOce' 1065 ssnd(jps_oemp )%clname = 'IOEvaMPr' 1066 ssnd(jps_otx1 )%clname = 'I_OTaux1' 1067 ssnd(jps_oty1 )%clname = 'I_OTauy1' 1068 ssnd(jps_rnf )%clname = 'I_Runoff' 1069 ssnd(jps_taum )%clname = 'I_TauMod' 1065 ssnd(jps_qsroce)%clname = 'I_QsrOce' 1066 ssnd(jps_qnsoce)%clname = 'I_QnsOce' 1067 ssnd(jps_oemp )%clname = 'IOEvaMPr' 1068 ssnd(jps_otx1 )%clname = 'I_OTaux1' 1069 ssnd(jps_oty1 )%clname = 'I_OTauy1' 1070 ssnd(jps_rnf )%clname = 'I_Runoff' 1071 ssnd(jps_taum )%clname = 'I_TauMod' 1070 1072 ! 1071 1073 IF( nn_components == jp_iam_sas ) THEN … … 1102 1104 ! ================================ ! 1103 1105 CALL cpl_define(jprcv, jpsnd, nn_cplmodel) 1104 1105 IF(ln_usecplmask) THEN 1106 1107 IF(ln_usecplmask) THEN 1106 1108 xcplmask(:,:,:) = 0. 1107 1109 CALL iom_open( 'cplmask', inum ) … … 1118 1120 1119 1121 1120 SUBROUTINE sbc_cpl_rcv( kt, k_fsbc, k_ice, Kbb, Kmm ) 1122 SUBROUTINE sbc_cpl_rcv( kt, k_fsbc, k_ice, Kbb, Kmm ) 1121 1123 !!---------------------------------------------------------------------- 1122 1124 !! *** ROUTINE sbc_cpl_rcv *** … … 1132 1134 !! 1133 1135 !! - transform the received ocean stress vector from the received 1134 !! referential and grid into an atmosphere-ocean stress in 1135 !! the (i,j) ocean referencial and at the ocean velocity point. 1136 !! referential and grid into an atmosphere-ocean stress in 1137 !! the (i,j) ocean referencial and at the ocean velocity point. 1136 1138 !! The received stress are : 1137 1139 !! - defined by 3 components (if cartesian coordinate) … … 1141 1143 !! - given at U- and V-point, resp. if received on 2 grids 1142 1144 !! or at T-point if received on 1 grid 1143 !! Therefore and if necessary, they are successively 1144 !! processed in order to obtain them 1145 !! first as 2 components on the sphere 1145 !! Therefore and if necessary, they are successively 1146 !! processed in order to obtain them 1147 !! first as 2 components on the sphere 1146 1148 !! second as 2 components oriented along the local grid 1147 !! third as 2 components on the U,V grid 1149 !! third as 2 components on the U,V grid 1148 1150 !! 1149 !! --> 1151 !! --> 1150 1152 !! 1151 !! - In 'ocean only' case, non solar and solar ocean heat fluxes 1152 !! and total ocean freshwater fluxes 1153 !! - In 'ocean only' case, non solar and solar ocean heat fluxes 1154 !! and total ocean freshwater fluxes 1153 1155 !! 1154 !! ** Method : receive all fields from the atmosphere and transform 1155 !! them into ocean surface boundary condition fields 1156 !! ** Method : receive all fields from the atmosphere and transform 1157 !! them into ocean surface boundary condition fields 1156 1158 !! 1157 !! ** Action : update utau, vtau ocean stress at U,V grid 1159 !! ** Action : update utau, vtau ocean stress at U,V grid 1158 1160 !! taum wind stress module at T-point 1159 1161 !! wndm wind speed module at T-point over free ocean or leads in presence of sea-ice … … 1166 1168 ! 1167 1169 INTEGER, INTENT(in) :: kt ! ocean model time step index 1168 INTEGER, INTENT(in) :: k_fsbc ! frequency of sbc (-> ice model) computation 1170 INTEGER, INTENT(in) :: k_fsbc ! frequency of sbc (-> ice model) computation 1169 1171 INTEGER, INTENT(in) :: k_ice ! ice management in the sbc (=0/1/2/3) 1170 1172 INTEGER, INTENT(in) :: Kbb, Kmm ! ocean model time level indices … … 1173 1175 INTEGER :: ji, jj, jn ! dummy loop indices 1174 1176 INTEGER :: isec ! number of seconds since nit000 (assuming rdt did not change since nit000) 1175 REAL(wp) :: zcumulneg, zcumulpos ! temporary scalars 1177 REAL(wp) :: zcumulneg, zcumulpos ! temporary scalars 1176 1178 REAL(wp) :: zcoef ! temporary scalar 1177 1179 REAL(wp) :: zrhoa = 1.22 ! Air density kg/m3 … … 1188 1190 1189 1191 IF( ncpl_qsr_freq /= 0) ncpl_qsr_freq = 86400 / ncpl_qsr_freq ! used by top 1190 1192 1191 1193 IF ( ln_wave .AND. nn_components == 0 ) THEN 1192 1194 ncpl_qsr_freq = 1; … … 1231 1233 IF( TRIM( sn_rcv_tau%clvor ) == 'eastward-northward' ) THEN ! 2 components oriented along the local grid 1232 1234 ! ! (geographical to local grid -> rotate the components) 1233 CALL rot_rep( frcv(jpr_otx1)%z3(:,:,1), frcv(jpr_oty1)%z3(:,:,1), srcv(jpr_otx1)%clgrid, 'en->i', ztx ) 1235 CALL rot_rep( frcv(jpr_otx1)%z3(:,:,1), frcv(jpr_oty1)%z3(:,:,1), srcv(jpr_otx1)%clgrid, 'en->i', ztx ) 1234 1236 IF( srcv(jpr_otx2)%laction ) THEN 1235 CALL rot_rep( frcv(jpr_otx2)%z3(:,:,1), frcv(jpr_oty2)%z3(:,:,1), srcv(jpr_otx2)%clgrid, 'en->j', zty ) 1237 CALL rot_rep( frcv(jpr_otx2)%z3(:,:,1), frcv(jpr_oty2)%z3(:,:,1), srcv(jpr_otx2)%clgrid, 'en->j', zty ) 1236 1238 ELSE 1237 CALL rot_rep( frcv(jpr_otx1)%z3(:,:,1), frcv(jpr_oty1)%z3(:,:,1), srcv(jpr_otx1)%clgrid, 'en->j', zty ) 1239 CALL rot_rep( frcv(jpr_otx1)%z3(:,:,1), frcv(jpr_oty1)%z3(:,:,1), srcv(jpr_otx1)%clgrid, 'en->j', zty ) 1238 1240 ENDIF 1239 1241 frcv(jpr_otx1)%z3(:,:,1) = ztx(:,:) ! overwrite 1st component on the 1st grid 1240 1242 frcv(jpr_oty1)%z3(:,:,1) = zty(:,:) ! overwrite 2nd component on the 2nd grid 1241 1243 ENDIF 1242 ! 1244 ! 1243 1245 IF( srcv(jpr_otx1)%clgrid == 'T' ) THEN 1244 1246 DO_2D( 0, 0, 0, 0 ) ! T ==> (U,V) … … 1255 1257 ELSE ! No dynamical coupling ! 1256 1258 ! ! ========================= ! 1257 frcv(jpr_otx1)%z3(:,:,1) = 0.e0 ! here simply set to zero 1259 frcv(jpr_otx1)%z3(:,:,1) = 0.e0 ! here simply set to zero 1258 1260 frcv(jpr_oty1)%z3(:,:,1) = 0.e0 ! an external read in a file can be added instead 1259 1261 llnewtx = .TRUE. … … 1263 1265 ! ! wind stress module ! (taum) 1264 1266 ! ! ========================= ! 1265 IF( .NOT. srcv(jpr_taum)%laction ) THEN ! compute wind stress module from its components if not received 1267 IF( .NOT. srcv(jpr_taum)%laction ) THEN ! compute wind stress module from its components if not received 1266 1268 ! => need to be done only when otx1 was changed 1267 1269 IF( llnewtx ) THEN … … 1279 1281 llnewtau = nrcvinfo(jpr_taum) == OASIS_Rcv 1280 1282 ! Stress module can be negative when received (interpolation problem) 1281 IF( llnewtau ) THEN 1283 IF( llnewtau ) THEN 1282 1284 frcv(jpr_taum)%z3(:,:,1) = MAX( 0._wp, frcv(jpr_taum)%z3(:,:,1) ) 1283 1285 ENDIF … … 1287 1289 ! ! 10 m wind speed ! (wndm) 1288 1290 ! ! ========================= ! 1289 IF( .NOT. srcv(jpr_w10m)%laction ) THEN ! compute wind spreed from wind stress module if not received 1291 IF( .NOT. srcv(jpr_w10m)%laction ) THEN ! compute wind spreed from wind stress module if not received 1290 1292 ! => need to be done only when taumod was changed 1291 IF( llnewtau ) THEN 1292 zcoef = 1. / ( zrhoa * zcdrag ) 1293 IF( llnewtau ) THEN 1294 zcoef = 1. / ( zrhoa * zcdrag ) 1293 1295 DO_2D( 1, 1, 1, 1 ) 1294 1296 frcv(jpr_w10m)%z3(ji,jj,1) = SQRT( frcv(jpr_taum)%z3(ji,jj,1) * zcoef ) … … 1310 1312 ! ! ========================= ! 1311 1313 ! u(v)tau and taum will be modified by ice model 1312 ! -> need to be reset before each call of the ice/fsbc 1314 ! -> need to be reset before each call of the ice/fsbc 1313 1315 IF( MOD( kt-1, k_fsbc ) == 0 ) THEN 1314 1316 ! … … 1325 1327 ENDIF 1326 1328 CALL iom_put( "taum_oce", taum ) ! output wind stress module 1327 ! 1329 ! 1328 1330 ENDIF 1329 1331 … … 1333 1335 IF( srcv(jpr_co2)%laction ) atm_co2(:,:) = frcv(jpr_co2)%z3(:,:,1) 1334 1336 ! 1335 ! ! ========================= ! 1336 ! ! Mean Sea Level Pressure ! (taum) 1337 ! ! ========================= ! 1338 IF( srcv(jpr_mslp)%laction ) THEN ! UKMO SHELF effect of atmospheric pressure on SSH 1339 IF( kt /= nit000 ) ssh_ibb(:,:) = ssh_ib(:,:) !* Swap of ssh_ib fields 1340 1341 r1_grau = 1.e0 / (grav * rho0) !* constant for optimization 1342 ssh_ib(:,:) = - ( frcv(jpr_mslp)%z3(:,:,1) - rpref ) * r1_grau ! equivalent ssh (inverse barometer) 1343 apr (:,:) = frcv(jpr_mslp)%z3(:,:,1) !atmospheric pressure 1344 1345 IF( kt == nit000 ) ssh_ibb(:,:) = ssh_ib(:,:) ! correct this later (read from restart if possible) 1346 ENDIF 1337 ! ! ========================= ! 1338 ! ! Mean Sea Level Pressure ! (taum) 1339 ! ! ========================= ! 1340 IF( srcv(jpr_mslp)%laction ) THEN ! UKMO SHELF effect of atmospheric pressure on SSH 1341 IF( kt /= nit000 ) ssh_ibb(:,:) = ssh_ib(:,:) !* Swap of ssh_ib fields 1342 1343 r1_grau = 1.e0 / (grav * rho0) !* constant for optimization 1344 ssh_ib(:,:) = - ( frcv(jpr_mslp)%z3(:,:,1) - rpref ) * r1_grau ! equivalent ssh (inverse barometer) 1345 apr (:,:) = frcv(jpr_mslp)%z3(:,:,1) !atmospheric pressure 1346 1347 IF( kt == nit000 ) ssh_ibb(:,:) = ssh_ib(:,:) ! correct this later (read from restart if possible) 1348 ENDIF 1347 1349 ! 1348 1350 IF( ln_sdw ) THEN ! Stokes Drift correction activated 1349 ! ! ========================= ! 1351 ! ! ========================= ! 1350 1352 ! ! Stokes drift u ! 1351 ! ! ========================= ! 1353 ! ! ========================= ! 1352 1354 IF( srcv(jpr_sdrftx)%laction ) ut0sd(:,:) = frcv(jpr_sdrftx)%z3(:,:,1) 1353 1355 ! 1354 ! ! ========================= ! 1356 ! ! ========================= ! 1355 1357 ! ! Stokes drift v ! 1356 ! ! ========================= ! 1358 ! ! ========================= ! 1357 1359 IF( srcv(jpr_sdrfty)%laction ) vt0sd(:,:) = frcv(jpr_sdrfty)%z3(:,:,1) 1358 1360 ! 1359 ! ! ========================= ! 1361 ! ! ========================= ! 1360 1362 ! ! Wave mean period ! 1361 ! ! ========================= ! 1363 ! ! ========================= ! 1362 1364 IF( srcv(jpr_wper)%laction ) wmp(:,:) = frcv(jpr_wper)%z3(:,:,1) 1363 1365 ! 1364 ! ! ========================= ! 1366 ! ! ========================= ! 1365 1367 ! ! Significant wave height ! 1366 ! ! ========================= ! 1368 ! ! ========================= ! 1367 1369 IF( srcv(jpr_hsig)%laction ) hsw(:,:) = frcv(jpr_hsig)%z3(:,:,1) 1368 ! 1369 ! ! ========================= ! 1370 ! 1371 ! ! ========================= ! 1370 1372 ! ! Vertical mixing Qiao ! 1371 ! ! ========================= ! 1373 ! ! ========================= ! 1372 1374 IF( srcv(jpr_wnum)%laction .AND. ln_zdfswm ) wnum(:,:) = frcv(jpr_wnum)%z3(:,:,1) 1373 1375 … … 1378 1380 ENDIF 1379 1381 ENDIF 1380 ! ! ========================= ! 1382 ! ! ========================= ! 1381 1383 ! ! Stress adsorbed by waves ! 1382 ! ! ========================= ! 1384 ! ! ========================= ! 1383 1385 IF( srcv(jpr_wstrf)%laction .AND. ln_tauoc ) tauoc_wave(:,:) = frcv(jpr_wstrf)%z3(:,:,1) 1384 1386 ! 1385 ! ! ========================= ! 1387 ! ! ========================= ! 1386 1388 ! ! Wave drag coefficient ! 1387 ! ! ========================= ! 1389 ! ! ========================= ! 1388 1390 IF( srcv(jpr_wdrag)%laction .AND. ln_cdgw ) cdn_wave(:,:) = frcv(jpr_wdrag)%z3(:,:,1) 1389 1391 ! … … 1404 1406 IF( srcv(jpr_twox)%laction .AND. ln_taw ) twox(:,:) = frcv(jpr_twox)%z3(:,:,1) 1405 1407 IF( srcv(jpr_twoy)%laction .AND. ln_taw ) twoy(:,:) = frcv(jpr_twoy)%z3(:,:,1) 1406 ! 1408 ! 1407 1409 ! ! ========================= ! 1408 1410 ! ! wave TKE flux at sfc ! … … 1434 1436 CALL iom_put( 'sss_m', sss_m ) 1435 1437 ENDIF 1436 ! 1438 ! 1437 1439 ! ! ================== ! 1438 1440 ! ! SST ! … … 1480 1482 CALL iom_put( 'frq_m', frq_m ) 1481 1483 ENDIF 1482 1484 1483 1485 ! ! ========================= ! 1484 1486 IF( k_ice <= 1 .AND. MOD( kt-1, k_fsbc ) == 0 ) THEN ! heat & freshwater fluxes ! (Ocean only case) … … 1502 1504 IF( srcv(jpr_rnf)%laction ) rnf(:,:) = frcv(jpr_rnf)%z3(:,:,1) 1503 1505 IF( srcv(jpr_cal)%laction ) zemp(:,:) = zemp(:,:) - frcv(jpr_cal)%z3(:,:,1) 1504 1505 IF( srcv(jpr_icb)%laction ) THEN 1506 1507 IF( srcv(jpr_icb)%laction ) THEN 1506 1508 fwficb(:,:) = frcv(jpr_icb)%z3(:,:,1) 1507 1509 rnf(:,:) = rnf(:,:) + fwficb(:,:) ! iceberg added to runfofs … … 1510 1512 ! ice shelf fwf 1511 1513 IF( srcv(jpr_isf)%laction ) THEN 1512 fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1) ! fresh water flux from the isf (fwfisf <0 mean melting) 1514 fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1) ! fresh water flux from the isf (fwfisf <0 mean melting) 1513 1515 END IF 1514 1516 1515 1517 IF( ln_mixcpl ) THEN ; emp(:,:) = emp(:,:) * xcplmask(:,:,0) + zemp(:,:) * zmsk(:,:) 1516 1518 ELSE ; emp(:,:) = zemp(:,:) … … 1554 1556 ! 1555 1557 END SUBROUTINE sbc_cpl_rcv 1556 1557 1558 SUBROUTINE sbc_cpl_ice_tau( p_taui, p_tauj ) 1558 1559 1560 SUBROUTINE sbc_cpl_ice_tau( p_taui, p_tauj ) 1559 1561 !!---------------------------------------------------------------------- 1560 1562 !! *** ROUTINE sbc_cpl_ice_tau *** 1561 1563 !! 1562 !! ** Purpose : provide the stress over sea-ice in coupled mode 1564 !! ** Purpose : provide the stress over sea-ice in coupled mode 1563 1565 !! 1564 1566 !! ** Method : transform the received stress from the atmosphere into 1565 1567 !! an atmosphere-ice stress in the (i,j) ocean referencial 1566 1568 !! and at the velocity point of the sea-ice model: 1567 !! 'C'-grid : i- (j-) components given at U- (V-) point 1569 !! 'C'-grid : i- (j-) components given at U- (V-) point 1568 1570 !! 1569 1571 !! The received stress are : … … 1574 1576 !! - given at U- and V-point, resp. if received on 2 grids 1575 1577 !! or at a same point (T or I) if received on 1 grid 1576 !! Therefore and if necessary, they are successively 1577 !! processed in order to obtain them 1578 !! first as 2 components on the sphere 1578 !! Therefore and if necessary, they are successively 1579 !! processed in order to obtain them 1580 !! first as 2 components on the sphere 1579 1581 !! second as 2 components oriented along the local grid 1580 !! third as 2 components on the ice grid point 1582 !! third as 2 components on the ice grid point 1581 1583 !! 1582 !! Except in 'oce and ice' case, only one vector stress field 1584 !! Except in 'oce and ice' case, only one vector stress field 1583 1585 !! is received. It has already been processed in sbc_cpl_rcv 1584 1586 !! so that it is now defined as (i,j) components given at U- 1585 !! and V-points, respectively. 1587 !! and V-points, respectively. 1586 1588 !! 1587 1589 !! ** Action : return ptau_i, ptau_j, the stress over the ice … … 1593 1595 INTEGER :: itx ! index of taux over ice 1594 1596 REAL(wp) :: zztmp1, zztmp2 1595 REAL(wp), DIMENSION(jpi,jpj) :: ztx, zty 1597 REAL(wp), DIMENSION(jpi,jpj) :: ztx, zty 1596 1598 !!---------------------------------------------------------------------- 1597 1599 ! 1598 IF( srcv(jpr_itx1)%laction ) THEN ; itx = jpr_itx1 1600 IF( srcv(jpr_itx1)%laction ) THEN ; itx = jpr_itx1 1599 1601 ELSE ; itx = jpr_otx1 1600 1602 ENDIF … … 1605 1607 IF( srcv(jpr_itx1)%laction ) THEN ! ice stress received ! 1606 1608 ! ! ======================= ! 1607 ! 1609 ! 1608 1610 IF( TRIM( sn_rcv_tau%clvref ) == 'cartesian' ) THEN ! 2 components on the sphere 1609 1611 ! ! (cartesian to spherical -> 3 to 2 components) … … 1624 1626 IF( TRIM( sn_rcv_tau%clvor ) == 'eastward-northward' ) THEN ! 2 components oriented along the local grid 1625 1627 ! ! (geographical to local grid -> rotate the components) 1626 CALL rot_rep( frcv(jpr_itx1)%z3(:,:,1), frcv(jpr_ity1)%z3(:,:,1), srcv(jpr_itx1)%clgrid, 'en->i', ztx ) 1628 CALL rot_rep( frcv(jpr_itx1)%z3(:,:,1), frcv(jpr_ity1)%z3(:,:,1), srcv(jpr_itx1)%clgrid, 'en->i', ztx ) 1627 1629 IF( srcv(jpr_itx2)%laction ) THEN 1628 CALL rot_rep( frcv(jpr_itx2)%z3(:,:,1), frcv(jpr_ity2)%z3(:,:,1), srcv(jpr_itx2)%clgrid, 'en->j', zty ) 1630 CALL rot_rep( frcv(jpr_itx2)%z3(:,:,1), frcv(jpr_ity2)%z3(:,:,1), srcv(jpr_itx2)%clgrid, 'en->j', zty ) 1629 1631 ELSE 1630 CALL rot_rep( frcv(jpr_itx1)%z3(:,:,1), frcv(jpr_ity1)%z3(:,:,1), srcv(jpr_itx1)%clgrid, 'en->j', zty ) 1632 CALL rot_rep( frcv(jpr_itx1)%z3(:,:,1), frcv(jpr_ity1)%z3(:,:,1), srcv(jpr_itx1)%clgrid, 'en->j', zty ) 1631 1633 ENDIF 1632 1634 frcv(jpr_itx1)%z3(:,:,1) = ztx(:,:) ! overwrite 1st component on the 1st grid … … 1643 1645 ! ! put on ice grid ! 1644 1646 ! ! ======================= ! 1645 ! 1647 ! 1646 1648 ! j+1 j -----V---F 1647 1649 ! ice stress on ice velocity point ! | … … 1658 1660 CASE( 'T' ) 1659 1661 DO_2D( 0, 0, 0, 0 ) ! T ==> (U,V) 1660 ! take care of the land-sea mask to avoid "pollution" of coastal stress. p[uv]taui used in frazil and rheology 1662 ! take care of the land-sea mask to avoid "pollution" of coastal stress. p[uv]taui used in frazil and rheology 1661 1663 zztmp1 = 0.5_wp * ( 2. - umask(ji,jj,1) ) * MAX( tmask(ji,jj,1),tmask(ji+1,jj ,1) ) 1662 1664 zztmp2 = 0.5_wp * ( 2. - vmask(ji,jj,1) ) * MAX( tmask(ji,jj,1),tmask(ji ,jj+1,1) ) … … 1666 1668 CALL lbc_lnk_multi( 'sbccpl', p_taui, 'U', -1., p_tauj, 'V', -1. ) 1667 1669 END SELECT 1668 1670 1669 1671 ENDIF 1670 1672 ! 1671 1673 END SUBROUTINE sbc_cpl_ice_tau 1672 1674 1673 1675 1674 1676 SUBROUTINE sbc_cpl_ice_flx( picefr, palbi, psst, pist, phs, phi ) … … 1679 1681 !! 1680 1682 !! ** Method : transform the fields received from the atmosphere into 1681 !! surface heat and fresh water boundary condition for the 1683 !! surface heat and fresh water boundary condition for the 1682 1684 !! ice-ocean system. The following fields are provided: 1683 !! * total non solar, solar and freshwater fluxes (qns_tot, 1685 !! * total non solar, solar and freshwater fluxes (qns_tot, 1684 1686 !! qsr_tot and emp_tot) (total means weighted ice-ocean flux) 1685 1687 !! NB: emp_tot include runoffs and calving. 1686 1688 !! * fluxes over ice (qns_ice, qsr_ice, emp_ice) where 1687 1689 !! emp_ice = sublimation - solid precipitation as liquid 1688 !! precipitation are re-routed directly to the ocean and 1690 !! precipitation are re-routed directly to the ocean and 1689 1691 !! calving directly enter the ocean (runoffs are read but included in trasbc.F90) 1690 !! * solid precipitation (sprecip), used to add to qns_tot 1692 !! * solid precipitation (sprecip), used to add to qns_tot 1691 1693 !! the heat lost associated to melting solid precipitation 1692 1694 !! over the ocean fraction. … … 1720 1722 !! emp_ice ice sublimation - solid precipitation over the ice 1721 1723 !! dqns_ice d(non-solar heat flux)/d(Temperature) over the ice 1722 !! sprecip solid precipitation over the ocean 1724 !! sprecip solid precipitation over the ocean 1723 1725 !!---------------------------------------------------------------------- 1724 1726 REAL(wp), INTENT(in) , DIMENSION(:,:) :: picefr ! ice fraction [0 to 1] 1725 1727 ! !! ! optional arguments, used only in 'mixed oce-ice' case or for Met-Office coupling 1726 REAL(wp), INTENT(in) , DIMENSION(:,:,:), OPTIONAL :: palbi ! all skies ice albedo 1728 REAL(wp), INTENT(in) , DIMENSION(:,:,:), OPTIONAL :: palbi ! all skies ice albedo 1727 1729 REAL(wp), INTENT(in) , DIMENSION(:,: ), OPTIONAL :: psst ! sea surface temperature [Celsius] 1728 1730 REAL(wp), INTENT(inout), DIMENSION(:,:,:), OPTIONAL :: pist ! ice surface temperature [Kelvin] => inout for Met-Office … … 1761 1763 zsprecip(:,:) = frcv(jpr_ievp)%z3(:,:,1) - frcv(jpr_semp)%z3(:,:,1) 1762 1764 ztprecip(:,:) = frcv(jpr_semp)%z3(:,:,1) - frcv(jpr_sbpr)%z3(:,:,1) + zsprecip(:,:) 1763 CASE( 'none' ) ! Not available as for now: needs additional coding below when computing zevap_oce 1765 CASE( 'none' ) ! Not available as for now: needs additional coding below when computing zevap_oce 1764 1766 ! ! since fields received are not defined with none option 1765 1767 CALL ctl_stop( 'STOP', 'sbccpl/sbc_cpl_ice_flx: some fields are not defined. Change sn_rcv_emp value in namelist namsbc_cpl' ) … … 1808 1810 ! zsnw = snow fraction over ice after wind blowing (=picefr if no blowing) 1809 1811 zsnw(:,:) = 0._wp ; CALL ice_var_snwblow( ziceld, zsnw ) 1810 1812 1811 1813 ! --- evaporation minus precipitation corrected (because of wind blowing on snow) --- ! 1812 1814 zemp_ice(:,:) = zemp_ice(:,:) + zsprecip(:,:) * ( picefr(:,:) - zsnw(:,:) ) ! emp_ice = A * sublimation - zsnw * sprecip … … 1819 1821 ! therefore, sublimation is not redistributed over the ice categories when no subgrid scale fluxes are provided by atm. 1820 1822 zdevap_ice(:,:) = 0._wp 1821 1823 1822 1824 ! --- Continental fluxes --- ! 1823 1825 IF( srcv(jpr_rnf)%laction ) THEN ! runoffs (included in emp later on) … … 1833 1835 ENDIF 1834 1836 IF( srcv(jpr_isf)%laction ) THEN ! iceshelf (fwfisf <0 mean melting) 1835 fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1) 1837 fwfisf_oasis(:,:) = - frcv(jpr_isf)%z3(:,:,1) 1836 1838 ENDIF 1837 1839 … … 1849 1851 emp_tot (:,:) = zemp_tot (:,:) 1850 1852 emp_ice (:,:) = zemp_ice (:,:) 1851 emp_oce (:,:) = zemp_oce (:,:) 1853 emp_oce (:,:) = zemp_oce (:,:) 1852 1854 sprecip (:,:) = zsprecip (:,:) 1853 1855 tprecip (:,:) = ztprecip (:,:) … … 1896 1898 IF( iom_use('snowpre') ) CALL iom_put( 'snowpre' , sprecip(:,:) ) ! Snow 1897 1899 IF( iom_use('precip') ) CALL iom_put( 'precip' , tprecip(:,:) ) ! total precipitation 1898 IF( iom_use('rain') ) CALL iom_put( 'rain' , tprecip(:,:) - sprecip(:,:) ) ! liquid precipitation 1900 IF( iom_use('rain') ) CALL iom_put( 'rain' , tprecip(:,:) - sprecip(:,:) ) ! liquid precipitation 1899 1901 IF( iom_use('snow_ao_cea') ) CALL iom_put( 'snow_ao_cea' , sprecip(:,:) * ( 1._wp - zsnw(:,:) ) ) ! Snow over ice-free ocean (cell average) 1900 1902 IF( iom_use('snow_ai_cea') ) CALL iom_put( 'snow_ai_cea' , sprecip(:,:) * zsnw(:,:) ) ! Snow over sea-ice (cell average) … … 1912 1914 ! For Met Office sea ice non-solar fluxes are already delt with by JULES so setting to zero 1913 1915 ! here so the only flux is the ocean only one. 1914 zqns_ice(:,:,:) = 0._wp 1916 zqns_ice(:,:,:) = 0._wp 1915 1917 CASE( 'conservative' ) ! the required fields are directly provided 1916 1918 zqns_tot(:,:) = frcv(jpr_qnsmix)%z3(:,:,1) … … 1926 1928 IF( TRIM(sn_rcv_qns%clcat) == 'yes' ) THEN 1927 1929 DO jl=1,jpl 1928 zqns_tot(:,: ) = zqns_tot(:,:) + a_i(:,:,jl) * frcv(jpr_qnsice)%z3(:,:,jl) 1930 zqns_tot(:,: ) = zqns_tot(:,:) + a_i(:,:,jl) * frcv(jpr_qnsice)%z3(:,:,jl) 1929 1931 zqns_ice(:,:,jl) = frcv(jpr_qnsice)%z3(:,:,jl) 1930 1932 ENDDO … … 1952 1954 ENDIF 1953 1955 END SELECT 1954 ! 1956 ! 1955 1957 ! --- calving (removed from qns_tot) --- ! 1956 1958 IF( srcv(jpr_cal)%laction ) zqns_tot(:,:) = zqns_tot(:,:) - frcv(jpr_cal)%z3(:,:,1) * rLfus ! remove latent heat of calving … … 1959 1961 IF( srcv(jpr_icb)%laction ) zqns_tot(:,:) = zqns_tot(:,:) - frcv(jpr_icb)%z3(:,:,1) * rLfus ! remove latent heat of iceberg melting 1960 1962 1961 #if defined key_si3 1963 #if defined key_si3 1962 1964 ! --- non solar flux over ocean --- ! 1963 1965 ! note: ziceld cannot be = 0 since we limit the ice concentration to amax … … 1970 1972 ENDWHERE 1971 1973 ! Heat content per unit mass of rain (J/kg) 1972 zcptrain(:,:) = rcp * ( SUM( (tn_ice(:,:,:) - rt0) * a_i(:,:,:), dim=3 ) + sst_m(:,:) * ziceld(:,:) ) 1974 zcptrain(:,:) = rcp * ( SUM( (tn_ice(:,:,:) - rt0) * a_i(:,:,:), dim=3 ) + sst_m(:,:) * ziceld(:,:) ) 1973 1975 1974 1976 ! --- enthalpy of snow precip over ice in J/m3 (to be used in 1D-thermo) --- ! … … 1987 1989 !! zqemp_ice(:,:) = - frcv(jpr_ievp)%z3(:,:,1) * picefr(:,:) * zcptsnw (:,:) & ! ice evap 1988 1990 !! & + zsprecip(:,:) * zsnw * zqprec_ice(:,:) * r1_rhos ! solid precip over ice 1989 1991 1990 1992 ! --- total non solar flux (including evap/precip) --- ! 1991 1993 zqns_tot(:,:) = zqns_tot(:,:) + zqemp_ice(:,:) + zqemp_oce(:,:) 1992 1994 1993 ! --- in case both coupled/forced are active, we must mix values --- ! 1995 ! --- in case both coupled/forced are active, we must mix values --- ! 1994 1996 IF( ln_mixcpl ) THEN 1995 1997 qns_tot(:,:) = qns_tot(:,:) * xcplmask(:,:,0) + zqns_tot(:,:)* zmsk(:,:) … … 2015 2017 zcptsnw (:,:) = zcptn(:,:) 2016 2018 zcptrain(:,:) = zcptn(:,:) 2017 2019 2018 2020 ! clem: this formulation is certainly wrong... but better than it was... 2019 2021 zqns_tot(:,:) = zqns_tot(:,:) & ! zqns_tot update over free ocean with: 2020 2022 & - ( ziceld(:,:) * zsprecip(:,:) * rLfus ) & ! remove the latent heat flux of solid precip. melting 2021 2023 & - ( zemp_tot(:,:) & ! remove the heat content of mass flux (assumed to be at SST) 2022 & - zemp_ice(:,:) ) * zcptn(:,:) 2024 & - zemp_ice(:,:) ) * zcptn(:,:) 2023 2025 2024 2026 IF( ln_mixcpl ) THEN … … 2045 2047 IF( iom_use('hflx_snow_ao_cea') ) CALL iom_put('hflx_snow_ao_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) & 2046 2048 & * ( 1._wp - zsnw(:,:) ) ) ! heat flux from snow (over ocean) 2047 IF( iom_use('hflx_snow_ai_cea') ) CALL iom_put('hflx_snow_ai_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) & 2049 IF( iom_use('hflx_snow_ai_cea') ) CALL iom_put('hflx_snow_ai_cea', sprecip(:,:) * ( zcptsnw(:,:) - rLfus ) & 2048 2050 & * zsnw(:,:) ) ! heat flux from snow (over ice) 2049 2051 ! note: hflx for runoff and iceshelf are done in sbcrnf and sbcisf resp. … … 2071 2073 IF( TRIM(sn_rcv_qsr%clcat) == 'yes' ) THEN 2072 2074 DO jl = 1, jpl 2073 zqsr_tot(:,: ) = zqsr_tot(:,:) + a_i(:,:,jl) * frcv(jpr_qsrice)%z3(:,:,jl) 2075 zqsr_tot(:,: ) = zqsr_tot(:,:) + a_i(:,:,jl) * frcv(jpr_qsrice)%z3(:,:,jl) 2074 2076 zqsr_ice(:,:,jl) = frcv(jpr_qsrice)%z3(:,:,jl) 2075 2077 END DO … … 2098 2100 END DO 2099 2101 ENDIF 2100 CASE( 'none' ) ! Not available as for now: needs additional coding 2102 CASE( 'none' ) ! Not available as for now: needs additional coding 2101 2103 ! ! since fields received, here zqsr_tot, are not defined with none option 2102 2104 CALL ctl_stop( 'STOP', 'sbccpl/sbc_cpl_ice_flx: some fields are not defined. Change sn_rcv_qsr value in namelist namsbc_cpl' ) … … 2142 2144 ENDDO 2143 2145 ENDIF 2144 CASE( 'none' ) 2146 CASE( 'none' ) 2145 2147 zdqns_ice(:,:,:) = 0._wp 2146 2148 END SELECT 2147 2149 2148 2150 IF( ln_mixcpl ) THEN 2149 2151 DO jl=1,jpl … … 2154 2156 ENDIF 2155 2157 2156 #if defined key_si3 2158 #if defined key_si3 2157 2159 ! ! ========================= ! 2158 2160 SELECT CASE( TRIM( sn_rcv_iceflx%cldes ) ) ! ice topmelt and botmelt ! … … 2186 2188 ztri(:,:) = 0.18 * ( 1.0 - cloud_fra(:,:) ) + 0.35 * cloud_fra(:,:) ! surface transmission when hi>10cm 2187 2189 DO jl = 1, jpl 2188 WHERE ( phs(:,:,jl) <= 0._wp .AND. phi(:,:,jl) < 0.1_wp ) ! linear decrease from hi=0 to 10cm 2190 WHERE ( phs(:,:,jl) <= 0._wp .AND. phi(:,:,jl) < 0.1_wp ) ! linear decrease from hi=0 to 10cm 2189 2191 zqtr_ice_top(:,:,jl) = zqsr_ice(:,:,jl) * ( ztri(:,:) + ( 1._wp - ztri(:,:) ) * ( 1._wp - phi(:,:,jl) * 10._wp ) ) 2190 2192 ELSEWHERE( phs(:,:,jl) <= 0._wp .AND. phi(:,:,jl) >= 0.1_wp ) ! constant (ztri) when hi>10cm 2191 2193 zqtr_ice_top(:,:,jl) = zqsr_ice(:,:,jl) * ztri(:,:) 2192 2194 ELSEWHERE ! zero when hs>0 2193 zqtr_ice_top(:,:,jl) = 0._wp 2195 zqtr_ice_top(:,:,jl) = 0._wp 2194 2196 END WHERE 2195 2197 ENDDO … … 2200 2202 zqtr_ice_top(:,:,:) = 0.3_wp * zqsr_ice(:,:,:) 2201 2203 ENDIF 2202 ! 2204 ! 2203 2205 ELSEIF( ln_cndflx .AND. .NOT.ln_cndemulate ) THEN !== conduction flux as surface forcing ==! 2204 2206 ! … … 2220 2222 ! ! ================== ! 2221 2223 ! needed by Met Office 2222 IF( srcv(jpr_ts_ice)%laction ) THEN 2223 WHERE ( frcv(jpr_ts_ice)%z3(:,:,:) > 0.0 ) ; ztsu(:,:,:) = 0. + rt0 2224 IF( srcv(jpr_ts_ice)%laction ) THEN 2225 WHERE ( frcv(jpr_ts_ice)%z3(:,:,:) > 0.0 ) ; ztsu(:,:,:) = 0. + rt0 2224 2226 ELSEWHERE( frcv(jpr_ts_ice)%z3(:,:,:) < -60. ) ; ztsu(:,:,:) = -60. + rt0 2225 2227 ELSEWHERE ; ztsu(:,:,:) = frcv(jpr_ts_ice)%z3(:,:,:) + rt0 … … 2239 2241 ! 2240 2242 END SUBROUTINE sbc_cpl_ice_flx 2241 2242 2243 2244 2243 2245 SUBROUTINE sbc_cpl_snd( kt, Kbb, Kmm ) 2244 2246 !!---------------------------------------------------------------------- … … 2257 2259 REAL(wp) :: zumax, zvmax 2258 2260 REAL(wp), DIMENSION(jpi,jpj) :: zfr_l, ztmp1, ztmp2, zotx1, zoty1, zotz1, zitx1, zity1, zitz1 2259 REAL(wp), DIMENSION(jpi,jpj,jpl) :: ztmp3, ztmp4 2261 REAL(wp), DIMENSION(jpi,jpj,jpl) :: ztmp3, ztmp4 2260 2262 !!---------------------------------------------------------------------- 2261 2263 ! … … 2268 2270 ! ! ------------------------- ! 2269 2271 IF( ssnd(jps_toce)%laction .OR. ssnd(jps_tice)%laction .OR. ssnd(jps_tmix)%laction ) THEN 2270 2272 2271 2273 IF( nn_components == jp_iam_opa ) THEN 2272 2274 ztmp1(:,:) = ts(:,:,1,jp_tem,Kmm) ! send temperature as it is (potential or conservative) -> use of l_useCT on the received part 2273 2275 ELSE 2274 ! we must send the surface potential temperature 2276 ! we must send the surface potential temperature 2275 2277 IF( l_useCT ) THEN ; ztmp1(:,:) = eos_pt_from_ct( ts(:,:,1,jp_tem,Kmm), ts(:,:,1,jp_sal,Kmm) ) 2276 2278 ELSE ; ztmp1(:,:) = ts(:,:,1,jp_tem,Kmm) … … 2281 2283 CASE( 'oce and ice' ) ; ztmp1(:,:) = ztmp1(:,:) + rt0 2282 2284 SELECT CASE( sn_snd_temp%clcat ) 2283 CASE( 'yes' ) 2285 CASE( 'yes' ) 2284 2286 ztmp3(:,:,1:jpl) = tn_ice(:,:,1:jpl) 2285 2287 CASE( 'no' ) … … 2291 2293 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_temp%clcat' ) 2292 2294 END SELECT 2293 CASE( 'weighted oce and ice' ) ; ztmp1(:,:) = ( ztmp1(:,:) + rt0 ) * zfr_l(:,:) 2295 CASE( 'weighted oce and ice' ) ; ztmp1(:,:) = ( ztmp1(:,:) + rt0 ) * zfr_l(:,:) 2294 2296 SELECT CASE( sn_snd_temp%clcat ) 2295 CASE( 'yes' ) 2297 CASE( 'yes' ) 2296 2298 ztmp3(:,:,1:jpl) = tn_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2297 2299 CASE( 'no' ) … … 2302 2304 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_temp%clcat' ) 2303 2305 END SELECT 2304 CASE( 'oce and weighted ice') ; ztmp1(:,:) = ts(:,:,1,jp_tem,Kmm) + rt0 2305 SELECT CASE( sn_snd_temp%clcat ) 2306 CASE( 'yes' ) 2307 ztmp3(:,:,1:jpl) = tn_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2308 CASE( 'no' ) 2309 ztmp3(:,:,:) = 0.0 2310 DO jl=1,jpl 2311 ztmp3(:,:,1) = ztmp3(:,:,1) + tn_ice(:,:,jl) * a_i(:,:,jl) 2312 ENDDO 2313 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_temp%clcat' ) 2314 END SELECT 2315 CASE( 'mixed oce-ice' ) 2316 ztmp1(:,:) = ( ztmp1(:,:) + rt0 ) * zfr_l(:,:) 2306 CASE( 'oce and weighted ice') ; ztmp1(:,:) = ts(:,:,1,jp_tem,Kmm) + rt0 2307 SELECT CASE( sn_snd_temp%clcat ) 2308 CASE( 'yes' ) 2309 ztmp3(:,:,1:jpl) = tn_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2310 CASE( 'no' ) 2311 ztmp3(:,:,:) = 0.0 2312 DO jl=1,jpl 2313 ztmp3(:,:,1) = ztmp3(:,:,1) + tn_ice(:,:,jl) * a_i(:,:,jl) 2314 ENDDO 2315 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_temp%clcat' ) 2316 END SELECT 2317 CASE( 'mixed oce-ice' ) 2318 ztmp1(:,:) = ( ztmp1(:,:) + rt0 ) * zfr_l(:,:) 2317 2319 DO jl=1,jpl 2318 2320 ztmp1(:,:) = ztmp1(:,:) + tn_ice(:,:,jl) * a_i(:,:,jl) … … 2334 2336 SELECT CASE( sn_snd_ttilyr%cldes) 2335 2337 CASE ('weighted ice') 2336 ztmp3(:,:,1:jpl) = t1_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2338 ztmp3(:,:,1:jpl) = t1_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2337 2339 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_ttilyr%cldes' ) 2338 2340 END SELECT … … 2343 2345 ! ! Albedo ! 2344 2346 ! ! ------------------------- ! 2345 IF( ssnd(jps_albice)%laction ) THEN ! ice 2347 IF( ssnd(jps_albice)%laction ) THEN ! ice 2346 2348 SELECT CASE( sn_snd_alb%cldes ) 2347 2349 CASE( 'ice' ) 2348 2350 SELECT CASE( sn_snd_alb%clcat ) 2349 CASE( 'yes' ) 2351 CASE( 'yes' ) 2350 2352 ztmp3(:,:,1:jpl) = alb_ice(:,:,1:jpl) 2351 2353 CASE( 'no' ) … … 2359 2361 CASE( 'weighted ice' ) ; 2360 2362 SELECT CASE( sn_snd_alb%clcat ) 2361 CASE( 'yes' ) 2363 CASE( 'yes' ) 2362 2364 ztmp3(:,:,1:jpl) = alb_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2363 2365 CASE( 'no' ) … … 2373 2375 2374 2376 SELECT CASE( sn_snd_alb%clcat ) 2375 CASE( 'yes' ) 2377 CASE( 'yes' ) 2376 2378 CALL cpl_snd( jps_albice, isec, ztmp3, info ) !-> MV this has never been checked in coupled mode 2377 CASE( 'no' ) 2378 CALL cpl_snd( jps_albice, isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ), info ) 2379 CASE( 'no' ) 2380 CALL cpl_snd( jps_albice, isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ), info ) 2379 2381 END SELECT 2380 2382 ENDIF … … 2388 2390 ENDIF 2389 2391 ! ! ------------------------- ! 2390 ! ! Ice fraction & Thickness ! 2392 ! ! Ice fraction & Thickness ! 2391 2393 ! ! ------------------------- ! 2392 2394 ! Send ice fraction field to atmosphere … … 2401 2403 2402 2404 #if defined key_si3 || defined key_cice 2403 ! If this coupling was successful then save ice fraction for use between coupling points. 2404 ! This is needed for some calculations where the ice fraction at the last coupling point 2405 ! is needed. 2406 IF( info == OASIS_Sent .OR. info == OASIS_ToRest .OR. & 2407 & info == OASIS_SentOut .OR. info == OASIS_ToRestOut ) THEN 2408 IF ( sn_snd_thick%clcat == 'yes' ) THEN 2405 ! If this coupling was successful then save ice fraction for use between coupling points. 2406 ! This is needed for some calculations where the ice fraction at the last coupling point 2407 ! is needed. 2408 IF( info == OASIS_Sent .OR. info == OASIS_ToRest .OR. & 2409 & info == OASIS_SentOut .OR. info == OASIS_ToRestOut ) THEN 2410 IF ( sn_snd_thick%clcat == 'yes' ) THEN 2409 2411 a_i_last_couple(:,:,1:jpl) = a_i(:,:,1:jpl) 2410 2412 ENDIF … … 2420 2422 CALL cpl_snd( jps_fice1, isec, ztmp3, info ) 2421 2423 ENDIF 2422 2424 2423 2425 ! Send ice fraction field to OPA (sent by SAS in SAS-OPA coupling) 2424 2426 IF( ssnd(jps_fice2)%laction ) THEN … … 2427 2429 ENDIF 2428 2430 2429 ! Send ice and snow thickness field 2430 IF( ssnd(jps_hice)%laction .OR. ssnd(jps_hsnw)%laction ) THEN 2431 ! Send ice and snow thickness field 2432 IF( ssnd(jps_hice)%laction .OR. ssnd(jps_hsnw)%laction ) THEN 2431 2433 SELECT CASE( sn_snd_thick%cldes) 2432 2434 CASE( 'none' ) ! nothing to do 2433 CASE( 'weighted ice and snow' ) 2435 CASE( 'weighted ice and snow' ) 2434 2436 SELECT CASE( sn_snd_thick%clcat ) 2435 CASE( 'yes' ) 2437 CASE( 'yes' ) 2436 2438 ztmp3(:,:,1:jpl) = h_i(:,:,1:jpl) * a_i(:,:,1:jpl) 2437 2439 ztmp4(:,:,1:jpl) = h_s(:,:,1:jpl) * a_i(:,:,1:jpl) … … 2444 2446 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_thick%clcat' ) 2445 2447 END SELECT 2446 CASE( 'ice and snow' ) 2448 CASE( 'ice and snow' ) 2447 2449 SELECT CASE( sn_snd_thick%clcat ) 2448 2450 CASE( 'yes' ) … … 2467 2469 #if defined key_si3 2468 2470 ! ! ------------------------- ! 2469 ! ! Ice melt ponds ! 2470 ! ! ------------------------- ! 2471 ! needed by Met Office: 1) fraction of ponded ice 2) local/actual pond depth 2472 IF( ssnd(jps_a_p)%laction .OR. ssnd(jps_ht_p)%laction ) THEN 2473 SELECT CASE( sn_snd_mpnd%cldes) 2474 CASE( 'ice only' ) 2475 SELECT CASE( sn_snd_mpnd%clcat ) 2476 CASE( 'yes' ) 2471 ! ! Ice melt ponds ! 2472 ! ! ------------------------- ! 2473 ! needed by Met Office: 1) fraction of ponded ice 2) local/actual pond depth 2474 IF( ssnd(jps_a_p)%laction .OR. ssnd(jps_ht_p)%laction ) THEN 2475 SELECT CASE( sn_snd_mpnd%cldes) 2476 CASE( 'ice only' ) 2477 SELECT CASE( sn_snd_mpnd%clcat ) 2478 CASE( 'yes' ) 2477 2479 ztmp3(:,:,1:jpl) = a_ip_eff(:,:,1:jpl) 2478 ztmp4(:,:,1:jpl) = h_ip(:,:,1:jpl) 2479 CASE( 'no' ) 2480 ztmp3(:,:,:) = 0.0 2481 ztmp4(:,:,:) = 0.0 2482 DO jl=1,jpl 2480 ztmp4(:,:,1:jpl) = h_ip(:,:,1:jpl) 2481 CASE( 'no' ) 2482 ztmp3(:,:,:) = 0.0 2483 ztmp4(:,:,:) = 0.0 2484 DO jl=1,jpl 2483 2485 ztmp3(:,:,1) = ztmp3(:,:,1) + a_ip_frac(:,:,jpl) 2484 2486 ztmp4(:,:,1) = ztmp4(:,:,1) + h_ip(:,:,jpl) 2485 ENDDO 2486 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_mpnd%clcat' ) 2487 END SELECT 2488 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_mpnd%cldes' ) 2489 END SELECT 2490 IF( ssnd(jps_a_p)%laction ) CALL cpl_snd( jps_a_p , isec, ztmp3, info ) 2491 IF( ssnd(jps_ht_p)%laction ) CALL cpl_snd( jps_ht_p, isec, ztmp4, info ) 2492 ENDIF 2493 ! 2494 ! ! ------------------------- ! 2495 ! ! Ice conductivity ! 2487 ENDDO 2488 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_mpnd%clcat' ) 2489 END SELECT 2490 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_mpnd%cldes' ) 2491 END SELECT 2492 IF( ssnd(jps_a_p)%laction ) CALL cpl_snd( jps_a_p , isec, ztmp3, info ) 2493 IF( ssnd(jps_ht_p)%laction ) CALL cpl_snd( jps_ht_p, isec, ztmp4, info ) 2494 ENDIF 2495 ! 2496 ! ! ------------------------- ! 2497 ! ! Ice conductivity ! 2496 2498 ! ! ------------------------- ! 2497 2499 ! needed by Met Office 2498 IF( ssnd(jps_kice)%laction ) THEN 2499 SELECT CASE( sn_snd_cond%cldes) 2500 CASE( 'weighted ice' ) 2501 SELECT CASE( sn_snd_cond%clcat ) 2502 CASE( 'yes' ) 2503 ztmp3(:,:,1:jpl) = cnd_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2504 CASE( 'no' ) 2505 ztmp3(:,:,:) = 0.0 2506 DO jl=1,jpl 2507 ztmp3(:,:,1) = ztmp3(:,:,1) + cnd_ice(:,:,jl) * a_i(:,:,jl) 2508 ENDDO 2509 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_cond%clcat' ) 2510 END SELECT 2511 CASE( 'ice only' ) 2512 ztmp3(:,:,1:jpl) = cnd_ice(:,:,1:jpl) 2513 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_cond%cldes' ) 2514 END SELECT 2515 IF( ssnd(jps_kice)%laction ) CALL cpl_snd( jps_kice, isec, ztmp3, info ) 2516 ENDIF 2500 IF( ssnd(jps_kice)%laction ) THEN 2501 SELECT CASE( sn_snd_cond%cldes) 2502 CASE( 'weighted ice' ) 2503 SELECT CASE( sn_snd_cond%clcat ) 2504 CASE( 'yes' ) 2505 ztmp3(:,:,1:jpl) = cnd_ice(:,:,1:jpl) * a_i(:,:,1:jpl) 2506 CASE( 'no' ) 2507 ztmp3(:,:,:) = 0.0 2508 DO jl=1,jpl 2509 ztmp3(:,:,1) = ztmp3(:,:,1) + cnd_ice(:,:,jl) * a_i(:,:,jl) 2510 ENDDO 2511 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_cond%clcat' ) 2512 END SELECT 2513 CASE( 'ice only' ) 2514 ztmp3(:,:,1:jpl) = cnd_ice(:,:,1:jpl) 2515 CASE default ; CALL ctl_stop( 'sbc_cpl_snd: wrong definition of sn_snd_cond%cldes' ) 2516 END SELECT 2517 IF( ssnd(jps_kice)%laction ) CALL cpl_snd( jps_kice, isec, ztmp3, info ) 2518 ENDIF 2517 2519 #endif 2518 2520 2519 2521 ! ! ------------------------- ! 2520 ! ! CO2 flux from PISCES ! 2521 ! ! ------------------------- ! 2522 IF( ssnd(jps_co2)%laction .AND. l_co2cpl ) THEN 2522 ! ! CO2 flux from PISCES ! 2523 ! ! ------------------------- ! 2524 IF( ssnd(jps_co2)%laction .AND. l_co2cpl ) THEN 2523 2525 ztmp1(:,:) = oce_co2(:,:) * 1000. ! conversion in molC/m2/s 2524 2526 CALL cpl_snd( jps_co2, isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ) , info ) … … 2528 2530 IF( ssnd(jps_ocx1)%laction ) THEN ! Surface current ! 2529 2531 ! ! ------------------------- ! 2530 ! 2532 ! 2531 2533 ! j+1 j -----V---F 2532 2534 ! surface velocity always sent from T point ! | … … 2538 2540 ! i i+1 (for I) 2539 2541 IF( nn_components == jp_iam_opa ) THEN 2540 zotx1(:,:) = uu(:,:,1,Kmm) 2541 zoty1(:,:) = vv(:,:,1,Kmm) 2542 ELSE 2542 zotx1(:,:) = uu(:,:,1,Kmm) 2543 zoty1(:,:) = vv(:,:,1,Kmm) 2544 ELSE 2543 2545 SELECT CASE( TRIM( sn_snd_crt%cldes ) ) 2544 2546 CASE( 'oce only' ) ! C-grid ==> T 2545 2547 DO_2D( 0, 0, 0, 0 ) 2546 2548 zotx1(ji,jj) = 0.5 * ( uu(ji,jj,1,Kmm) + uu(ji-1,jj ,1,Kmm) ) 2547 zoty1(ji,jj) = 0.5 * ( vv(ji,jj,1,Kmm) + vv(ji ,jj-1,1,Kmm) ) 2549 zoty1(ji,jj) = 0.5 * ( vv(ji,jj,1,Kmm) + vv(ji ,jj-1,1,Kmm) ) 2548 2550 END_2D 2549 CASE( 'weighted oce and ice' ) ! Ocean and Ice on C-grid ==> T 2551 CASE( 'weighted oce and ice' ) ! Ocean and Ice on C-grid ==> T 2550 2552 DO_2D( 0, 0, 0, 0 ) 2551 zotx1(ji,jj) = 0.5 * ( uu (ji,jj,1,Kmm) + uu (ji-1,jj ,1,Kmm) ) * zfr_l(ji,jj) 2553 zotx1(ji,jj) = 0.5 * ( uu (ji,jj,1,Kmm) + uu (ji-1,jj ,1,Kmm) ) * zfr_l(ji,jj) 2552 2554 zoty1(ji,jj) = 0.5 * ( vv (ji,jj,1,Kmm) + vv (ji ,jj-1,1,Kmm) ) * zfr_l(ji,jj) 2553 2555 zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj ) + u_ice(ji-1,jj ) ) * fr_i(ji,jj) … … 2570 2572 IF( TRIM( sn_snd_crt%clvor ) == 'eastward-northward' ) THEN ! Rotation of the components 2571 2573 ! ! Ocean component 2572 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocx1)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2573 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocx1)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2574 zotx1(:,:) = ztmp1(:,:) ! overwrite the components 2574 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocx1)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2575 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocx1)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2576 zotx1(:,:) = ztmp1(:,:) ! overwrite the components 2575 2577 zoty1(:,:) = ztmp2(:,:) 2576 2578 IF( ssnd(jps_ivx1)%laction ) THEN ! Ice component 2577 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2578 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2579 zitx1(:,:) = ztmp1(:,:) ! overwrite the components 2579 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2580 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2581 zitx1(:,:) = ztmp1(:,:) ! overwrite the components 2580 2582 zity1(:,:) = ztmp2(:,:) 2581 2583 ENDIF … … 2602 2604 IF( ssnd(jps_ivy1)%laction ) CALL cpl_snd( jps_ivy1, isec, RESHAPE ( zity1, (/jpi,jpj,1/) ), info ) ! ice y current 1st grid 2603 2605 IF( ssnd(jps_ivz1)%laction ) CALL cpl_snd( jps_ivz1, isec, RESHAPE ( zitz1, (/jpi,jpj,1/) ), info ) ! ice z current 1st grid 2604 ! 2605 ENDIF 2606 ! 2607 ! ! ------------------------- ! 2608 ! ! Surface current to waves ! 2609 ! ! ------------------------- ! 2610 IF( ssnd(jps_ocxw)%laction .OR. ssnd(jps_ocyw)%laction ) THEN 2611 ! 2612 ! j+1 j -----V---F 2613 ! surface velocity always sent from T point ! | 2614 ! j | T U 2615 ! | | 2616 ! j j-1 -I-------| 2617 ! (for I) | | 2618 ! i-1 i i 2619 ! i i+1 (for I) 2620 SELECT CASE( TRIM( sn_snd_crtw%cldes ) ) 2621 CASE( 'oce only' ) ! C-grid ==> T 2606 ! 2607 ENDIF 2608 ! 2609 ! ! ------------------------- ! 2610 ! ! Surface current to waves ! 2611 ! ! ------------------------- ! 2612 IF( ssnd(jps_ocxw)%laction .OR. ssnd(jps_ocyw)%laction ) THEN 2613 ! 2614 ! j+1 j -----V---F 2615 ! surface velocity always sent from T point ! | 2616 ! j | T U 2617 ! | | 2618 ! j j-1 -I-------| 2619 ! (for I) | | 2620 ! i-1 i i 2621 ! i i+1 (for I) 2622 SELECT CASE( TRIM( sn_snd_crtw%cldes ) ) 2623 CASE( 'oce only' ) ! C-grid ==> T 2622 2624 DO_2D( 0, 0, 0, 0 ) 2623 zotx1(ji,jj) = 0.5 * ( uu(ji,jj,1,Kmm) + uu(ji-1,jj ,1,Kmm) ) 2624 zoty1(ji,jj) = 0.5 * ( vv(ji,jj,1,Kmm) + vv(ji , jj-1,1,Kmm) ) 2625 zotx1(ji,jj) = 0.5 * ( uu(ji,jj,1,Kmm) + uu(ji-1,jj ,1,Kmm) ) 2626 zoty1(ji,jj) = 0.5 * ( vv(ji,jj,1,Kmm) + vv(ji , jj-1,1,Kmm) ) 2625 2627 END_2D 2626 CASE( 'weighted oce and ice' ) ! Ocean and Ice on C-grid ==> T 2628 CASE( 'weighted oce and ice' ) ! Ocean and Ice on C-grid ==> T 2627 2629 DO_2D( 0, 0, 0, 0 ) 2628 zotx1(ji,jj) = 0.5 * ( uu (ji,jj,1,Kmm) + uu (ji-1,jj ,1,Kmm) ) * zfr_l(ji,jj) 2629 zoty1(ji,jj) = 0.5 * ( vv (ji,jj,1,Kmm) + vv (ji ,jj-1,1,Kmm) ) * zfr_l(ji,jj) 2630 zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj ) + u_ice(ji-1,jj ) ) * fr_i(ji,jj) 2631 zity1(ji,jj) = 0.5 * ( v_ice(ji,jj ) + v_ice(ji ,jj-1 ) ) * fr_i(ji,jj) 2630 zotx1(ji,jj) = 0.5 * ( uu (ji,jj,1,Kmm) + uu (ji-1,jj ,1,Kmm) ) * zfr_l(ji,jj) 2631 zoty1(ji,jj) = 0.5 * ( vv (ji,jj,1,Kmm) + vv (ji ,jj-1,1,Kmm) ) * zfr_l(ji,jj) 2632 zitx1(ji,jj) = 0.5 * ( u_ice(ji,jj ) + u_ice(ji-1,jj ) ) * fr_i(ji,jj) 2633 zity1(ji,jj) = 0.5 * ( v_ice(ji,jj ) + v_ice(ji ,jj-1 ) ) * fr_i(ji,jj) 2632 2634 END_2D 2633 CALL lbc_lnk_multi( 'sbccpl', zitx1, 'T', -1.0_wp, zity1, 'T', -1.0_wp ) 2634 CASE( 'mixed oce-ice' ) ! Ocean and Ice on C-grid ==> T 2635 CALL lbc_lnk_multi( 'sbccpl', zitx1, 'T', -1.0_wp, zity1, 'T', -1.0_wp ) 2636 CASE( 'mixed oce-ice' ) ! Ocean and Ice on C-grid ==> T 2635 2637 DO_2D( 0, 0, 0, 0 ) 2636 zotx1(ji,jj) = 0.5 * ( uu (ji,jj,1,Kmm) + uu (ji-1,jj ,1,Kmm) ) * zfr_l(ji,jj) & 2637 & + 0.5 * ( u_ice(ji,jj ) + u_ice(ji-1,jj ) ) * fr_i(ji,jj) 2638 zoty1(ji,jj) = 0.5 * ( vv (ji,jj,1,Kmm) + vv (ji ,jj-1,1,Kmm) ) * zfr_l(ji,jj) & 2639 & + 0.5 * ( v_ice(ji,jj ) + v_ice(ji ,jj-1 ) ) * fr_i(ji,jj) 2638 zotx1(ji,jj) = 0.5 * ( uu (ji,jj,1,Kmm) + uu (ji-1,jj ,1,Kmm) ) * zfr_l(ji,jj) & 2639 & + 0.5 * ( u_ice(ji,jj ) + u_ice(ji-1,jj ) ) * fr_i(ji,jj) 2640 zoty1(ji,jj) = 0.5 * ( vv (ji,jj,1,Kmm) + vv (ji ,jj-1,1,Kmm) ) * zfr_l(ji,jj) & 2641 & + 0.5 * ( v_ice(ji,jj ) + v_ice(ji ,jj-1 ) ) * fr_i(ji,jj) 2640 2642 END_2D 2641 2643 END SELECT 2642 CALL lbc_lnk_multi( 'sbccpl', zotx1, ssnd(jps_ocxw)%clgrid, -1.0_wp, zoty1, ssnd(jps_ocyw)%clgrid, -1.0_wp ) 2643 ! 2644 ! 2645 IF( TRIM( sn_snd_crtw%clvor ) == 'eastward-northward' ) THEN ! Rotation of the components 2646 ! ! Ocean component 2647 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocxw)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2648 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocxw)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2649 zotx1(:,:) = ztmp1(:,:) ! overwrite the components 2650 zoty1(:,:) = ztmp2(:,:) 2651 IF( ssnd(jps_ivx1)%laction ) THEN ! Ice component 2652 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2653 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2654 zitx1(:,:) = ztmp1(:,:) ! overwrite the components 2655 zity1(:,:) = ztmp2(:,:) 2656 ENDIF 2657 ENDIF 2658 ! 2659 ! ! spherical coordinates to cartesian -> 2 components to 3 components 2660 ! IF( TRIM( sn_snd_crtw%clvref ) == 'cartesian' ) THEN 2661 ! ztmp1(:,:) = zotx1(:,:) ! ocean currents 2662 ! ztmp2(:,:) = zoty1(:,:) 2663 ! CALL oce2geo ( ztmp1, ztmp2, 'T', zotx1, zoty1, zotz1 ) 2664 ! ! 2665 ! IF( ssnd(jps_ivx1)%laction ) THEN ! ice velocities 2666 ! ztmp1(:,:) = zitx1(:,:) 2667 ! ztmp1(:,:) = zity1(:,:) 2668 ! CALL oce2geo ( ztmp1, ztmp2, 'T', zitx1, zity1, zitz1 ) 2669 ! ENDIF 2670 ! ENDIF 2671 ! 2672 IF( ssnd(jps_ocxw)%laction ) CALL cpl_snd( jps_ocxw, isec, RESHAPE ( zotx1, (/jpi,jpj,1/) ), info ) ! ocean x current 1st grid 2673 IF( ssnd(jps_ocyw)%laction ) CALL cpl_snd( jps_ocyw, isec, RESHAPE ( zoty1, (/jpi,jpj,1/) ), info ) ! ocean y current 1st grid 2674 ! 2675 ENDIF 2676 ! 2677 IF( ssnd(jps_ficet)%laction ) THEN 2678 CALL cpl_snd( jps_ficet, isec, RESHAPE ( fr_i, (/jpi,jpj,1/) ), info ) 2679 ENDIF 2680 ! ! ------------------------- ! 2681 ! ! Water levels to waves ! 2682 ! ! ------------------------- ! 2683 IF( ssnd(jps_wlev)%laction ) THEN 2684 IF( ln_apr_dyn ) THEN 2685 IF( kt /= nit000 ) THEN 2686 ztmp1(:,:) = ssh(:,:,Kbb) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 2687 ELSE 2688 ztmp1(:,:) = ssh(:,:,Kbb) 2689 ENDIF 2690 ELSE 2691 ztmp1(:,:) = ssh(:,:,Kmm) 2692 ENDIF 2693 CALL cpl_snd( jps_wlev , isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ), info ) 2694 ENDIF 2644 CALL lbc_lnk_multi( 'sbccpl', zotx1, ssnd(jps_ocxw)%clgrid, -1.0_wp, zoty1, ssnd(jps_ocyw)%clgrid, -1.0_wp ) 2645 ! 2646 ! 2647 IF( TRIM( sn_snd_crtw%clvor ) == 'eastward-northward' ) THEN ! Rotation of the components 2648 ! ! Ocean component 2649 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocxw)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2650 CALL rot_rep( zotx1, zoty1, ssnd(jps_ocxw)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2651 zotx1(:,:) = ztmp1(:,:) ! overwrite the components 2652 zoty1(:,:) = ztmp2(:,:) 2653 IF( ssnd(jps_ivx1)%laction ) THEN ! Ice component 2654 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->e', ztmp1 ) ! 1st component 2655 CALL rot_rep( zitx1, zity1, ssnd(jps_ivx1)%clgrid, 'ij->n', ztmp2 ) ! 2nd component 2656 zitx1(:,:) = ztmp1(:,:) ! overwrite the components 2657 zity1(:,:) = ztmp2(:,:) 2658 ENDIF 2659 ENDIF 2660 ! 2661 ! ! spherical coordinates to cartesian -> 2 components to 3 components 2662 ! IF( TRIM( sn_snd_crtw%clvref ) == 'cartesian' ) THEN 2663 ! ztmp1(:,:) = zotx1(:,:) ! ocean currents 2664 ! ztmp2(:,:) = zoty1(:,:) 2665 ! CALL oce2geo ( ztmp1, ztmp2, 'T', zotx1, zoty1, zotz1 ) 2666 ! ! 2667 ! IF( ssnd(jps_ivx1)%laction ) THEN ! ice velocities 2668 ! ztmp1(:,:) = zitx1(:,:) 2669 ! ztmp1(:,:) = zity1(:,:) 2670 ! CALL oce2geo ( ztmp1, ztmp2, 'T', zitx1, zity1, zitz1 ) 2671 ! ENDIF 2672 ! ENDIF 2673 ! 2674 IF( ssnd(jps_ocxw)%laction ) CALL cpl_snd( jps_ocxw, isec, RESHAPE ( zotx1, (/jpi,jpj,1/) ), info ) ! ocean x current 1st grid 2675 IF( ssnd(jps_ocyw)%laction ) CALL cpl_snd( jps_ocyw, isec, RESHAPE ( zoty1, (/jpi,jpj,1/) ), info ) ! ocean y current 1st grid 2676 ! 2677 ENDIF 2678 ! 2679 IF( ssnd(jps_ficet)%laction ) THEN 2680 CALL cpl_snd( jps_ficet, isec, RESHAPE ( fr_i, (/jpi,jpj,1/) ), info ) 2681 ENDIF 2682 ! ! ------------------------- ! 2683 ! ! Water levels to waves ! 2684 ! ! ------------------------- ! 2685 IF( ssnd(jps_wlev)%laction ) THEN 2686 IF( ln_apr_dyn ) THEN 2687 IF( kt /= nit000 ) THEN 2688 ztmp1(:,:) = ssh(:,:,Kbb) - 0.5 * ( ssh_ib(:,:) + ssh_ibb(:,:) ) 2689 ELSE 2690 ztmp1(:,:) = ssh(:,:,Kbb) 2691 ENDIF 2692 ELSE 2693 ztmp1(:,:) = ssh(:,:,Kmm) 2694 ENDIF 2695 CALL cpl_snd( jps_wlev , isec, RESHAPE ( ztmp1, (/jpi,jpj,1/) ), info ) 2696 ENDIF 2695 2697 ! 2696 2698 ! Fields sent by OPA to SAS when doing OPA<->SAS coupling … … 2709 2711 CALL cpl_snd( jps_soce , isec, RESHAPE ( ts(:,:,1,jp_sal,Kmm), (/jpi,jpj,1/) ), info ) 2710 2712 ENDIF 2711 ! ! first T level thickness 2713 ! ! first T level thickness 2712 2714 IF( ssnd(jps_e3t1st )%laction ) THEN 2713 2715 CALL cpl_snd( jps_e3t1st, isec, RESHAPE ( e3t(:,:,1,Kmm) , (/jpi,jpj,1/) ), info ) … … 2731 2733 #if defined key_si3 2732 2734 ! ! ------------------------- ! 2733 ! ! Sea surface freezing temp ! 2735 ! ! Sea surface freezing temp ! 2734 2736 ! ! ------------------------- ! 2735 2737 ! needed by Met Office … … 2740 2742 ! 2741 2743 END SUBROUTINE sbc_cpl_snd 2742 2744 2743 2745 !!====================================================================== 2744 2746 END MODULE sbccpl -
NEMO/trunk/src/OCE/SBC/sbcflx.F90
r13982 r14072 35 35 INTEGER , PARAMETER :: jp_emp = 5 ! index of evaporation-precipation file 36 36 !!INTEGER , PARAMETER :: jp_sfx = 6 ! index of salt flux flux 37 INTEGER , PARAMETER :: jpfld = 5 !! 6 ! maximum number of files to read 37 INTEGER , PARAMETER :: jpfld = 5 !! 6 ! maximum number of files to read 38 38 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf ! structure of input fields (file informations, fields read) 39 39 … … 50 50 !!--------------------------------------------------------------------- 51 51 !! *** ROUTINE sbc_flx *** 52 !! 52 !! 53 53 !! ** Purpose : provide at each time step the surface ocean fluxes 54 !! (momentum, heat, freshwater and runoff) 54 !! (momentum, heat, freshwater and runoff) 55 55 !! 56 56 !! ** Method : - READ each fluxes in NetCDF files: … … 91 91 !!--------------------------------------------------------------------- 92 92 ! 93 IF( kt == nit000 ) THEN ! First call kt=nit000 93 IF( kt == nit000 ) THEN ! First call kt=nit000 94 94 ! set file information 95 95 READ ( numnam_ref, namsbc_flx, IOSTAT = ios, ERR = 901) … … 98 98 READ ( numnam_cfg, namsbc_flx, IOSTAT = ios, ERR = 902 ) 99 99 902 IF( ios > 0 ) CALL ctl_nam ( ios , 'namsbc_flx in configuration namelist' ) 100 IF(lwm) WRITE ( numond, namsbc_flx ) 100 IF(lwm) WRITE ( numond, namsbc_flx ) 101 101 ! 102 102 ! ! check: do we plan to use ln_dm2dc with non-daily forcing? 103 103 IF( ln_dm2dc .AND. sn_qsr%freqh /= 24. ) & 104 & CALL ctl_stop( 'sbc_blk_core: ln_dm2dc can be activated only with daily short-wave forcing' ) 104 & CALL ctl_stop( 'sbc_blk_core: ln_dm2dc can be activated only with daily short-wave forcing' ) 105 105 ! 106 106 ! ! store namelist information in an array 107 107 slf_i(jp_utau) = sn_utau ; slf_i(jp_vtau) = sn_vtau 108 slf_i(jp_qtot) = sn_qtot ; slf_i(jp_qsr ) = sn_qsr 108 slf_i(jp_qtot) = sn_qtot ; slf_i(jp_qsr ) = sn_qsr 109 109 slf_i(jp_emp ) = sn_emp !! ; slf_i(jp_sfx ) = sn_sfx 110 110 ! 111 111 ALLOCATE( sf(jpfld), STAT=ierror ) ! set sf structure 112 IF( ierror > 0 ) THEN 113 CALL ctl_stop( 'sbc_flx: unable to allocate sf structure' ) ; RETURN 112 IF( ierror > 0 ) THEN 113 CALL ctl_stop( 'sbc_flx: unable to allocate sf structure' ) ; RETURN 114 114 ENDIF 115 115 DO ji= 1, jpfld … … 123 123 124 124 CALL fld_read( kt, nn_fsbc, sf ) ! input fields provided at the current time-step 125 125 126 126 IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN ! update ocean fluxes at each SBC frequency 127 127 … … 138 138 qns (ji,jj) = ( sf(jp_qtot)%fnow(ji,jj,1) - sf(jp_qsr)%fnow(ji,jj,1) ) * tmask(ji,jj,1) 139 139 emp (ji,jj) = sf(jp_emp )%fnow(ji,jj,1) * tmask(ji,jj,1) 140 !!sfx (ji,jj) = sf(jp_sfx )%fnow(ji,jj,1) * tmask(ji,jj,1) 140 !!sfx (ji,jj) = sf(jp_sfx )%fnow(ji,jj,1) * tmask(ji,jj,1) 141 141 END_2D 142 142 ! ! add to qns the heat due to e-p … … 144 144 !!qns(:,:) = qns(:,:) - emp(:,:) * sst_m(:,:) * rcp ! mass flux is at SST 145 145 ! 146 ! clem: without these lbc calls, it seems that the northfold is not ok (true in 3.6, not sure in 4.x) 146 ! clem: without these lbc calls, it seems that the northfold is not ok (true in 3.6, not sure in 4.x) 147 147 CALL lbc_lnk_multi( 'sbcflx', utau, 'U', -1._wp, vtau, 'V', -1._wp, & 148 148 & qns, 'T', 1._wp, emp , 'T', 1._wp, qsr, 'T', 1._wp ) !! sfx, 'T', 1._wp ) 149 149 ! 150 150 IF( nitend-nit000 <= 100 .AND. lwp ) THEN ! control print (if less than 100 time-step asked) 151 WRITE(numout,*) 151 WRITE(numout,*) 152 152 WRITE(numout,*) ' read daily momentum, heat and freshwater fluxes OK' 153 153 DO jf = 1, jpfld … … 155 155 IF( jf == jp_qtot .OR. jf == jp_qsr ) zfact = 0.1 156 156 IF( jf == jp_emp ) zfact = 86400. 157 WRITE(numout,*) 157 WRITE(numout,*) 158 158 WRITE(numout,*) ' day: ', ndastp , TRIM(sf(jf)%clvar), ' * ', zfact 159 159 END DO … … 166 166 DO_2D( 0, 0, 0, 0 ) 167 167 ztx = ( utau(ji-1,jj ) + utau(ji,jj) ) * 0.5_wp * ( 2._wp - MIN( umask(ji-1,jj ,1), umask(ji,jj,1) ) ) 168 zty = ( vtau(ji ,jj-1) + vtau(ji,jj) ) * 0.5_wp * ( 2._wp - MIN( vmask(ji ,jj-1,1), vmask(ji,jj,1) ) ) 168 zty = ( vtau(ji ,jj-1) + vtau(ji,jj) ) * 0.5_wp * ( 2._wp - MIN( vmask(ji ,jj-1,1), vmask(ji,jj,1) ) ) 169 169 zmod = 0.5_wp * SQRT( ztx * ztx + zty * zty ) * tmask(ji,jj,1) 170 170 taum(ji,jj) = zmod -
NEMO/trunk/src/OCE/SBC/sbcmod.F90
r14053 r14072 16 16 !! 4.0 ! 2016-06 (L. Brodeau) new general bulk formulation 17 17 !! 4.0 ! 2019-03 (F. Lemarié & G. Samson) add ABL compatibility (ln_abl=TRUE) 18 !! 4.2 ! 2020-12 (G. Madec, E. Clementi) modified wave forcing and coupling 18 !! 4.2 ! 2020-12 (G. Madec, E. Clementi) modified wave forcing and coupling 19 19 !!---------------------------------------------------------------------- 20 20 … … 28 28 USE closea ! closed seas 29 29 USE phycst ! physical constants 30 USE sbc_phy, ONLY : pp_cldf 30 31 USE sbc_oce ! Surface boundary condition: ocean fields 31 32 USE trc_oce ! shared ocean-passive tracers variables … … 46 47 USE sbcssr ! surface boundary condition: sea surface restoring 47 48 USE sbcrnf ! surface boundary condition: runoffs 48 USE sbcapr ! surface boundary condition: atmo pressure 49 USE sbcapr ! surface boundary condition: atmo pressure 49 50 USE sbcfwb ! surface boundary condition: freshwater budget 50 51 USE icbstp ! Icebergs … … 139 140 WRITE(numout,*) ' ocean-atmosphere coupled formulation ln_cpl = ', ln_cpl 140 141 WRITE(numout,*) ' mixed forced-coupled formulation ln_mixcpl = ', ln_mixcpl 141 !!gm lk_oasis is controlled by key_oasis3 ===>>> It shoud be removed from the namelist 142 !!gm lk_oasis is controlled by key_oasis3 ===>>> It shoud be removed from the namelist 142 143 WRITE(numout,*) ' OASIS coupling (with atm or sas) lk_oasis = ', lk_oasis 143 144 WRITE(numout,*) ' components of your executable nn_components = ', nn_components … … 162 163 ! !** check option consistency 163 164 ! 164 IF(lwp) WRITE(numout,*) !* Single / Multi - executable (NEMO / OPA+SAS) 165 IF(lwp) WRITE(numout,*) !* Single / Multi - executable (NEMO / OPA+SAS) 165 166 SELECT CASE( nn_components ) 166 167 CASE( jp_iam_nemo ) … … 194 195 SELECT CASE( nn_ice ) 195 196 CASE( 0 ) !- no ice in the domain 196 CASE( 1 ) !- Ice-cover climatology ("Ice-if" model) 197 CASE( 1 ) !- Ice-cover climatology ("Ice-if" model) 197 198 CASE( 2 ) !- SI3 ice model 198 199 IF( .NOT.( ln_blk .OR. ln_cpl .OR. ln_abl .OR. ln_usr ) ) & … … 202 203 & CALL ctl_stop( 'sbc_init : CICE sea-ice model requires ln_blk or ln_cpl or ln_abl or ln_usr = T' ) 203 204 IF( lk_agrif ) & 204 & CALL ctl_stop( 'sbc_init : CICE sea-ice model not currently available with AGRIF' ) 205 & CALL ctl_stop( 'sbc_init : CICE sea-ice model not currently available with AGRIF' ) 205 206 CASE DEFAULT !- not supported 206 207 END SELECT … … 217 218 ! 218 219 IF( sbc_ssr_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_init : unable to allocate sbc_ssr arrays' ) 219 IF( .NOT.ln_ssr ) THEN !* Initialize qrp and erp if no restoring 220 IF( .NOT.ln_ssr ) THEN !* Initialize qrp and erp if no restoring 220 221 qrp(:,:) = 0._wp 221 222 erp(:,:) = 0._wp … … 306 307 & CALL ctl_warn( 'sbc_init : diurnal cycle for qsr: the sampling of the diurnal cycle is too small...' ) 307 308 ! 308 309 309 310 ! !** associated modules : initialization 310 311 ! … … 378 379 ! 379 380 REAL(wp) :: zthscl ! wd tanh scale 380 REAL(wp), DIMENSION(jpi,jpj) :: zwdht, zwght ! wd dep over wd limit, wgt 381 REAL(wp), DIMENSION(jpi,jpj) :: zwdht, zwght ! wd dep over wd limit, wgt 381 382 382 383 !!--------------------------------------------------------------------- … … 408 409 ! 409 410 ! !== sbc formulation ==! 410 ! 411 ! 411 412 ! 412 413 SELECT CASE( nsbc ) ! Compute ocean surface boundary condition 413 414 ! ! (i.e. utau,vtau, qns, qsr, emp, sfx) 414 CASE( jp_usr ) ; CALL usrdef_sbc_oce( kt, Kbb ) ! user defined formulation 415 CASE( jp_usr ) ; CALL usrdef_sbc_oce( kt, Kbb ) ! user defined formulation 415 416 CASE( jp_flx ) ; CALL sbc_flx ( kt ) ! flux formulation 416 417 CASE( jp_blk ) … … 476 477 IF( ln_icebergs ) THEN 477 478 CALL icb_stp( kt, Kmm ) ! compute icebergs 478 ! Icebergs do not melt over the haloes. 479 ! So emp values over the haloes are no more consistent with the inner domain values. 479 ! Icebergs do not melt over the haloes. 480 ! So emp values over the haloes are no more consistent with the inner domain values. 480 481 ! A lbc_lnk is therefore needed to ensure reproducibility and restartability. 481 482 ! see ticket #2113 for discussion about this lbc_lnk. … … 491 492 ! Special treatment of freshwater fluxes over closed seas in the model domain 492 493 ! Should not be run if ln_diurnal_only 493 IF( l_sbc_clo ) CALL sbc_clo( kt ) 494 IF( l_sbc_clo ) CALL sbc_clo( kt ) 494 495 495 496 !!$!RBbug do not understand why see ticket 667 … … 497 498 !!$ CALL lbc_lnk( 'sbcmod', emp, 'T', 1.0_wp ) 498 499 IF( ll_wd ) THEN ! If near WAD point limit the flux for now 499 zthscl = atanh(rn_wd_sbcfra) ! taper frac default is .999 500 zthscl = atanh(rn_wd_sbcfra) ! taper frac default is .999 500 501 zwdht(:,:) = ssh(:,:,Kmm) + ht_0(:,:) - rn_wdmin1 ! do this calc of water 501 502 ! depth above wd limit once -
NEMO/trunk/src/OCE/SBC/sbcrnf.F90
r14053 r14072 34 34 PUBLIC sbc_rnf_alloc ! called in sbcmod module 35 35 PUBLIC sbc_rnf_init ! called in sbcmod module 36 36 37 37 ! !!* namsbc_rnf namelist * 38 38 CHARACTER(len=100) :: cn_dir !: Root directory for location of rnf files … … 58 58 LOGICAL , PUBLIC :: l_rnfcpl = .false. !: runoffs recieved from oasis 59 59 INTEGER , PUBLIC :: nkrnf = 0 !: nb of levels over which Kz is increased at river mouths 60 60 61 61 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: rnfmsk !: river mouth mask (hori.) 62 62 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: rnfmsk_z !: river mouth mask (vert.) 63 63 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: h_rnf !: depth of runoff in m 64 64 INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: nk_rnf !: depth of runoff in model levels 65 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: rnf_tsc_b, rnf_tsc !: before and now T & S runoff contents [K.m/s & PSU.m/s] 65 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: rnf_tsc_b, rnf_tsc !: before and now T & S runoff contents [K.m/s & PSU.m/s] 66 66 67 67 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_rnf ! structure: river runoff (file information, fields read) 68 68 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_i_rnf ! structure: iceberg flux (file information, fields read) 69 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_s_rnf ! structure: river runoff salinity (file information, fields read) 70 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_t_rnf ! structure: river runoff temperature (file information, fields read) 71 69 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_s_rnf ! structure: river runoff salinity (file information, fields read) 70 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_t_rnf ! structure: river runoff temperature (file information, fields read) 71 72 72 !! * Substitutions 73 73 # include "do_loop_substitute.h90" … … 247 247 INTEGER :: ios ! Local integer output status for namelist read 248 248 INTEGER :: nbrec ! temporary integer 249 REAL(wp) :: zacoef 250 REAL(wp), DIMENSION(jpi,jpj,2) :: zrnfcl 249 REAL(wp) :: zacoef 250 REAL(wp), DIMENSION(jpi,jpj,2) :: zrnfcl 251 251 !! 252 252 NAMELIST/namsbc_rnf/ cn_dir , ln_rnf_depth, ln_rnf_tem, ln_rnf_sal, ln_rnf_icb, & … … 259 259 IF( sbc_rnf_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_rnf_alloc : unable to allocate arrays' ) 260 260 ! 261 IF( .NOT. ln_rnf ) THEN ! no specific treatment in vicinity of river mouths 261 IF( .NOT. ln_rnf ) THEN ! no specific treatment in vicinity of river mouths 262 262 ln_rnf_mouth = .FALSE. ! default definition needed for example by sbc_ssr or by tra_adv_muscl 263 263 nkrnf = 0 … … 295 295 ! ! ================== 296 296 ! 297 IF( .NOT. l_rnfcpl ) THEN 297 IF( .NOT. l_rnfcpl ) THEN 298 298 ALLOCATE( sf_rnf(1), STAT=ierror ) ! Create sf_rnf structure (runoff inflow) 299 299 IF(lwp) WRITE(numout,*) … … 350 350 IF(lwp) WRITE(numout,*) ' ==>>> runoffs depth read in a file' 351 351 rn_dep_file = TRIM( cn_dir )//TRIM( sn_dep_rnf%clname ) 352 IF( .NOT. sn_dep_rnf%ln_clim ) THEN ; WRITE(rn_dep_file, '(a,"_y",i4)' ) TRIM( rn_dep_file ), nyear ! add year 353 IF( sn_dep_rnf%clftyp == 'monthly' ) WRITE(rn_dep_file, '(a,"m",i2)' ) TRIM( rn_dep_file ), nmonth ! add month 352 IF( .NOT. sn_dep_rnf%ln_clim ) THEN ; WRITE(rn_dep_file, '(a,"_y",i4)' ) TRIM( rn_dep_file ), nyear ! add year 353 IF( sn_dep_rnf%clftyp == 'monthly' ) WRITE(rn_dep_file, '(a,"m",i2)' ) TRIM( rn_dep_file ), nmonth ! add month 354 354 ENDIF 355 355 CALL iom_open ( rn_dep_file, inum ) ! open file -
NEMO/trunk/src/OCE/SBC/sbcssm.F90
r13970 r14072 10 10 11 11 !!---------------------------------------------------------------------- 12 !! sbc_ssm : calculate sea surface mean currents, temperature, 12 !! sbc_ssm : calculate sea surface mean currents, temperature, 13 13 !! and salinity over nn_fsbc time-step 14 14 !!---------------------------------------------------------------------- … … 31 31 32 32 LOGICAL, SAVE :: l_ssm_mean = .FALSE. ! keep track of whether means have been read from restart file 33 33 34 34 # include "domzgr_substitute.h90" 35 35 !!---------------------------------------------------------------------- … … 43 43 !!--------------------------------------------------------------------- 44 44 !! *** ROUTINE sbc_oce *** 45 !! 45 !! 46 46 !! ** Purpose : provide ocean surface variable to sea-surface boundary 47 !! condition computation 48 !! 49 !! ** Method : compute mean surface velocity (2 components at U and 47 !! condition computation 48 !! 49 !! ** Method : compute mean surface velocity (2 components at U and 50 50 !! V-points) [m/s], temperature [Celsius] and salinity [psu] over 51 51 !! the periode (kt - nn_fsbc) to kt … … 199 199 ! 200 200 ELSE 201 ! 201 ! 202 202 IF(lwp) WRITE(numout,*) 203 203 IF(lwp) WRITE(numout,*) 'sbc_ssm_init : sea surface mean fields' … … 221 221 ! 222 222 IF( zf_sbc /= REAL( nn_fsbc, wp ) ) THEN ! nn_fsbc has changed between 2 runs 223 IF(lwp) WRITE(numout,*) ' restart with a change in the frequency of mean from ', zf_sbc, ' to ', nn_fsbc 224 zcoef = REAL( nn_fsbc - 1, wp ) / zf_sbc 225 ssu_m(:,:) = zcoef * ssu_m(:,:) 223 IF(lwp) WRITE(numout,*) ' restart with a change in the frequency of mean from ', zf_sbc, ' to ', nn_fsbc 224 zcoef = REAL( nn_fsbc - 1, wp ) / zf_sbc 225 ssu_m(:,:) = zcoef * ssu_m(:,:) 226 226 ssv_m(:,:) = zcoef * ssv_m(:,:) 227 227 sst_m(:,:) = zcoef * sst_m(:,:) … … 251 251 ENDIF 252 252 ! 253 IF( .NOT. ln_traqsr ) fraqsr_1lev(:,:) = 1._wp ! default definition: qsr 100% in the fisrt level 253 IF( .NOT. ln_traqsr ) fraqsr_1lev(:,:) = 1._wp ! default definition: qsr 100% in the fisrt level 254 254 ! 255 255 END SUBROUTINE sbc_ssm_init -
NEMO/trunk/src/OCE/SBC/sbcwave.F90
r14007 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE sbcwave *** 4 !! Wave module 4 !! Wave module 5 5 !!====================================================================== 6 !! History : 3.3 ! 2011-09 (M. Adani) Original code: Drag Coefficient 7 !! : 3.4 ! 2012-10 (M. Adani) Stokes Drift 6 !! History : 3.3 ! 2011-09 (M. Adani) Original code: Drag Coefficient 7 !! : 3.4 ! 2012-10 (M. Adani) Stokes Drift 8 8 !! 3.6 ! 2014-09 (E. Clementi,P. Oddo) New Stokes Drift Computation 9 9 !! - ! 2016-12 (G. Madec, E. Clementi) update Stoke drift computation 10 10 !! + add sbc_wave_ini routine 11 !! 4.2 ! 2020-12 (G. Madec, E. Clementi) updates, new Stoke drift computation 11 !! 4.2 ! 2020-12 (G. Madec, E. Clementi) updates, new Stoke drift computation 12 12 !! according to Couvelard et al.,2019 13 13 !!---------------------------------------------------------------------- … … 16 16 !! sbc_stokes : calculate 3D Stokes-drift velocities 17 17 !! sbc_wave : wave data from wave model: forced (netcdf files) or coupled mode 18 !! sbc_wave_init : initialisation fo surface waves 18 !! sbc_wave_init : initialisation fo surface waves 19 19 !!---------------------------------------------------------------------- 20 20 USE phycst ! physical constants … … 36 36 PUBLIC sbc_wave ! routine called in sbcmod 37 37 PUBLIC sbc_wave_init ! routine called in sbcmod 38 38 39 39 ! Variables checking if the wave parameters are coupled (if not, they are read from file) 40 40 LOGICAL, PUBLIC :: cpl_hsig = .FALSE. … … 113 113 INTEGER, INTENT(in) :: Kmm ! ocean time level index 114 114 INTEGER :: jj, ji, jk ! dummy loop argument 115 INTEGER :: ik ! local integer 115 INTEGER :: ik ! local integer 116 116 REAL(wp) :: ztransp, zfac, ztemp, zsp0, zsqrt, zbreiv16_w 117 117 REAL(wp) :: zdep_u, zdep_v, zkh_u, zkh_v, zda_u, zda_v, sdtrp … … 143 143 IF( cpl_tusd .AND. cpl_tvsd ) THEN !stokes transport is provided in coupled mode 144 144 sdtrp = SQRT( tusd(ji,jj)*tusd(ji,jj) + tvsd(ji,jj)*tvsd(ji,jj) ) !<-- norm of Surface Stokes drift transport 145 ELSE 146 ! Stokes drift transport estimated from Hs and Tmean 145 ELSE 146 ! Stokes drift transport estimated from Hs and Tmean 147 147 sdtrp = 2.0_wp * rpi / 16.0_wp * & 148 148 & hsw(ji,jj)*hsw(ji,jj) / MAX( wmp(ji,jj), 0.0000001_wp ) … … 240 240 ! !== Horizontal divergence of barotropic Stokes transport ==! 241 241 div_sd(:,:) = 0._wp 242 DO jk = 1, jpkm1 ! 242 DO jk = 1, jpkm1 ! 243 243 div_sd(:,:) = div_sd(:,:) + ze3divh(:,:,jk) 244 244 END DO … … 300 300 ENDIF 301 301 302 IF( ln_sdw .AND. .NOT. cpl_sdrftx) THEN !== Computation of the 3d Stokes Drift ==! 302 IF( ln_sdw .AND. .NOT. cpl_sdrftx) THEN !== Computation of the 3d Stokes Drift ==! 303 303 ! 304 304 IF( jpfld > 0 ) THEN ! Read from file only if the field is not coupled … … 329 329 !! - create the structure used to read required wave fields 330 330 !! (its size depends on namelist options) 331 !! ** action 331 !! ** action 332 332 !!--------------------------------------------------------------------- 333 333 INTEGER :: ierror, ios ! local integer … … 487 487 jp_wmp = jpfld 488 488 ENDIF 489 ! 2. Read from file only the non-coupled fields 489 ! 2. Read from file only the non-coupled fields 490 490 IF( jpfld > 0 ) THEN 491 491 ALLOCATE( slf_i(jpfld) ) -
NEMO/trunk/src/OCE/TRA/eosbn2.F90
r14010 r14072 31 31 !! bn2 : compute the Brunt-Vaisala frequency 32 32 !! eos_pt_from_ct: compute the potential temperature from the Conservative Temperature 33 !! eos_rab : generic interface of in situ thermal/haline expansion ratio 33 !! eos_rab : generic interface of in situ thermal/haline expansion ratio 34 34 !! eos_rab_3d : compute in situ thermal/haline expansion ratio 35 35 !! eos_rab_2d : compute in situ thermal/haline expansion ratio for 2d fields … … 46 46 USE in_out_manager ! I/O manager 47 47 USE lib_mpp ! MPP library 48 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 48 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 49 49 USE prtctl ! Print control 50 50 USE lbclnk ! ocean lateral boundary conditions … … 63 63 END INTERFACE 64 64 ! 65 INTERFACE eos_fzp 65 INTERFACE eos_fzp 66 66 MODULE PROCEDURE eos_fzp_2d, eos_fzp_0d 67 67 END INTERFACE … … 89 89 90 90 ! !!! simplified eos coefficients (default value: Vallis 2006) 91 REAL(wp) :: rn_a0 = 1.6550e-1_wp ! thermal expansion coeff. 92 REAL(wp) :: rn_b0 = 7.6554e-1_wp ! saline expansion coeff. 93 REAL(wp) :: rn_lambda1 = 5.9520e-2_wp ! cabbeling coeff. in T^2 94 REAL(wp) :: rn_lambda2 = 5.4914e-4_wp ! cabbeling coeff. in S^2 95 REAL(wp) :: rn_mu1 = 1.4970e-4_wp ! thermobaric coeff. in T 96 REAL(wp) :: rn_mu2 = 1.1090e-5_wp ! thermobaric coeff. in S 97 REAL(wp) :: rn_nu = 2.4341e-3_wp ! cabbeling coeff. in theta*salt 98 91 REAL(wp) :: rn_a0 = 1.6550e-1_wp ! thermal expansion coeff. 92 REAL(wp) :: rn_b0 = 7.6554e-1_wp ! saline expansion coeff. 93 REAL(wp) :: rn_lambda1 = 5.9520e-2_wp ! cabbeling coeff. in T^2 94 REAL(wp) :: rn_lambda2 = 5.4914e-4_wp ! cabbeling coeff. in S^2 95 REAL(wp) :: rn_mu1 = 1.4970e-4_wp ! thermobaric coeff. in T 96 REAL(wp) :: rn_mu2 = 1.1090e-5_wp ! thermobaric coeff. in S 97 REAL(wp) :: rn_nu = 2.4341e-3_wp ! cabbeling coeff. in theta*salt 98 99 99 ! TEOS10/EOS80 parameters 100 100 REAL(wp) :: r1_S0, r1_T0, r1_Z0, rdeltaS 101 101 102 102 ! EOS parameters 103 103 REAL(wp) :: EOS000 , EOS100 , EOS200 , EOS300 , EOS400 , EOS500 , EOS600 … … 117 117 REAL(wp) :: EOS022 118 118 REAL(wp) :: EOS003 , EOS103 119 REAL(wp) :: EOS013 120 119 REAL(wp) :: EOS013 120 121 121 ! ALPHA parameters 122 122 REAL(wp) :: ALP000 , ALP100 , ALP200 , ALP300 , ALP400 , ALP500 … … 133 133 REAL(wp) :: ALP012 134 134 REAL(wp) :: ALP003 135 135 136 136 ! BETA parameters 137 137 REAL(wp) :: BET000 , BET100 , BET200 , BET300 , BET400 , BET500 … … 160 160 REAL(wp) :: PEN002 , PEN102 161 161 REAL(wp) :: PEN012 162 162 163 163 ! ALPHA_PEN parameters 164 164 REAL(wp) :: APE000 , APE100 , APE200 , APE300 … … 295 295 & + rn_b0 * ( 1._wp - 0.5_wp*rn_lambda2*zs - rn_mu2*zh ) * zs & 296 296 & - rn_nu * zt * zs 297 ! 297 ! 298 298 prd(ji,jj,jk) = zn * r1_rho0 * ztm ! density anomaly (masked) 299 299 END_3D … … 448 448 END_3D 449 449 ENDIF 450 450 451 451 CASE( np_seos ) !== simplified EOS ==! 452 452 ! … … 997 997 !! *** ROUTINE bn2 *** 998 998 !! 999 !! ** Purpose : Compute the local Brunt-Vaisala frequency at the 999 !! ** Purpose : Compute the local Brunt-Vaisala frequency at the 1000 1000 !! time-step of the input arguments 1001 1001 !! … … 1004 1004 !! N.B. N^2 is set one for all to zero at jk=1 in istate module. 1005 1005 !! 1006 !! ** Action : pn2 : square of the brunt-vaisala frequency at w-point 1006 !! ** Action : pn2 : square of the brunt-vaisala frequency at w-point 1007 1007 !! 1008 1008 !!---------------------------------------------------------------------- … … 1021 1021 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 2, jpkm1 ) ! interior points only (2=< jk =< jpkm1 ); surface and bottom value set to zero one for all in istate.F90 1022 1022 zrw = ( gdepw(ji,jj,jk ,Kmm) - gdept(ji,jj,jk,Kmm) ) & 1023 & / ( gdept(ji,jj,jk-1,Kmm) - gdept(ji,jj,jk,Kmm) ) 1024 ! 1025 zaw = pab(ji,jj,jk,jp_tem) * (1. - zrw) + pab(ji,jj,jk-1,jp_tem) * zrw 1023 & / ( gdept(ji,jj,jk-1,Kmm) - gdept(ji,jj,jk,Kmm) ) 1024 ! 1025 zaw = pab(ji,jj,jk,jp_tem) * (1. - zrw) + pab(ji,jj,jk-1,jp_tem) * zrw 1026 1026 zbw = pab(ji,jj,jk,jp_sal) * (1. - zrw) + pab(ji,jj,jk-1,jp_sal) * zrw 1027 1027 ! … … 1151 1151 CALL ctl_stop( 'eos_fzp_2d:', ctmp1 ) 1152 1152 ! 1153 END SELECT 1153 END SELECT 1154 1154 ! 1155 1155 END SUBROUTINE eos_fzp_2d_t … … 1208 1208 !! ** Purpose : Calculates nonlinear anomalies of alpha_PE, beta_PE and PE at T-points 1209 1209 !! 1210 !! ** Method : PE is defined analytically as the vertical 1210 !! ** Method : PE is defined analytically as the vertical 1211 1211 !! primitive of EOS times -g integrated between 0 and z>0. 1212 1212 !! pen is the nonlinear bsq-PE anomaly: pen = ( PE - rho0 gz ) / rho0 gz - rd 1213 !! = 1/z * /int_0^z rd dz - rd 1213 !! = 1/z * /int_0^z rd dz - rd 1214 1214 !! where rd is the density anomaly (see eos_rhd function) 1215 1215 !! ab_pe are partial derivatives of PE anomaly with respect to T and S: … … 1275 1275 ! 1276 1276 zn = ( zn2 * zh + zn1 ) * zh + zn0 1277 ! 1277 ! 1278 1278 pab_pe(ji,jj,jk,jp_tem) = zn * zh * r1_rho0 * ztm 1279 1279 ! … … 1290 1290 ! 1291 1291 zn = ( zn2 * zh + zn1 ) * zh + zn0 1292 ! 1292 ! 1293 1293 pab_pe(ji,jj,jk,jp_sal) = zn / zs * zh * r1_rho0 * ztm 1294 1294 ! … … 1370 1370 IF(lwp) WRITE(numout,*) ' ==>>> use of TEOS-10 equation of state (cons. temp. and abs. salinity)' 1371 1371 ! 1372 l_useCT = .TRUE. ! model temperature is Conservative temperature 1372 l_useCT = .TRUE. ! model temperature is Conservative temperature 1373 1373 ! 1374 1374 rdeltaS = 32._wp … … 1751 1751 1752 1752 r1_S0 = 0.875_wp/35.16504_wp ! Used to convert CT in potential temperature when using bulk formulae (eos_pt_from_ct) 1753 1753 1754 1754 IF(lwp) THEN 1755 1755 WRITE(numout,*) … … 1775 1775 END SELECT 1776 1776 ! 1777 rho0_rcp = rho0 * rcp 1777 rho0_rcp = rho0 * rcp 1778 1778 r1_rho0 = 1._wp / rho0 1779 1779 r1_rcp = 1._wp / rcp 1780 r1_rho0_rcp = 1._wp / rho0_rcp 1780 r1_rho0_rcp = 1._wp / rho0_rcp 1781 1781 ! 1782 1782 IF(lwp) THEN -
NEMO/trunk/src/OCE/TRA/traadv.F90
r13982 r14072 2 2 !!============================================================================== 3 3 !! *** MODULE traadv *** 4 !! Ocean active tracers: advection trend 4 !! Ocean active tracers: advection trend 5 5 !!============================================================================== 6 6 !! History : 2.0 ! 2005-11 (G. Madec) Original code 7 7 !! 3.3 ! 2010-09 (C. Ethe, G. Madec) merge TRC-TRA + switch from velocity to transport 8 8 !! 3.6 ! 2011-06 (G. Madec) Addition of Mixed Layer Eddy parameterisation 9 !! 3.7 ! 2014-05 (G. Madec) Add 2nd/4th order cases for CEN and FCT schemes 9 !! 3.7 ! 2014-05 (G. Madec) Add 2nd/4th order cases for CEN and FCT schemes 10 10 !! - ! 2014-12 (G. Madec) suppression of cross land advection option 11 11 !! 3.6 ! 2015-06 (E. Clementi) Addition of Stokes drift in case of wave coupling … … 34 34 USE ldfslp ! Lateral diffusion: slopes of neutral surfaces 35 35 USE trd_oce ! trends: ocean variables 36 USE trdtra ! trends manager: tracers 37 USE diaptr ! Poleward heat transport 36 USE trdtra ! trends manager: tracers 37 USE diaptr ! Poleward heat transport 38 38 ! 39 39 USE in_out_manager ! I/O manager … … 195 195 CASE ( np_MUS ) ! MUSCL 196 196 ! NOTE: [tiling-comms-merge] I added this lbc_lnk as it did not validate against the trunk when using ln_zco 197 IF (nn_hls.EQ.2) THEN 197 IF (nn_hls.EQ.2) THEN 198 198 CALL lbc_lnk( 'traadv', pts(:,:,:,:,Kbb), 'T', 1.) 199 199 #if defined key_loop_fusion 200 CALL tra_adv_mus_lf ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 200 CALL tra_adv_mus_lf ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 201 201 #else 202 CALL tra_adv_mus ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 202 CALL tra_adv_mus ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 203 203 #endif 204 204 ELSE 205 CALL tra_adv_mus ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 205 CALL tra_adv_mus ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 206 206 END IF 207 207 CASE ( np_UBS ) ! UBS … … 248 248 !!--------------------------------------------------------------------- 249 249 !! *** ROUTINE tra_adv_init *** 250 !! 251 !! ** Purpose : Control the consistency between namelist options for 250 !! 251 !! ** Purpose : Control the consistency between namelist options for 252 252 !! tracer advection schemes and set nadv 253 253 !!---------------------------------------------------------------------- … … 290 290 ! 291 291 ! !== Parameter control & set nadv ==! 292 ioptio = 0 292 ioptio = 0 293 293 IF( ln_traadv_OFF ) THEN ; ioptio = ioptio + 1 ; nadv = np_NO_adv ; ENDIF 294 294 IF( ln_traadv_cen ) THEN ; ioptio = ioptio + 1 ; nadv = np_CEN ; ENDIF … … 319 319 ENDIF 320 320 ! 321 ! !== Print the choice ==! 321 ! !== Print the choice ==! 322 322 IF(lwp) THEN 323 323 WRITE(numout,*) -
NEMO/trunk/src/OCE/TRA/traadv_cen.F90
r13982 r14072 13 13 USE dom_oce ! ocean space and time domain 14 14 USE eosbn2 ! equation of state 15 USE traadv_fct ! acces to routine interp_4th_cpt 15 USE traadv_fct ! acces to routine interp_4th_cpt 16 16 USE trd_oce ! trends: ocean variables 17 USE trdtra ! trends manager: tracers 17 USE trdtra ! trends manager: tracers 18 18 USE diaptr ! poleward transport diagnostics 19 19 USE diaar5 ! AR5 diagnostics … … 28 28 29 29 PUBLIC tra_adv_cen ! called by traadv.F90 30 30 31 31 REAL(wp) :: r1_6 = 1._wp / 6._wp ! =1/6 32 32 … … 46 46 47 47 SUBROUTINE tra_adv_cen( kt, kit000, cdtype, pU, pV, pW, & 48 & Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v ) 48 & Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v ) 49 49 !!---------------------------------------------------------------------- 50 50 !! *** ROUTINE tra_adv_cen *** 51 !! 51 !! 52 52 !! ** Purpose : Compute the now trend due to the advection of tracers 53 53 !! and add it to the general trend of passive tracer equations. 54 54 !! 55 55 !! ** Method : The advection is evaluated by a 2nd or 4th order scheme 56 !! using now fields (leap-frog scheme). 56 !! using now fields (leap-frog scheme). 57 57 !! kn_cen_h = 2 ==>> 2nd order centered scheme on the horizontal 58 58 !! = 4 ==>> 4th order - - - - … … 98 98 ENDIF 99 99 ! 100 ! 100 ! 101 101 zwz(:,:, 1 ) = 0._wp ! surface & bottom vertical flux set to zero for all tracers 102 102 zwz(:,:,jpk) = 0._wp … … 155 155 IF( ln_isfcav ) THEN ! ice-shelf cavities (top of the ocean) 156 156 DO_2D( 1, 1, 1, 1 ) 157 zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm) 157 zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm) 158 158 END_2D 159 159 ELSE ! no ice-shelf cavities (only ocean surface) … … 163 163 ENDIF 164 164 ENDIF 165 ! 165 ! 166 166 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) !-- Divergence of advective fluxes --! 167 167 pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) & … … 185 185 ! 186 186 END SUBROUTINE tra_adv_cen 187 187 188 188 !!====================================================================== 189 189 END MODULE traadv_cen -
NEMO/trunk/src/OCE/TRA/traadv_fct.F90
r13982 r14072 10 10 !! tra_adv_fct : update the tracer trend with a 3D advective trends using a 2nd or 4th order FCT scheme 11 11 !! with sub-time-stepping in the vertical direction 12 !! nonosc : compute monotonic tracer fluxes by a non-oscillatory algorithm 12 !! nonosc : compute monotonic tracer fluxes by a non-oscillatory algorithm 13 13 !! interp_4th_cpt : 4th order compact scheme for the vertical component of the advection 14 14 !!---------------------------------------------------------------------- … … 24 24 ! 25 25 USE in_out_manager ! I/O manager 26 USE iom ! 26 USE iom ! 27 27 USE lib_mpp ! MPP library 28 USE lbclnk ! ocean lateral boundary condition (or mpp link) 29 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 28 USE lbclnk ! ocean lateral boundary condition (or mpp link) 29 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 30 30 31 31 IMPLICIT NONE … … 60 60 !!---------------------------------------------------------------------- 61 61 !! *** ROUTINE tra_adv_fct *** 62 !! 62 !! 63 63 !! ** Purpose : Compute the now trend due to total advection of tracers 64 64 !! and add it to the general trend of tracer equations … … 66 66 !! ** Method : - 2nd or 4th FCT scheme on the horizontal direction 67 67 !! (choice through the value of kn_fct) 68 !! - on the vertical the 4th order is a compact scheme 69 !! - corrected flux (monotonic correction) 68 !! - on the vertical the 4th order is a compact scheme 69 !! - corrected flux (monotonic correction) 70 70 !! 71 71 !! ** Action : - update pt(:,:,:,:,Krhs) with the now advective tracer trends … … 154 154 ! 155 155 ! !== upstream advection with initial mass fluxes & intermediate update ==! 156 ! !* upstream tracer flux in the i and j direction 156 ! !* upstream tracer flux in the i and j direction 157 157 DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 ) 158 158 ! upstream scheme … … 173 173 IF( ln_isfcav ) THEN ! top of the ice-shelf cavities and at the ocean surface 174 174 DO_2D( 1, 1, 1, 1 ) 175 zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb) ! linear free surface 175 zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb) ! linear free surface 176 176 END_2D 177 177 ELSE ! no cavities: only at the ocean surface … … 181 181 ENDIF 182 182 ENDIF 183 ! 183 ! 184 184 DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 ) !* trend and after field with monotonic scheme 185 185 ! ! total intermediate advective trends … … 193 193 & / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk) 194 194 END_3D 195 195 196 196 IF ( ll_zAimp ) THEN 197 197 CALL tridia_solver( zwdia, zwsup, zwinf, zwi, zwi , 0 ) … … 215 215 END IF 216 216 ! ! "Poleward" heat and salt transports (contribution of upstream fluxes) 217 IF( l_ptr ) zptry(:,:,:) = zwy(:,:,:) 217 IF( l_ptr ) zptry(:,:,:) = zwy(:,:,:) 218 218 ! 219 219 ! !== anti-diffusive flux : high order minus low order ==! … … 268 268 zC4t_u = zC2t_u + r1_6 * ( ztu(ji-1,jj ,jk) - ztu(ji+1,jj ,jk) ) 269 269 zC4t_v = zC2t_v + r1_6 * ( ztv(ji ,jj-1,jk) - ztv(ji ,jj+1,jk) ) 270 ! ! C4 minus upstream advective fluxes 270 ! ! C4 minus upstream advective fluxes 271 271 zwx(ji,jj,jk) = 0.5_wp * pU(ji,jj,jk) * zC4t_u - zwx(ji,jj,jk) 272 272 zwy(ji,jj,jk) = 0.5_wp * pV(ji,jj,jk) * zC4t_v - zwy(ji,jj,jk) … … 275 275 ! 276 276 END SELECT 277 ! 277 ! 278 278 SELECT CASE( kn_fct_v ) !* vertical anti-diffusive fluxes (w-masked interior values) 279 279 ! … … 384 384 DEALLOCATE( ztrdx, ztrdy, ztrdz ) 385 385 ENDIF 386 IF( l_ptr ) THEN 386 IF( l_ptr ) THEN 387 387 DEALLOCATE( zptry ) 388 388 ENDIF … … 394 394 !!--------------------------------------------------------------------- 395 395 !! *** ROUTINE nonosc *** 396 !! 397 !! ** Purpose : compute monotonic tracer fluxes from the upstream 398 !! scheme and the before field by a nonoscillatory algorithm 396 !! 397 !! ** Purpose : compute monotonic tracer fluxes from the upstream 398 !! scheme and the before field by a nonoscillatory algorithm 399 399 !! 400 400 !! ** Method : ... ??? … … 492 492 !!---------------------------------------------------------------------- 493 493 !! *** ROUTINE interp_4th_cpt_org *** 494 !! 494 !! 495 495 !! ** Purpose : Compute the interpolation of tracer at w-point 496 496 !! … … 503 503 REAL(wp),DIMENSION(jpi,jpj,jpk) :: zwd, zwi, zws, zwrm, zwt 504 504 !!---------------------------------------------------------------------- 505 505 506 506 DO_3D( 1, 1, 1, 1, 3, jpkm1 ) !== build the three diagonal matrix ==! 507 507 zwd (ji,jj,jk) = 4._wp … … 514 514 zwi (ji,jj,jk) = 0._wp 515 515 zws (ji,jj,jk) = 0._wp 516 zwrm(ji,jj,jk) = 0.5 * ( pt_in(ji,jj,jk-1) + pt_in(ji,jj,jk) ) 516 zwrm(ji,jj,jk) = 0.5 * ( pt_in(ji,jj,jk-1) + pt_in(ji,jj,jk) ) 517 517 ENDIF 518 518 END_3D … … 538 538 END_2D 539 539 DO_3D( 1, 1, 1, 1, 3, jpkm1 ) 540 pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 540 pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 541 541 END_3D 542 542 … … 547 547 pt_out(ji,jj,jk) = ( pt_out(ji,jj,jk) - zws(ji,jj,jk) * pt_out(ji,jj,jk+1) ) / zwt(ji,jj,jk) 548 548 END_3D 549 ! 549 ! 550 550 END SUBROUTINE interp_4th_cpt_org 551 551 552 552 553 553 SUBROUTINE interp_4th_cpt( pt_in, pt_out ) 554 554 !!---------------------------------------------------------------------- 555 555 !! *** ROUTINE interp_4th_cpt *** 556 !! 556 !! 557 557 !! ** Purpose : Compute the interpolation of tracer at w-point 558 558 !! … … 582 582 ! CASE( np_CEN2 ) ! 2nd order centered at top & bottom 583 583 ! END SELECT 584 !!gm 584 !!gm 585 585 ! 586 586 IF ( ln_isfcav ) THEN ! set level two values which may not be set in ISF case … … 600 600 zwi (ji,jj,ikb) = 0._wp 601 601 zws (ji,jj,ikb) = 0._wp 602 zwrm(ji,jj,ikb) = 0.5_wp * ( pt_in(ji,jj,ikb-1) + pt_in(ji,jj,ikb) ) 602 zwrm(ji,jj,ikb) = 0.5_wp * ( pt_in(ji,jj,ikb-1) + pt_in(ji,jj,ikb) ) 603 603 END_2D 604 604 ! … … 616 616 END_2D 617 617 DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 3, jpkm1 ) 618 pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 618 pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 619 619 END_3D 620 620 … … 625 625 pt_out(ji,jj,jk) = ( pt_out(ji,jj,jk) - zws(ji,jj,jk) * pt_out(ji,jj,jk+1) ) / zwt(ji,jj,jk) 626 626 END_3D 627 ! 627 ! 628 628 END SUBROUTINE interp_4th_cpt 629 629 … … 632 632 !!---------------------------------------------------------------------- 633 633 !! *** ROUTINE tridia_solver *** 634 !! 634 !! 635 635 !! ** Purpose : solve a symmetric 3diagonal system 636 636 !! 637 637 !! ** Method : solve M.t_out = RHS(t) where M is a tri diagonal matrix ( jpk*jpk ) 638 !! 638 !! 639 639 !! ( D_1 U_1 0 0 0 )( t_1 ) ( RHS_1 ) 640 640 !! ( L_2 D_2 U_2 0 0 )( t_2 ) ( RHS_2 ) … … 642 642 !! ( ... )( ... ) ( ... ) 643 643 !! ( 0 0 0 L_k D_k )( t_k ) ( RHS_k ) 644 !! 644 !! 645 645 !! M is decomposed in the product of an upper and lower triangular matrix. 646 !! The tri-diagonals matrix is given as input 3D arrays: pD, pU, pL 646 !! The tri-diagonals matrix is given as input 3D arrays: pD, pU, pL 647 647 !! (i.e. the Diagonal, the Upper diagonal, and the Lower diagonal). 648 648 !! The solution is pta. … … 672 672 END_2D 673 673 DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, kstart+1, jpkm1 ) 674 pt_out(ji,jj,jk) = pRHS(ji,jj,jk) - pL(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 674 pt_out(ji,jj,jk) = pRHS(ji,jj,jk) - pL(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 675 675 END_3D 676 676 -
NEMO/trunk/src/OCE/TRA/traadv_mus.F90
r13982 r14072 29 29 USE in_out_manager ! I/O manager 30 30 USE lib_mpp ! distribued memory computing 31 USE lbclnk ! ocean lateral boundary condition (or mpp link) 32 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 31 USE lbclnk ! ocean lateral boundary condition (or mpp link) 32 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 33 33 34 34 IMPLICIT NONE … … 36 36 37 37 PUBLIC tra_adv_mus ! routine called by traadv.F90 38 38 39 39 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: upsmsk !: mixed upstream/centered scheme near some straits 40 40 ! ! and in closed seas (orca 2 and 1 configurations) 41 41 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: xind !: mixed upstream/centered index 42 42 43 43 LOGICAL :: l_trd ! flag to compute trends 44 44 LOGICAL :: l_ptr ! flag to compute poleward transport … … 50 50 !!---------------------------------------------------------------------- 51 51 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 52 !! $Id$ 52 !! $Id$ 53 53 !! Software governed by the CeCILL license (see ./LICENSE) 54 54 !!---------------------------------------------------------------------- … … 65 65 !! 66 66 !! ** Method : MUSCL scheme plus centered scheme at ocean boundaries 67 !! ld_msc_ups=T : 67 !! ld_msc_ups=T : 68 68 !! 69 69 !! ** Action : - update pt(:,:,:,:,Krhs) with the now advective tracer trends … … 134 134 ! !-- first guess of the slopes 135 135 zwx(:,:,jpk) = 0._wp ! bottom values 136 zwy(:,:,jpk) = 0._wp 136 zwy(:,:,jpk) = 0._wp 137 137 DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 ) 138 138 zwx(ji,jj,jk) = umask(ji,jj,jk) * ( pt(ji+1,jj,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) ) … … 188 188 CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, zwy, pV, pt(:,:,:,jn,Kbb) ) 189 189 END IF 190 ! ! "Poleward" heat and salt transports 190 ! ! "Poleward" heat and salt transports 191 191 IF( l_ptr ) CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) ) 192 192 ! ! heat transport -
NEMO/trunk/src/OCE/TRA/traadv_qck.F90
r13982 r14072 19 19 USE trc_oce ! share passive tracers/Ocean variables 20 20 USE trd_oce ! trends: ocean variables 21 USE trdtra ! trends manager: tracers 21 USE trdtra ! trends manager: tracers 22 22 USE diaptr ! poleward transport diagnostics 23 23 USE iom … … 26 26 USE lib_mpp ! distribued memory computing 27 27 USE lbclnk ! ocean lateral boundary condition (or mpp link) 28 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 28 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 29 29 30 30 IMPLICIT NONE … … 112 112 ! 113 113 ! ! horizontal fluxes are computed with the QUICKEST + ULTIMATE scheme 114 CALL tra_adv_qck_i( kt, cdtype, p2dt, pU, Kbb, Kmm, pt, kjpt, Krhs ) 115 CALL tra_adv_qck_j( kt, cdtype, p2dt, pV, Kbb, Kmm, pt, kjpt, Krhs ) 114 CALL tra_adv_qck_i( kt, cdtype, p2dt, pU, Kbb, Kmm, pt, kjpt, Krhs ) 115 CALL tra_adv_qck_j( kt, cdtype, p2dt, pV, Kbb, Kmm, pt, kjpt, Krhs ) 116 116 117 117 ! ! vertical fluxes are computed with the 2nd order centered scheme … … 142 142 DO jn = 1, kjpt ! tracer loop 143 143 ! ! =========== 144 zfu(:,:,:) = 0._wp ; zfc(:,:,:) = 0._wp 145 zfd(:,:,:) = 0._wp ; zwx(:,:,:) = 0._wp 144 zfu(:,:,:) = 0._wp ; zfc(:,:,:) = 0._wp 145 zfd(:,:,:) = 0._wp ; zwx(:,:,:) = 0._wp 146 146 ! 147 147 !!gm why not using a SHIFT instruction... … … 151 151 END_3D 152 152 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp ) ! Lateral boundary conditions 153 153 154 154 ! 155 155 ! Horizontal advective fluxes 156 156 ! --------------------------- 157 157 DO_3D( 0, 0, nn_hls-1, 0, 1, jpkm1 ) 158 zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 159 zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji+1,jj,jk) ! FU in the x-direction for T 158 zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 159 zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji+1,jj,jk) ! FU in the x-direction for T 160 160 END_3D 161 161 ! 162 162 DO_3D( 0, 0, nn_hls-1, 0, 1, jpkm1 ) 163 zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 163 zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 164 164 zdx = ( zdir * e1t(ji,jj) + ( 1. - zdir ) * e1t(ji+1,jj) ) * e2u(ji,jj) * e3u(ji,jj,jk,Kmm) 165 165 zwx(ji,jj,jk) = ABS( pU(ji,jj,jk) ) * p2dt / zdx ! (0<zc_cfl<1 : Courant number on x-direction) … … 167 167 zfd(ji,jj,jk) = zdir * pt(ji+1,jj,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji ,jj,jk,jn,Kbb) ! FD in the x-direction for T 168 168 END_3D 169 !--- Lateral boundary conditions 169 !--- Lateral boundary conditions 170 170 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp, zwx(:,:,:), 'T', 1.0_wp ) 171 171 … … 227 227 DO jn = 1, kjpt ! tracer loop 228 228 ! ! =========== 229 zfu(:,:,:) = 0.0 ; zfc(:,:,:) = 0.0 230 zfd(:,:,:) = 0.0 ; zwy(:,:,:) = 0.0 231 ! 232 DO jk = 1, jpkm1 233 ! 229 zfu(:,:,:) = 0.0 ; zfc(:,:,:) = 0.0 230 zfd(:,:,:) = 0.0 ; zwy(:,:,:) = 0.0 231 ! 232 DO jk = 1, jpkm1 233 ! 234 234 !--- Computation of the ustream and downstream value of the tracer and the mask 235 235 DO_2D( nn_hls-1, nn_hls-1, 0, 0 ) … … 241 241 END DO 242 242 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp ) ! Lateral boundary conditions 243 243 244 244 ! 245 245 ! Horizontal advective fluxes … … 247 247 ! 248 248 DO_3D( nn_hls-1, 0, 0, 0, 1, jpkm1 ) 249 zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 250 zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji,jj+1,jk) ! FU in the x-direction for T 249 zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 250 zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji,jj+1,jk) ! FU in the x-direction for T 251 251 END_3D 252 252 ! 253 253 DO_3D( nn_hls-1, 0, 0, 0, 1, jpkm1 ) 254 zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 254 zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) ) ! if pU > 0 : zdir = 1 otherwise zdir = 0 255 255 zdx = ( zdir * e2t(ji,jj) + ( 1. - zdir ) * e2t(ji,jj+1) ) * e1v(ji,jj) * e3v(ji,jj,jk,Kmm) 256 256 zwy(ji,jj,jk) = ABS( pV(ji,jj,jk) ) * p2dt / zdx ! (0<zc_cfl<1 : Courant number on x-direction) … … 259 259 END_3D 260 260 261 !--- Lateral boundary conditions 261 !--- Lateral boundary conditions 262 262 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp, zwy(:,:,:), 'T', 1.0_wp ) 263 263 … … 328 328 IF( ln_isfcav ) THEN ! ice-shelf cavities (top of the ocean) 329 329 DO_2D( 0, 0, 0, 0 ) 330 zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm) ! linear free surface 330 zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm) ! linear free surface 331 331 END_2D 332 332 ELSE ! no ocean cavities (only ocean surface) … … 354 354 !! ** Purpose : Computation of advective flux with Quickest scheme 355 355 !! 356 !! ** Method : 356 !! ** Method : 357 357 !!---------------------------------------------------------------------- 358 358 REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in ) :: pfu ! second upwind point … … 361 361 REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) :: puc ! input as Courant number ; output as flux 362 362 !! 363 INTEGER :: ji, jj, jk ! dummy loop indices 364 REAL(wp) :: zcoef1, zcoef2, zcoef3 ! local scalars 363 INTEGER :: ji, jj, jk ! dummy loop indices 364 REAL(wp) :: zcoef1, zcoef2, zcoef3 ! local scalars 365 365 REAL(wp) :: zc, zcurv, zfho ! - - 366 366 !---------------------------------------------------------------------- … … 372 372 zcoef2 = 0.5 * zc * ( pfd(ji,jj,jk) - pfc(ji,jj,jk) ) 373 373 zcoef3 = ( 1. - ( zc * zc ) ) * r1_6 * zcurv 374 zfho = zcoef1 - zcoef2 - zcoef3 ! phi_f QUICKEST 374 zfho = zcoef1 - zcoef2 - zcoef3 ! phi_f QUICKEST 375 375 ! 376 376 zcoef1 = pfd(ji,jj,jk) - pfu(ji,jj,jk) … … 378 378 zcoef3 = ABS( zcurv ) 379 379 IF( zcoef3 >= zcoef2 ) THEN 380 zfho = pfc(ji,jj,jk) 380 zfho = pfc(ji,jj,jk) 381 381 ELSE 382 382 zcoef3 = pfu(ji,jj,jk) + ( ( pfc(ji,jj,jk) - pfu(ji,jj,jk) ) / MAX( zc, 1.e-9 ) ) ! phi_REF 383 383 IF( zcoef1 >= 0. ) THEN 384 zfho = MAX( pfc(ji,jj,jk), zfho ) 385 zfho = MIN( zfho, MIN( zcoef3, pfd(ji,jj,jk) ) ) 384 zfho = MAX( pfc(ji,jj,jk), zfho ) 385 zfho = MIN( zfho, MIN( zcoef3, pfd(ji,jj,jk) ) ) 386 386 ELSE 387 zfho = MIN( pfc(ji,jj,jk), zfho ) 388 zfho = MAX( zfho, MAX( zcoef3, pfd(ji,jj,jk) ) ) 387 zfho = MIN( pfc(ji,jj,jk), zfho ) 388 zfho = MAX( zfho, MAX( zcoef3, pfd(ji,jj,jk) ) ) 389 389 ENDIF 390 390 ENDIF -
NEMO/trunk/src/OCE/TRA/traadv_ubs.F90
r13982 r14072 10 10 !!---------------------------------------------------------------------- 11 11 !! tra_adv_ubs : update the tracer trend with the horizontal 12 !! advection trends using a third order biaised scheme 12 !! advection trends using a third order biaised scheme 13 13 !!---------------------------------------------------------------------- 14 14 USE oce ! ocean dynamics and active tracers … … 16 16 USE trc_oce ! share passive tracers/Ocean variables 17 17 USE trd_oce ! trends: ocean variables 18 USE traadv_fct ! acces to routine interp_4th_cpt 19 USE trdtra ! trends manager: tracers 18 USE traadv_fct ! acces to routine interp_4th_cpt 19 USE trdtra ! trends manager: tracers 20 20 USE diaptr ! poleward transport diagnostics 21 21 USE diaar5 ! AR5 diagnostics … … 25 25 USE lib_mpp ! massively parallel library 26 26 USE lbclnk ! ocean lateral boundary condition (or mpp link) 27 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 27 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 28 28 29 29 IMPLICIT NONE … … 51 51 !!---------------------------------------------------------------------- 52 52 !! *** ROUTINE tra_adv_ubs *** 53 !! 53 !! 54 54 !! ** Purpose : Compute the now trend due to the advection of tracers 55 55 !! and add it to the general trend of passive tracer equations. … … 60 60 !! For example the i-component of the advective fluxes are given by : 61 61 !! ! e2u e3u un ( mi(Tn) - zltu(i ) ) if un(i) >= 0 62 !! ztu = ! or 62 !! ztu = ! or 63 63 !! ! e2u e3u un ( mi(Tn) - zltu(i+1) ) if un(i) < 0 64 64 !! where zltu is the second derivative of the before temperature field: 65 65 !! zltu = 1/e3t di[ e2u e3u / e1u di[Tb] ] 66 !! This results in a dissipatively dominant (i.e. hyper-diffusive) 67 !! truncation error. The overall performance of the advection scheme 68 !! is similar to that reported in (Farrow and Stevens, 1995). 66 !! This results in a dissipatively dominant (i.e. hyper-diffusive) 67 !! truncation error. The overall performance of the advection scheme 68 !! is similar to that reported in (Farrow and Stevens, 1995). 69 69 !! For stability reasons, the first term of the fluxes which corresponds 70 !! to a second order centered scheme is evaluated using the now velocity 71 !! (centered in time) while the second term which is the diffusive part 72 !! of the scheme, is evaluated using the before velocity (forward in time). 70 !! to a second order centered scheme is evaluated using the now velocity 71 !! (centered in time) while the second term which is the diffusive part 72 !! of the scheme, is evaluated using the before velocity (forward in time). 73 73 !! Note that UBS is not positive. Do not use it on passive tracers. 74 74 !! On the vertical, the advection is evaluated using a FCT scheme, 75 !! as the UBS have been found to be too diffusive. 76 !! kn_ubs_v argument controles whether the FCT is based on 77 !! a 2nd order centrered scheme (kn_ubs_v=2) or on a 4th order compact 75 !! as the UBS have been found to be too diffusive. 76 !! kn_ubs_v argument controles whether the FCT is based on 77 !! a 2nd order centrered scheme (kn_ubs_v=2) or on a 4th order compact 78 78 !! scheme (kn_ubs_v=4). 79 79 !! … … 82 82 !! - poleward advective heat and salt transport (ln_diaptr=T) 83 83 !! 84 !! Reference : Shchepetkin, A. F., J. C. McWilliams, 2005, Ocean Modelling, 9, 347-404. 84 !! Reference : Shchepetkin, A. F., J. C. McWilliams, 2005, Ocean Modelling, 9, 347-404. 85 85 !! Farrow, D.E., Stevens, D.P., 1995, J. Phys. Ocean. 25, 1731�1741. 86 86 !!---------------------------------------------------------------------- … … 125 125 DO jn = 1, kjpt ! tracer loop 126 126 ! ! =========== 127 ! 127 ! 128 128 DO jk = 1, jpkm1 !== horizontal laplacian of before tracer ==! 129 129 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) ! First derivative (masked gradient) … … 138 138 zltv(ji,jj,jk) = ( ztv(ji,jj,jk) - ztv(ji,jj-1,jk) ) * zcoef 139 139 END_2D 140 ! 141 END DO 140 ! 141 END DO 142 142 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_ubs', zltu, 'T', 1.0_wp, zltv, 'T', 1.0_wp ) ! Lateral boundary cond. (unchanged sgn) 143 ! 143 ! 144 144 DO_3D( 1, 0, 1, 0, 1, jpkm1 ) !== Horizontal advective fluxes ==! (UBS) 145 145 zfp_ui = pU(ji,jj,jk) + ABS( pU(ji,jj,jk) ) ! upstream transport (x2) … … 166 166 & * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 167 167 END_2D 168 ! 168 ! 169 169 END DO 170 170 ! … … 177 177 CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, ztv, pV, pt(:,:,:,jn,Kmm) ) 178 178 END IF 179 ! 179 ! 180 180 ! ! "Poleward" heat and salt transports (contribution of upstream fluxes) 181 181 IF( l_ptr ) CALL dia_ptr_hst( jn, 'adv', ztv(:,:,:) ) … … 188 188 SELECT CASE( kn_ubs_v ) ! select the vertical advection scheme 189 189 ! 190 CASE( 2 ) ! 2nd order FCT 191 ! 190 CASE( 2 ) ! 2nd order FCT 191 ! 192 192 IF( l_trd ) THEN 193 193 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) … … 205 205 IF( ln_isfcav ) THEN ! top of the ice-shelf cavities and at the ocean surface 206 206 DO_2D( 1, 1, 1, 1 ) 207 ztw(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb) ! linear free surface 207 ztw(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb) ! linear free surface 208 208 END_2D 209 209 ELSE ! no cavities: only at the ocean surface … … 217 217 ztak = - ( ztw(ji,jj,jk) - ztw(ji,jj,jk+1) ) & 218 218 & * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 219 pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztak 219 pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztak 220 220 zti(ji,jj,jk) = ( pt(ji,jj,jk,jn,Kbb) + p2dt * ( ztak + zltu(ji,jj,jk) ) ) * tmask(ji,jj,jk) 221 221 END_3D … … 266 266 !!--------------------------------------------------------------------- 267 267 !! *** ROUTINE nonosc_z *** 268 !! 269 !! ** Purpose : compute monotonic tracer fluxes from the upstream 270 !! scheme and the before field by a nonoscillatory algorithm 268 !! 269 !! ** Purpose : compute monotonic tracer fluxes from the upstream 270 !! scheme and the before field by a nonoscillatory algorithm 271 271 !! 272 272 !! ** Method : ... ??? -
NEMO/trunk/src/OCE/TRA/traatf.F90
r14045 r14072 26 26 !!---------------------------------------------------------------------- 27 27 USE oce ! ocean dynamics and tracers variables 28 USE dom_oce ! ocean space and time domain variables 28 USE dom_oce ! ocean space and time domain variables 29 29 USE sbc_oce ! surface boundary condition: ocean 30 30 USE sbcrnf ! river runoffs … … 33 33 USE domvvl ! variable volume 34 34 USE trd_oce ! trends: ocean variables 35 USE trdtra ! trends manager: tracers 35 USE trdtra ! trends manager: tracers 36 36 USE traqsr ! penetrative solar radiation (needed for nksr) 37 37 USE phycst ! physical constant … … 70 70 !! *** ROUTINE traatf *** 71 71 !! 72 !! ** Purpose : Apply the boundary condition on the after temperature 72 !! ** Purpose : Apply the boundary condition on the after temperature 73 73 !! and salinity fields and add the Asselin time filter on now fields. 74 !! 75 !! ** Method : At this stage of the computation, ta and sa are the 74 !! 75 !! ** Method : At this stage of the computation, ta and sa are the 76 76 !! after temperature and salinity as the time stepping has 77 77 !! been performed in trazdf_imp or trazdf_exp module. 78 78 !! 79 !! - Apply lateral boundary conditions on (ta,sa) 80 !! at the local domain boundaries through lbc_lnk call, 81 !! at the one-way open boundaries (ln_bdy=T), 79 !! - Apply lateral boundary conditions on (ta,sa) 80 !! at the local domain boundaries through lbc_lnk call, 81 !! at the one-way open boundaries (ln_bdy=T), 82 82 !! at the AGRIF zoom boundaries (lk_agrif=T) 83 83 !! … … 89 89 INTEGER , INTENT(in ) :: kt ! ocean time-step index 90 90 INTEGER , INTENT(in ) :: Kbb, Kmm, Kaa ! time level indices 91 REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts ! active tracers 91 REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts ! active tracers 92 92 !! 93 93 INTEGER :: ji, jj, jk, jn ! dummy loop indices … … 105 105 106 106 ! Update after tracer on domain lateral boundaries 107 ! 107 ! 108 108 #if defined key_agrif 109 109 CALL Agrif_tra ! AGRIF zoom boundaries … … 113 113 ! 114 114 IF( ln_bdy ) CALL bdy_tra( kt, Kbb, pts, Kaa ) ! BDY open boundaries 115 115 116 116 ! trends computation initialisation 117 IF( l_trdtra ) THEN 117 IF( l_trdtra ) THEN 118 118 ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) ) 119 119 ztrdt(:,:,:) = 0._wp 120 120 ztrds(:,:,:) = 0._wp 121 IF( ln_traldf_iso ) THEN ! diagnose the "pure" Kz diffusive trend 121 IF( ln_traldf_iso ) THEN ! diagnose the "pure" Kz diffusive trend 122 122 CALL trd_tra( kt, Kmm, Kaa, 'TRA', jp_tem, jptra_zdfp, ztrdt ) 123 123 CALL trd_tra( kt, Kmm, Kaa, 'TRA', jp_sal, jptra_zdfp, ztrds ) 124 124 ENDIF 125 ! total trend for the non-time-filtered variables. 125 ! total trend for the non-time-filtered variables. 126 126 zfact = 1.0 / rn_Dt 127 127 ! G Nurser 23 Mar 2017. Recalculate trend as Delta(e3t*T)/e3tn; e3tn cancel from pts(Kmm) terms … … 133 133 CALL trd_tra( kt, Kmm, Kaa, 'TRA', jp_sal, jptra_tot, ztrds ) 134 134 IF( ln_linssh ) THEN ! linear sea surface height only 135 ! Store now fields before applying the Asselin filter 135 ! Store now fields before applying the Asselin filter 136 136 ! in order to calculate Asselin filter trend later. 137 ztrdt(:,:,:) = pts(:,:,:,jp_tem,Kmm) 137 ztrdt(:,:,:) = pts(:,:,:,jp_tem,Kmm) 138 138 ztrds(:,:,:) = pts(:,:,:,jp_sal,Kmm) 139 139 ENDIF 140 140 ENDIF 141 141 142 IF( l_1st_euler ) THEN ! Euler time-stepping 142 IF( l_1st_euler ) THEN ! Euler time-stepping 143 143 ! 144 144 IF (l_trdtra .AND. .NOT. ln_linssh ) THEN ! Zero Asselin filter contribution must be explicitly written out since for vvl … … 152 152 ELSE ! Leap-Frog + Asselin filter time stepping 153 153 ! 154 IF( ln_linssh ) THEN ; CALL tra_atf_fix( kt, Kbb, Kmm, Kaa, nit000, 'TRA', pts, jpts ) ! linear free surface 154 IF( ln_linssh ) THEN ; CALL tra_atf_fix( kt, Kbb, Kmm, Kaa, nit000, 'TRA', pts, jpts ) ! linear free surface 155 155 ELSE ; CALL tra_atf_vvl( kt, Kbb, Kmm, Kaa, nit000, rn_Dt, 'TRA', pts, sbc_tsc, sbc_tsc_b, jpts ) ! non-linear free surface 156 156 ENDIF 157 157 ! 158 CALL lbc_lnk_multi( 'traatf', pts(:,:,:,jp_tem,Kmm) , 'T', 1.0_wp, pts(:,:,:,jp_sal,Kmm) , 'T', 1.0_wp ) 159 160 ENDIF 161 ! 162 IF( l_trdtra .AND. ln_linssh ) THEN ! trend of the Asselin filter (tb filtered - tb)/dt 158 CALL lbc_lnk_multi( 'traatf', pts(:,:,:,jp_tem,Kmm) , 'T', 1.0_wp, pts(:,:,:,jp_sal,Kmm) , 'T', 1.0_wp ) 159 160 ENDIF 161 ! 162 IF( l_trdtra .AND. ln_linssh ) THEN ! trend of the Asselin filter (tb filtered - tb)/dt 163 163 DO jk = 1, jpkm1 164 164 ztrdt(:,:,jk) = ( pts(:,:,jk,jp_tem,Kmm) - ztrdt(:,:,jk) ) * r1_Dt … … 184 184 !! 185 185 !! ** Purpose : fixed volume: apply the Asselin time filter to the "now" field 186 !! 186 !! 187 187 !! ** Method : - Apply a Asselin time filter on now fields. 188 188 !! … … 209 209 ! 210 210 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 ) 211 ztn = pt(ji,jj,jk,jn,Kmm) 211 ztn = pt(ji,jj,jk,jn,Kmm) 212 212 ztd = pt(ji,jj,jk,jn,Kaa) - 2._wp * ztn + pt(ji,jj,jk,jn,Kbb) ! time laplacian on tracers 213 213 ! … … 224 224 !! *** ROUTINE tra_atf_vvl *** 225 225 !! 226 !! ** Purpose : Time varying volume: apply the Asselin time filter 227 !! 226 !! ** Purpose : Time varying volume: apply the Asselin time filter 227 !! 228 228 !! ** Method : - Apply a thickness weighted Asselin time filter on now fields. 229 229 !! pt(Kmm) = ( e3t_Kmm*pt(Kmm) + rn_atfp*[ e3t_Kbb*pt(Kbb) - 2 e3t_Kmm*pt(Kmm) + e3t_Kaa*pt(Kaa) ] ) … … 255 255 ENDIF 256 256 ! 257 IF( cdtype == 'TRA' ) THEN 257 IF( cdtype == 'TRA' ) THEN 258 258 ll_traqsr = ln_traqsr ! active tracers case and solar penetration 259 259 ll_rnf = ln_rnf ! active tracers case and river runoffs … … 261 261 ELSE ! passive tracers case 262 262 ll_traqsr = .FALSE. ! NO solar penetration 263 ll_rnf = .FALSE. ! NO river runoffs ???? !!gm BUG ? 264 ll_isf = .FALSE. ! NO ice shelf melting/freezing !!gm BUG ?? 263 ll_rnf = .FALSE. ! NO river runoffs ???? !!gm BUG ? 264 ll_isf = .FALSE. ! NO ice shelf melting/freezing !!gm BUG ?? 265 265 ENDIF 266 266 ! … … 272 272 zfact1 = rn_atfp * p2dt 273 273 zfact2 = zfact1 * r1_rho0 274 DO jn = 1, kjpt 274 DO jn = 1, kjpt 275 275 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 ) 276 276 ze3t_b = e3t(ji,jj,jk,Kbb) … … 289 289 ! 290 290 ! Add asselin correction on scale factors: 291 zscale = tmask(ji,jj,jk) * e3t(ji,jj,jk,Kmm) / ( ht(ji,jj) + 1._wp - ssmask(ji,jj) ) 292 ze3t_f = ze3t_f - zfact2 * zscale * ( emp_b(ji,jj) - emp(ji,jj) ) 293 IF ( ll_rnf ) ze3t_f = ze3t_f + zfact2 * zscale * ( rnf_b(ji,jj) - rnf(ji,jj) ) 291 zscale = tmask(ji,jj,jk) * e3t(ji,jj,jk,Kmm) / ( ht(ji,jj) + 1._wp - ssmask(ji,jj) ) 292 ze3t_f = ze3t_f - zfact2 * zscale * ( emp_b(ji,jj) - emp(ji,jj) ) 293 IF ( ll_rnf ) ze3t_f = ze3t_f + zfact2 * zscale * ( rnf_b(ji,jj) - rnf(ji,jj) ) 294 294 IF ( ll_isf ) THEN 295 295 IF ( ln_isfcav_mlt ) ze3t_f = ze3t_f - zfact2 * zscale * ( fwfisf_cav_b(ji,jj) - fwfisf_cav(ji,jj) ) … … 297 297 ENDIF 298 298 ! 299 IF( jk == mikt(ji,jj) ) THEN ! first level 299 IF( jk == mikt(ji,jj) ) THEN ! first level 300 300 ztc_f = ztc_f - zfact1 * ( psbc_tc(ji,jj,jn) - psbc_tc_b(ji,jj,jn) ) 301 301 ENDIF 302 302 ! 303 303 ! solar penetration (temperature only) 304 IF( ll_traqsr .AND. jn == jp_tem .AND. jk <= nksr ) & 305 & ztc_f = ztc_f - zfact1 * ( qsr_hc(ji,jj,jk) - qsr_hc_b(ji,jj,jk) ) 304 IF( ll_traqsr .AND. jn == jp_tem .AND. jk <= nksr ) & 305 & ztc_f = ztc_f - zfact1 * ( qsr_hc(ji,jj,jk) - qsr_hc_b(ji,jj,jk) ) 306 306 ! 307 307 ! 308 308 IF( ll_rnf .AND. jk <= nk_rnf(ji,jj) ) & 309 & ztc_f = ztc_f - zfact1 * ( rnf_tsc(ji,jj,jn) - rnf_tsc_b(ji,jj,jn) ) & 309 & ztc_f = ztc_f - zfact1 * ( rnf_tsc(ji,jj,jn) - rnf_tsc_b(ji,jj,jn) ) & 310 310 & * e3t(ji,jj,jk,Kmm) / h_rnf(ji,jj) 311 311 … … 321 321 & * e3t(ji,jj,jk,Kmm) / rhisf_tbl_cav(ji,jj) 322 322 END IF 323 ! level partially include in Losch_2008 ice shelf boundary layer 323 ! level partially include in Losch_2008 ice shelf boundary layer 324 324 IF ( jk == misfkb_cav(ji,jj) ) THEN 325 325 ztc_f = ztc_f - zfact1 * ( risf_cav_tsc(ji,jj,jn) - risf_cav_tsc_b(ji,jj,jn) ) & … … 335 335 & * e3t(ji,jj,jk,Kmm) / rhisf_tbl_par(ji,jj) 336 336 END IF 337 ! level partially include in Losch_2008 ice shelf boundary layer 337 ! level partially include in Losch_2008 ice shelf boundary layer 338 338 IF ( jk == misfkb_par(ji,jj) ) THEN 339 339 ztc_f = ztc_f - zfact1 * ( risf_par_tsc(ji,jj,jn) - risf_par_tsc_b(ji,jj,jn) ) & … … 364 364 ! 365 365 END_3D 366 ! 366 ! 367 367 END DO 368 368 ! 369 369 IF( ( l_trdtra .AND. cdtype == 'TRA' ) .OR. ( l_trdtrc .AND. cdtype == 'TRC' ) ) THEN 370 IF( l_trdtra .AND. cdtype == 'TRA' ) THEN 370 IF( l_trdtra .AND. cdtype == 'TRA' ) THEN 371 371 CALL trd_tra( kt, Kmm, Kaa, cdtype, jp_tem, jptra_atf, ztrd_atf(:,:,:,jp_tem) ) 372 372 CALL trd_tra( kt, Kmm, Kaa, cdtype, jp_sal, jptra_atf, ztrd_atf(:,:,:,jp_sal) ) -
NEMO/trunk/src/OCE/TRA/traatf_qco.F90
r14053 r14072 100 100 IF(lwp) WRITE(numout,*) '~~~~~~~' 101 101 ENDIF 102 !!st Update after tracer on domain lateral boundaries as been removed outside 102 !!st Update after tracer on domain lateral boundaries as been removed outside 103 103 104 104 ! trends computation initialisation -
NEMO/trunk/src/OCE/TRA/trabbc.F90
r13982 r14072 12 12 13 13 !!---------------------------------------------------------------------- 14 !! tra_bbc : update the tracer trend at ocean bottom 14 !! tra_bbc : update the tracer trend at ocean bottom 15 15 !! tra_bbc_init : initialization of geothermal heat flux trend 16 16 !!---------------------------------------------------------------------- … … 19 19 USE phycst ! physical constants 20 20 USE trd_oce ! trends: ocean variables 21 USE trdtra ! trends manager: tracers 21 USE trdtra ! trends manager: tracers 22 22 ! 23 23 USE in_out_manager ! I/O manager 24 USE iom ! xIOS 24 USE iom ! xIOS 25 25 USE fldread ! read input fields 26 26 USE lbclnk ! ocean lateral boundary conditions (or mpp link) … … 43 43 44 44 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_qgh ! structure of input qgh (file informations, fields read) 45 45 46 46 !! * Substitutions 47 47 # include "do_loop_substitute.h90" … … 58 58 !! *** ROUTINE tra_bbc *** 59 59 !! 60 !! ** Purpose : Compute the bottom boundary contition on temperature 61 !! associated with geothermal heating and add it to the 60 !! ** Purpose : Compute the bottom boundary contition on temperature 61 !! associated with geothermal heating and add it to the 62 62 !! general trend of temperature equations. 63 63 !! 64 !! ** Method : The geothermal heat flux set to its constant value of 64 !! ** Method : The geothermal heat flux set to its constant value of 65 65 !! 86.4 mW/m2 (Stein and Stein 1992, Huang 1999). 66 66 !! The temperature trend associated to this heat flux through the … … 135 135 CHARACTER(len=256) :: cn_dir ! Root directory for location of ssr files 136 136 !! 137 NAMELIST/nambbc/ln_trabbc, nn_geoflx, rn_geoflx_cst, sn_qgh, cn_dir 137 NAMELIST/nambbc/ln_trabbc, nn_geoflx, rn_geoflx_cst, sn_qgh, cn_dir 138 138 !!---------------------------------------------------------------------- 139 139 ! -
NEMO/trunk/src/OCE/TRA/trabbl.F90
r13982 r14072 31 31 USE trdtra ! trends: active tracers 32 32 ! 33 USE iom ! IOM library 33 USE iom ! IOM library 34 34 USE in_out_manager ! I/O manager 35 35 USE lbclnk ! ocean lateral boundary conditions 36 36 USE prtctl ! Print control 37 37 USE timing ! Timing 38 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 38 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 39 39 40 40 IMPLICIT NONE … … 200 200 zptb(ji,jj) = pt(ji,jj,ik,jn) ! bottom before T and S 201 201 END_2D 202 ! 202 ! 203 203 DO_2D( 0, 0, 0, 0 ) ! Compute the trend 204 204 ik = mbkt(ji,jj) ! bottom T-level index … … 399 399 za = zab(ji+1,jj,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at u-point 400 400 zb = zab(ji+1,jj,jp_sal) + zab(ji,jj,jp_sal) 401 ! ! 2*masked bottom density gradient 401 ! ! 2*masked bottom density gradient 402 402 zgdrho = ( za * ( zts(ji+1,jj,jp_tem) - zts(ji,jj,jp_tem) ) & 403 403 - zb * ( zts(ji+1,jj,jp_sal) - zts(ji,jj,jp_sal) ) ) * umask(ji,jj,1) … … 523 523 END_2D 524 524 ! converte into REAL to use lbc_lnk ; impose a min value of 1 as a zero can be set in lbclnk 525 zmbku(:,:) = REAL( mbku_d(:,:), wp ) ; zmbkv(:,:) = REAL( mbkv_d(:,:), wp ) 526 CALL lbc_lnk_multi( 'trabbl', zmbku,'U',1.0_wp, zmbkv,'V',1.0_wp) 525 zmbku(:,:) = REAL( mbku_d(:,:), wp ) ; zmbkv(:,:) = REAL( mbkv_d(:,:), wp ) 526 CALL lbc_lnk_multi( 'trabbl', zmbku,'U',1.0_wp, zmbkv,'V',1.0_wp) 527 527 mbku_d(:,:) = MAX( INT( zmbku(:,:) ), 1 ) ; mbkv_d(:,:) = MAX( NINT( zmbkv(:,:) ), 1 ) 528 528 ! -
NEMO/trunk/src/OCE/TRA/tradmp.F90
r13982 r14072 11 11 !! NEMO 1.0 ! 2002-08 (G. Madec, E. Durand) free form + modules 12 12 !! 3.2 ! 2009-08 (G. Madec, C. Talandier) DOCTOR norm for namelist parameter 13 !! 3.3 ! 2010-06 (C. Ethe, G. Madec) merge TRA-TRC 13 !! 3.3 ! 2010-06 (C. Ethe, G. Madec) merge TRA-TRC 14 14 !! 3.4 ! 2011-04 (G. Madec, C. Ethe) Merge of dtatem and dtasal + suppression of CPP keys 15 15 !! 3.6 ! 2015-06 (T. Graham) read restoring coefficient in a file … … 26 26 USE c1d ! 1D vertical configuration 27 27 USE trd_oce ! trends: ocean variables 28 USE trdtra ! trends manager: tracers 28 USE trdtra ! trends manager: tracers 29 29 USE zdf_oce ! ocean: vertical physics 30 30 USE phycst ! physical constants … … 55 55 !!---------------------------------------------------------------------- 56 56 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 57 !! $Id$ 57 !! $Id$ 58 58 !! Software governed by the CeCILL license (see ./LICENSE) 59 59 !!---------------------------------------------------------------------- … … 75 75 !!---------------------------------------------------------------------- 76 76 !! *** ROUTINE tra_dmp *** 77 !! 77 !! 78 78 !! ** Purpose : Compute the tracer trend due to a newtonian damping 79 79 !! of the tracer field towards given data field and add it to the 80 80 !! general tracer trends. 81 81 !! 82 !! ** Method : Newtonian damping towards t_dta and s_dta computed 82 !! ** Method : Newtonian damping towards t_dta and s_dta computed 83 83 !! and add to the general tracer trends: 84 84 !! ta = ta + resto * (t_dta - tb) … … 158 158 !!---------------------------------------------------------------------- 159 159 !! *** ROUTINE tra_dmp_init *** 160 !! 161 !! ** Purpose : Initialization for the newtonian damping 160 !! 161 !! ** Purpose : Initialization for the newtonian damping 162 162 !! 163 163 !! ** Method : read the namtra_dmp namelist and check the parameters 164 164 !!---------------------------------------------------------------------- 165 INTEGER :: ios, imask ! local integers 165 INTEGER :: ios, imask ! local integers 166 166 ! 167 167 NAMELIST/namtra_dmp/ ln_tradmp, nn_zdmp, cn_resto -
NEMO/trunk/src/OCE/TRA/traisf.F90
r13982 r14072 35 35 !!---------------------------------------------------------------------- 36 36 !! *** ROUTINE tra_isf *** 37 !! 37 !! 38 38 !! ** Purpose : Compute the temperature trend due to the ice shelf melting (qhoce + qhc) 39 39 !! … … 65 65 ! 66 66 ! Dynamical stability at start up after change in under ice shelf cavity geometry is achieve by correcting the divergence. 67 ! This is achieved by applying a volume flux in order to keep the horizontal divergence after remapping 67 ! This is achieved by applying a volume flux in order to keep the horizontal divergence after remapping 68 68 ! the same as at the end of the latest time step. So correction need to be apply at nit000 (euler time step) and 69 69 ! half of it at nit000+1 (leap frog time step). … … 95 95 !! *** Purpose : Compute the temperature trend due to the ice shelf melting (qhoce + qhc) for cav or par case 96 96 !! 97 !! *** Action :: Update pts(:,:,:,:,Krhs) with the surface boundary condition trend 97 !! *** Action :: Update pts(:,:,:,:,Krhs) with the surface boundary condition trend 98 98 !! 99 99 !!---------------------------------------------------------------------- … … 104 104 REAL(wp), DIMENSION(jpi,jpj,jpts), INTENT(in ) :: ptsc , ptsc_b 105 105 !!---------------------------------------------------------------------- 106 INTEGER :: ji,jj,jk ! loop index 106 INTEGER :: ji,jj,jk ! loop index 107 107 INTEGER :: ikt, ikb ! top and bottom level of the tbl 108 108 REAL(wp), DIMENSION(A2D(nn_hls)) :: ztc ! total ice shelf tracer trend … … 125 125 END DO 126 126 ! 127 ! level partially include in ice shelf boundary layer 127 ! level partially include in ice shelf boundary layer 128 128 pts(ji,jj,ikb,jp_tem) = pts(ji,jj,ikb,jp_tem) + ztc(ji,jj) * pfrac(ji,jj) 129 129 ! … … 136 136 !! *** ROUTINE tra_isf_cpl *** 137 137 !! 138 !! *** Action :: Update pts(:,:,:,:,Krhs) with the ice shelf coupling trend 138 !! *** Action :: Update pts(:,:,:,:,Krhs) with the ice shelf coupling trend 139 139 !! 140 140 !!---------------------------------------------------------------------- -
NEMO/trunk/src/OCE/TRA/traldf.F90
r13982 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE traldf *** 4 !! Ocean Active tracers : lateral diffusive trends 4 !! Ocean Active tracers : lateral diffusive trends 5 5 !!===================================================================== 6 6 !! History : 9.0 ! 2005-11 (G. Madec) Original code 7 !! NEMO 3.0 ! 2008-01 (C. Ethe, G. Madec) merge TRC-TRA 7 !! NEMO 3.0 ! 2008-01 (C. Ethe, G. Madec) merge TRC-TRA 8 8 !! 3.7 ! 2013-12 (G. Madec) remove the optional computation from T & S anomaly profiles and traldf_bilapg 9 9 !! - ! 2013-12 (F. Lemarie, G. Madec) triad operator (Griffies) + Method of Stabilizing Correction … … 37 37 PRIVATE 38 38 39 PUBLIC tra_ldf ! called by step.F90 40 PUBLIC tra_ldf_init ! called by nemogcm.F90 39 PUBLIC tra_ldf ! called by step.F90 40 PUBLIC tra_ldf_init ! called by nemogcm.F90 41 41 42 42 !!---------------------------------------------------------------------- 43 43 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 44 !! $Id$ 44 !! $Id$ 45 45 !! Software governed by the CeCILL license (see ./LICENSE) 46 46 !!---------------------------------------------------------------------- … … 50 50 !!---------------------------------------------------------------------- 51 51 !! *** ROUTINE tra_ldf *** 52 !! 52 !! 53 53 !! ** Purpose : compute the lateral ocean tracer physics. 54 54 !!---------------------------------------------------------------------- … … 120 120 !!---------------------------------------------------------------------- 121 121 !! *** ROUTINE tra_ldf_init *** 122 !! 122 !! 123 123 !! ** Purpose : Choice of the operator for the lateral tracer diffusion 124 124 !! 125 125 !! ** Method : set nldf_tra from the namtra_ldf logicals 126 126 !!---------------------------------------------------------------------- 127 INTEGER :: ioptio, ierr ! temporary integers 127 INTEGER :: ioptio, ierr ! temporary integers 128 128 !!---------------------------------------------------------------------- 129 129 ! -
NEMO/trunk/src/OCE/TRA/traldf_iso.F90
r13982 r14072 15 15 !!---------------------------------------------------------------------- 16 16 !! tra_ldf_iso : update the tracer trend with the horizontal component of a iso-neutral laplacian operator 17 !! and with the vertical part of the isopycnal or geopotential s-coord. operator 17 !! and with the vertical part of the isopycnal or geopotential s-coord. operator 18 18 !!---------------------------------------------------------------------- 19 19 USE oce ! ocean dynamics and active tracers … … 79 79 !! *** ROUTINE tra_ldf_iso *** 80 80 !! 81 !! ** Purpose : Compute the before horizontal tracer (t & s) diffusive 82 !! trend for a laplacian tensor (ezxcept the dz[ dz[.] ] term) and 81 !! ** Purpose : Compute the before horizontal tracer (t & s) diffusive 82 !! trend for a laplacian tensor (ezxcept the dz[ dz[.] ] term) and 83 83 !! add it to the general trend of tracer equation. 84 84 !! 85 !! ** Method : The horizontal component of the lateral diffusive trends 85 !! ** Method : The horizontal component of the lateral diffusive trends 86 86 !! is provided by a 2nd order operator rotated along neural or geopo- 87 87 !! tential surfaces to which an eddy induced advection can be added … … 94 94 !! 95 95 !! 2nd part : horizontal fluxes of the lateral mixing operator 96 !! ======== 96 !! ======== 97 97 !! zftu = pahu e2u*e3u/e1u di[ tb ] 98 98 !! - pahu e2u*uslp dk[ mi(mk(tb)) ] … … 165 165 ELSE ; zsign = -1._wp 166 166 ENDIF 167 167 168 168 !!---------------------------------------------------------------------- 169 169 !! 0 - calculate ah_wslp2 and akz … … 223 223 DO jn = 1, kjpt ! tracer loop 224 224 ! ! =========== 225 ! 226 !!---------------------------------------------------------------------- 227 !! I - masked horizontal derivative 225 ! 226 !!---------------------------------------------------------------------- 227 !! I - masked horizontal derivative 228 228 !!---------------------------------------------------------------------- 229 229 !!gm : bug.... why (x,:,:)? (1,jpj,:) and (jpi,1,:) should be sufficient.... … … 232 232 !!end 233 233 234 ! Horizontal tracer gradient 234 ! Horizontal tracer gradient 235 235 DO_3D( 1, 0, 1, 0, 1, jpkm1 ) 236 236 zdit(ji,jj,jk) = ( pt(ji+1,jj ,jk,jn) - pt(ji,jj,jk,jn) ) * umask(ji,jj,jk) … … 239 239 IF( ln_zps ) THEN ! botton and surface ocean correction of the horizontal gradient 240 240 DO_2D( 1, 0, 1, 0 ) ! bottom correction (partial bottom cell) 241 zdit(ji,jj,mbku(ji,jj)) = pgu(ji,jj,jn) 241 zdit(ji,jj,mbku(ji,jj)) = pgu(ji,jj,jn) 242 242 zdjt(ji,jj,mbkv(ji,jj)) = pgv(ji,jj,jn) 243 243 END_2D 244 244 IF( ln_isfcav ) THEN ! first wet level beneath a cavity 245 245 DO_2D( 1, 0, 1, 0 ) 246 IF( miku(ji,jj) > 1 ) zdit(ji,jj,miku(ji,jj)) = pgui(ji,jj,jn) 247 IF( mikv(ji,jj) > 1 ) zdjt(ji,jj,mikv(ji,jj)) = pgvi(ji,jj,jn) 246 IF( miku(ji,jj) > 1 ) zdit(ji,jj,miku(ji,jj)) = pgui(ji,jj,jn) 247 IF( mikv(ji,jj) > 1 ) zdjt(ji,jj,mikv(ji,jj)) = pgvi(ji,jj,jn) 248 248 END_2D 249 249 ENDIF … … 283 283 zftv(ji,jj,jk) = ( zabe2 * zdjt(ji,jj,jk) & 284 284 & + zcof2 * ( zdkt (ji,jj+1) + zdk1t(ji,jj) & 285 & + zdk1t(ji,jj+1) + zdkt (ji,jj) ) ) * vmask(ji,jj,jk) 285 & + zdk1t(ji,jj+1) + zdkt (ji,jj) ) ) * vmask(ji,jj,jk) 286 286 END_2D 287 287 ! … … 291 291 & * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 292 292 END_2D 293 END DO ! End of slab 293 END DO ! End of slab 294 294 295 295 !!---------------------------------------------------------------------- … … 301 301 ! ! Surface and bottom vertical fluxes set to zero 302 302 ztfw(:,:, 1 ) = 0._wp ; ztfw(:,:,jpk) = 0._wp 303 303 304 304 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) ! interior (2=<jk=<jpk-1) 305 305 ! … … 330 330 END_3D 331 331 ! 332 ELSE ! bilaplacian 332 ELSE ! bilaplacian 333 333 SELECT CASE( kpass ) 334 334 CASE( 1 ) ! 1st pass : eddy coef = ah_wslp2 … … 346 346 END SELECT 347 347 ENDIF 348 ! 348 ! 349 349 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) !== Divergence of vertical fluxes added to pta ==! 350 350 pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn) + zsign * ( ztfw (ji,jj,jk) - ztfw(ji,jj,jk+1) ) * r1_e1e2t(ji,jj) & -
NEMO/trunk/src/OCE/TRA/traldf_lap_blp.F90
r13982 r14072 4 4 !! Ocean tracers: lateral diffusivity trend (laplacian and bilaplacian) 5 5 !!============================================================================== 6 !! History : 3.7 ! 2014-01 (G. Madec, S. Masson) Original code, re-entrant laplacian 6 !! History : 3.7 ! 2014-01 (G. Madec, S. Masson) Original code, re-entrant laplacian 7 7 !!---------------------------------------------------------------------- 8 8 … … 74 74 !!---------------------------------------------------------------------- 75 75 !! *** ROUTINE tra_ldf_lap *** 76 !! 77 !! ** Purpose : Compute the before horizontal tracer (t & s) diffusive 76 !! 77 !! ** Purpose : Compute the before horizontal tracer (t & s) diffusive 78 78 !! trend and add it to the general trend of tracer equation. 79 79 !! 80 80 !! ** Method : Second order diffusive operator evaluated using before 81 !! fields (forward time scheme). The horizontal diffusive trends of 81 !! fields (forward time scheme). The horizontal diffusive trends of 82 82 !! the tracer is given by: 83 83 !! difft = 1/(e1e2t*e3t) { di-1[ pahu e2u*e3u/e1u di(tb) ] … … 86 86 !! pt_rhs = pt_rhs + difft 87 87 !! 88 !! ** Action : - Update pt_rhs arrays with the before iso-level 88 !! ** Action : - Update pt_rhs arrays with the before iso-level 89 89 !! harmonic mixing trend. 90 90 !!---------------------------------------------------------------------- … … 139 139 ! ! =========== ! 140 140 DO jn = 1, kjpt ! tracer loop ! 141 ! ! =========== ! 142 ! 141 ! ! =========== ! 142 ! 143 143 DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 ) !== First derivative (gradient) ==! 144 144 ztu(ji,jj,jk) = zaheeu(ji,jj,jk) * ( pt(ji+1,jj ,jk,jn) - pt(ji,jj,jk,jn) ) … … 152 152 IF( ln_isfcav ) THEN ! top in ocean cavities only 153 153 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 154 IF( miku(ji,jj) > 1 ) ztu(ji,jj,miku(ji,jj)) = zaheeu(ji,jj,miku(ji,jj)) * pgui(ji,jj,jn) 155 IF( mikv(ji,jj) > 1 ) ztv(ji,jj,mikv(ji,jj)) = zaheev(ji,jj,mikv(ji,jj)) * pgvi(ji,jj,jn) 154 IF( miku(ji,jj) > 1 ) ztu(ji,jj,miku(ji,jj)) = zaheeu(ji,jj,miku(ji,jj)) * pgui(ji,jj,jn) 155 IF( mikv(ji,jj) > 1 ) ztv(ji,jj,mikv(ji,jj)) = zaheev(ji,jj,mikv(ji,jj)) * pgvi(ji,jj,jn) 156 156 END_2D 157 157 ENDIF … … 177 177 ! 178 178 END SUBROUTINE tra_ldf_lap_t 179 179 180 180 181 181 SUBROUTINE tra_ldf_blp( kt, Kmm, kit000, cdtype, pahu, pahv , & … … 184 184 !!---------------------------------------------------------------------- 185 185 !! *** ROUTINE tra_ldf_blp *** 186 !! 187 !! ** Purpose : Compute the before lateral tracer diffusive 186 !! 187 !! ** Purpose : Compute the before lateral tracer diffusive 188 188 !! trend and add it to the general trend of tracer equation. 189 189 !! … … 238 238 ! NOTE: [tiling-comms-merge] Needed for both nn_hls as tra_ldf_iso and tra_ldf_triad have not yet been adjusted to work with nn_hls = 2. In the zps case the lbc_lnk in zps_hde handles this, but in the zco case zlap always needs this lbc_lnk. I did try adjusting the bounds in tra_ldf_iso and tra_ldf_triad so this lbc_lnk was only needed for nn_hls = 1, but this was not correct and I did not have time to figure out why 239 239 CALL lbc_lnk( 'traldf_lap_blp', zlap(:,:,:,:) , 'T', 1.0_wp ) ! Lateral boundary conditions (unchanged sign) 240 ! ! Partial top/bottom cell: GRADh( zlap ) 240 ! ! Partial top/bottom cell: GRADh( zlap ) 241 241 IF( ln_isfcav .AND. ln_zps ) THEN ; CALL zps_hde_isf( kt, Kmm, kjpt, zlap, zglu, zglv, zgui, zgvi ) ! both top & bottom 242 ELSEIF( ln_zps ) THEN ; CALL zps_hde ( kt, Kmm, kjpt, zlap, zglu, zglv ) ! only bottom 242 ELSEIF( ln_zps ) THEN ; CALL zps_hde ( kt, Kmm, kjpt, zlap, zglu, zglv ) ! only bottom 243 243 ENDIF 244 244 ! -
NEMO/trunk/src/OCE/TRA/traldf_triad.F90
r13982 r14072 145 145 ELSE ; zsign = -1._wp 146 146 ENDIF 147 ! 147 ! 148 148 !!---------------------------------------------------------------------- 149 149 !! 0 - calculate ah_wslp2, akz, and optionally zpsi_uw, zpsi_vw … … 175 175 END DO 176 176 ! 177 DO jp = 0, 1 ! j-k triads 177 DO jp = 0, 1 ! j-k triads 178 178 DO kp = 0, 1 179 179 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) … … 264 264 IF( ln_isfcav ) THEN ! top level (ocean cavities only) 265 265 DO_2D( 1, 0, 1, 0 ) 266 IF( miku(ji,jj) > 1 ) zdit(ji,jj,miku(ji,jj) ) = pgui(ji,jj,jn) 267 IF( mikv(ji,jj) > 1 ) zdjt(ji,jj,mikv(ji,jj) ) = pgvi(ji,jj,jn) 266 IF( miku(ji,jj) > 1 ) zdit(ji,jj,miku(ji,jj) ) = pgui(ji,jj,jn) 267 IF( mikv(ji,jj) > 1 ) zdjt(ji,jj,mikv(ji,jj) ) = pgvi(ji,jj,jn) 268 268 END_2D 269 269 ENDIF … … 392 392 & * ( pt(ji,jj,jk-1,jn) - pt(ji,jj,jk,jn) ) 393 393 END_3D 394 ELSE ! bilaplacian 394 ELSE ! bilaplacian 395 395 SELECT CASE( kpass ) 396 396 CASE( 1 ) ! 1st pass : eddy coef = ah_wslp2 … … 405 405 & + akz (ji,jj,jk) * ( pt2(ji,jj,jk-1,jn) - pt2(ji,jj,jk,jn) ) ) 406 406 END_3D 407 END SELECT 407 END SELECT 408 408 ENDIF 409 409 ! -
NEMO/trunk/src/OCE/TRA/tranpc.F90
r13982 r14072 97 97 IF( l_LB_debug ) THEN 98 98 ! Location of 1 known convection site to follow what's happening in the water column 99 ilc1 = 45 ; jlc1 = 3 ; ! ORCA2 4x4, Antarctic coast, more than 2 unstable portions in the water column... 99 ilc1 = 45 ; jlc1 = 3 ; ! ORCA2 4x4, Antarctic coast, more than 2 unstable portions in the water column... 100 100 nncpu = 1 ; ! the CPU domain contains the convection spot 101 klc1 = mbkt(ilc1,jlc1) ! bottom of the ocean for debug point... 101 klc1 = mbkt(ilc1,jlc1) ! bottom of the ocean for debug point... 102 102 ENDIF 103 103 ! … … 116 116 ! 117 117 IF( tmask(ji,jj,2) == 1 ) THEN ! At least 2 ocean points 118 ! ! consider one ocean column 118 ! ! consider one ocean column 119 119 zvts(:,jp_tem) = pts(ji,jj,:,jp_tem,Kaa) ! temperature 120 120 zvts(:,jp_sal) = pts(ji,jj,:,jp_sal,Kaa) ! salinity 121 121 ! 122 zvab(:,jp_tem) = zab(ji,jj,:,jp_tem) ! Alpha 123 zvab(:,jp_sal) = zab(ji,jj,:,jp_sal) ! Beta 124 zvn2(:) = zn2(ji,jj,:) ! N^2 122 zvab(:,jp_tem) = zab(ji,jj,:,jp_tem) ! Alpha 123 zvab(:,jp_sal) = zab(ji,jj,:,jp_sal) ! Beta 124 zvn2(:) = zn2(ji,jj,:) ! N^2 125 125 ! 126 126 IF( l_LB_debug ) THEN !LB debug: … … 128 128 IF( ( ji == ilc1 ).AND.( jj == jlc1 ) ) lp_monitor_point = .TRUE. 129 129 ! writing only if on CPU domain where conv region is: 130 lp_monitor_point = (narea == nncpu).AND.lp_monitor_point 130 lp_monitor_point = (narea == nncpu).AND.lp_monitor_point 131 131 ENDIF !LB debug end 132 132 ! … … 140 140 ! 141 141 jiter = jiter + 1 142 ! 142 ! 143 143 IF( jiter >= 400 ) EXIT 144 144 ! … … 155 155 ilayer = ilayer + 1 ! yet another instable portion of the water column found.... 156 156 ! 157 IF( lp_monitor_point ) THEN 157 IF( lp_monitor_point ) THEN 158 158 WRITE(numout,*) 159 159 IF( ilayer == 1 .AND. jiter == 1 ) THEN ! first time a column is spoted with an instability … … 195 195 zsum_beta = 0._wp 196 196 zsum_z = 0._wp 197 197 198 198 DO jk = ikup, ikbot ! Inside the instable (and overlying neutral) portion of the column 199 199 ! … … 204 204 zsum_beta = zsum_beta + zvab(jk,jp_sal)*zdz 205 205 zsum_z = zsum_z + zdz 206 ! 206 ! 207 207 IF( jk == ikbot ) EXIT ! avoid array-index overshoot in case ikbot = jpk, cause we're calling jk+1 next line 208 208 !! EXIT when we have reached the last layer that is instable (N2<0) or neutral (N2=0): 209 209 IF( zvn2(jk+1) > zn2_zero ) EXIT 210 210 END DO 211 211 212 212 ikdown = jk ! for the current unstable layer, ikdown is the deepest point with a negative or neutral N2 213 213 IF( ikup == ikdown ) CALL ctl_stop( 'tra_npc : PROBLEM #2') … … 235 235 zvab(jk,jp_sal) = zbeta 236 236 END DO 237 238 237 238 239 239 !! Updating N2 in the relvant portion of the water column 240 240 !! Temperature, Salinity, Alpha and Beta have been homogenized in the unstable portion 241 241 !! => Need to re-compute N2! will use Alpha and Beta! 242 242 243 243 ikup = MAX(2,ikup) ! ikup can never be 1 ! 244 244 ik_low = MIN(ikdown+1,ikbot) ! we must go 1 point deeper than ikdown! 245 245 246 246 DO jk = ikup, ik_low ! we must go 1 point deeper than ikdown! 247 247 … … 263 263 264 264 END DO 265 265 266 266 ikp = MIN(ikdown+1,ikbot) 267 267 268 268 269 269 ENDIF !IF( zvn2(ikp) < 0. ) … … 275 275 276 276 IF( ikp /= ikbot ) CALL ctl_stop( 'tra_npc : PROBLEM #3') 277 277 278 278 ! ******* At this stage ikp == ikbot ! ******* 279 279 280 280 IF( ilayer > 0 ) THEN !! least an unstable layer has been found 281 281 ! -
NEMO/trunk/src/OCE/TRA/traqsr.F90
r14053 r14072 9 9 !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module 10 10 !! - ! 2005-11 (G. Madec) zco, zps, sco coordinate 11 !! 3.2 ! 2009-04 (G. Madec & NEMO team) 12 !! 3.6 ! 2012-05 (C. Rousset) store attenuation coef for use in ice model 11 !! 3.2 ! 2009-04 (G. Madec & NEMO team) 12 !! 3.6 ! 2012-05 (C. Rousset) store attenuation coef for use in ice model 13 13 !! 3.6 ! 2015-12 (O. Aumont, J. Jouanno, C. Ethe) use vertical profile of chlorophyll 14 !! 3.7 ! 2015-11 (G. Madec, A. Coward) remove optimisation for fix volume 14 !! 3.7 ! 2015-11 (G. Madec, A. Coward) remove optimisation for fix volume 15 15 !!---------------------------------------------------------------------- 16 16 17 17 !!---------------------------------------------------------------------- 18 !! tra_qsr : temperature trend due to the penetration of solar radiation 19 !! tra_qsr_init : initialization of the qsr penetration 18 !! tra_qsr : temperature trend due to the penetration of solar radiation 19 !! tra_qsr_init : initialization of the qsr penetration 20 20 !!---------------------------------------------------------------------- 21 21 USE oce ! ocean dynamics and active tracers … … 45 45 ! !!* Namelist namtra_qsr: penetrative solar radiation 46 46 LOGICAL , PUBLIC :: ln_traqsr !: light absorption (qsr) flag 47 LOGICAL , PUBLIC :: ln_qsr_rgb !: Red-Green-Blue light absorption flag 47 LOGICAL , PUBLIC :: ln_qsr_rgb !: Red-Green-Blue light absorption flag 48 48 LOGICAL , PUBLIC :: ln_qsr_2bd !: 2 band light absorption flag 49 49 LOGICAL , PUBLIC :: ln_qsr_bio !: bio-model light absorption flag … … 54 54 ! 55 55 INTEGER , PUBLIC :: nksr !: levels below which the light cannot penetrate (depth larger than 391 m) 56 56 57 57 INTEGER, PARAMETER :: np_RGB = 1 ! R-G-B light penetration with constant Chlorophyll 58 58 INTEGER, PARAMETER :: np_RGBc = 2 ! R-G-B light penetration with Chlorophyll data … … 88 88 !! Considering the 2 wavebands case: 89 89 !! I(k) = Qsr*( rn_abs*EXP(z(k)/rn_si0) + (1.-rn_abs)*EXP(z(k)/rn_si1) ) 90 !! The temperature trend associated with the solar radiation penetration 90 !! The temperature trend associated with the solar radiation penetration 91 91 !! is given by : zta = 1/e3t dk[ I ] / (rho0*Cp) 92 92 !! At the bottom, boudary condition for the radiation is no flux : 93 93 !! all heat which has not been absorbed in the above levels is put 94 94 !! in the last ocean level. 95 !! The computation is only done down to the level where 96 !! I(k) < 1.e-15 W/m2 (i.e. over the top nksr levels) . 95 !! The computation is only done down to the level where 96 !! I(k) < 1.e-15 W/m2 (i.e. over the top nksr levels) . 97 97 !! 98 98 !! ** Action : - update ta with the penetrative solar radiation trend … … 193 193 DO_2D( isj, iej, isi, iei ) 194 194 ! zlogc = log(zchl) 195 zlogc = LOG ( MIN( 10. , MAX( 0.03, sf_chl(1)%fnow(ji,jj,1) ) ) ) 195 zlogc = LOG ( MIN( 10. , MAX( 0.03, sf_chl(1)%fnow(ji,jj,1) ) ) ) 196 196 ! zc1 : log(zCze) = log (1.12 * zchl**0.803) 197 zc1 = 0.113328685307 + 0.803 * zlogc 197 zc1 = 0.113328685307 + 0.803 * zlogc 198 198 ! zc2 : log(zCtot) = log(40.6 * zchl**0.459) 199 zc2 = 3.703768066608 + 0.459 * zlogc 199 zc2 = 3.703768066608 + 0.459 * zlogc 200 200 ! zc3 : log(zze) = log(568.2 * zCtot**(-0.746)) 201 zc3 = 6.34247346942 - 0.746 * zc2 201 zc3 = 6.34247346942 - 0.746 * zc2 202 202 ! IF( log(zze) > log(102.) ) log(zze) = log(200.0 * zCtot**(-0.293)) 203 IF( zc3 > 4.62497281328 ) zc3 = 5.298317366548 - 0.293 * zc2 204 ! 203 IF( zc3 > 4.62497281328 ) zc3 = 5.298317366548 - 0.293 * zc2 204 ! 205 205 ze0(ji,jj) = zlogc ! ze0 = log(zchl) 206 206 ze1(ji,jj) = EXP( zc1 ) ! ze1 = zCze … … 208 208 ze3(ji,jj) = EXP( - zc3 ) ! ze3 = 1/zze 209 209 END_2D 210 210 211 211 ! 212 212 DO_3D( isj, iej, isi, iei, 1, nksr + 1 ) … … 230 230 ELSE !* constant chlorophyll 231 231 zchl = 0.05 232 ! NB. make sure constant value is such that: 232 ! NB. make sure constant value is such that: 233 233 zchl = MIN( 10. , MAX( 0.03, zchl ) ) 234 234 ! Convert chlorophyll value to attenuation coefficient look-up table index … … 245 245 ze2(ji,jj) = zcoef * qsr(ji,jj) 246 246 ze3(ji,jj) = zcoef * qsr(ji,jj) 247 ! store the surface SW radiation; re-use the surface ztmp3d array 247 ! store the surface SW radiation; re-use the surface ztmp3d array 248 248 ! since the surface attenuation coefficient is not used 249 249 ztmp3d(ji,jj,1) = qsr(ji,jj) … … 269 269 END_3D 270 270 ! 271 DEALLOCATE( ze0 , ze1 , ze2 , ze3 , ztmp3d ) 271 DEALLOCATE( ze0 , ze1 , ze2 , ze3 , ztmp3d ) 272 272 ! 273 273 CASE( np_2BD ) !== 2-bands fluxes ==! … … 278 278 zc0 = zz0 * EXP( -gdepw(ji,jj,jk ,Kmm)*xsi0r ) + zz1 * EXP( -gdepw(ji,jj,jk ,Kmm)*xsi1r ) 279 279 zc1 = zz0 * EXP( -gdepw(ji,jj,jk+1,Kmm)*xsi0r ) + zz1 * EXP( -gdepw(ji,jj,jk+1,Kmm)*xsi1r ) 280 qsr_hc(ji,jj,jk) = qsr(ji,jj) * ( zc0 * wmask(ji,jj,jk) - zc1 * wmask(ji,jj,jk+1) ) 280 qsr_hc(ji,jj,jk) = qsr(ji,jj) * ( zc0 * wmask(ji,jj,jk) - zc1 * wmask(ji,jj,jk+1) ) 281 281 END_3D 282 282 ! … … 341 341 !! from two length scale of penetration (rn_si0,rn_si1) and a ratio 342 342 !! (rn_abs). These parameters are read in the namtra_qsr namelist. The 343 !! default values correspond to clear water (type I in Jerlov' 343 !! default values correspond to clear water (type I in Jerlov' 344 344 !! (1968) classification. 345 345 !! called by tra_qsr at the first timestep (nit000) … … 391 391 & ' 2 bands, 3 RGB bands or bio-model light penetration' ) 392 392 ! 393 IF( ln_qsr_rgb .AND. nn_chldta == 0 ) nqsr = np_RGB 393 IF( ln_qsr_rgb .AND. nn_chldta == 0 ) nqsr = np_RGB 394 394 IF( ln_qsr_rgb .AND. nn_chldta == 1 ) nqsr = np_RGBc 395 395 IF( ln_qsr_2bd ) nqsr = np_2BD … … 401 401 ! 402 402 SELECT CASE( nqsr ) 403 ! 403 ! 404 404 CASE( np_RGB , np_RGBc ) !== Red-Green-Blue light penetration ==! 405 ! 405 ! 406 406 IF(lwp) WRITE(numout,*) ' ==>>> R-G-B light penetration ' 407 407 ! 408 408 CALL trc_oce_rgb( rkrgb ) ! tabulated attenuation coef. 409 ! 409 ! 410 410 nksr = trc_oce_ext_lev( r_si2, 33._wp ) ! level of light extinction 411 411 ! … … 441 441 ! 442 442 CALL trc_oce_rgb( rkrgb ) ! tabulated attenuation coef. 443 ! 443 ! 444 444 nksr = trc_oce_ext_lev( r_si2, 33._wp ) ! level of light extinction 445 445 ! -
NEMO/trunk/src/OCE/TRA/trasbc.F90
r14053 r14072 9 9 !! 3.3 ! 2010-04 (M. Leclair, G. Madec) Forcing averaged over 2 time steps 10 10 !! - ! 2010-09 (C. Ethe, G. Madec) Merge TRA-TRC 11 !! 3.6 ! 2014-11 (P. Mathiot) isf melting forcing 11 !! 3.6 ! 2014-11 (P. Mathiot) isf melting forcing 12 12 !! 4.1 ! 2019-09 (P. Mathiot) isf moved in traisf 13 13 !!---------------------------------------------------------------------- … … 21 21 USE phycst ! physical constant 22 22 USE eosbn2 ! Equation Of State 23 USE sbcmod ! ln_rnf 24 USE sbcrnf ! River runoff 23 USE sbcmod ! ln_rnf 24 USE sbcrnf ! River runoff 25 25 USE traqsr ! solar radiation penetration 26 26 USE trd_oce ! trends: ocean variables 27 USE trdtra ! trends manager: tracers 28 #if defined key_asminc 27 USE trdtra ! trends manager: tracers 28 #if defined key_asminc 29 29 USE asminc ! Assimilation increment 30 30 #endif … … 54 54 !!---------------------------------------------------------------------- 55 55 !! *** ROUTINE tra_sbc *** 56 !! 56 !! 57 57 !! ** Purpose : Compute the tracer surface boundary condition trend of 58 58 !! (flux through the interface, concentration/dilution effect) 59 59 !! and add it to the general trend of tracer equations. 60 60 !! 61 !! ** Method : The (air+ice)-sea flux has two components: 62 !! (1) Fext, external forcing (i.e. flux through the (air+ice)-sea interface); 63 !! (2) Fwe , tracer carried with the water that is exchanged with air+ice. 61 !! ** Method : The (air+ice)-sea flux has two components: 62 !! (1) Fext, external forcing (i.e. flux through the (air+ice)-sea interface); 63 !! (2) Fwe , tracer carried with the water that is exchanged with air+ice. 64 64 !! The input forcing fields (emp, rnf, sfx) contain Fext+Fwe, 65 65 !! they are simply added to the tracer trend (ts(Krhs)). … … 69 69 !! concentration/dilution effect associated with water exchanges. 70 70 !! 71 !! ** Action : - Update ts(Krhs) with the surface boundary condition trend 71 !! ** Action : - Update ts(Krhs) with the surface boundary condition trend 72 72 !! - send trends to trdtra module for further diagnostics(l_trdtra=T) 73 73 !!---------------------------------------------------------------------- … … 143 143 sbc_tsc(ji,jj,jp_sal) = r1_rho0 * sfx(ji,jj) ! salt flux due to freezing/melting 144 144 END_2D 145 IF( ln_linssh ) THEN !* linear free surface 145 IF( ln_linssh ) THEN !* linear free surface 146 146 DO_2D( isj, iej, isi, iei ) !==>> add concentration/dilution effect due to constant volume cell 147 147 sbc_tsc(ji,jj,jp_tem) = sbc_tsc(ji,jj,jp_tem) + r1_rho0 * emp(ji,jj) * pts(ji,jj,1,jp_tem,Kmm) … … 161 161 END_2D 162 162 END DO 163 ! 163 ! 164 164 IF( ntile == 0 .OR. ntile == nijtile ) THEN ! Do only on the last tile 165 165 IF( lrst_oce ) THEN !== write sbc_tsc in the ocean restart file ==! … … 173 173 !---------------------------------------- 174 174 ! 175 IF( ln_rnf ) THEN ! input of heat and salt due to river runoff 175 IF( ln_rnf ) THEN ! input of heat and salt due to river runoff 176 176 zfact = 0.5_wp 177 177 DO_2D( 0, 0, 0, 0 ) … … 182 182 & + ( rnf_tsc_b(ji,jj,jp_tem) + rnf_tsc(ji,jj,jp_tem) ) * zdep 183 183 IF( ln_rnf_sal ) pts(ji,jj,jk,jp_sal,Krhs) = pts(ji,jj,jk,jp_sal,Krhs) & 184 & + ( rnf_tsc_b(ji,jj,jp_sal) + rnf_tsc(ji,jj,jp_sal) ) * zdep 184 & + ( rnf_tsc_b(ji,jj,jp_sal) + rnf_tsc(ji,jj,jp_sal) ) * zdep 185 185 END DO 186 186 ENDIF … … 201 201 IF( ln_sshinc ) THEN ! input of heat and salt due to assimilation 202 202 ! 203 IF( ln_linssh ) THEN 203 IF( ln_linssh ) THEN 204 204 DO_2D( 0, 0, 0, 0 ) 205 205 ztim = ssh_iau(ji,jj) / e3t(ji,jj,1,Kmm) -
NEMO/trunk/src/OCE/TRA/trazdf.F90
r14010 r14072 17 17 USE phycst ! physical constant 18 18 USE zdf_oce ! ocean vertical physics variables 19 USE zdfmfc ! Mass FLux Convection 19 USE zdfmfc ! Mass FLux Convection 20 20 USE sbc_oce ! surface boundary condition: ocean 21 21 USE ldftra ! lateral diffusion: eddy diffusivity 22 USE ldfslp ! lateral diffusion: iso-neutral slope 22 USE ldfslp ! lateral diffusion: iso-neutral slope 23 23 USE trd_oce ! trends: ocean variables 24 24 USE trdtra ! trends: tracer trend manager … … 77 77 ! 78 78 ! !* compute lateral mixing trend and add it to the general trend 79 CALL tra_zdf_imp( kt, nit000, 'TRA', rDt, Kbb, Kmm, Krhs, pts, Kaa, jpts ) 79 CALL tra_zdf_imp( kt, nit000, 'TRA', rDt, Kbb, Kmm, Krhs, pts, Kaa, jpts ) 80 80 81 81 !!gm WHY here ! and I don't like that ! … … 113 113 END SUBROUTINE tra_zdf 114 114 115 116 SUBROUTINE tra_zdf_imp( kt, kit000, cdtype, p2dt, Kbb, Kmm, Krhs, pt, Kaa, kjpt ) 115 116 SUBROUTINE tra_zdf_imp( kt, kit000, cdtype, p2dt, Kbb, Kmm, Krhs, pt, Kaa, kjpt ) 117 117 !!---------------------------------------------------------------------- 118 118 !! *** ROUTINE tra_zdf_imp *** 119 119 !! 120 120 !! ** Purpose : Compute the after tracer through a implicit computation 121 !! of the vertical tracer diffusion (including the vertical component 122 !! of lateral mixing (only for 2nd order operator, for fourth order 123 !! it is already computed and add to the general trend in traldf) 121 !! of the vertical tracer diffusion (including the vertical component 122 !! of lateral mixing (only for 2nd order operator, for fourth order 123 !! it is already computed and add to the general trend in traldf) 124 124 !! 125 125 !! ** Method : The vertical diffusion of a tracer ,t , is given by: … … 169 169 zwt(:,:,1) = 0._wp 170 170 ! 171 IF( l_ldfslp ) THEN ! isoneutral diffusion: add the contribution 172 IF( ln_traldf_msc ) THEN ! MSC iso-neutral operator 171 IF( l_ldfslp ) THEN ! isoneutral diffusion: add the contribution 172 IF( ln_traldf_msc ) THEN ! MSC iso-neutral operator 173 173 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) 174 zwt(ji,jj,jk) = zwt(ji,jj,jk) + akz(ji,jj,jk) 174 zwt(ji,jj,jk) = zwt(ji,jj,jk) + akz(ji,jj,jk) 175 175 END_3D 176 176 ELSE ! standard or triad iso-neutral operator … … 220 220 ! The solution will be in the 4d array pta. 221 221 ! The 3d array zwt is used as a work space array. 222 ! En route to the solution pt(:,:,:,:,Kaa) is used a to evaluate the rhs and then 222 ! En route to the solution pt(:,:,:,:,Kaa) is used a to evaluate the rhs and then 223 223 ! used as a work space array: its value is modified. 224 224 ! … … 230 230 END_3D 231 231 ! 232 ENDIF 233 ! 232 ENDIF 233 ! 234 234 ! Modification of rhs to add MF scheme 235 235 IF ( ln_zdfmfc ) THEN … … 239 239 DO_2D( 0, 0, 0, 0 ) !* 2nd recurrence: Zk = Yk - Ik / Tk-1 Zk-1 240 240 pt(ji,jj,1,jn,Kaa) = e3t(ji,jj,1,Kbb) * pt(ji,jj,1,jn,Kbb) & 241 & + p2dt * e3t(ji,jj,1,Kmm) * pt(ji,jj,1,jn,Krhs) 241 & + p2dt * e3t(ji,jj,1,Kmm) * pt(ji,jj,1,jn,Krhs) 242 242 END_2D 243 243 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) -
NEMO/trunk/src/OCE/TRA/zpshde.F90
r13982 r14072 7 7 !! NEMO 1.0 ! 2002-08 (G. Madec E. Durand) Optimization and Free form 8 8 !! - ! 2004-03 (C. Ethe) adapted for passive tracers 9 !! 3.3 ! 2010-05 (C. Ethe, G. Madec) merge TRC-TRA 9 !! 3.3 ! 2010-05 (C. Ethe, G. Madec) merge TRC-TRA 10 10 !! 3.6 ! 2014-11 (P. Mathiot) Add zps_hde_isf (needed to open a cavity) 11 11 !!====================================================================== 12 12 13 13 !!---------------------------------------------------------------------- 14 14 !! zps_hde : Horizontal DErivative of T, S and rd at the last … … 66 66 !!---------------------------------------------------------------------- 67 67 !! *** ROUTINE zps_hde *** 68 !! 68 !! 69 69 !! ** Purpose : Compute the horizontal derivative of T, S and rho 70 70 !! at u- and v-points with a linear interpolation for z-coordinate 71 71 !! with partial steps. 72 72 !! 73 !! ** Method : In z-coord with partial steps, scale factors on last 74 !! levels are different for each grid point, so that T, S and rd 73 !! ** Method : In z-coord with partial steps, scale factors on last 74 !! levels are different for each grid point, so that T, S and rd 75 75 !! points are not at the same depth as in z-coord. To have horizontal 76 !! gradients again, we interpolate T and S at the good depth : 77 !! Linear interpolation of T, S 76 !! gradients again, we interpolate T and S at the good depth : 77 !! Linear interpolation of T, S 78 78 !! Computation of di(tb) and dj(tb) by vertical interpolation: 79 79 !! di(t) = t~ - t(i,j,k) or t(i+1,j,k) - t~ 80 80 !! dj(t) = t~ - t(i,j,k) or t(i,j+1,k) - t~ 81 81 !! This formulation computes the two cases: 82 !! CASE 1 CASE 2 82 !! CASE 1 CASE 2 83 83 !! k-1 ___ ___________ k-1 ___ ___________ 84 84 !! Ti T~ T~ Ti+1 … … 87 87 !! | |____ ____| | 88 88 !! ___ | | | ___ | | | 89 !! 89 !! 90 90 !! case 1-> e3w(i+1,:,:,Kmm) >= e3w(i,:,:,Kmm) ( and e3w(:,j+1,:,Kmm) >= e3w(:,j,:,Kmm) ) then 91 91 !! t~ = t(i+1,j ,k) + (e3w(i+1,j,k,Kmm) - e3w(i,j,k,Kmm)) * dk(Ti+1)/e3w(i+1,j,k,Kmm) … … 95 95 !! t~ = t(i,j,k) + (e3w(i,j,k,Kmm) - e3w(i+1,j,k,Kmm)) * dk(Ti)/e3w(i,j,k,Kmm) 96 96 !! ( t~ = t(i,j,k) + (e3w(i,j,k,Kmm) - e3w(i,j+1,k,Kmm)) * dk(Tj)/e3w(i,j,k,Kmm) ) 97 !! Idem for di(s) and dj(s) 97 !! Idem for di(s) and dj(s) 98 98 !! 99 99 !! For rho, we call eos which will compute rd~(t~,s~) at the right … … 175 175 ! 176 176 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp ) ! Lateral boundary cond. 177 ! 177 ! 178 178 IF( PRESENT( prd ) ) THEN !== horizontal derivative of density anomalies (rd) ==! (optional part) 179 179 pgru(:,:) = 0._wp … … 192 192 END_2D 193 193 ! 194 CALL eos( zti, zhi, zri ) ! interpolated density from zti, ztj 195 CALL eos( ztj, zhj, zrj ) ! at the partial step depth output in zri, zrj 194 CALL eos( zti, zhi, zri ) ! interpolated density from zti, ztj 195 CALL eos( ztj, zhj, zrj ) ! at the partial step depth output in zri, zrj 196 196 ! 197 197 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! Gradient of density at the last level … … 244 244 !!---------------------------------------------------------------------- 245 245 !! *** ROUTINE zps_hde_isf *** 246 !! 246 !! 247 247 !! ** Purpose : Compute the horizontal derivative of T, S and rho 248 248 !! at u- and v-points with a linear interpolation for z-coordinate 249 249 !! with partial steps for top (ice shelf) and bottom. 250 250 !! 251 !! ** Method : In z-coord with partial steps, scale factors on last 252 !! levels are different for each grid point, so that T, S and rd 251 !! ** Method : In z-coord with partial steps, scale factors on last 252 !! levels are different for each grid point, so that T, S and rd 253 253 !! points are not at the same depth as in z-coord. To have horizontal 254 254 !! gradients again, we interpolate T and S at the good depth : 255 255 !! For the bottom case: 256 !! Linear interpolation of T, S 256 !! Linear interpolation of T, S 257 257 !! Computation of di(tb) and dj(tb) by vertical interpolation: 258 258 !! di(t) = t~ - t(i,j,k) or t(i+1,j,k) - t~ 259 259 !! dj(t) = t~ - t(i,j,k) or t(i,j+1,k) - t~ 260 260 !! This formulation computes the two cases: 261 !! CASE 1 CASE 2 261 !! CASE 1 CASE 2 262 262 !! k-1 ___ ___________ k-1 ___ ___________ 263 263 !! Ti T~ T~ Ti+1 … … 266 266 !! | |____ ____| | 267 267 !! ___ | | | ___ | | | 268 !! 268 !! 269 269 !! case 1-> e3w(i+1,j,k,Kmm) >= e3w(i,j,k,Kmm) ( and e3w(i,j+1,k,Kmm) >= e3w(i,j,k,Kmm) ) then 270 270 !! t~ = t(i+1,j ,k) + (e3w(i+1,j ,k,Kmm) - e3w(i,j,k,Kmm)) * dk(Ti+1)/e3w(i+1,j ,k,Kmm) … … 274 274 !! t~ = t(i,j,k) + (e3w(i,j,k,Kmm) - e3w(i+1,j ,k,Kmm)) * dk(Ti)/e3w(i,j,k,Kmm) 275 275 !! ( t~ = t(i,j,k) + (e3w(i,j,k,Kmm) - e3w(i ,j+1,k,Kmm)) * dk(Tj)/e3w(i,j,k,Kmm) ) 276 !! Idem for di(s) and dj(s) 276 !! Idem for di(s) and dj(s) 277 277 !! 278 278 !! For rho, we call eos which will compute rd~(t~,s~) at the right … … 364 364 ! horizontal derivative of density anomalies (rd) 365 365 IF( PRESENT( prd ) ) THEN ! depth of the partial step level 366 pgru(:,:)=0.0_wp ; pgrv(:,:)=0.0_wp ; 366 pgru(:,:)=0.0_wp ; pgrv(:,:)=0.0_wp ; 367 367 ! 368 368 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) … … 418 418 ! the only common depth between cells (i,j) and (i,j+1) is gdepw_0 419 419 ze3wu = gdept(ji,jj,iku,Kmm) - gdept(ji+1,jj,iku,Kmm) 420 ze3wv = gdept(ji,jj,ikv,Kmm) - gdept(ji,jj+1,ikv,Kmm) 420 ze3wv = gdept(ji,jj,ikv,Kmm) - gdept(ji,jj+1,ikv,Kmm) 421 421 422 422 ! i- direction … … 463 463 ikv = mikv(ji,jj) 464 464 ze3wu = gdept(ji,jj,iku,Kmm) - gdept(ji+1,jj,iku,Kmm) 465 ze3wv = gdept(ji,jj,ikv,Kmm) - gdept(ji,jj+1,ikv,Kmm) 465 ze3wv = gdept(ji,jj,ikv,Kmm) - gdept(ji,jj+1,ikv,Kmm) 466 466 ! 467 467 IF( ze3wu >= 0._wp ) THEN ; zhi(ji,jj) = gdept(ji ,jj,iku,Kmm) ! i-direction: case 1 … … 475 475 END_2D 476 476 ! 477 CALL eos( zti, zhi, zri ) ! interpolated density from zti, ztj 478 CALL eos( ztj, zhj, zrj ) ! at the partial step depth output in zri, zrj 479 ! 480 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 481 iku = miku(ji,jj) 482 ikv = mikv(ji,jj) 477 CALL eos( zti, zhi, zri ) ! interpolated density from zti, ztj 478 CALL eos( ztj, zhj, zrj ) ! at the partial step depth output in zri, zrj 479 ! 480 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 481 iku = miku(ji,jj) 482 ikv = mikv(ji,jj) 483 483 ze3wu = gdept(ji,jj,iku,Kmm) - gdept(ji+1,jj,iku,Kmm) 484 ze3wv = gdept(ji,jj,ikv,Kmm) - gdept(ji,jj+1,ikv,Kmm) 484 ze3wv = gdept(ji,jj,ikv,Kmm) - gdept(ji,jj+1,ikv,Kmm) 485 485 486 486 IF( ze3wu >= 0._wp ) THEN ; pgrui(ji,jj) = ssumask(ji,jj) * ( zri(ji ,jj ) - prd(ji,jj,iku) ) ! i: 1 … … 494 494 IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'zpshde', pgrui, 'U', -1.0_wp , pgrvi, 'V', -1.0_wp ) ! Lateral boundary conditions 495 495 ! 496 END IF 496 END IF 497 497 ! 498 498 IF( ln_timing ) CALL timing_stop( 'zps_hde_isf') -
NEMO/trunk/src/OCE/TRD/trdini.F90
r13982 r14072 17 17 USE trdglo ! trends: global domain averaged tracers and dynamics 18 18 USE trdmxl ! trends: mixed layer averaged trends (tracer only) 19 USE trdvor ! trends: vertical averaged vorticity 19 USE trdvor ! trends: vertical averaged vorticity 20 20 USE in_out_manager ! I/O manager 21 21 USE lib_mpp ! MPP library … … 36 36 !!---------------------------------------------------------------------- 37 37 !! *** ROUTINE trd_init *** 38 !! 38 !! 39 39 !! ** Purpose : Initialization of trend diagnostics 40 40 !!---------------------------------------------------------------------- … … 43 43 !! 44 44 NAMELIST/namtrd/ ln_dyn_trd, ln_KE_trd, ln_vor_trd, ln_dyn_mxl, & 45 & ln_tra_trd, ln_PE_trd, ln_glo_trd, ln_tra_mxl, nn_trd 45 & ln_tra_trd, ln_PE_trd, ln_glo_trd, ln_tra_mxl, nn_trd 46 46 !!---------------------------------------------------------------------- 47 47 ! … … 70 70 ENDIF 71 71 ! 72 ! ! trend extraction flags 73 l_trdtra = .FALSE. ! tracers 72 ! ! trend extraction flags 73 l_trdtra = .FALSE. ! tracers 74 74 IF ( ln_tra_trd .OR. ln_PE_trd .OR. ln_tra_mxl .OR. & 75 & ln_glo_trd ) l_trdtra = .TRUE. 75 & ln_glo_trd ) l_trdtra = .TRUE. 76 76 ! 77 77 l_trddyn = .FALSE. ! momentum … … 80 80 ! 81 81 82 !!gm check the stop below 82 !!gm check the stop below 83 83 IF( ln_dyn_mxl ) CALL ctl_stop( 'ML diag on momentum are not yet coded we stop' ) 84 84 ! … … 97 97 98 98 !!gm : Potential BUG : 3D output only for vector invariant form! add a ctl_stop or code the flux form case 99 !!gm : bug/pb for vertical advection of tracer in vvl case: add T.dt[eta] in the output... 99 !!gm : bug/pb for vertical advection of tracer in vvl case: add T.dt[eta] in the output... 100 100 101 ! ! diagnostic initialization 101 ! ! diagnostic initialization 102 102 IF( ln_glo_trd ) CALL trd_glo_init( Kmm ) ! global domain averaged trends 103 IF( ln_tra_mxl ) CALL trd_mxl_init ! mixed-layer trends 103 IF( ln_tra_mxl ) CALL trd_mxl_init ! mixed-layer trends 104 104 IF( ln_vor_trd ) CALL trd_vor_init ! barotropic vorticity trends 105 105 IF( ln_KE_trd ) CALL trd_ken_init ! 3D Kinetic energy trends -
NEMO/trunk/src/OCE/USR/usrdef_nam.F90
r13982 r14072 12 12 !!---------------------------------------------------------------------- 13 13 !! usr_def_nam : read user defined namelist and set global domain size 14 !! usr_def_hgr : initialize the horizontal mesh 14 !! usr_def_hgr : initialize the horizontal mesh 15 15 !!---------------------------------------------------------------------- 16 16 USE dom_oce … … 20 20 USE in_out_manager ! I/O manager 21 21 USE lib_mpp ! MPP library 22 22 23 23 IMPLICIT NONE 24 24 PRIVATE … … 32 32 !!---------------------------------------------------------------------- 33 33 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 34 !! $Id$ 34 !! $Id$ 35 35 !! Software governed by the CeCILL license (see ./LICENSE) 36 36 !!---------------------------------------------------------------------- … … 40 40 !!---------------------------------------------------------------------- 41 41 !! *** ROUTINE dom_nam *** 42 !! 42 !! 43 43 !! ** Purpose : read user defined namelist and define the domain size 44 44 !! … … 51 51 CHARACTER(len=*), INTENT(out) :: cd_cfg ! configuration name 52 52 INTEGER , INTENT(out) :: kk_cfg ! configuration resolution 53 INTEGER , INTENT(out) :: kpi, kpj, kpk ! global domain sizes 54 INTEGER , INTENT(out) :: kperio ! lateral global domain b.c. 53 INTEGER , INTENT(out) :: kpi, kpj, kpk ! global domain sizes 54 INTEGER , INTENT(out) :: kperio ! lateral global domain b.c. 55 55 ! 56 56 INTEGER :: ios ! Local integer -
NEMO/trunk/src/OCE/ZDF/zdf_oce.F90
r14010 r14072 41 41 LOGICAL , PUBLIC :: ln_zdfiwm !: internal wave-induced mixing flag 42 42 LOGICAL , PUBLIC :: ln_zdfmfc !: convection: eddy diffusivity Mass Flux Convection 43 ! ! coefficients 43 ! ! coefficients 44 44 REAL(wp), PUBLIC :: rn_avm0 !: vertical eddy viscosity (m2/s) 45 45 REAL(wp), PUBLIC :: rn_avt0 !: vertical eddy diffusivity (m2/s) … … 56 56 !!---------------------------------------------------------------------- 57 57 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 58 !! $Id$ 58 !! $Id$ 59 59 !! Software governed by the CeCILL license (see ./LICENSE) 60 60 !!---------------------------------------------------------------------- … … 67 67 ! 68 68 ALLOCATE( avm (jpi,jpj,jpk) , avm_k(jpi,jpj,jpk) , avs(jpi,jpj,jpk) , & 69 & avt (jpi,jpj,jpk) , avt_k(jpi,jpj,jpk) , en (jpi,jpj,jpk) , & 69 & avt (jpi,jpj,jpk) , avt_k(jpi,jpj,jpk) , en (jpi,jpj,jpk) , & 70 70 & avmb(jpk) , avtb(jpk) , avtb_2d(jpi,jpj) , STAT = zdf_oce_alloc ) 71 71 ! -
NEMO/trunk/src/OCE/ZDF/zdfgls.F90
r13970 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE zdfgls *** 4 !! Ocean physics: vertical mixing coefficient computed from the gls 4 !! Ocean physics: vertical mixing coefficient computed from the gls 5 5 !! turbulent closure parameterization 6 6 !!====================================================================== 7 7 !! History : 3.0 ! 2009-09 (G. Reffray) Original code 8 8 !! 3.3 ! 2010-10 (C. Bricaud) Add in the reference 9 !! 4.0 ! 2017-04 (G. Madec) remove CPP keys & avm at t-point only 9 !! 4.0 ! 2017-04 (G. Madec) remove CPP keys & avm at t-point only 10 10 !! - ! 2017-05 (G. Madec) add top friction as boundary condition 11 11 !!---------------------------------------------------------------------- … … 16 16 !! gls_rst : read/write gls restart in ocean restart file 17 17 !!---------------------------------------------------------------------- 18 USE oce ! ocean dynamics and active tracers 18 USE oce ! ocean dynamics and active tracers 19 19 USE dom_oce ! ocean space and time domain 20 20 USE domvvl ! ocean space and time domain : variable volume layer … … 64 64 REAL(wp) :: rn_hsro ! Minimum surface roughness 65 65 REAL(wp) :: rn_hsri ! Ice ocean roughness 66 REAL(wp) :: rn_frac_hs ! Fraction of wave height as surface roughness (if nn_z0_met > 1) 66 REAL(wp) :: rn_frac_hs ! Fraction of wave height as surface roughness (if nn_z0_met > 1) 67 67 68 68 REAL(wp) :: rcm_sf = 0.73_wp ! Shear free turbulence parameters 69 REAL(wp) :: ra_sf = -2.0_wp ! Must be negative -2 < ra_sf < -1 70 REAL(wp) :: rl_sf = 0.2_wp ! 0 <rl_sf<vkarmn 69 REAL(wp) :: ra_sf = -2.0_wp ! Must be negative -2 < ra_sf < -1 70 REAL(wp) :: rl_sf = 0.2_wp ! 0 <rl_sf<vkarmn 71 71 REAL(wp) :: rghmin = -0.28_wp 72 72 REAL(wp) :: rgh0 = 0.0329_wp … … 75 75 REAL(wp) :: ra2 = 0.74_wp 76 76 REAL(wp) :: rb1 = 16.60_wp 77 REAL(wp) :: rb2 = 10.10_wp 78 REAL(wp) :: re2 = 1.33_wp 77 REAL(wp) :: rb2 = 10.10_wp 78 REAL(wp) :: re2 = 1.33_wp 79 79 REAL(wp) :: rl1 = 0.107_wp 80 80 REAL(wp) :: rl2 = 0.0032_wp … … 146 146 INTEGER :: itop, itopp1 ! - - 147 147 REAL(wp) :: zesh2, zsigpsi, zcoef, zex1 , zex2 ! local scalars 148 REAL(wp) :: ztx2, zty2, zup, zdown, zcof, zdir ! - - 148 REAL(wp) :: ztx2, zty2, zup, zdown, zcof, zdir ! - - 149 149 REAL(wp) :: zratio, zrn2, zflxb, sh , z_en ! - - 150 150 REAL(wp) :: prod, buoy, diss, zdiss, sm ! - - … … 153 153 REAL(wp), DIMENSION(jpi,jpj) :: zdep 154 154 REAL(wp), DIMENSION(jpi,jpj) :: zkar 155 REAL(wp), DIMENSION(jpi,jpj) :: zflxs ! Turbulence fluxed induced by internal waves 155 REAL(wp), DIMENSION(jpi,jpj) :: zflxs ! Turbulence fluxed induced by internal waves 156 156 REAL(wp), DIMENSION(jpi,jpj) :: zhsro ! Surface roughness (surface waves) 157 157 REAL(wp), DIMENSION(jpi,jpj) :: zice_fra ! Tapering of wave breaking under sea ice … … 167 167 ! Preliminary computing 168 168 169 ustar2_surf(:,:) = 0._wp ; psi(:,:,:) = 0._wp 169 ustar2_surf(:,:) = 0._wp ; psi(:,:,:) = 0._wp 170 170 ustar2_top (:,:) = 0._wp ; zwall_psi(:,:,:) = 0._wp 171 171 ustar2_bot (:,:) = 0._wp … … 177 177 CASE( 3 ) ; zice_fra(:,:) = MIN( 4._wp * fr_i(:,:) , 1._wp ) 178 178 END SELECT 179 179 180 180 ! Compute surface, top and bottom friction at T-points 181 181 DO_2D( 0, 0, 0, 0 ) !== surface ocean friction … … 184 184 ! 185 185 !!gm Rq we may add here r_ke0(_top/_bot) ? ==>> think about that... 186 ! 186 ! 187 187 IF( .NOT.ln_drg_OFF ) THEN !== top/bottom friction (explicit before friction) 188 188 DO_2D( 0, 0, 0, 0 ) ! bottom friction (explicit before friction) … … 201 201 ENDIF 202 202 ENDIF 203 203 204 204 SELECT CASE ( nn_z0_met ) !== Set surface roughness length ==! 205 CASE ( 0 ) ! Constant roughness 205 CASE ( 0 ) ! Constant roughness 206 206 zhsro(:,:) = rn_hsro 207 207 CASE ( 1 ) ! Standard Charnock formula … … 271 271 IF( ln_sigpsi ) THEN 272 272 zsigpsi = MIN( 1._wp, zesh2 / eps(ji,jj,jk) ) ! 0. <= zsigpsi <= 1. 273 zwall_psi(ji,jj,jk) = rsc_psi / & 273 zwall_psi(ji,jj,jk) = rsc_psi / & 274 274 & ( zsigpsi * rsc_psi + (1._wp-zsigpsi) * rsc_psi0 / MAX( zwall(ji,jj,jk), 1._wp ) ) 275 275 ELSE … … 286 286 & / ( e3t(ji,jj,jk ,Kmm) * e3w(ji,jj,jk,Kmm) ) 287 287 ! ! diagonal 288 zdiag(ji,jj,jk) = 1._wp - zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) + rn_Dt * zdiss * wmask(ji,jj,jk) 288 zdiag(ji,jj,jk) = 1._wp - zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) + rn_Dt * zdiss * wmask(ji,jj,jk) 289 289 ! ! right hand side in en 290 290 en(ji,jj,jk) = en(ji,jj,jk) + rn_Dt * zesh2 * wmask(ji,jj,jk) … … 302 302 SELECT CASE ( nn_bc_surf ) 303 303 ! 304 CASE ( 0 ) ! Dirichlet boundary condition (set e at k=1 & 2) 304 CASE ( 0 ) ! Dirichlet boundary condition (set e at k=1 & 2) 305 305 ! First level 306 306 en (:,:,1) = MAX( rn_emin , rc02r * ustar2_surf(:,:) * (1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1)**r2_3 ) … … 308 308 zd_up(:,:,1) = 0._wp 309 309 zdiag(:,:,1) = 1._wp 310 ! 310 ! 311 311 ! One level below 312 312 en (:,:,2) = MAX( rc02r * ustar2_surf(:,:) * ( 1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1 * ((zhsro(:,:)+gdepw(:,:,2,Kmm)) & 313 313 & / zhsro(:,:) )**(1.5_wp*ra_sf) )**(2._wp/3._wp) , rn_emin ) 314 zd_lw(:,:,2) = 0._wp 314 zd_lw(:,:,2) = 0._wp 315 315 zd_up(:,:,2) = 0._wp 316 316 zdiag(:,:,2) = 1._wp … … 345 345 SELECT CASE ( nn_bc_bot ) 346 346 ! 347 CASE ( 0 ) ! Dirichlet 347 CASE ( 0 ) ! Dirichlet 348 348 ! ! en(ibot) = u*^2 / Co2 and hmxl_n(ibot) = rn_lmin 349 349 ! ! Balance between the production and the dissipation terms … … 357 357 z_en = MAX( rc02r * ustar2_bot(ji,jj), rn_emin ) 358 358 ! 359 ! Dirichlet condition applied at: 360 ! Bottom level (ibot) & Just above it (ibotm1) 359 ! Dirichlet condition applied at: 360 ! Bottom level (ibot) & Just above it (ibotm1) 361 361 zd_lw(ji,jj,ibot) = 0._wp ; zd_lw(ji,jj,ibotm1) = 0._wp 362 362 zd_up(ji,jj,ibot) = 0._wp ; zd_up(ji,jj,ibotm1) = 0._wp … … 373 373 ! 374 374 !!gm TO BE VERIFIED !!! 375 ! Dirichlet condition applied at: 376 ! top level (itop) & Just below it (itopp1) 375 ! Dirichlet condition applied at: 376 ! top level (itop) & Just below it (itopp1) 377 377 zd_lw(ji,jj,itop) = 0._wp ; zd_lw(ji,jj,itopp1) = 0._wp 378 378 zd_up(ji,jj,itop) = 0._wp ; zd_up(ji,jj,itopp1) = 0._wp … … 383 383 ! 384 384 CASE ( 1 ) ! Neumman boundary condition 385 ! 385 ! 386 386 DO_2D( 0, 0, 0, 0 ) 387 387 ibot = mbkt(ji,jj) + 1 ! k bottom level of w-point … … 391 391 ! 392 392 ! Bottom level Dirichlet condition: 393 ! Bottom level (ibot) & Just above it (ibotm1) 393 ! Bottom level (ibot) & Just above it (ibotm1) 394 394 ! Dirichlet ! Neumann 395 395 zd_lw(ji,jj,ibot) = 0._wp ! ! Remove zd_up from zdiag … … 405 405 ! 406 406 ! Bottom level Dirichlet condition: 407 ! Bottom level (ibot) & Just above it (ibotm1) 407 ! Bottom level (ibot) & Just above it (ibotm1) 408 408 ! Dirichlet ! Neumann 409 409 zd_lw(ji,jj,itop) = 0._wp ! ! Remove zd_up from zdiag … … 427 427 en(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * en(ji,jj,jk+1) ) / zdiag(ji,jj,jk) 428 428 END_3D 429 ! ! set the minimum value of tke 429 ! ! set the minimum value of tke 430 430 en(:,:,:) = MAX( en(:,:,:), rn_emin ) 431 431 … … 455 455 CASE( 3 ) ! generic 456 456 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) 457 psi(ji,jj,jk) = rc02 * eb(ji,jj,jk) * hmxl_b(ji,jj,jk)**rnn 457 psi(ji,jj,jk) = rc02 * eb(ji,jj,jk) * hmxl_b(ji,jj,jk)**rnn 458 458 END_3D 459 459 ! … … 470 470 ! 471 471 ! psi / k 472 zratio = psi(ji,jj,jk) / eb(ji,jj,jk) 472 zratio = psi(ji,jj,jk) / eb(ji,jj,jk) 473 473 ! 474 474 ! psi3+ : stable : B=-KhN²<0 => N²>0 if rn2>0 zdir = 1 (stable) otherwise zdir = 0 (unstable) … … 490 490 zesh2 = zdir * ( prod + buoy ) + (1._wp - zdir ) * prod ! production term 491 491 zdiss = zdir * ( diss / psi(ji,jj,jk) ) + (1._wp - zdir ) * (diss-buoy) / psi(ji,jj,jk) ! dissipation term 492 ! 492 ! 493 493 ! building the matrix 494 494 zcof = rfact_psi * zwall_psi(ji,jj,jk) * tmask(ji,jj,jk) … … 528 528 zd_up(:,:,2) = 0._wp 529 529 zdiag(:,:,2) = 1._wp 530 ! 530 ! 531 531 CASE ( 1 ) ! Neumann boundary condition on d(psi)/dz 532 532 ! … … 564 564 SELECT CASE ( nn_bc_bot ) ! bottom boundary 565 565 ! 566 CASE ( 0 ) ! Dirichlet 566 CASE ( 0 ) ! Dirichlet 567 567 ! ! en(ibot) = u*^2 / Co2 and hmxl_n(ibot) = vkarmn * r_z0_bot 568 568 ! ! Balance between the production and the dissipation terms … … 585 585 ! 586 586 CASE ( 1 ) ! Neumman boundary condition 587 ! 587 ! 588 588 DO_2D( 0, 0, 0, 0 ) 589 589 ibot = mbkt(ji,jj) + 1 ! k bottom level of w-point … … 641 641 CASE( 2 ) ! k-w 642 642 DO_3D( 0, 0, 0, 0, 1, jpkm1 ) 643 eps(ji,jj,jk) = rc04 * en(ji,jj,jk) * psi(ji,jj,jk) 643 eps(ji,jj,jk) = rc04 * en(ji,jj,jk) * psi(ji,jj,jk) 644 644 END_3D 645 645 ! … … 660 660 eps (ji,jj,jk) = MAX( eps(ji,jj,jk), rn_epsmin ) 661 661 hmxl_n(ji,jj,jk) = rc03 * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / eps(ji,jj,jk) 662 ! Galperin criterium (NOTE : Not required if the proper value of C3 in stable cases is calculated) 662 ! Galperin criterium (NOTE : Not required if the proper value of C3 in stable cases is calculated) 663 663 zrn2 = MAX( rn2(ji,jj,jk), rsmall ) 664 664 IF( ln_length_lim ) hmxl_n(ji,jj,jk) = MIN( rn_clim_galp * SQRT( 2._wp * en(ji,jj,jk) / zrn2 ), hmxl_n(ji,jj,jk) ) … … 720 720 721 721 ! default value, in case jpk > mbkt(ji,jj)+1. Not needed but avoid a bug when looking for undefined values (-fpe0) 722 zstm(:,:,jpk) = 0. 722 zstm(:,:,jpk) = 0. 723 723 DO_2D( 0, 0, 0, 0 ) ! update bottom with good values 724 724 zstm(ji,jj,mbkt(ji,jj)+1) = zstm(ji,jj,mbkt(ji,jj)) … … 756 756 !!---------------------------------------------------------------------- 757 757 !! *** ROUTINE zdf_gls_init *** 758 !! 759 !! ** Purpose : Initialization of the vertical eddy diffivity and 758 !! 759 !! ** Purpose : Initialization of the vertical eddy diffivity and 760 760 !! viscosity computed using a GLS turbulent closure scheme 761 761 !! … … 983 983 ! 984 984 END SELECT 985 985 986 986 ! !* Set Schmidt number for psi diffusion in the wave breaking case 987 987 ! ! See Eq. (13) of Carniel et al, OM, 30, 225-239, 2009 988 988 ! ! or Eq. (17) of Burchard, JPO, 31, 3133-3145, 2001 989 989 IF( ln_sigpsi ) THEN 990 ra_sf = -1.5 ! Set kinetic energy slope, then deduce rsc_psi and rl_sf 990 ra_sf = -1.5 ! Set kinetic energy slope, then deduce rsc_psi and rl_sf 991 991 ! Verification: retrieve Burchard (2001) results by uncomenting the line below: 992 992 ! Note that the results depend on the value of rn_cm_sf which is constant (=rc0) in his work … … 996 996 rsc_psi0 = rsc_psi 997 997 ENDIF 998 998 999 999 ! !* Shear free turbulence parameters 1000 1000 ! … … 1039 1039 rc04 = rc03 * rc0 1040 1040 rsbc_tke1 = -3._wp/2._wp*rn_crban*ra_sf*rl_sf ! Dirichlet + Wave breaking 1041 rsbc_tke2 = rn_Dt * rn_crban / rl_sf ! Neumann + Wave breaking 1041 rsbc_tke2 = rn_Dt * rn_crban / rl_sf ! Neumann + Wave breaking 1042 1042 zcr = MAX(rsmall, rsbc_tke1**(1./(-ra_sf*3._wp/2._wp))-1._wp ) 1043 rtrans = 0.2_wp / zcr ! Ad. inverse transition length between log and wave layer 1043 rtrans = 0.2_wp / zcr ! Ad. inverse transition length between log and wave layer 1044 1044 rsbc_zs1 = rn_charn/grav ! Charnock formula for surface roughness 1045 rsbc_zs2 = rn_frac_hs / 0.85_wp / grav * 665._wp ! Rascle formula for surface roughness 1045 rsbc_zs2 = rn_frac_hs / 0.85_wp / grav * 665._wp ! Rascle formula for surface roughness 1046 1046 rsbc_psi1 = -0.5_wp * rn_Dt * rc0**(rpp-2._wp*rmm) / rsc_psi 1047 rsbc_psi2 = -0.5_wp * rn_Dt * rc0**rpp * rnn * vkarmn**rnn / rsc_psi ! Neumann + NO Wave breaking 1047 rsbc_psi2 = -0.5_wp * rn_Dt * rc0**rpp * rnn * vkarmn**rnn / rsc_psi ! Neumann + NO Wave breaking 1048 1048 ! 1049 1049 rfact_tke = -0.5_wp / rsc_tke * rn_Dt ! Cst used for the Diffusion term of tke … … 1054 1054 zwall(:,:,:) = 1._wp * tmask(:,:,:) 1055 1055 1056 ! !* read or initialize all required files 1056 ! !* read or initialize all required files 1057 1057 CALL gls_rst( nit000, 'READ' ) ! (en, avt_k, avm_k, hmxl_n) 1058 1058 ! … … 1063 1063 !!--------------------------------------------------------------------- 1064 1064 !! *** ROUTINE gls_rst *** 1065 !! 1065 !! 1066 1066 !! ** Purpose : Read or write TKE file (en) in restart file 1067 1067 !! 1068 1068 !! ** Method : use of IOM library 1069 !! if the restart does not contain TKE, en is either 1069 !! if the restart does not contain TKE, en is either 1070 1070 !! set to rn_emin or recomputed (nn_igls/=0) 1071 1071 !!---------------------------------------------------------------------- … … 1081 1081 !!---------------------------------------------------------------------- 1082 1082 ! 1083 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 1083 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 1084 1084 ! ! --------------- 1085 1085 IF( ln_rstart ) THEN !* Read the restart file … … 1094 1094 CALL iom_get( numror, jpdom_auto, 'avm_k' , avm_k ) 1095 1095 CALL iom_get( numror, jpdom_auto, 'hmxl_n', hmxl_n ) 1096 ELSE 1096 ELSE 1097 1097 IF(lwp) WRITE(numout,*) 1098 1098 IF(lwp) WRITE(numout,*) ' ==>> previous run without GLS scheme, set en and hmxl_n to background values' -
NEMO/trunk/src/OCE/ZDF/zdfosm.F90
r14045 r14072 146 146 INTEGER :: idebug = 236 147 147 INTEGER :: jdebug = 228 148 148 149 149 !! * Substitutions 150 150 # include "do_loop_substitute.h90" … … 309 309 REAL(wp) :: zl_c,zl_l,zl_eps ! Used to calculate turbulence length scale. 310 310 311 REAL(wp) :: za_cubic, zb_cubic, zc_cubic, zd_cubic ! coefficients in cubic polynomial specifying diffusivity in pycnocline. 311 REAL(wp) :: za_cubic, zb_cubic, zc_cubic, zd_cubic ! coefficients in cubic polynomial specifying diffusivity in pycnocline. 312 312 REAL(wp), DIMENSION(jpi,jpj) :: zsc_wth_1,zsc_ws_1 ! Temporary scales used to calculate scalar non-gradient terms. 313 313 REAL(wp), DIMENSION(jpi,jpj) :: zsc_wth_pyc, zsc_ws_pyc ! Scales for pycnocline transport term/ … … 665 665 ! 666 666 ! 667 ! Check to see if lpyc needs to be changed 667 ! Check to see if lpyc needs to be changed 668 668 669 669 CALL zdf_osm_pycnocline_thickness( dh, zdh ) 670 670 671 671 DO_2D( 0, 0, 0, 0 ) 672 IF ( zdb_bl(ji,jj) < rn_osm_bl_thresh .or. ibld(ji,jj) + jp_ext(ji,jj) >= mbkt(ji,jj) .or. ibld(ji,jj)-imld(ji,jj) == 1 ) lpyc(ji,jj) = .FALSE. 672 IF ( zdb_bl(ji,jj) < rn_osm_bl_thresh .or. ibld(ji,jj) + jp_ext(ji,jj) >= mbkt(ji,jj) .or. ibld(ji,jj)-imld(ji,jj) == 1 ) lpyc(ji,jj) = .FALSE. 673 673 END_2D 674 674 … … 790 790 ghams(ji,jj,jk) = ghams(ji,jj,jk) + 0.3 * 0.5 * zsc_ws_1(ji,jj) * zl_eps * zhml(ji,jj) / ( 0.15 + zznd_ml ) 791 791 END DO 792 792 793 793 IF ( lpyc(ji,jj) ) THEN 794 794 ztau_sc_u(ji,jj) = zhml(ji,jj) / ( zvstr(ji,jj)**3 + zwstrc(ji,jj)**3 )**pthird 795 795 ztau_sc_u(ji,jj) = ztau_sc_u(ji,jj) * ( 1.4 -0.4 / ( 1.0 + EXP( -3.5 * LOG10( -zhol(ji,jj) ) ) )**1.5 ) 796 zwth_ent = -0.003 * ( 0.15 * zvstr(ji,jj)**3 + zwstrc(ji,jj)**3 )**pthird * ( 1.0 - zdh(ji,jj) /zhbl(ji,jj) ) * zdt_ml(ji,jj) 796 zwth_ent = -0.003 * ( 0.15 * zvstr(ji,jj)**3 + zwstrc(ji,jj)**3 )**pthird * ( 1.0 - zdh(ji,jj) /zhbl(ji,jj) ) * zdt_ml(ji,jj) 797 797 zws_ent = -0.003 * ( 0.15 * zvstr(ji,jj)**3 + zwstrc(ji,jj)**3 )**pthird * ( 1.0 - zdh(ji,jj) /zhbl(ji,jj) ) * zds_ml(ji,jj) 798 798 ! Cubic profile used for buoyancy term … … 813 813 zws_pyc_sc_1 = 0.325 * ( zalpha_pyc(ji,jj) * zds_ml(ji,jj) / zdh(ji,jj) + zdsdz_bl_ext(ji,jj) ) * zdelta_pyc**2 / zdh(ji,jj) 814 814 ! 815 zzeta_pyc = 0.15 - 0.175 / ( 1.0 + EXP( -3.5 * LOG10( -zhol(ji,jj) ) ) ) 815 zzeta_pyc = 0.15 - 0.175 / ( 1.0 + EXP( -3.5 * LOG10( -zhol(ji,jj) ) ) ) 816 816 DO jk = 2, ibld(ji,jj) 817 817 zznd_pyc = -( gdepw(ji,jj,jk,Kmm) - zhbl(ji,jj) ) / zdh(ji,jj) … … 820 820 ghams(ji,jj,jk) = ghams(ji,jj,jk) + 0.05 * zws_pyc_sc_1 * EXP( -0.25 * ( zznd_pyc / zzeta_pyc )**2 ) * zdh(ji,jj) / ( zvstr(ji,jj)**3 + zwstrc(ji,jj)**3 )**pthird 821 821 END DO 822 ENDIF ! End of pycnocline 822 ENDIF ! End of pycnocline 823 823 ELSE ! lconv test - stable conditions 824 824 DO jk = 2, ibld(ji,jj) … … 870 870 zd_cubic = zdh(ji,jj) / zhbl(ji,jj) * zuw0(ji,jj) - ( 2.0 + zdh(ji,jj) /zhml(ji,jj) ) * zuw_bse 871 871 zc_cubic = zuw_bse - zd_cubic 872 ! need ztau_sc_u to be available. Change to array. 872 ! need ztau_sc_u to be available. Change to array. 873 873 DO jk = imld(ji,jj), ibld(ji,jj) 874 874 zznd_pyc = - ( gdepw(ji,jj,jk,Kmm) - zhbl(ji,jj) ) / zdh(ji,jj) … … 892 892 893 893 DO_2D( 1, 0, 1, 0 ) 894 894 895 895 IF ( lconv(ji,jj) ) THEN 896 896 zsc_wth_1(ji,jj) = zwth0(ji,jj) / ( 1.0 - 0.56 * EXP( zhol(ji,jj) ) ) … … 926 926 DO jk = imld(ji,jj), ibld(ji,jj) 927 927 zznd_pyc = - ( gdepw(ji,jj,jk,Kmm) - zhbl(ji,jj) ) / zdh(ji,jj) 928 ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 4.0 * zsc_wth_pyc(ji,jj) * ( 0.48 - EXP( -1.5 * ( zznd_pyc -0.3)**2 ) ) 929 ghams(ji,jj,jk) = ghams(ji,jj,jk) + 4.0 * zsc_ws_pyc(ji,jj) * ( 0.48 - EXP( -1.5 * ( zznd_pyc -0.3)**2 ) ) 928 ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 4.0 * zsc_wth_pyc(ji,jj) * ( 0.48 - EXP( -1.5 * ( zznd_pyc -0.3)**2 ) ) 929 ghams(ji,jj,jk) = ghams(ji,jj,jk) + 4.0 * zsc_ws_pyc(ji,jj) * ( 0.48 - EXP( -1.5 * ( zznd_pyc -0.3)**2 ) ) 930 930 END DO 931 931 ENDIF … … 1136 1136 END DO 1137 1137 ELSE 1138 ! Surface transports limited to OSBL. 1138 ! Surface transports limited to OSBL. 1139 1139 ! Viscosity for MLEs 1140 1140 DO jk = 1, mld_prof(ji,jj) … … 1261 1261 !! ** Purpose : Determines the eddy diffusivity and eddy viscosity profiles in the mixed layer and the pycnocline. 1262 1262 !! 1263 !! ** Method : 1263 !! ** Method : 1264 1264 !! 1265 1265 !! !!---------------------------------------------------------------------- … … 1275 1275 ! 1276 1276 REAL(wp) :: zvel_sc_pyc, zvel_sc_ml, zstab_fac 1277 1277 1278 1278 REAL(wp), PARAMETER :: rn_dif_ml = 0.8, rn_vis_ml = 0.375 1279 1279 REAL(wp), PARAMETER :: rn_dif_pyc = 0.15, rn_vis_pyc = 0.142 1280 1280 REAL(wp), PARAMETER :: rn_vispyc_shr = 0.15 1281 1281 1282 1282 DO_2D( 0, 0, 0, 0 ) 1283 1283 IF ( lconv(ji,jj) ) THEN 1284 1284 1285 1285 zvel_sc_pyc = ( 0.15 * zvstr(ji,jj)**3 + zwstrc(ji,jj)**3 + 4.25 * zshear(ji,jj) * zhbl(ji,jj) )**pthird 1286 1286 zvel_sc_ml = ( zvstr(ji,jj)**3 + 0.5 * zwstrc(ji,jj)**3 )**pthird … … 1296 1296 zdifpyc_n_sc(ji,jj) = zdifpyc_n_sc(ji,jj) + rn_vispyc_shr * ( zshear(ji,jj) * zhbl(ji,jj) )**pthird * zhbl(ji,jj) 1297 1297 ENDIF 1298 1298 1299 1299 zdifpyc_s_sc(ji,jj) = zwb_ent(ji,jj) + 0.0025 * zvel_sc_pyc * ( zhbl(ji,jj) / zdh(ji,jj) - 1.0 ) * ( zb_ml(ji,jj) - zb_bl(ji,jj) ) 1300 1300 zdifpyc_s_sc(ji,jj) = 0.09 * zdifpyc_s_sc(ji,jj) * zstab_fac 1301 1301 zdifpyc_s_sc(ji,jj) = MAX( zdifpyc_s_sc(ji,jj), -0.5 * zdifpyc_n_sc(ji,jj) ) 1302 1302 1303 1303 zvispyc_n_sc(ji,jj) = 0.09 * zvel_sc_pyc * ( 1.0 - zhbl(ji,jj) / zdh(ji,jj) )**2 * ( 0.005 * ( zu_ml(ji,jj)-zu_bl(ji,jj) )**2 + 0.0075 * ( zv_ml(ji,jj)-zv_bl(ji,jj) )**2 ) / zdh(ji,jj) 1304 1304 zvispyc_n_sc(ji,jj) = rn_vis_pyc * zvel_sc_ml * zdh(ji,jj) + zvispyc_n_sc(ji,jj) * zstab_fac … … 1306 1306 zvispyc_n_sc(ji,jj) = zvispyc_n_sc(ji,jj) + rn_vispyc_shr * ( zshear(ji,jj) * zhbl(ji,jj ) )**pthird * zhbl(ji,jj) 1307 1307 ENDIF 1308 1308 1309 1309 zvispyc_s_sc(ji,jj) = 0.09 * ( zwb_min(ji,jj) + 0.0025 * zvel_sc_pyc * ( zhbl(ji,jj) / zdh(ji,jj) - 1.0 ) * ( zb_ml(ji,jj) - zb_bl(ji,jj) ) ) 1310 1310 zvispyc_s_sc(ji,jj) = zvispyc_s_sc(ji,jj) * zstab_fac … … 1383 1383 ! 1384 1384 END_2D 1385 1385 1386 1386 END SUBROUTINE zdf_osm_diffusivity_viscosity 1387 1387 1388 1388 SUBROUTINE zdf_osm_osbl_state( lconv, lshear, j_ddh, zwb_ent, zwb_min, zshear, zri_i ) 1389 1389 … … 1393 1393 !! ** Purpose : Determines the state of the OSBL, stable/unstable, shear/ noshear. Also determines shear production, entrainment buoyancy flux and interfacial Richardson number 1394 1394 !! 1395 !! ** Method : 1395 !! ** Method : 1396 1396 !! 1397 1397 !! !!---------------------------------------------------------------------- 1398 1398 1399 1399 INTEGER, DIMENSION(jpi,jpj) :: j_ddh ! j_ddh = 0, active shear layer; j_ddh=1, shear layer not active; j_ddh=2 shear production low. 1400 1400 1401 1401 LOGICAL, DIMENSION(jpi,jpj) :: lconv, lshear 1402 1402 … … 1408 1408 1409 1409 INTEGER :: jj, ji 1410 1410 1411 1411 REAL(wp), DIMENSION(jpi,jpj) :: zekman 1412 1412 REAL(wp) :: zri_p, zri_b ! Richardson numbers … … 1416 1416 REAL, PARAMETER :: za_shr = 0.4, zb_shr = 6.5, za_wb_s = 0.1 1417 1417 REAL, PARAMETER :: rn_ri_thres_a = 0.5, rn_ri_thresh_b = 0.59 1418 REAL, PARAMETER :: zalpha_c = 0.2, zalpha_lc = 0.04 1418 REAL, PARAMETER :: zalpha_c = 0.2, zalpha_lc = 0.04 1419 1419 REAL, PARAMETER :: zalpha_ls = 0.06, zalpha_s = 0.15 1420 1420 REAL, PARAMETER :: rn_ri_p_thresh = 27.0 1421 1421 REAL, PARAMETER :: zrot=0._wp ! dummy rotation rate of surface stress. 1422 1422 1423 1423 ! Determins stability and set flag lconv 1424 1424 DO_2D( 0, 0, 0, 0 ) … … 1429 1429 ENDIF 1430 1430 END_2D 1431 1431 1432 1432 zekman(:,:) = EXP( - 4.0 * ABS( ff_t(:,:) ) * zhbl(:,:) / MAX(zustar(:,:), 1.e-8 ) ) 1433 1433 1434 1434 WHERE ( lconv ) 1435 1435 zri_i = zdb_ml * zhml**2 / MAX( ( zvstr**3 + 0.5 * zwstrc**3 )**p2third * zdh, 1.e-12 ) … … 1437 1437 1438 1438 zshear(:,:) = 0._wp 1439 j_ddh(:,:) = 1 1440 1439 j_ddh(:,:) = 1 1440 1441 1441 DO_2D( 0, 0, 0, 0 ) 1442 1442 IF ( lconv(ji,jj) ) THEN … … 1444 1444 zri_p = MAX ( SQRT( zdb_bl(ji,jj) * zdh(ji,jj) / MAX( zdu_bl(ji,jj)**2 + zdv_bl(ji,jj)**2, 1.e-8) ) * ( zhbl(ji,jj) / zdh(ji,jj) ) * ( zvstr(ji,jj) / MAX( zustar(ji,jj), 1.e-6 ) )**2 & 1445 1445 & / MAX( zekman(ji,jj), 1.e-6 ) , 5._wp ) 1446 1446 1447 1447 zri_b = zdb_ml(ji,jj) * zdh(ji,jj) / MAX( zdu_ml(ji,jj)**2 + zdv_ml(ji,jj)**2, 1.e-8 ) 1448 1448 1449 1449 zshear(ji,jj) = za_shr * zekman(ji,jj) * ( MAX( zustar(ji,jj)**2 * zdu_ml(ji,jj) / zhbl(ji,jj), 0._wp ) + zb_shr * MAX( -ff_t(ji,jj) * zustke(ji,jj) * dstokes(ji,jj) * zdv_ml(ji,jj) / zhbl(ji,jj), 0._wp ) ) 1450 1450 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! … … 1465 1465 zshear(ji,jj) = 0.5 * zshear(ji,jj) 1466 1466 lshear(ji,jj) = .FALSE. 1467 ENDIF 1468 ENDIF 1467 ENDIF 1468 ENDIF 1469 1469 ELSE ! zdb_bl test, note zshear set to zero 1470 1470 j_ddh(ji,jj) = 2 … … 1473 1473 ENDIF 1474 1474 END_2D 1475 1475 1476 1476 ! Calculate entrainment buoyancy flux due to surface fluxes. 1477 1477 … … 1513 1513 zshear(ji,jj) = zshear(ji,jj) + zshear_u * ( 1.0 - MIN( zri_p / rn_ri_p_thresh, 1.d0 ) ) 1514 1514 zshear(ji,jj) = MIN( zshear(ji,jj), zshear_u ) 1515 1515 1516 1516 zwb_shr = -za_wb_s * zshear(ji,jj) 1517 1518 ENDIF 1517 1518 ENDIF 1519 1519 zwb_ent(ji,jj) = zwb_ent(ji,jj) + zwb_shr 1520 1520 zwb_min(ji,jj) = zwb_ent(ji,jj) + zdh(ji,jj) / zhbl(ji,jj) * zwb0(ji,jj) 1521 1521 ELSE ! IF ( lconv ) THEN - ENDIF 1522 ! Stable OSBL - shear production not coded for first attempt. 1522 ! Stable OSBL - shear production not coded for first attempt. 1523 1523 ENDIF ! lconv 1524 1524 ELSE ! lshear … … 1532 1532 END_2D 1533 1533 END SUBROUTINE zdf_osm_osbl_state 1534 1535 1534 1535 1536 1536 SUBROUTINE zdf_osm_vertical_average( jnlev_av, jp_ext, zt, zs, zb, zu, zv, zdt, zds, zdb, zdu, zdv ) 1537 1537 !!--------------------------------------------------------------------- … … 1636 1636 !! lpyc :: determines whether pycnocline flux-grad relationship needs to be determined 1637 1637 !! lflux :: determines whether effects of surface flux extend below the base of the OSBL 1638 !! lmle :: determines whether the layer with MLE is increasing with time or if base is relaxing towards hbl. 1639 !! 1640 !! ** Method : 1641 !! 1642 !! 1638 !! lmle :: determines whether the layer with MLE is increasing with time or if base is relaxing towards hbl. 1639 !! 1640 !! ** Method : 1641 !! 1642 !! 1643 1643 !!---------------------------------------------------------------------- 1644 1644 1645 1645 ! Outputs 1646 1646 LOGICAL, DIMENSION(jpi,jpj) :: lpyc, lflux, lmle … … 1650 1650 REAL(wp) :: zbuoy, ztmp, zpe_mle_layer 1651 1651 REAL(wp) :: zpe_mle_ref, zwb_ent, zdbdz_mle_int 1652 1652 1653 1653 znd_param(:,:) = 0._wp 1654 1654 … … 1674 1674 END DO 1675 1675 ! Non-dimensional parameter to diagnose the presence of thermocline 1676 1676 1677 1677 znd_param(ji,jj) = ( zpe_mle_layer - zpe_mle_ref ) * ABS( ff_t(ji,jj) ) / ( MAX( zwb_fk(ji,jj), 1.0e-10 ) * zhmle(ji,jj) ) 1678 1678 ENDIF … … 1717 1717 lflux(ji,jj) = .FALSE. 1718 1718 lmle(ji,jj) = .FALSE. 1719 ENDIF ! zdb_bl < rn_mle_thresh_bl and 1719 ENDIF ! zdb_bl < rn_mle_thresh_bl and 1720 1720 ENDIF ! zhmle > 1.2 zhbl 1721 1721 ELSE … … 1724 1724 lmle(ji,jj) = .FALSE. 1725 1725 IF ( zdb_bl(ji,jj) < rn_osm_bl_thresh ) lpyc(ji,jj) = .FALSE. 1726 ENDIF ! -2.0 * zwb_fk(ji,jj) / zwb_ent > 0.5 1726 ENDIF ! -2.0 * zwb_fk(ji,jj) / zwb_ent > 0.5 1727 1727 ELSE 1728 1728 ! Stable Boundary Layer … … 1928 1928 REAL(wp) :: alpha_bc = 0.5 1929 1929 REAL, PARAMETER :: a_ddh = 2.5, a_ddh_2 = 3.5 ! also in pycnocline_depth 1930 1930 1931 1931 DO_2D( 0, 0, 0, 0 ) 1932 1932 1933 1933 IF ( lshear(ji,jj) ) THEN 1934 1934 IF ( lconv(ji,jj) ) THEN ! Convective … … 1965 1965 ! Relaxation to dh_ref = zari * hbl 1966 1966 zddhdt(ji,jj) = -a_ddh_2 * ( 1.0 - zdh(ji,jj) / ( zari * zhbl(ji,jj) ) ) * zwb_ent(ji,jj) / zdb_bl(ji,jj) 1967 1967 1968 1968 ELSE ! j_ddh == 0 1969 1969 ! Growing shear layer … … 2184 2184 dh(ji,jj) = dh(ji,jj) + zddhdt(ji,jj) * rn_Dt 2185 2185 ELSE 2186 ! Temporary (probably) Recalculate dh_ref to ensure dh doesn't go negative. Can't do this using zddhdt from calculate_dhdt 2186 ! Temporary (probably) Recalculate dh_ref to ensure dh doesn't go negative. Can't do this using zddhdt from calculate_dhdt 2187 2187 IF ( ( zwstrc(ji,jj) / zvstr(ji,jj) )**3 <= 0.5 ) THEN 2188 2188 zari = MIN( 1.5 * zdb_bl(ji,jj) / ( zhbl(ji,jj) * ( MAX(zdbdz_bl_ext(ji,jj),0._wp) + zdb_bl(ji,jj)**2 / MAX(4.5 * zvstr(ji,jj)**2 , 1.e-12 )) ), 0.2d0 ) … … 2194 2194 IF ( dh(ji,jj) >= hbl(ji,jj) ) dh(ji,jj) = zari * zhbl(ji,jj) 2195 2195 ENDIF 2196 2196 2197 2197 ELSE ! lconv 2198 ! Initially shear only for entraining OSBL. Stable code will be needed if extended to stable OSBL 2198 ! Initially shear only for entraining OSBL. Stable code will be needed if extended to stable OSBL 2199 2199 2200 2200 ztau = hbl(ji,jj) / MAX(zvstr(ji,jj), epsln) … … 2216 2216 ! Alan: this hml is never defined or used -- do we need it? 2217 2217 ENDIF 2218 2219 ELSE ! lshear 2218 2219 ELSE ! lshear 2220 2220 ! for lshear = .FALSE. calculate ddhdt here 2221 2221 … … 2280 2280 ENDIF ! IF (lconv) 2281 2281 ENDIF ! lshear 2282 2282 2283 2283 hml(ji,jj) = hbl(ji,jj) - dh(ji,jj) 2284 2284 inhml = MAX( INT( dh(ji,jj) / MAX(e3t(ji,jj,ibld(ji,jj),Kmm), 1.e-3) ) , 1 ) … … 2378 2378 & + dbdx_mle(ji-1,jj) * dbdx_mle(ji-1,jj) + dbdy_mle(ji,jj-1) * dbdy_mle(ji,jj-1) ) ) 2379 2379 END_2D 2380 2380 2381 2381 END SUBROUTINE zdf_osm_zmld_horizontal_gradients 2382 2382 SUBROUTINE zdf_osm_mle_parameters( mld_prof, hmle, zhmle, zvel_mle, zdiff_mle ) … … 2416 2416 jkb = mld_prof(ji,jj) 2417 2417 jkb1 = MIN(jkb + 1, mbkt(ji,jj)) 2418 ! 2418 ! 2419 2419 zbuoy = grav * ( zthermal * ts(ji,jj,mld_prof(ji,jj)+2,jp_tem,Kmm) - zbeta * ts(ji,jj,mld_prof(ji,jj)+2,jp_sal,Kmm) ) 2420 zdb_mle = zb_bl(ji,jj) - zbuoy 2421 ! Timestep hmle. 2420 zdb_mle = zb_bl(ji,jj) - zbuoy 2421 ! Timestep hmle. 2422 2422 hmle(ji,jj) = hmle(ji,jj) + zwb0(ji,jj) * rn_Dt / zdb_mle 2423 2423 ELSE -
NEMO/trunk/src/OCE/ZDF/zdfphy.F90
r14045 r14072 9 9 !!---------------------------------------------------------------------- 10 10 !! zdf_phy_init : initialization of all vertical physics packages 11 !! zdf_phy : upadate at each time-step the vertical mixing coeff. 11 !! zdf_phy : upadate at each time-step the vertical mixing coeff. 12 12 !!---------------------------------------------------------------------- 13 13 USE oce ! ocean dynamics and tracers variables 14 USE zdf_oce ! vertical physics: shared variables 14 USE zdf_oce ! vertical physics: shared variables 15 15 USE zdfdrg ! vertical physics: top/bottom drag coef. 16 16 USE zdfsh2 ! vertical physics: shear production term of TKE 17 USE zdfric ! vertical physics: RIChardson dependent vertical mixing 17 USE zdfric ! vertical physics: RIChardson dependent vertical mixing 18 18 USE zdftke ! vertical physics: TKE vertical mixing 19 19 USE zdfgls ! vertical physics: GLS vertical mixing 20 20 USE zdfosm ! vertical physics: OSMOSIS vertical mixing 21 USE zdfddm ! vertical physics: double diffusion mixing 22 USE zdfevd ! vertical physics: convection via enhanced vertical diffusion 23 USE zdfmfc ! vertical physics: Mass Flux Convection 24 USE zdfiwm ! vertical physics: internal wave-induced mixing 21 USE zdfddm ! vertical physics: double diffusion mixing 22 USE zdfevd ! vertical physics: convection via enhanced vertical diffusion 23 USE zdfmfc ! vertical physics: Mass Flux Convection 24 USE zdfiwm ! vertical physics: internal wave-induced mixing 25 25 USE zdfswm ! vertical physics: surface wave-induced mixing 26 26 USE zdfmxl ! vertical physics: mixed layer 27 27 USE tranpc ! convection: non penetrative adjustment 28 USE trc_oce ! variables shared between passive tracer & ocean 28 USE trc_oce ! variables shared between passive tracer & ocean 29 29 USE sbc_oce ! surface module (only for nn_isf in the option compatibility test) 30 30 USE sbcrnf ! surface boundary condition: runoff variables … … 46 46 PUBLIC zdf_phy ! called by step.F90 47 47 48 INTEGER :: nzdf_phy ! type of vertical closure used 48 INTEGER :: nzdf_phy ! type of vertical closure used 49 49 ! ! associated indicators 50 50 INTEGER, PARAMETER :: np_CST = 1 ! Constant Kz … … 66 66 !!---------------------------------------------------------------------- 67 67 !! *** ROUTINE zdf_phy_init *** 68 !! 68 !! 69 69 !! ** Purpose : initializations of the vertical ocean physics 70 70 !! 71 !! ** Method : Read namelist namzdf, control logicals 71 !! ** Method : Read namelist namzdf, control logicals 72 72 !! set horizontal shape and vertical profile of background mixing coef. 73 73 !!---------------------------------------------------------------------- … … 143 143 IF( nn_avb == 0 ) THEN ! Define avmb, avtb from namelist parameter 144 144 avmb(:) = rn_avm0 145 avtb(:) = rn_avt0 145 avtb(:) = rn_avt0 146 146 ELSE ! Background profile of avt (fit a theoretical/observational profile (Krauss 1990) 147 147 avmb(:) = rn_avm0 … … 150 150 ENDIF 151 151 ! ! 2D shape of the avtb 152 avtb_2d(:,:) = 1._wp ! uniform 152 avtb_2d(:,:) = 1._wp ! uniform 153 153 ! 154 154 IF( nn_havtb == 1 ) THEN ! decrease avtb by a factor of ten in the equatorial band … … 198 198 199 199 ! !== type of vertical turbulent closure ==! (set nzdf_phy) 200 ioptio = 0 200 ioptio = 0 201 201 IF( ln_zdfcst ) THEN ; ioptio = ioptio + 1 ; nzdf_phy = np_CST ; ENDIF 202 202 IF( ln_zdfric ) THEN ; ioptio = ioptio + 1 ; nzdf_phy = np_RIC ; CALL zdf_ric_init ; ENDIF … … 236 236 !! ** Purpose : Update ocean physics at each time-step 237 237 !! 238 !! ** Method : 238 !! ** Method : 239 239 !! 240 240 !! ** Action : avm, avt vertical eddy viscosity and diffusivity at w-points … … 254 254 ! 255 255 ! !* bottom drag 256 CALL zdf_drg( kt, Kmm, mbkt , r_Cdmin_bot, r_Cdmax_bot, & ! <<== in 256 CALL zdf_drg( kt, Kmm, mbkt , r_Cdmin_bot, r_Cdmax_bot, & ! <<== in 257 257 & r_z0_bot, r_ke0_bot, rCd0_bot, & 258 258 & rCdU_bot ) ! ==>> out : bottom drag [m/s] 259 259 IF( ln_isfcav ) THEN !* top drag (ocean cavities) 260 CALL zdf_drg( kt, Kmm, mikt , r_Cdmin_top, r_Cdmax_top, & ! <<== in 260 CALL zdf_drg( kt, Kmm, mikt , r_Cdmin_top, r_Cdmax_top, & ! <<== in 261 261 & r_z0_top, r_ke0_top, rCd0_top, & 262 262 & rCdU_top ) ! ==>> out : bottom drag [m/s] … … 273 273 ENDIF 274 274 #endif 275 ! 275 ! 276 276 ! !== Kz from chosen turbulent closure ==! (avm_k, avt_k) 277 277 ! … … 290 290 !!gm avm(2:jpim1,2:jpjm1,1:jpkm1) = rn_avm0 * wmask(2:jpim1,2:jpjm1,1:jpkm1) 291 291 END SELECT 292 ! 292 ! 293 293 ! !== ocean Kz ==! (avt, avs, avm) 294 294 ! … … 312 312 ENDIF 313 313 ! 314 ! !* wave-induced mixing 315 IF( ln_zdfswm ) CALL zdf_swm( kt, Kmm, avm, avt, avs ) ! surface wave (Qiao et al. 2004) 314 ! !* wave-induced mixing 315 IF( ln_zdfswm ) CALL zdf_swm( kt, Kmm, avm, avt, avs ) ! surface wave (Qiao et al. 2004) 316 316 IF( ln_zdfiwm ) CALL zdf_iwm( kt, Kmm, avm, avt, avs ) ! internal wave (de Lavergne et al 2017) 317 317 318 #if defined key_agrif 318 #if defined key_agrif 319 319 ! interpolation parent grid => child grid for avm_k ( ex : at west border: update column 1 and 2) 320 320 IF( l_zdfsh2 ) CALL Agrif_avm … … 340 340 IF( ln_zdftke ) CALL tke_rst( kt, 'WRITE' ) 341 341 IF( ln_zdfgls ) CALL gls_rst( kt, 'WRITE' ) 342 IF( ln_zdfric ) CALL ric_rst( kt, 'WRITE' ) 342 IF( ln_zdfric ) CALL ric_rst( kt, 'WRITE' ) 343 343 ! NB. OSMOSIS restart (osm_rst) will be called in step.F90 after ww has been updated 344 344 ENDIF -
NEMO/trunk/src/OCE/ZDF/zdfric.F90
r13970 r14072 12 12 !! 3.3 ! 2010-10 (C. Ethe, G. Madec) reorganisation of initialisation phase 13 13 !! 3.3.1! 2011-09 (P. Oddo) Mixed layer depth parameterization 14 !! 4.0 ! 2017-04 (G. Madec) remove CPP ddm key & avm at t-point only 14 !! 4.0 ! 2017-04 (G. Madec) remove CPP ddm key & avm at t-point only 15 15 !!---------------------------------------------------------------------- 16 16 … … 28 28 USE in_out_manager ! I/O manager 29 29 USE iom ! I/O manager library 30 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 30 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 31 31 32 32 … … 43 43 REAL(wp) :: rn_alp ! coefficient of the parameterization 44 44 REAL(wp) :: rn_ekmfc ! Ekman Factor Coeff 45 REAL(wp) :: rn_mldmin ! minimum mixed layer (ML) depth 45 REAL(wp) :: rn_mldmin ! minimum mixed layer (ML) depth 46 46 REAL(wp) :: rn_mldmax ! maximum mixed layer depth 47 47 REAL(wp) :: rn_wtmix ! Vertical eddy Diff. in the ML … … 61 61 !!---------------------------------------------------------------------- 62 62 !! *** ROUTINE zdf_ric_init *** 63 !! 63 !! 64 64 !! ** Purpose : Initialization of the vertical eddy diffusivity and 65 65 !! viscosity coef. for the Richardson number dependent formulation. … … 109 109 !!---------------------------------------------------------------------- 110 110 !! *** ROUTINE zdfric *** 111 !! 111 !! 112 112 !! ** Purpose : Compute the before eddy viscosity and diffusivity as 113 113 !! a function of the local richardson number. 114 114 !! 115 !! ** Method : Local richardson number dependent formulation of the 116 !! vertical eddy viscosity and diffusivity coefficients. 115 !! ** Method : Local richardson number dependent formulation of the 116 !! vertical eddy viscosity and diffusivity coefficients. 117 117 !! The eddy coefficients are given by: 118 118 !! avm = avm0 + avmb … … 122 122 !! avm0= rn_avmri / (1 + rn_alp*Ri)**nn_ric 123 123 !! where ri is the before local Richardson number, 124 !! rn_avmri is the maximum value reaches by avm and avt 124 !! rn_avmri is the maximum value reaches by avm and avt 125 125 !! and rn_alp, nn_ric are adjustable parameters. 126 126 !! Typical values : rn_alp=5. and nn_ric=2. … … 164 164 END_3D 165 165 ! 166 !!gm BUG <<<<==== This param can't work at low latitude 166 !!gm BUG <<<<==== This param can't work at low latitude 167 167 !!gm it provides there much to thick mixed layer ( summer 150m in GYRE configuration !!! ) 168 168 ! … … 188 188 !!--------------------------------------------------------------------- 189 189 !! *** ROUTINE ric_rst *** 190 !! 190 !! 191 191 !! ** Purpose : Read or write TKE file (en) in restart file 192 192 !! 193 193 !! ** Method : use of IOM library 194 !! if the restart does not contain TKE, en is either 195 !! set to rn_emin or recomputed 194 !! if the restart does not contain TKE, en is either 195 !! set to rn_emin or recomputed 196 196 !!---------------------------------------------------------------------- 197 197 INTEGER , INTENT(in) :: kt ! ocean time-step … … 202 202 !!---------------------------------------------------------------------- 203 203 ! 204 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 204 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 205 205 ! ! --------------- 206 206 ! !* Read the restart file -
NEMO/trunk/src/OCE/ZDF/zdfsh2.F90
r14007 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE zdfsh2 *** 4 !! Ocean physics: shear production term of TKE 4 !! Ocean physics: shear production term of TKE 5 5 !!===================================================================== 6 6 !! History : - ! 2014-10 (A. Barthelemy, G. Madec) original code … … 36 36 CONTAINS 37 37 38 SUBROUTINE zdf_sh2( Kbb, Kmm, p_avm, p_sh2 ) 38 SUBROUTINE zdf_sh2( Kbb, Kmm, p_avm, p_sh2 ) 39 39 !!---------------------------------------------------------------------- 40 40 !! *** ROUTINE zdf_sh2 *** … … 44 44 !! ** Method : - a stable discretization of this term is linked to the 45 45 !! time-space discretization of the vertical diffusion 46 !! of the OGCM. NEMO uses C-grid, a leap-frog environment 46 !! of the OGCM. NEMO uses C-grid, a leap-frog environment 47 47 !! and an implicit computation of vertical mixing term, 48 48 !! so the shear production at w-point is given by: 49 !! sh2 = mi[ mi(avm) * dk[ub]/e3ub * dk[un]/e3un ] 50 !! + mj[ mj(avm) * dk[vb]/e3vb * dk[vn]/e3vn ] 49 !! sh2 = mi[ mi(avm) * dk[ub]/e3ub * dk[un]/e3un ] 50 !! + mj[ mj(avm) * dk[vb]/e3vb * dk[vn]/e3vn ] 51 51 !! NB: wet-point only horizontal averaging of shear 52 52 !! … … 81 81 zsh2u(ji,jj) = ( p_avm(ji+1,jj,jk) + p_avm(ji,jj,jk) ) & 82 82 & * ( uu(ji,jj,jk-1,Kmm) - uu(ji,jj,jk,Kmm) ) & 83 & * ( uu(ji,jj,jk-1,Kbb) - uu(ji,jj,jk,Kbb) ) & 83 & * ( uu(ji,jj,jk-1,Kbb) - uu(ji,jj,jk,Kbb) ) & 84 84 & / ( e3uw(ji,jj,jk ,Kmm) * e3uw(ji,jj,jk,Kbb) ) & 85 85 & * wumask(ji,jj,jk) -
NEMO/trunk/src/OCE/ZDF/zdftke.F90
r14057 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE zdftke *** 4 !! Ocean physics: vertical mixing coefficient computed from the tke 4 !! Ocean physics: vertical mixing coefficient computed from the tke 5 5 !! turbulent closure parameterization 6 6 !!===================================================================== … … 22 22 !! - ! 2008-05 (J.-M. Molines, G. Madec) 2D form of avtb 23 23 !! - ! 2008-06 (G. Madec) style + DOCTOR name for namelist parameters 24 !! - ! 2008-12 (G. Reffray) stable discretization of the production term 25 !! 3.2 ! 2009-06 (G. Madec, S. Masson) TKE restart compatible with key_cpl 24 !! - ! 2008-12 (G. Reffray) stable discretization of the production term 25 !! 3.2 ! 2009-06 (G. Madec, S. Masson) TKE restart compatible with key_cpl 26 26 !! ! + cleaning of the parameters + bugs correction 27 27 !! 3.3 ! 2010-10 (C. Ethe, G. Madec) reorganisation of initialisation phase 28 28 !! 3.6 ! 2014-11 (P. Mathiot) add ice shelf capability 29 !! 4.0 ! 2017-04 (G. Madec) remove CPP ddm key & avm at t-point only 29 !! 4.0 ! 2017-04 (G. Madec) remove CPP ddm key & avm at t-point only 30 30 !! - ! 2017-05 (G. Madec) add top/bottom friction as boundary condition 31 31 !! 4.2 ! 2020-12 (G. Madec, E. Clementi) add wave coupling … … 59 59 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 60 60 USE prtctl ! Print control 61 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 61 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 62 62 USE sbcwave ! Surface boundary waves 63 63 … … 78 78 INTEGER :: nn_pdl ! Prandtl number or not (ratio avt/avm) (=0/1) 79 79 REAL(wp) :: rn_ediff ! coefficient for avt: avt=rn_ediff*mxl*sqrt(e) 80 REAL(wp) :: rn_ediss ! coefficient of the Kolmogoroff dissipation 80 REAL(wp) :: rn_ediss ! coefficient of the Kolmogoroff dissipation 81 81 REAL(wp) :: rn_ebb ! coefficient of the surface input of tke 82 82 REAL(wp) :: rn_emin ! minimum value of tke [m2/s2] … … 90 90 LOGICAL :: ln_lc ! Langmuir cells (LC) as a source term of TKE or not 91 91 REAL(wp) :: rn_lc ! coef to compute vertical velocity of Langmuir cells 92 INTEGER :: nn_eice ! attenutaion of langmuir & surface wave breaking under ice (=0/1/2/3) 92 INTEGER :: nn_eice ! attenutaion of langmuir & surface wave breaking under ice (=0/1/2/3) 93 93 94 94 REAL(wp) :: ri_cri ! critic Richardson number (deduced from rn_ediff and rn_ediss values) … … 139 139 !! surface: en = max( rn_emin0, rn_ebb * taum ) 140 140 !! bottom : en = rn_emin 141 !! The associated critical Richardson number is: ri_cri = 2/(2+rn_ediss/rn_ediff) 142 !! 143 !! The now Turbulent kinetic energy is computed using the following 141 !! The associated critical Richardson number is: ri_cri = 2/(2+rn_ediss/rn_ediff) 142 !! 143 !! The now Turbulent kinetic energy is computed using the following 144 144 !! time stepping: implicit for vertical diffusion term, linearized semi 145 !! implicit for kolmogoroff dissipation term, and explicit forward for 146 !! both buoyancy and shear production terms. Therefore a tridiagonal 145 !! implicit for kolmogoroff dissipation term, and explicit forward for 146 !! both buoyancy and shear production terms. Therefore a tridiagonal 147 147 !! linear system is solved. Note that buoyancy and shear terms are 148 148 !! discretized in a energy conserving form (Bruchard 2002). … … 152 152 !! 153 153 !! The now vertical eddy vicosity and diffusivity coefficients are 154 !! given by: 154 !! given by: 155 155 !! avm = max( avtb, rn_ediff * zmxlm * en^1/2 ) 156 !! avt = max( avmb, pdl * avm ) 156 !! avt = max( avmb, pdl * avm ) 157 157 !! eav = max( avmb, avm ) 158 158 !! where pdl, the inverse of the Prandtl number is 1 if nn_pdl=0 and 159 !! given by an empirical funtion of the localRichardson number if nn_pdl=1 159 !! given by an empirical funtion of the localRichardson number if nn_pdl=1 160 160 !! 161 161 !! ** Action : compute en (now turbulent kinetic energy) … … 193 193 !! a tridiagonal linear system by a "methode de chasse" 194 194 !! - increase TKE due to surface and internal wave breaking 195 !! NB: when sea-ice is present, both LC parameterization 196 !! and TKE penetration are turned off when the ice fraction 197 !! is smaller than 0.25 195 !! NB: when sea-ice is present, both LC parameterization 196 !! and TKE penetration are turned off when the ice fraction 197 !! is smaller than 0.25 198 198 !! 199 199 !! ** Action : - en : now turbulent kinetic energy) … … 223 223 zbbrau = rn_ebb / rho0 ! Local constant initialisation 224 224 zbbirau = 3.75_wp / rho0 225 zfact1 = -.5_wp * rn_Dt 225 zfact1 = -.5_wp * rn_Dt 226 226 zfact2 = 1.5_wp * rn_Dt * rn_ediss 227 227 zfact3 = 0.5_wp * rn_ediss … … 244 244 en(ji,jj,1) = MAX( rn_emin0, zbbrau * taum(ji,jj) ) 245 245 zdiag(ji,jj,1) = 1._wp/en(ji,jj,1) 246 zd_lw(ji,jj,1) = 1._wp 246 zd_lw(ji,jj,1) = 1._wp 247 247 zd_up(ji,jj,1) = 0._wp 248 248 END_2D … … 345 345 END_2D 346 346 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) !* TKE Langmuir circulation source term added to en 347 IF ( zus3(ji,jj) /= 0._wp ) THEN 347 IF ( zus3(ji,jj) /= 0._wp ) THEN 348 348 IF ( gdepw(ji,jj,jk,Kmm) - zhlc(ji,jj) < 0 .AND. wmask(ji,jj,jk) /= 0. ) THEN 349 349 ! ! vertical velocity due to LC … … 376 376 END_3D 377 377 ENDIF 378 ! 378 ! 379 379 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) !* Matrix and right hand side in en 380 380 zcof = zfact1 * tmask(ji,jj,jk) … … 403 403 ! 404 404 IF ( cpl_phioc .and. ln_phioc ) THEN 405 SELECT CASE (nn_bc_surf) ! Boundary Condition using surface TKE flux from waves 405 SELECT CASE (nn_bc_surf) ! Boundary Condition using surface TKE flux from waves 406 406 407 407 CASE ( 0 ) ! Dirichlet BC … … 456 456 ! 457 457 IF( nn_etau == 1 ) THEN !* penetration below the mixed layer (rn_efr fraction) 458 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) 458 DO_3D( 0, 0, 0, 0, 2, jpkm1 ) 459 459 en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -gdepw(ji,jj,jk,Kmm) / htau(ji,jj) ) & 460 460 & * MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * wmask(ji,jj,jk) * tmask(ji,jj,1) … … 470 470 ztx2 = utau(ji-1,jj ) + utau(ji,jj) 471 471 zty2 = vtau(ji ,jj-1) + vtau(ji,jj) 472 ztau = 0.5_wp * SQRT( ztx2 * ztx2 + zty2 * zty2 ) * tmask(ji,jj,1) ! module of the mean stress 473 zdif = taum(ji,jj) - ztau ! mean of modulus - modulus of the mean 472 ztau = 0.5_wp * SQRT( ztx2 * ztx2 + zty2 * zty2 ) * tmask(ji,jj,1) ! module of the mean stress 473 zdif = taum(ji,jj) - ztau ! mean of modulus - modulus of the mean 474 474 zdif = rhftau_scl * MAX( 0._wp, zdif + rhftau_add ) ! apply some modifications... 475 475 en(ji,jj,jk) = en(ji,jj,jk) + zbbrau * zdif * EXP( -gdepw(ji,jj,jk,Kmm) / htau(ji,jj) ) & … … 487 487 !! ** Purpose : Compute the vertical eddy viscosity and diffusivity 488 488 !! 489 !! ** Method : At this stage, en, the now TKE, is known (computed in 490 !! the tke_tke routine). First, the now mixing lenth is 489 !! ** Method : At this stage, en, the now TKE, is known (computed in 490 !! the tke_tke routine). First, the now mixing lenth is 491 491 !! computed from en and the strafification (N^2), then the mixings 492 492 !! coefficients are computed. 493 493 !! - Mixing length : a first evaluation of the mixing lengh 494 494 !! scales is: 495 !! mxl = sqrt(2*en) / N 495 !! mxl = sqrt(2*en) / N 496 496 !! where N is the brunt-vaisala frequency, with a minimum value set 497 497 !! to rmxl_min (rn_mxl0) in the interior (surface) ocean. 498 !! The mixing and dissipative length scale are bound as follow : 498 !! The mixing and dissipative length scale are bound as follow : 499 499 !! nn_mxl=0 : mxl bounded by the distance to surface and bottom. 500 500 !! zmxld = zmxlm = mxl 501 501 !! nn_mxl=1 : mxl bounded by the e3w and zmxld = zmxlm = mxl 502 !! nn_mxl=2 : mxl bounded such that the vertical derivative of mxl is 502 !! nn_mxl=2 : mxl bounded such that the vertical derivative of mxl is 503 503 !! less than 1 (|d/dz(mxl)|<1) and zmxld = zmxlm = mxl 504 504 !! nn_mxl=3 : mxl is bounded from the surface to the bottom usings 505 !! |d/dz(xml)|<1 to obtain lup, and from the bottom to 506 !! the surface to obtain ldown. the resulting length 505 !! |d/dz(xml)|<1 to obtain lup, and from the bottom to 506 !! the surface to obtain ldown. the resulting length 507 507 !! scales are: 508 !! zmxld = sqrt( lup * ldown ) 508 !! zmxld = sqrt( lup * ldown ) 509 509 !! zmxlm = min ( lup , ldown ) 510 510 !! - Vertical eddy viscosity and diffusivity: 511 511 !! avm = max( avtb, rn_ediff * zmxlm * en^1/2 ) 512 !! avt = max( avmb, pdlr * avm ) 512 !! avt = max( avmb, pdlr * avm ) 513 513 !! with pdlr=1 if nn_pdl=0, pdlr=1/pdl=F(Ri) otherwise. 514 514 !! … … 534 534 ! 535 535 ! initialisation of interior minimum value (avoid a 2d loop with mikt) 536 zmxlm(:,:,:) = rmxl_min 536 zmxlm(:,:,:) = rmxl_min 537 537 zmxld(:,:,:) = rmxl_min 538 538 ! … … 543 543 zmxlm(:,:,1)= zcoef * MAX ( 1.6 * hsw(:,:) , 0.02 ) ! surface mixing length = F(wave height) 544 544 ELSE 545 ! 545 ! 546 546 IF( ln_mxl0 ) THEN ! surface mixing length = F(stress) : l=vkarmn*2.e5*taum/(rho0*g) 547 547 ! … … 603 603 ! !* Physical limits for the mixing length 604 604 ! 605 zmxld(:,:, 1 ) = zmxlm(:,:,1) ! surface set to the minimum value 605 zmxld(:,:, 1 ) = zmxlm(:,:,1) ! surface set to the minimum value 606 606 zmxld(:,:,jpk) = rmxl_min ! last level set to the minimum value 607 607 ! … … 686 686 !!---------------------------------------------------------------------- 687 687 !! *** ROUTINE zdf_tke_init *** 688 !! 689 !! ** Purpose : Initialization of the vertical eddy diffivity and 688 !! 689 !! ** Purpose : Initialization of the vertical eddy diffivity and 690 690 !! viscosity when using a tke turbulent closure scheme 691 691 !! … … 707 707 & rn_mxl0 , nn_mxlice, rn_mxlice, & 708 708 & nn_pdl , ln_lc , rn_lc , & 709 & nn_etau , nn_htau , rn_efr , nn_eice , & 709 & nn_etau , nn_htau , rn_efr , nn_eice , & 710 710 & nn_bc_surf, nn_bc_bot, ln_mxhsw 711 711 !!---------------------------------------------------------------------- … … 760 760 WRITE(numout,*) ' fraction of TKE that penetrates rn_efr = ', rn_efr 761 761 WRITE(numout,*) ' langmuir & surface wave breaking under ice nn_eice = ', nn_eice 762 SELECT CASE( nn_eice ) 762 SELECT CASE( nn_eice ) 763 763 CASE( 0 ) ; WRITE(numout,*) ' ==>>> no impact of ice cover on langmuir & surface wave breaking' 764 764 CASE( 1 ) ; WRITE(numout,*) ' ==>>> weigthed by 1-TANH( fr_i(:,:) * 10 )' … … 767 767 CASE DEFAULT 768 768 CALL ctl_stop( 'zdf_tke_init: wrong value for nn_eice, should be 0,1,2, or 3') 769 END SELECT 769 END SELECT 770 770 WRITE(numout,*) 771 771 WRITE(numout,*) ' ==>>> critical Richardson nb with your parameters ri_cri = ', ri_cri … … 796 796 rn_mxl0 = rmxl_min 797 797 ENDIF 798 799 IF( nn_etau == 2 ) CALL zdf_mxl( nit000, Kmm ) ! Initialization of nmln 798 799 IF( nn_etau == 2 ) CALL zdf_mxl( nit000, Kmm ) ! Initialization of nmln 800 800 801 801 ! !* depth of penetration of surface tke 802 IF( nn_etau /= 0 ) THEN 802 IF( nn_etau /= 0 ) THEN 803 803 SELECT CASE( nn_htau ) ! Choice of the depth of penetration 804 804 CASE( 0 ) ! constant depth penetration (here 10 meters) 805 805 htau(:,:) = 10._wp 806 806 CASE( 1 ) ! F(latitude) : 0.5m to 30m poleward of 40 degrees 807 htau(:,:) = MAX( 0.5_wp, MIN( 30._wp, 45._wp* ABS( SIN( rpi/180._wp * gphit(:,:) ) ) ) ) 807 htau(:,:) = MAX( 0.5_wp, MIN( 30._wp, 45._wp* ABS( SIN( rpi/180._wp * gphit(:,:) ) ) ) ) 808 808 END SELECT 809 809 ENDIF 810 810 ! !* read or initialize all required files 811 CALL tke_rst( nit000, 'READ' ) ! (en, avt_k, avm_k, dissl) 811 CALL tke_rst( nit000, 'READ' ) ! (en, avt_k, avm_k, dissl) 812 812 ! 813 813 END SUBROUTINE zdf_tke_init … … 817 817 !!--------------------------------------------------------------------- 818 818 !! *** ROUTINE tke_rst *** 819 !! 819 !! 820 820 !! ** Purpose : Read or write TKE file (en) in restart file 821 821 !! 822 822 !! ** Method : use of IOM library 823 !! if the restart does not contain TKE, en is either 824 !! set to rn_emin or recomputed 823 !! if the restart does not contain TKE, en is either 824 !! set to rn_emin or recomputed 825 825 !!---------------------------------------------------------------------- 826 826 USE zdf_oce , ONLY : en, avt_k, avm_k ! ocean vertical physics … … 833 833 !!---------------------------------------------------------------------- 834 834 ! 835 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 835 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 836 836 ! ! --------------- 837 837 IF( ln_rstart ) THEN !* Read the restart file -
NEMO/trunk/src/OCE/do_loop_substitute.h90
r13982 r14072 14 14 ! DO jj = .... DO jj = ... 15 15 ! DO ji = .... DO ji = ... 16 ! . OR . 16 ! . OR . 17 17 ! . . 18 18 ! END DO END DO … … 25 25 ! Upper limits of jpi, jpim1 or fs_jpim1 (for ji) or jpj, jpjm1 or fs_jpjm1 (for jj) 26 26 ! 27 ! The macro naming convention takes the form: DO_2D( B, T, L, R) where: 27 ! The macro naming convention takes the form: DO_2D( B, T, L, R) where: 28 28 ! B is the Bottom offset from the PE's inner domain; 29 29 ! T is the Top offset from the PE's inner domain; … … 32 32 ! 33 33 ! So, given an inner domain of 2,jpim1 and 2,jpjm1, a typical example would replace: 34 ! 34 ! 35 35 ! DO jj = 2, jpj 36 36 ! DO ji = 1, jpim1 … … 46 46 ! . 47 47 ! END_2D 48 ! 49 ! similar conventions apply to the 3D loops macros. jk loop limits are retained through macro arguments 50 ! and are not restricted. This includes the possibility of strides for which an extra set of DO_3DS 48 ! 49 ! similar conventions apply to the 3D loops macros. jk loop limits are retained through macro arguments 50 ! and are not restricted. This includes the possibility of strides for which an extra set of DO_3DS 51 51 ! macros are defined. 52 52 ! 53 ! In the following definitions the inner PE domain is defined by start indices of (Nis0, Njs0) and end 53 ! In the following definitions the inner PE domain is defined by start indices of (Nis0, Njs0) and end 54 54 ! indices of (Nie0, Nje0) where: 55 55 ! 56 56 ! Nis0 = 1 + nn_hls Njs0 = 1 + nn_hls 57 57 ! Nie0 = jpi - nn_hls Nje0 = jpj - nn_hls 58 ! 58 ! 59 59 #endif 60 60 -
NEMO/trunk/src/OCE/nemogcm.F90
r14053 r14072 29 29 !! 3.3.1! 2011-01 (A. R. Porter, STFC Daresbury) dynamical allocation 30 30 !! - ! 2011-11 (C. Harris) decomposition changes for running with CICE 31 !! 3.6 ! 2012-05 (C. Calone, J. Simeon, G. Madec, C. Ethe) Add grid coarsening 31 !! 3.6 ! 2012-05 (C. Calone, J. Simeon, G. Madec, C. Ethe) Add grid coarsening 32 32 !! - ! 2014-12 (G. Madec) remove KPP scheme and cross-land advection (cla) 33 33 !! 4.0 ! 2016-10 (G. Madec, S. Flavoni) domain configuration / user defined interface … … 74 74 USE lib_mpp ! distributed memory computing 75 75 USE mppini ! shared/distributed memory setting (mpp_init routine) 76 USE lbcnfd , ONLY : isendto, nsndto ! Setup of north fold exchanges 76 USE lbcnfd , ONLY : isendto, nsndto ! Setup of north fold exchanges 77 77 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 78 78 USE halo_mng ! Halo manager … … 184 184 CALL stp_MLF ( istp ) 185 185 # else 186 CALL stp ( istp ) 186 CALL stp ( istp ) 187 187 # endif 188 188 istp = istp + 1 … … 195 195 ! 196 196 DO WHILE( istp <= nitend .AND. nstop == 0 ) 197 CALL stp_diurnal( istp ) ! time step only the diurnal SST 197 CALL stp_diurnal( istp ) ! time step only the diurnal SST 198 198 istp = istp + 1 199 199 END DO … … 308 308 #ifdef key_agrif 309 309 ELSE 310 numnul = Agrif_Parent(numnul) 310 numnul = Agrif_Parent(numnul) 311 311 #endif 312 312 ENDIF … … 373 373 903 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namcfg in reference namelist' ) 374 374 READ ( numnam_cfg, namcfg, IOSTAT = ios, ERR = 904 ) 375 904 IF( ios > 0 ) CALL ctl_nam ( ios , 'namcfg in configuration namelist' ) 375 904 IF( ios > 0 ) CALL ctl_nam ( ios , 'namcfg in configuration namelist' ) 376 376 ! 377 377 IF( ln_read_cfg ) THEN ! Read sizes in domain configuration file … … 396 396 #if defined key_agrif 397 397 Kbb_a = Nbb ; Kmm_a = Nnn ; Krhs_a = Nrhs ! agrif_oce module copies of time level indices 398 #endif 398 #endif 399 399 ! !-------------------------------! 400 400 ! ! NEMO general initialization ! … … 416 416 #endif 417 417 CALL dom_init( Nbb, Nnn, Naa ) ! Domain 418 IF( ln_crs ) CALL crs_init( Nnn ) ! coarsened grid: domain initialization 418 IF( ln_crs ) CALL crs_init( Nnn ) ! coarsened grid: domain initialization 419 419 IF( sn_cfctl%l_prtctl ) & 420 420 & CALL prt_ctl_init ! Print control 421 421 422 422 CALL diurnal_sst_bulk_init ! diurnal sst 423 IF( ln_diurnal ) CALL diurnal_sst_coolskin_init ! cool skin 424 ! 423 IF( ln_diurnal ) CALL diurnal_sst_coolskin_init ! cool skin 424 ! 425 425 IF( ln_diurnal_only ) THEN ! diurnal only: a subset of the initialisation routines 426 426 CALL istate_init( Nbb, Nnn, Naa ) ! ocean initial state (Dynamics and tracers) … … 430 430 CALL dia_obs_init( Nnn ) ! Initialize observational data 431 431 CALL dia_obs( nit000 - 1, Nnn ) ! Observation operator for restart 432 ENDIF 432 ENDIF 433 433 IF( lk_asminc ) CALL asm_inc_init( Nbb, Nnn, Nrhs ) ! Assimilation increments 434 434 ! … … 439 439 CALL istate_init( Nbb, Nnn, Naa ) ! ocean initial state (Dynamics and tracers) 440 440 441 ! ! external forcing 441 ! ! external forcing 442 442 CALL tide_init ! tidal harmonics 443 443 CALL sbc_init( Nbb, Nnn, Naa ) ! surface boundary conditions (including sea-ice) … … 446 446 ! ! Ocean physics 447 447 CALL zdf_phy_init( Nnn ) ! Vertical physics 448 448 449 449 ! ! Lateral physics 450 450 CALL ldf_tra_init ! Lateral ocean tracer physics … … 482 482 CALL sto_par_init ! Stochastic parametrization 483 483 IF( ln_sto_eos ) CALL sto_pts_init ! RRandom T/S fluctuations 484 484 485 485 ! ! Diagnostics 486 486 CALL flo_init( Nnn ) ! drifting Floats … … 526 526 WRITE(numout,*) ' sn_cfctl%l_prttrc = ', sn_cfctl%l_prttrc 527 527 WRITE(numout,*) ' sn_cfctl%l_oasout = ', sn_cfctl%l_oasout 528 WRITE(numout,*) ' sn_cfctl%procmin = ', sn_cfctl%procmin 529 WRITE(numout,*) ' sn_cfctl%procmax = ', sn_cfctl%procmax 530 WRITE(numout,*) ' sn_cfctl%procincr = ', sn_cfctl%procincr 531 WRITE(numout,*) ' sn_cfctl%ptimincr = ', sn_cfctl%ptimincr 528 WRITE(numout,*) ' sn_cfctl%procmin = ', sn_cfctl%procmin 529 WRITE(numout,*) ' sn_cfctl%procmax = ', sn_cfctl%procmax 530 WRITE(numout,*) ' sn_cfctl%procincr = ', sn_cfctl%procincr 531 WRITE(numout,*) ' sn_cfctl%ptimincr = ', sn_cfctl%ptimincr 532 532 WRITE(numout,*) ' timing by routine ln_timing = ', ln_timing 533 533 WRITE(numout,*) ' CFL diagnostics ln_diacfl = ', ln_diacfl … … 599 599 !!---------------------------------------------------------------------- 600 600 ! 601 ierr = oce_alloc () ! ocean 601 ierr = oce_alloc () ! ocean 602 602 ierr = ierr + dia_wri_alloc() 603 603 ierr = ierr + dom_oce_alloc() ! ocean domain … … 611 611 END SUBROUTINE nemo_alloc 612 612 613 613 614 614 SUBROUTINE nemo_set_cfctl(sn_cfctl, setto ) 615 615 !!---------------------------------------------------------------------- -
NEMO/trunk/src/OCE/par_oce.F90
r13982 r14072 22 22 ! 23 23 LOGICAL :: ln_use_jattr !: input file read offset 24 ! ! Use file global attribute: open_ocean_jstart to determine start j-row 25 ! ! when reading input from those netcdf files that have the 26 ! ! attribute defined. This is designed to enable input files associated 27 ! ! with the extended grids used in the under ice shelf configurations to 24 ! ! Use file global attribute: open_ocean_jstart to determine start j-row 25 ! ! when reading input from those netcdf files that have the 26 ! ! attribute defined. This is designed to enable input files associated 27 ! ! with the extended grids used in the under ice shelf configurations to 28 28 ! ! be used without redundant rows when the ice shelves are not in use. 29 29 LOGICAL :: ln_closea !: (=T) special treatment of closed sea 30 ! 30 ! 31 31 32 32 !!--------------------------------------------------------------------- 33 !! Domain Matrix size 33 !! Domain Matrix size 34 34 !!--------------------------------------------------------------------- 35 35 ! configuration name & resolution (required only in ORCA family case) 36 36 CHARACTER(lc) :: cn_cfg !: name of the configuration 37 INTEGER :: nn_cfg !: resolution of the configuration 37 INTEGER :: nn_cfg !: resolution of the configuration 38 38 39 39 ! time dimension … … 84 84 !!---------------------------------------------------------------------- 85 85 !! if we dont use massively parallel computer (parameters jpni=jpnj=1) so jpiglo=jpi and jpjglo=jpj 86 INTEGER, PUBLIC :: jpni !: number of processors following i 86 INTEGER, PUBLIC :: jpni !: number of processors following i 87 87 INTEGER, PUBLIC :: jpnj !: number of processors following j 88 88 INTEGER, PUBLIC :: jpnij !: nb of local domain = nb of processors ( <= jpni x jpnj ) 89 INTEGER, PUBLIC, PARAMETER :: jpr2di = 0 !: number of columns for extra outer halo 90 INTEGER, PUBLIC, PARAMETER :: jpr2dj = 0 !: number of rows for extra outer halo 89 INTEGER, PUBLIC, PARAMETER :: jpr2di = 0 !: number of columns for extra outer halo 90 INTEGER, PUBLIC, PARAMETER :: jpr2dj = 0 !: number of rows for extra outer halo 91 91 92 92 ! halo with and starting/inding DO-loop indices … … 101 101 !!---------------------------------------------------------------------- 102 102 !! NEMO/OCE 4.0 , NEMO Consortium (2018) 103 !! $Id$ 103 !! $Id$ 104 104 !! Software governed by the CeCILL license (see ./LICENSE) 105 105 !!====================================================================== -
NEMO/trunk/src/OCE/step.F90
r14053 r14072 27 27 !! 3.6 ! 2014-04 (F. Roquet, G. Madec) New equations of state 28 28 !! 3.6 ! 2014-10 (E. Clementi, P. Oddo) Add Qiao vertical mixing in case of waves 29 !! 3.7 ! 2014-10 (G. Madec) LDF simplication 29 !! 3.7 ! 2014-10 (G. Madec) LDF simplication 30 30 !! - ! 2014-12 (G. Madec) remove KPP scheme 31 31 !! - ! 2015-11 (J. Chanut) free surface simplification (remove filtered free surface) … … 109 109 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 110 110 ! 111 IF( l_1st_euler ) THEN 111 IF( l_1st_euler ) THEN 112 112 ! start or restart with Euler 1st time-step 113 rDt = rn_Dt 113 rDt = rn_Dt 114 114 r1_Dt = 1._wp / rDt 115 115 ENDIF 116 116 ! 117 117 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 118 ! update I/O and calendar 118 ! update I/O and calendar 119 119 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 120 120 IF( kstp == nit000 ) THEN ! initialize IOM context (must be done after nemo_init for AGRIF+XIOS+OASIS) … … 149 149 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 150 150 IF( ln_tide ) CALL tide_update( kstp ) ! update tide potential 151 IF( ln_apr_dyn ) CALL sbc_apr ( kstp ) ! atmospheric pressure (NB: call before bdy_dta which needs ssh_ib) 151 IF( ln_apr_dyn ) CALL sbc_apr ( kstp ) ! atmospheric pressure (NB: call before bdy_dta which needs ssh_ib) 152 152 IF( ln_bdy ) CALL bdy_dta ( kstp, Nnn ) ! update dynamic & tracer data at open boundaries 153 153 IF( ln_isf ) CALL isf_stp ( kstp, Nnn ) … … 184 184 & CALL zps_hde_isf( kstp, Nnn, jpts, ts(:,:,:,:,Nbb), gtsu, gtsv, gtui, gtvi, & ! Partial steps for top cell (ISF) 185 185 & rhd, gru , grv , grui, grvi ) ! of t, s, rd at the first ocean level 186 IF( ln_traldf_triad ) THEN 186 IF( ln_traldf_triad ) THEN 187 187 CALL ldf_slp_triad( kstp, Nbb, Nnn ) ! before slope for triad operator 188 ELSE 188 ELSE 189 189 CALL ldf_slp ( kstp, rhd, rn2b, Nbb, Nnn ) ! before slope for standard operator 190 190 ENDIF … … 192 192 ! ! eddy diffusivity coeff. 193 193 IF( l_ldftra_time .OR. l_ldfeiv_time ) CALL ldf_tra( kstp, Nbb, Nnn ) ! and/or eiv coeff. 194 IF( l_ldfdyn_time ) CALL ldf_dyn( kstp, Nbb ) ! eddy viscosity coeff. 194 IF( l_ldfdyn_time ) CALL ldf_dyn( kstp, Nbb ) ! eddy viscosity coeff. 195 195 196 196 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> … … 199 199 200 200 CALL ssh_nxt ( kstp, Nbb, Nnn, ssh, Naa ) ! after ssh (includes call to div_hor) 201 IF( .NOT.ln_linssh ) CALL dom_vvl_sf_nxt( kstp, Nbb, Nnn, Naa ) ! after vertical scale factors 202 CALL wzv ( kstp, Nbb, Nnn, Naa, ww ) ! now cross-level velocity 201 IF( .NOT.ln_linssh ) CALL dom_vvl_sf_nxt( kstp, Nbb, Nnn, Naa ) ! after vertical scale factors 202 CALL wzv ( kstp, Nbb, Nnn, Naa, ww ) ! now cross-level velocity 203 203 IF( ln_zad_Aimp ) CALL wAimp ( kstp, Nnn ) ! Adaptive-implicit vertical advection partitioning 204 204 CALL eos ( ts(:,:,:,:,Nnn), rhd, rhop, gdept(:,:,:,Nnn) ) ! now in situ density for hpg computation 205 206 205 206 207 207 uu(:,:,:,Nrhs) = 0._wp ! set dynamics trends to zero 208 208 vv(:,:,:,Nrhs) = 0._wp … … 212 212 IF( ln_bdy ) CALL bdy_dyn3d_dmp ( kstp, Nbb, uu, vv, Nrhs ) ! bdy damping trends 213 213 #if defined key_agrif 214 IF(.NOT. Agrif_Root()) & 214 IF(.NOT. Agrif_Root()) & 215 215 & CALL Agrif_Sponge_dyn ! momentum sponge 216 216 #endif … … 229 229 CALL dyn_zdf ( kstp, Nbb, Nnn, Nrhs, uu, vv, Naa ) ! vertical diffusion 230 230 IF( ln_dynspg_ts ) THEN ! vertical scale factors and vertical velocity need to be updated 231 CALL wzv ( kstp, Nbb, Nnn, Naa, ww ) ! now cross-level velocity 231 CALL wzv ( kstp, Nbb, Nnn, Naa, ww ) ! now cross-level velocity 232 232 IF( ln_zad_Aimp ) CALL wAimp ( kstp, Nnn ) ! Adaptive-implicit vertical advection partitioning 233 233 ENDIF 234 234 235 235 236 236 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 237 237 ! cool skin 238 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 238 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 239 239 IF ( ln_diurnal ) CALL diurnal_layers( kstp ) 240 240 241 241 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 242 242 ! diagnostics and outputs … … 252 252 IF( lk_diadetide ) CALL dia_detide( kstp ) ! Weights computation for daily detiding of model diagnostics 253 253 IF( lk_diamlr ) CALL dia_mlr ! Update time used in multiple-linear-regression analysis 254 254 255 255 #if defined key_top 256 256 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> … … 261 261 262 262 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 263 ! Active tracers 263 ! Active tracers 264 264 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 265 265 ! Loop over tile domains … … 294 294 295 295 CALL tra_adv ( kstp, Nbb, Nnn, ts, Nrhs ) ! hor. + vert. advection ==> RHS 296 IF( ln_zdfmfc ) CALL tra_mfc ( kstp, Nbb, ts, Nrhs ) ! Mass Flux Convection 296 IF( ln_zdfmfc ) CALL tra_mfc ( kstp, Nbb, ts, Nrhs ) ! Mass Flux Convection 297 297 IF( ln_zdfosm ) CALL tra_osm ( kstp, Nnn, ts, Nrhs ) ! OSMOSIS non-local tracer fluxes ==> RHS 298 298 IF( lrst_oce .AND. ln_zdfosm ) & … … 308 308 ! Set boundary conditions, time filter and swap time levels 309 309 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 310 !!jc1: For agrif, it would be much better to finalize tracers/momentum here (e.g. bdy conditions) and move the swap 311 !! (and time filtering) after Agrif update. Then restart would be done after and would contain updated fields. 312 !! If so: 310 !!jc1: For agrif, it would be much better to finalize tracers/momentum here (e.g. bdy conditions) and move the swap 311 !! (and time filtering) after Agrif update. Then restart would be done after and would contain updated fields. 312 !! If so: 313 313 !! (i) no need to call agrif update at initialization time 314 !! (ii) no need to update "before" fields 314 !! (ii) no need to update "before" fields 315 315 !! 316 !! Apart from creating new tra_swp/dyn_swp routines, this however: 317 !! (i) makes boundary conditions at initialization time computed from updated fields which is not the case between 318 !! two restarts => restartability issue. One can circumvent this, maybe, by assuming "interface separation", 319 !! e.g. a shift of the feedback interface inside child domain. 316 !! Apart from creating new tra_swp/dyn_swp routines, this however: 317 !! (i) makes boundary conditions at initialization time computed from updated fields which is not the case between 318 !! two restarts => restartability issue. One can circumvent this, maybe, by assuming "interface separation", 319 !! e.g. a shift of the feedback interface inside child domain. 320 320 !! (ii) requires that all restart outputs of updated variables by agrif (e.g. passive tracers/tke/barotropic arrays) are done at the same 321 321 !! place. 322 !! 322 !! 323 323 !!jc2: dynnxt must be the latest call. e3t(:,:,:,Nbb) are indeed updated in that routine 324 324 CALL tra_atf ( kstp, Nbb, Nnn, Naa, ts ) ! time filtering of "now" tracer arrays … … 347 347 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 348 348 ! AGRIF recursive integration 349 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 349 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 350 350 Kbb_a = Nbb; Kmm_a = Nnn; Krhs_a = Nrhs ! agrif_oce module copies of time level indices 351 351 CALL Agrif_Integrate_ChildGrids( stp ) ! allows to finish all the Child Grids before updating … … 360 360 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 361 361 ! AGRIF update 362 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 362 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 363 363 IF( Agrif_NbStepint() == 0 .AND. nstop == 0 ) THEN 364 364 CALL Agrif_update_all( ) ! Update all components … … 370 370 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 371 371 ! File manipulation at the end of the first time step 372 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 372 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 373 373 IF( kstp == nit000 ) THEN ! 1st time step only 374 374 CALL iom_close( numror ) ! close input ocean restart file … … 386 386 !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 387 387 ! Finalize contextes if end of simulation or error detected 388 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 389 IF( kstp == nitend .OR. nstop > 0 ) THEN 388 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 389 IF( kstp == nitend .OR. nstop > 0 ) THEN 390 390 CALL iom_context_finalize( cxios_context ) ! needed for XIOS+AGRIF 391 IF( ln_crs ) CALL iom_context_finalize( trim(cxios_context)//"_crs" ) ! 391 IF( ln_crs ) CALL iom_context_finalize( trim(cxios_context)//"_crs" ) ! 392 392 ENDIF 393 393 #endif 394 394 ! 395 395 IF( l_1st_euler ) THEN ! recover Leap-frog timestep 396 rDt = 2._wp * rn_Dt 396 rDt = 2._wp * rn_Dt 397 397 r1_Dt = 1._wp / rDt 398 l_1st_euler = .FALSE. 398 l_1st_euler = .FALSE. 399 399 ENDIF 400 400 ! -
NEMO/trunk/src/OCE/step_oce.F90
r14053 r14072 6 6 !!====================================================================== 7 7 !! History : 3.3 ! 2010-08 (C. Ethe) Original code - reorganisation of the initial phase 8 !! 3.7 ! 2014-01 (G. Madec) LDF simplication 8 !! 3.7 ! 2014-01 (G. Madec) LDF simplication 9 9 !!---------------------------------------------------------------------- 10 10 USE oce ! ocean dynamics and tracers variables … … 35 35 USE domvvl ! variable vertical scale factors (dom_vvl_sf_nxt routine) 36 36 ! (dom_vvl_sf_swp routine) 37 37 38 38 USE divhor ! horizontal divergence (div_hor routine) 39 39 USE dynadv ! advection (dyn_adv routine) … … 60 60 61 61 USE stopar ! Stochastic parametrization (sto_par routine) 62 USE stopts 62 USE stopts 63 63 64 64 USE ldfslp ! iso-neutral slopes (ldf_slp routine) … … 73 73 74 74 USE diu_layers ! diurnal SST bulk and coolskin routines 75 USE sbc_oce ! surface fluxes 76 75 USE sbc_oce ! surface fluxes 76 77 77 USE zpshde ! partial step: hor. derivative (zps_hde routine) 78 78 -
NEMO/trunk/src/OCE/timing.F90
r13982 r14072 3 3 !! *** MODULE timing *** 4 4 !!======================================================================== 5 !! History : 4.0 ! 2001-05 (R. Benshila) 5 !! History : 4.0 ! 2001-05 (R. Benshila) 6 6 !!------------------------------------------------------------------------ 7 7 8 8 !!------------------------------------------------------------------------ 9 !! timming_init : initialize timing process 9 !! timming_init : initialize timing process 10 10 !! timing_start : start Timer 11 11 !! timing_stop : stop Timer 12 12 !! timing_reset : end timing variable creation 13 !! timing_finalize : compute stats and write output in calling w*_info 14 !! timing_ini_var : create timing variables 13 !! timing_finalize : compute stats and write output in calling w*_info 14 !! timing_ini_var : create timing variables 15 15 !! timing_listing : print instumented subroutines in ocean.output 16 16 !! wcurrent_info : compute and print detailed stats on the current CPU 17 17 !! wave_info : compute and print averaged statson all processors 18 !! wmpi_info : compute and write global stats 19 !! supress : suppress an element of the timing linked list 20 !! insert : insert an element of the timing linked list 18 !! wmpi_info : compute and write global stats 19 !! supress : suppress an element of the timing linked list 20 !! insert : insert an element of the timing linked list 21 21 !!------------------------------------------------------------------------ 22 USE in_out_manager ! I/O manager 22 USE in_out_manager ! I/O manager 23 23 USE dom_oce ! ocean domain 24 USE lib_mpp 25 24 USE lib_mpp 25 26 26 IMPLICIT NONE 27 27 PRIVATE 28 28 29 PUBLIC timing_init, timing_finalize ! called in nemogcm module 30 PUBLIC timing_reset ! called in step module 31 PUBLIC timing_start, timing_stop ! called in each routine to time 32 29 PUBLIC timing_init, timing_finalize ! called in nemogcm module 30 PUBLIC timing_reset ! called in step module 31 PUBLIC timing_start, timing_stop ! called in each routine to time 32 33 33 #if defined key_mpp_mpi 34 34 INCLUDE 'mpif.h' … … 41 41 INTEGER :: rank 42 42 REAL(wp) :: t_cpu, t_clock, tsum_cpu, tsum_clock, tmax_cpu, tmax_clock, tmin_cpu, tmin_clock, tsub_cpu, tsub_clock 43 INTEGER :: ncount, ncount_max, ncount_rate 43 INTEGER :: ncount, ncount_max, ncount_rate 44 44 INTEGER :: niter 45 45 LOGICAL :: l_tdone … … 48 48 TYPE(timer), POINTER :: parent_section => NULL() 49 49 END TYPE timer 50 50 51 51 TYPE alltimer 52 52 CHARACTER(LEN=20), DIMENSION(:), POINTER :: cname => NULL() … … 56 56 TYPE(alltimer), POINTER :: next => NULL() 57 57 TYPE(alltimer), POINTER :: prev => NULL() 58 END TYPE alltimer 59 58 END TYPE alltimer 59 60 60 TYPE(timer), POINTER :: s_timer_root => NULL() 61 61 TYPE(timer), POINTER :: s_timer => NULL() … … 66 66 LOGICAL :: l_initdone = .FALSE. 67 67 INTEGER :: nsize 68 68 69 69 ! Variables for coarse grain timing 70 70 REAL(wp) :: tot_etime, tot_ctime … … 76 76 CHARACTER(LEN=10), DIMENSION(2) :: ctime 77 77 CHARACTER(LEN=5) :: czone 78 78 79 79 ! From of ouput file (1/proc or one global) !RB to put in nammpp or namctl 80 LOGICAL :: ln_onefile = .TRUE. 80 LOGICAL :: ln_onefile = .TRUE. 81 81 LOGICAL :: lwriter 82 82 !!---------------------------------------------------------------------- … … 96 96 IF(ASSOCIATED(s_timer) ) s_timer_old => s_timer 97 97 ! 98 ! Create timing structure at first call of the routine 98 ! Create timing structure at first call of the routine 99 99 CALL timing_ini_var(cdinfo) 100 100 ! write(*,*) 'after inivar ', s_timer%cname … … 102 102 ! ici timing_ini_var a soit retrouve s_timer et fait return soit ajoute un maillon 103 103 ! maintenant on regarde si le call d'avant corrsspond a un parent ou si il est ferme 104 IF( .NOT. s_timer_old%l_tdone ) THEN 104 IF( .NOT. s_timer_old%l_tdone ) THEN 105 105 s_timer%parent_section => s_timer_old 106 106 ELSE 107 107 s_timer%parent_section => NULL() 108 ENDIF 108 ENDIF 109 109 110 110 s_timer%l_tdone = .FALSE. … … 112 112 s_timer%t_cpu = 0. 113 113 s_timer%t_clock = 0. 114 114 115 115 ! CPU time collection 116 116 CALL CPU_TIME( s_timer%t_cpu ) … … 136 136 CHARACTER(len=*), INTENT(in), OPTIONAL :: csection 137 137 ! 138 INTEGER :: ifinal_count, iperiods 138 INTEGER :: ifinal_count, iperiods 139 139 REAL(wp) :: zcpu_end, zmpitime,zcpu_raw,zclock_raw 140 140 ! … … 152 152 !!$ IF(associated(s_timer%parent_section))then 153 153 !!$ write(*,*) s_timer%cname,' <-- ', s_timer%parent_section%cname 154 !!$ ENDIF 154 !!$ ENDIF 155 155 156 156 ! No need to search ... : s_timer has the last value defined in start 157 157 ! s_timer => s_timer_root 158 ! DO WHILE( TRIM(s_timer%cname) /= TRIM(cdinfo) ) 158 ! DO WHILE( TRIM(s_timer%cname) /= TRIM(cdinfo) ) 159 159 ! IF( ASSOCIATED(s_timer%next) ) s_timer => s_timer%next 160 160 ! END DO 161 161 162 162 ! CPU time correction 163 163 zcpu_raw = zcpu_end - s_timer%t_cpu - t_overcpu ! total time including child … … 172 172 iperiods = ifinal_count - s_timer%ncount 173 173 IF( ifinal_count < s_timer%ncount ) & 174 iperiods = iperiods + s_timer%ncount_max 175 zclock_raw = REAL(iperiods) / s_timer%ncount_rate !- t_overclock 174 iperiods = iperiods + s_timer%ncount_max 175 zclock_raw = REAL(iperiods) / s_timer%ncount_rate !- t_overclock 176 176 s_timer%t_clock = zclock_raw - s_timer%tsub_clock 177 177 #endif 178 178 ! IF(s_timer%cname==trim('lbc_lnk_2d')) write(*,*) zclock_raw , s_timer%tsub_clock 179 179 180 180 ! Correction of parent section 181 181 IF( .NOT. PRESENT(csection) ) THEN 182 182 IF ( ASSOCIATED(s_timer%parent_section ) ) THEN 183 s_timer%parent_section%tsub_cpu = zcpu_raw + s_timer%parent_section%tsub_cpu 184 s_timer%parent_section%tsub_clock = zclock_raw + s_timer%parent_section%tsub_clock 183 s_timer%parent_section%tsub_cpu = zcpu_raw + s_timer%parent_section%tsub_cpu 184 s_timer%parent_section%tsub_clock = zclock_raw + s_timer%parent_section%tsub_clock 185 185 ENDIF 186 186 ENDIF 187 188 ! time diagnostics 189 s_timer%tsum_clock = s_timer%tsum_clock + s_timer%t_clock 187 188 ! time diagnostics 189 s_timer%tsum_clock = s_timer%tsum_clock + s_timer%t_clock 190 190 s_timer%tsum_cpu = s_timer%tsum_cpu + s_timer%t_cpu 191 191 !RB to use to get min/max during a time integration 192 192 ! IF( .NOT. l_initdone ) THEN 193 ! s_timer%tmin_clock = s_timer%t_clock 194 ! s_timer%tmin_cpu = s_timer%t_cpu 193 ! s_timer%tmin_clock = s_timer%t_clock 194 ! s_timer%tmin_cpu = s_timer%t_cpu 195 195 ! ELSE 196 ! s_timer%tmin_clock = MIN( s_timer%tmin_clock, s_timer%t_clock ) 197 ! s_timer%tmin_cpu = MIN( s_timer%tmin_cpu , s_timer%t_cpu ) 198 ! ENDIF 199 ! s_timer%tmax_clock = MAX( s_timer%tmax_clock, s_timer%t_clock ) 200 ! s_timer%tmax_cpu = MAX( s_timer%tmax_cpu , s_timer%t_cpu ) 196 ! s_timer%tmin_clock = MIN( s_timer%tmin_clock, s_timer%t_clock ) 197 ! s_timer%tmin_cpu = MIN( s_timer%tmin_cpu , s_timer%t_cpu ) 198 ! ENDIF 199 ! s_timer%tmax_clock = MAX( s_timer%tmax_clock, s_timer%t_clock ) 200 ! s_timer%tmax_cpu = MAX( s_timer%tmax_cpu , s_timer%t_cpu ) 201 201 ! 202 202 s_timer%tsub_clock = 0. … … 207 207 ! we come back 208 208 IF ( ASSOCIATED(s_timer%parent_section ) ) s_timer => s_timer%parent_section 209 209 210 210 ! write(*,*) 'end of stop ', s_timer%cname 211 211 212 212 END SUBROUTINE timing_stop 213 214 213 214 215 215 SUBROUTINE timing_init( clname ) 216 216 !!---------------------------------------------------------------------- … … 235 235 lwriter = .TRUE. 236 236 ENDIF 237 238 IF( lwriter) THEN 237 238 IF( lwriter) THEN 239 239 WRITE(numtime,*) 240 240 WRITE(numtime,*) ' CNRS - NERC - Met OFFICE - MERCATOR-ocean - CMCC - INGV' … … 246 246 WRITE(numtime,*) 247 247 WRITE(numtime,*) 248 ENDIF 249 248 ENDIF 249 250 250 ! Compute clock function overhead 251 #if defined key_mpp_mpi 251 #if defined key_mpp_mpi 252 252 t_overclock = MPI_WTIME() 253 253 t_overclock = MPI_WTIME() - t_overclock 254 #else 254 #else 255 255 CALL SYSTEM_CLOCK(COUNT_RATE=ncount_rate, COUNT_MAX=ncount_max) 256 256 CALL SYSTEM_CLOCK(COUNT = istart_count) … … 258 258 iperiods = ifinal_count - istart_count 259 259 IF( ifinal_count < istart_count ) & 260 iperiods = iperiods + ncount_max 260 iperiods = iperiods + ncount_max 261 261 t_overclock = REAL(iperiods) / ncount_rate 262 262 #endif … … 265 265 CALL CPU_TIME(zdum) 266 266 CALL CPU_TIME(t_overcpu) 267 268 ! End overhead omputation 269 t_overcpu = t_overcpu - zdum 270 t_overclock = t_overcpu + t_overclock 267 268 ! End overhead omputation 269 t_overcpu = t_overcpu - zdum 270 t_overclock = t_overcpu + t_overclock 271 271 272 272 ! Timing on date and time 273 273 CALL DATE_AND_TIME(cdate(1),ctime(1),czone,nvalues) 274 275 CALL CPU_TIME(t_cpu(1)) 276 #if defined key_mpp_mpi 274 275 CALL CPU_TIME(t_cpu(1)) 276 #if defined key_mpp_mpi 277 277 ! Start elapsed and CPU time counters 278 278 t_elaps(1) = MPI_WTIME() … … 280 280 CALL SYSTEM_CLOCK(COUNT_RATE=ncount_rate, COUNT_MAX=ncount_max) 281 281 CALL SYSTEM_CLOCK(COUNT = ncount) 282 #endif 282 #endif 283 283 ! 284 284 END SUBROUTINE timing_init … … 288 288 !!---------------------------------------------------------------------- 289 289 !! *** ROUTINE timing_finalize *** 290 !! ** Purpose : compute average time 290 !! ** Purpose : compute average time 291 291 !! write timing output file 292 292 !!---------------------------------------------------------------------- … … 295 295 INTEGER :: ji 296 296 LOGICAL :: ll_ord, ll_averep 297 CHARACTER(len=120) :: clfmt 297 CHARACTER(len=120) :: clfmt 298 298 REAL(wp), DIMENSION(:), ALLOCATABLE :: timing_glob 299 299 REAL(wp) :: zsypd ! simulated years per day (Balaji 2017) … … 301 301 302 302 ll_averep = .TRUE. 303 303 304 304 ! total CPU and elapse 305 305 CALL CPU_TIME(t_cpu(2)) … … 311 311 iperiods = nfinal_count - ncount 312 312 IF( nfinal_count < ncount ) & 313 iperiods = iperiods + ncount_max 313 iperiods = iperiods + ncount_max 314 314 t_elaps(2) = REAL(iperiods) / ncount_rate - t_overclock 315 #endif 315 #endif 316 316 317 317 ! End of timings on date & time 318 318 CALL DATE_AND_TIME(cdate(2),ctime(2),czone,nvalues) 319 319 320 320 ! Compute the numer of routines 321 nsize = 0 321 nsize = 0 322 322 s_timer => s_timer_root 323 323 DO WHILE( ASSOCIATED(s_timer) ) … … 334 334 IF( lwriter ) WRITE(numtime,*) 335 335 ll_averep = .FALSE. 336 ENDIF 337 338 #if defined key_mpp_mpi 336 ENDIF 337 338 #if defined key_mpp_mpi 339 339 ! in MPI gather some info 340 340 ALLOCATE( all_etime(jpnij), all_ctime(jpnij) ) … … 349 349 #else 350 350 tot_etime = t_elaps(2) 351 tot_ctime = t_cpu (2) 351 tot_ctime = t_cpu (2) 352 352 #endif 353 353 354 354 ! write output file 355 IF( lwriter ) WRITE(numtime,*) 356 IF( lwriter ) WRITE(numtime,*) 355 IF( lwriter ) WRITE(numtime,*) 356 IF( lwriter ) WRITE(numtime,*) 357 357 IF( lwriter ) WRITE(numtime,*) 'Total timing (sum) :' 358 358 IF( lwriter ) WRITE(numtime,*) '--------------------' 359 359 IF( lwriter ) WRITE(numtime,"('Elapsed Time (s) CPU Time (s)')") 360 360 IF( lwriter ) WRITE(numtime,'(5x,f12.3,1x,f12.3)') tot_etime, tot_ctime 361 IF( lwriter ) WRITE(numtime,*) 361 IF( lwriter ) WRITE(numtime,*) 362 362 #if defined key_mpp_mpi 363 363 IF( ll_averep ) CALL waver_info 364 364 CALL wmpi_info 365 #endif 365 #endif 366 366 IF( lwriter ) CALL wcurrent_info 367 367 368 368 clfmt='(1X,"Timing started on ",2(A2,"/"),A4," at ",2(A2,":"),A2," MET ",A3,":",A2," from GMT")' 369 IF( lwriter ) WRITE(numtime, TRIM(clfmt)) & 369 IF( lwriter ) WRITE(numtime, TRIM(clfmt)) & 370 370 & cdate(1)(7:8), cdate(1)(5:6), cdate(1)(1:4), & 371 371 & ctime(1)(1:2), ctime(1)(3:4), ctime(1)(5:6), & 372 & czone(1:3), czone(4:5) 372 & czone(1:3), czone(4:5) 373 373 clfmt='(1X, "Timing ended on ",2(A2,"/"),A4," at ",2(A2,":"),A2," MET ",A3,":",A2," from GMT")' 374 IF( lwriter ) WRITE(numtime, TRIM(clfmt)) & 374 IF( lwriter ) WRITE(numtime, TRIM(clfmt)) & 375 375 & cdate(2)(7:8), cdate(2)(5:6), cdate(2)(1:4), & 376 376 & ctime(2)(1:2), ctime(2)(3:4), ctime(2)(5:6), & … … 402 402 ENDIF 403 403 DEALLOCATE(timing_glob) 404 #endif 405 406 IF( lwriter ) CLOSE(numtime) 404 #endif 405 406 IF( lwriter ) CLOSE(numtime) 407 407 ! 408 408 END SUBROUTINE timing_finalize 409 409 410 410 411 411 SUBROUTINE wcurrent_info … … 415 415 !!---------------------------------------------------------------------- 416 416 LOGICAL :: ll_ord 417 CHARACTER(len=2048) :: clfmt 418 419 ! reorder the current list by elapse time 417 CHARACTER(len=2048) :: clfmt 418 419 ! reorder the current list by elapse time 420 420 s_wrk => NULL() 421 421 s_timer => s_timer_root … … 425 425 DO WHILE ( ASSOCIATED( s_timer%next ) ) 426 426 IF (.NOT. ASSOCIATED(s_timer%next)) EXIT 427 IF ( s_timer%tsum_clock < s_timer%next%tsum_clock ) THEN 427 IF ( s_timer%tsum_clock < s_timer%next%tsum_clock ) THEN 428 428 ALLOCATE(s_wrk) 429 429 s_wrk = s_timer%next 430 430 CALL insert (s_timer, s_timer_root, s_wrk) 431 CALL suppress(s_timer%next) 431 CALL suppress(s_timer%next) 432 432 ll_ord = .FALSE. 433 CYCLE 433 CYCLE 434 434 ENDIF 435 435 IF( ASSOCIATED(s_timer%next) ) s_timer => s_timer%next … … 437 437 IF( ll_ord ) EXIT 438 438 END DO 439 439 440 440 ! write current info 441 441 WRITE(numtime,*) 'Detailed timing for proc :', narea-1 … … 443 443 WRITE(numtime,*) 'Section ', & 444 444 & 'Elapsed Time (s) ','Elapsed Time (%) ', & 445 & 'CPU Time(s) ','CPU Time (%) ','CPU/Elapsed ','Frequency' 446 s_timer => s_timer_root 445 & 'CPU Time(s) ','CPU Time (%) ','CPU/Elapsed ','Frequency' 446 s_timer => s_timer_root 447 447 clfmt = '(1x,a,4x,f12.3,6x,f12.3,x,f12.3,2x,f12.3,6x,f7.3,2x,i9)' 448 448 DO WHILE ( ASSOCIATED(s_timer) ) … … 455 455 END DO 456 456 WRITE(numtime,*) 457 ! 457 ! 458 458 END SUBROUTINE wcurrent_info 459 459 460 #if defined key_mpp_mpi 460 #if defined key_mpp_mpi 461 461 SUBROUTINE waver_info 462 462 !!---------------------------------------------------------------------- … … 470 470 INTEGER :: icode 471 471 INTEGER :: ierr 472 LOGICAL :: ll_ord 473 CHARACTER(len=200) :: clfmt 474 475 ! Initialised the global strucutre 472 LOGICAL :: ll_ord 473 CHARACTER(len=200) :: clfmt 474 475 ! Initialised the global strucutre 476 476 ALLOCATE(sl_timer_glob_root, Stat=ierr) 477 477 IF(ierr /= 0)THEN … … 524 524 sl_timer_ave_root%prev => NULL() 525 525 ALLOCATE(sl_timer_ave) 526 sl_timer_ave => sl_timer_ave_root 527 ENDIF 526 sl_timer_ave => sl_timer_ave_root 527 ENDIF 528 528 529 529 ! Gather info from all processors … … 552 552 sl_timer_glob%next%next => NULL() 553 553 sl_timer_glob => sl_timer_glob%next 554 ENDIF 554 ENDIF 555 555 s_timer => s_timer%next 556 END DO 557 558 IF( narea == 1 ) THEN 556 END DO 557 558 IF( narea == 1 ) THEN 559 559 ! Compute some stats 560 560 sl_timer_glob => sl_timer_glob_root … … 570 570 ! 571 571 IF( ASSOCIATED(sl_timer_glob%next) ) THEN 572 ALLOCATE(sl_timer_ave%next) 572 ALLOCATE(sl_timer_ave%next) 573 573 sl_timer_ave%next%prev => sl_timer_ave 574 sl_timer_ave%next%next => NULL() 574 sl_timer_ave%next%next => NULL() 575 575 sl_timer_ave => sl_timer_ave%next 576 576 ENDIF 577 sl_timer_glob => sl_timer_glob%next 577 sl_timer_glob => sl_timer_glob%next 578 578 END DO 579 580 ! reorder the averaged list by CPU time 579 580 ! reorder the averaged list by CPU time 581 581 s_wrk => NULL() 582 582 sl_timer_ave => sl_timer_ave_root … … 588 588 IF( .NOT. ASSOCIATED(sl_timer_ave%next) ) EXIT 589 589 590 IF ( sl_timer_ave%tsum_clock < sl_timer_ave%next%tsum_clock ) THEN 590 IF ( sl_timer_ave%tsum_clock < sl_timer_ave%next%tsum_clock ) THEN 591 591 ALLOCATE(s_wrk) 592 592 ! Copy data into the new object pointed to by s_wrk … … 595 595 CALL insert (sl_timer_ave, sl_timer_ave_root, s_wrk) 596 596 ! Remove the old object from the list 597 CALL suppress(sl_timer_ave%next) 597 CALL suppress(sl_timer_ave%next) 598 598 ll_ord = .FALSE. 599 CYCLE 600 ENDIF 599 CYCLE 600 ENDIF 601 601 IF( ASSOCIATED(sl_timer_ave%next) ) sl_timer_ave => sl_timer_ave%next 602 END DO 602 END DO 603 603 IF( ll_ord ) EXIT 604 604 END DO … … 609 609 WRITE(numtime,"('Section',13x,'Elap. Time(s)',2x,'Elap. Time(%)',2x, & 610 610 & 'CPU Time(s)',2x,'CPU Time(%)',2x,'CPU/Elap',1x, & 611 & 'Max elap(%)',2x,'Min elap(%)',2x, & 611 & 'Max elap(%)',2x,'Min elap(%)',2x, & 612 612 & 'Freq')") 613 sl_timer_ave => sl_timer_ave_root 613 sl_timer_ave => sl_timer_ave_root 614 614 clfmt = '((A),E15.7,2x,f6.2,5x,f12.2,5x,f6.2,5x,f7.2,2x,f12.2,4x,f6.2,2x,f9.2)' 615 615 DO WHILE ( ASSOCIATED(sl_timer_ave) ) 616 IF( sl_timer_ave%tsum_clock > 0. ) & 616 IF( sl_timer_ave%tsum_clock > 0. ) & 617 617 WRITE(numtime,TRIM(clfmt)) sl_timer_ave%cname(1:18), & 618 618 & sl_timer_ave%tsum_clock,sl_timer_ave%tsum_clock*100.*jpnij/tot_etime, & … … 630 630 ! 631 631 DEALLOCATE(sl_timer_glob_root) 632 ! 632 ! 633 633 END SUBROUTINE waver_info 634 635 634 635 636 636 SUBROUTINE wmpi_info 637 637 !!---------------------------------------------------------------------- 638 638 !! *** ROUTINE wmpi_time *** 639 !! ** Purpose : compute and write a summary of MPI infos 640 !!---------------------------------------------------------------------- 641 ! 639 !! ** Purpose : compute and write a summary of MPI infos 640 !!---------------------------------------------------------------------- 641 ! 642 642 INTEGER :: idum, icode 643 643 INTEGER, ALLOCATABLE, DIMENSION(:) :: iall_rank … … 648 648 CHARACTER(LEN=128), dimension(8) :: cllignes 649 649 CHARACTER(LEN=128) :: clhline, clstart_date, clfinal_date 650 CHARACTER(LEN=2048) :: clfmt 651 650 CHARACTER(LEN=2048) :: clfmt 651 652 652 ! Gather all times 653 653 ALLOCATE( zall_ratio(jpnij), iall_rank(jpnij) ) 654 654 IF( narea == 1 ) THEN 655 655 iall_rank(:) = (/ (idum,idum=0,jpnij-1) /) 656 656 657 657 ! Compute elapse user time 658 658 zavg_etime = tot_etime/REAL(jpnij,wp) … … 664 664 zmax_ctime = MAXVAL(all_ctime(:)) 665 665 zmin_ctime = MINVAL(all_ctime(:)) 666 666 667 667 ! Compute cpu/elapsed ratio 668 668 zall_ratio(:) = all_ctime(:) / all_etime(:) … … 670 670 zavg_ratio = SUM(zall_ratio(:))/REAL(jpnij,wp) 671 671 zmax_ratio = MAXVAL(zall_ratio(:)) 672 zmin_ratio = MINVAL(zall_ratio(:)) 673 672 zmin_ratio = MINVAL(zall_ratio(:)) 673 674 674 ! Output Format 675 675 clhline ='1x,13("-"),"|",18("-"),"|",14("-"),"|",18("-"),/,' … … 693 693 zmax_etime, zmax_ctime, zmax_ratio, & 694 694 zavg_etime, zavg_ctime, zavg_ratio 695 WRITE(numtime,*) 695 WRITE(numtime,*) 696 696 END IF 697 697 ! … … 699 699 ! 700 700 END SUBROUTINE wmpi_info 701 #endif 701 #endif 702 702 703 703 … … 705 705 !!---------------------------------------------------------------------- 706 706 !! *** ROUTINE timing_ini_var *** 707 !! ** Purpose : create timing structure 707 !! ** Purpose : create timing structure 708 708 !!---------------------------------------------------------------------- 709 709 CHARACTER(len=*), INTENT(in) :: cdinfo 710 710 LOGICAL :: ll_section 711 711 712 712 ! 713 713 IF( .NOT. ASSOCIATED(s_timer_root) ) THEN … … 760 760 ! case of already existing area (typically inside a loop) 761 761 ! write(*,*) 'in ini_var for routine : ', cdinfo 762 DO WHILE( ASSOCIATED(s_timer) ) 762 DO WHILE( ASSOCIATED(s_timer) ) 763 763 IF( TRIM(s_timer%cname) .EQ. TRIM(cdinfo) ) THEN 764 ! write(*,*) 'in ini_var for routine : ', cdinfo,' we return' 764 ! write(*,*) 'in ini_var for routine : ', cdinfo,' we return' 765 765 RETURN ! cdinfo is already in the chain 766 766 ENDIF … … 775 775 776 776 ! write(*,*) 'after search', s_timer%cname 777 ! cdinfo is not part of the chain so we add it with initialisation 777 ! cdinfo is not part of the chain so we add it with initialisation 778 778 ALLOCATE(s_timer%next) 779 779 ! write(*,*) 'after allocation of next' 780 780 781 781 s_timer%next%cname = cdinfo 782 782 s_timer%next%t_cpu = 0._wp 783 783 s_timer%next%t_clock = 0._wp 784 784 s_timer%next%tsum_cpu = 0._wp 785 s_timer%next%tsum_clock = 0._wp 785 s_timer%next%tsum_clock = 0._wp 786 786 s_timer%next%tmax_cpu = 0._wp 787 787 s_timer%next%tmax_clock = 0._wp … … 799 799 s_timer%next%next => NULL() 800 800 s_timer => s_timer%next 801 ENDIF 801 ENDIF 802 802 ! write(*,*) 'after allocation' 803 803 ! … … 808 808 !!---------------------------------------------------------------------- 809 809 !! *** ROUTINE timing_reset *** 810 !! ** Purpose : go to root of timing tree 811 !!---------------------------------------------------------------------- 812 l_initdone = .TRUE. 810 !! ** Purpose : go to root of timing tree 811 !!---------------------------------------------------------------------- 812 l_initdone = .TRUE. 813 813 ! IF(lwp) WRITE(numout,*) 814 814 ! IF(lwp) WRITE(numout,*) 'timing_reset : instrumented routines for timing' … … 821 821 822 822 RECURSIVE SUBROUTINE timing_list(ptr) 823 823 824 824 TYPE(timer), POINTER, INTENT(inout) :: ptr 825 825 ! 826 826 IF( ASSOCIATED(ptr%next) ) CALL timing_list(ptr%next) 827 IF(lwp) WRITE(numout,*)' ', ptr%cname 827 IF(lwp) WRITE(numout,*)' ', ptr%cname 828 828 ! 829 829 END SUBROUTINE timing_list … … 837 837 TYPE(timer), POINTER, INTENT(inout) :: sd_current, sd_root, sd_ptr 838 838 ! 839 839 840 840 IF( ASSOCIATED( sd_current, sd_root ) ) THEN 841 841 ! If our current element is the root element then … … 852 852 ! to ALLOCATE memory to this pointer will fail. 853 853 sd_ptr => NULL() 854 ! 854 ! 855 855 END SUBROUTINE insert 856 857 856 857 858 858 SUBROUTINE suppress(sd_ptr) 859 859 !!---------------------------------------------------------------------- … … 864 864 ! 865 865 TYPE(timer), POINTER :: sl_temp 866 866 867 867 sl_temp => sd_ptr 868 sd_ptr => sd_ptr%next 868 sd_ptr => sd_ptr%next 869 869 IF ( ASSOCIATED(sl_temp%next) ) sl_temp%next%prev => sl_temp%prev 870 870 DEALLOCATE(sl_temp)
Note: See TracChangeset
for help on using the changeset viewer.