123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- MODULE sbcice_lim_2
- !!======================================================================
- !! *** MODULE sbcice_lim_2 ***
- !! Surface module : update surface ocean boundary condition over ice covered area using LIM sea-ice model
- !! Sea-Ice model : LIM-2 Sea ice model time-stepping
- !!======================================================================
- !! History : 1.0 ! 06-2006 (G. Madec) from icestp_2.F90
- !! 3.0 ! 08-2008 (S. Masson, E. .... ) coupled interface
- !! 3.3 ! 05-2009 (G.Garric) addition of the lim2_evp case
- !!----------------------------------------------------------------------
- #if defined key_lim2
- !!----------------------------------------------------------------------
- !! 'key_lim2' : LIM-2 sea-ice model
- !!----------------------------------------------------------------------
- !! sbc_ice_lim_2 : sea-ice model time-stepping and update ocean sbc over ice-covered area
- !!----------------------------------------------------------------------
- USE oce ! ocean dynamics and tracers
- USE dom_oce ! ocean space and time domain
- USE ice_2
- USE par_ice_2
- USE iceini_2
- USE dom_ice_2
- USE sbc_oce ! Surface boundary condition: ocean fields
- USE sbc_ice ! Surface boundary condition: ice fields
- USE sbcblk_core ! Surface boundary condition: CORE bulk
- USE sbcblk_clio ! Surface boundary condition: CLIO bulk
- USE sbccpl ! Surface boundary condition: coupled interface
- USE albedo
- USE phycst ! Define parameters for the routines
- USE eosbn2 ! equation of state
- USE limdyn_2
- USE limtrp_2
- USE limdmp_2
- USE limthd_2
- USE limsbc_2 ! sea surface boundary condition
- USE limdia_2
- USE limwri_2
- USE limrst_2
- USE c1d ! 1D vertical configuration
- USE lbclnk ! lateral boundary condition - MPP link
- USE lib_mpp ! MPP library
- USE wrk_nemo ! work arrays
- USE iom ! I/O manager library
- USE in_out_manager ! I/O manager
- USE prtctl ! Print control
- # if defined key_agrif
- USE agrif_ice
- USE agrif_lim2_update
- # endif
- #if defined key_bdy
- USE bdyice_lim ! unstructured open boundary data (bdy_ice_lim routine)
- #endif
- IMPLICIT NONE
- PRIVATE
- PUBLIC sbc_ice_lim_2 ! routine called by sbcmod.F90
- !! * Substitutions
- # include "domzgr_substitute.h90"
- # include "vectopt_loop_substitute.h90"
- !!----------------------------------------------------------------------
- !! NEMO/OPA 3.3 , NEMO Consortium (2010)
- !! $Id: sbcice_lim_2.F90 5540 2015-07-02 15:11:23Z jchanut $
- !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
- !!----------------------------------------------------------------------
- CONTAINS
- SUBROUTINE sbc_ice_lim_2( kt, ksbc )
- !!---------------------------------------------------------------------
- !! *** ROUTINE sbc_ice_lim_2 ***
- !!
- !! ** Purpose : update the ocean surface boundary condition via the
- !! Louvain la Neuve Sea Ice Model time stepping
- !!
- !! ** Method : ice model time stepping
- !! - call the ice dynamics routine
- !! - call the ice advection/diffusion routine
- !! - call the ice thermodynamics routine
- !! - call the routine that computes mass and
- !! heat fluxes at the ice/ocean interface
- !! - save the outputs
- !! - save the outputs for restart when necessary
- !!
- !! ** Action : - time evolution of the LIM sea-ice model
- !! - update all sbc variables below sea-ice:
- !! utau, vtau, taum, wndm, qns , qsr, emp , sfx
- !!---------------------------------------------------------------------
- INTEGER, INTENT(in) :: kt ! ocean time step
- INTEGER, INTENT(in) :: ksbc ! type of sbc ( =3 CLIO bulk ; =4 CORE bulk ; =5 coupled )
- !!
- INTEGER :: ji, jj ! dummy loop indices
- REAL(wp), DIMENSION(:,:,:), POINTER :: zalb_os ! ice albedo under overcast sky
- REAL(wp), DIMENSION(:,:,:), POINTER :: zalb_cs ! ice albedo under clear sky
- REAL(wp), DIMENSION(:,:,:), POINTER :: zalb_ice ! mean ice albedo
- REAL(wp), DIMENSION(:,:,:), POINTER :: zsist ! ice surface temperature (K)
- REAL(wp), DIMENSION(:,: ), POINTER :: zutau_ice, zvtau_ice
- !!----------------------------------------------------------------------
- IF( kt == nit000 ) THEN
- IF(lwp) WRITE(numout,*)
- IF(lwp) WRITE(numout,*) 'sbc_ice_lim_2 : update ocean surface boudary condition'
- IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~ via Louvain la Neuve Ice Model (LIM) time stepping'
- !
- CALL ice_init_2
- !
- # if defined key_agrif
- IF( .NOT. Agrif_Root() ) CALL Agrif_InitValues_cont_lim2 ! AGRIF: set the meshes
- # endif
- ENDIF
- ! !----------------------!
- IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN ! Ice time-step only !
- ! !----------------------!
- # if defined key_agrif
- IF( .NOT. Agrif_Root() ) lim_nbstep = MOD(lim_nbstep,Agrif_rhot()&
- &*Agrif_PArent(nn_fsbc)/REAL(nn_fsbc)) + 1
- # endif
- CALL wrk_alloc( jpi,jpj , zutau_ice, zvtau_ice)
- CALL wrk_alloc( jpi,jpj,1, zalb_os, zalb_cs, zalb_ice, zsist )
- ! Bulk Formulea !
- !----------------!
- ! ... mean surface ocean current at ice dynamics point
- SELECT CASE( cp_ice_msh )
- CASE( 'I' ) !== B-grid ice dynamics : I-point (i.e. F-point with sea-ice indexation)
- DO jj = 2, jpj
- DO ji = 2, jpi ! NO vector opt. possible
- u_oce(ji,jj) = 0.5_wp * ( ssu_m(ji-1,jj ) * umask(ji-1,jj ,1) &
- & + ssu_m(ji-1,jj-1) * umask(ji-1,jj-1,1) ) * tmu(ji,jj)
- v_oce(ji,jj) = 0.5_wp * ( ssv_m(ji ,jj-1) * vmask(ji ,jj-1,1) &
- & + ssv_m(ji-1,jj-1) * vmask(ji-1,jj-1,1) ) * tmu(ji,jj)
- END DO
- END DO
- CALL lbc_lnk( u_oce, 'I', -1. ) ! I-point (i.e. F-point with ice indices)
- CALL lbc_lnk( v_oce, 'I', -1. ) ! I-point (i.e. F-point with ice indices)
- !
- CASE( 'C' ) !== C-grid ice dynamics : U & V-points (same as ocean)
- u_oce(:,:) = ssu_m(:,:) * umask(:,:,1) ! mean surface ocean current at ice velocity point
- v_oce(:,:) = ssv_m(:,:) * vmask(:,:,1)
- !
- END SELECT
- ! ... masked sea surface freezing temperature [Kelvin] (set to rt0 over land)
- CALL eos_fzp( sss_m(:,:), tfu(:,:) )
- tfu(:,:) = tfu(:,:) + rt0
- zsist (:,:,1) = sist (:,:) + rt0 * ( 1. - tmask(:,:,1) )
- ! Ice albedo
- CALL albedo_ice( zsist, reshape( hicif, (/jpi,jpj,1/) ), &
- reshape( hsnif, (/jpi,jpj,1/) ), &
- zalb_cs, zalb_os )
- SELECT CASE( ksbc )
- CASE( jp_core , jp_purecpl ) ! CORE and COUPLED bulk formulations
- ! albedo depends on cloud fraction because of non-linear spectral effects
- zalb_ice(:,:,:) = ( 1. - cldf_ice ) * zalb_cs(:,:,:) + cldf_ice * zalb_os(:,:,:)
- ! In CLIO the cloud fraction is read in the climatology and the all-sky albedo
- ! (zalb_ice) is computed within the bulk routine
- END SELECT
- ! ... Sea-ice surface boundary conditions output from bulk formulae :
- ! - utau_ice ! surface ice stress i-component (I-point) [N/m2]
- ! - vtau_ice ! surface ice stress j-component (I-point) [N/m2]
- ! - qns_ice ! non solar heat flux over ice (T-point) [W/m2]
- ! - qsr_ice ! solar heat flux over ice (T-point) [W/m2]
- ! - qla_ice ! latent heat flux over ice (T-point) [W/m2]
- ! - dqns_ice ! non solar heat sensistivity (T-point) [W/m2]
- ! - dqla_ice ! latent heat sensistivity (T-point) [W/m2]
- ! - tprecip ! total precipitation (T-point) [Kg/m2/s]
- ! - sprecip ! solid precipitation (T-point) [Kg/m2/s]
- ! - fr1_i0 ! 1sr fraction of qsr penetration in ice [%]
- ! - fr2_i0 ! 2nd fraction of qsr penetration in ice [%]
- !
- SELECT CASE( ksbc )
- CASE( jp_clio ) ! CLIO bulk formulation
- ! CALL blk_ice_clio( zsist, zalb_cs , zalb_os , zalb_ice , &
- ! & utau_ice , vtau_ice , qns_ice , qsr_ice, &
- ! & qla_ice , dqns_ice , dqla_ice , &
- ! & tprecip , sprecip , &
- ! & fr1_i0 , fr2_i0 , cp_ice_msh , jpl )
- CALL blk_ice_clio_tau
- CALL blk_ice_clio_flx( zsist, zalb_cs, zalb_os, zalb_ice )
- CASE( jp_core ) ! CORE bulk formulation
- CALL blk_ice_core_tau
- CALL blk_ice_core_flx( zsist, zalb_ice )
- CASE( jp_purecpl ) ! Coupled formulation : atmosphere-ice stress only (fluxes provided after ice dynamics)
- CALL sbc_cpl_ice_tau( utau_ice , vtau_ice )
- END SELECT
-
- IF( ln_mixcpl) THEN
- CALL sbc_cpl_ice_tau( zutau_ice , zvtau_ice )
- utau_ice(:,:) = utau_ice(:,:) * xcplmask(:,:,0) + zutau_ice(:,:) * ( 1. - xcplmask(:,:,0) )
- vtau_ice(:,:) = vtau_ice(:,:) * xcplmask(:,:,0) + zvtau_ice(:,:) * ( 1. - xcplmask(:,:,0) )
- ENDIF
- CALL iom_put( 'utau_ice', utau_ice ) ! Wind stress over ice along i-axis at I-point
- CALL iom_put( 'vtau_ice', vtau_ice ) ! Wind stress over ice along j-axis at I-point
- IF(ln_ctl) THEN ! print mean trends (used for debugging)
- CALL prt_ctl_info( 'Ice Forcings ' )
- CALL prt_ctl( tab2d_1=tprecip ,clinfo1=' sbc_ice_lim: precip : ', tab2d_2=sprecip , clinfo2=' Snow : ' )
- CALL prt_ctl( tab2d_1=utau_ice,clinfo1=' sbc_ice_lim: utau_ice: ', tab2d_2=vtau_ice, clinfo2=' vtau_ice: ' )
- CALL prt_ctl( tab2d_1=sst_m ,clinfo1=' sbc_ice_lim: sst : ', tab2d_2=sss_m , clinfo2=' sss : ' )
- CALL prt_ctl( tab2d_1=u_oce ,clinfo1=' sbc_ice_lim: u_io : ', tab2d_2=v_oce , clinfo2=' v_io : ' )
- CALL prt_ctl( tab2d_1=hsnif ,clinfo1=' sbc_ice_lim: hsnif 1: ', tab2d_2=hicif , clinfo2=' hicif : ' )
- CALL prt_ctl( tab2d_1=frld ,clinfo1=' sbc_ice_lim: frld 1: ', tab2d_2=sist , clinfo2=' sist : ' )
- ENDIF
- ! ---------------- !
- ! Ice model step !
- ! ---------------- !
- numit = numit + nn_fsbc ! Ice model time step
- CALL lim_rst_opn_2 ( kt ) ! Open Ice restart file
- IF( .NOT. lk_c1d ) THEN ! Ice dynamics & transport (except in 1D case)
- CALL lim_dyn_2 ( kt ) ! Ice dynamics ( rheology/dynamics )
- CALL lim_trp_2 ( kt ) ! Ice transport ( Advection/diffusion )
- IF( ln_limdmp ) CALL lim_dmp_2 ( kt ) ! Ice damping
- #if defined key_bdy
- CALL bdy_ice_lim( kt ) ! bdy ice thermo
- #endif
- END IF
- ! ! Ice surface fluxes in coupled mode
- IF( ln_cpl ) THEN ! pure coupled and mixed forced-coupled configurations
- a_i(:,:,1)=fr_i
- CALL sbc_cpl_ice_flx( frld, &
- ! optional arguments, used only in 'mixed oce-ice' case
- & palbi=zalb_ice, psst=sst_m, pist=zsist )
- sprecip(:,:) = - emp_ice(:,:) ! Ugly patch, WARNING, in coupled mode, sublimation included in snow (parsub = 0.)
- ENDIF
- CALL lim_thd_2 ( kt ) ! Ice thermodynamics
- CALL lim_sbc_flx_2 ( kt ) ! update surface ocean mass, heat & salt fluxes
- IF( .NOT. lk_mpp )THEN
- IF( MOD( kt+nn_fsbc-1, ninfo ) == 0 .OR. ntmoy == 1 ) &
- & CALL lim_dia_2 ( kt ) ! Ice Diagnostics
- ENDIF
- # if ! defined key_iomput
- CALL lim_wri_2 ( kt ) ! Ice outputs
- # endif
- IF( lrst_ice ) CALL lim_rst_write_2( kt ) ! Ice restart file
- !
- # if defined key_agrif && defined key_lim2
- IF( .NOT. Agrif_Root() ) CALL agrif_update_lim2( kt )
- # endif
- !
- CALL wrk_dealloc( jpi,jpj , zutau_ice, zvtau_ice)
- CALL wrk_dealloc( jpi,jpj,1, zalb_os, zalb_cs, zalb_ice, zsist )
- !
- ENDIF ! End sea-ice time step only
- !
- ! !--------------------------!
- ! ! at all ocean time step !
- ! !--------------------------!
- !
- ! ! Update surface ocean stresses (only in ice-dynamic case)
- ! ! otherwise the atm.-ocean stresses are used everywhere
- IF( ln_limdyn ) CALL lim_sbc_tau_2( kt, ub(:,:,1), vb(:,:,1) ) ! using before instantaneous surf. currents
- !
- END SUBROUTINE sbc_ice_lim_2
- #else
- !!----------------------------------------------------------------------
- !! Default option Dummy module NO LIM 2.0 sea-ice model
- !!----------------------------------------------------------------------
- CONTAINS
- SUBROUTINE sbc_ice_lim_2 ( kt, ksbc ) ! Dummy routine
- INTEGER, INTENT(in) :: kt, ksbc
- WRITE(*,*) 'sbc_ice_lim_2: You should not have seen this print! error?', kt, ksbc
- END SUBROUTINE sbc_ice_lim_2
- #endif
- !!======================================================================
- END MODULE sbcice_lim_2
|