MODULE icb_oce
!!======================================================================
!! *** MODULE icb_oce ***
!! Icebergs: declare variables for iceberg tracking
!!======================================================================
!! History : 3.3 ! 2010-01 (T. Martin & A. Adcroft) Original code
!! - ! 2011-03 (G. Madec) Part conversion to NEMO form
!! - ! Removal of mapping from another grid
!! - ! 2011-04 (S. Alderson) Extensive rewrite ; Split into separate modules
!!----------------------------------------------------------------------
!!
!! Track Icebergs as Lagrangian objects within the model domain
!! Interaction with the other model variables through 'icebergs_gridded'
!!
!! A single iceberg is held as an instance of type 'iceberg'
!! This type defines a linked list, so each instance contains a pointer
!! to the previous and next icebergs in the list
!!
!! Type 'icebergs' is a convenience container for all relevant arrays
!! It contains one pointer to an 'iceberg' instance representing all icebergs in the processor
!!
!! Each iceberg has a position represented as a real cartesian coordinate which is
!! fractional grid cell, centred on T-points; so an iceberg position of (1.0,1.0) lies
!! exactly on the first T-point and the T-cell spans 0.5 to 1.5 in each direction
!!
!! Each iceberg is assigned a unique id even in MPI
!! This consists of an array of integers: the first element is used to label, the second
!! and subsequent elements are used to count the number of times the first element wraps
!! around all possible values within the valid size for this datatype.
!! Labelling is done by starting the first label in each processor (even when only one)
!! as narea, and then incrementing by jpnij (i.e. the total number of processors.
!! This means that the source processor for each iceberg can be identified by arithmetic
!! modulo jpnij.
!!
!!----------------------------------------------------------------------
USE par_oce ! ocean parameters
USE lib_mpp ! MPP library
IMPLICIT NONE
PUBLIC
PUBLIC icb_alloc ! routine called by icb_init in icbini.F90 module
INTEGER, PUBLIC, PARAMETER :: nclasses = 10 !: Number of icebergs classes
INTEGER, PUBLIC, PARAMETER :: nkounts = 3 !: Number of integers combined for unique naming
TYPE, PUBLIC :: icebergs_gridded !: various icebergs properties on model grid
REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: calving ! Calving mass rate (into stored ice) [kg/s]
REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: calving_hflx ! Calving heat flux [heat content of calving] [W/m2]
REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: floating_melt ! Net melting rate to icebergs + bits [kg/s/m^2]
INTEGER , DIMENSION(:,:) , ALLOCATABLE :: maxclass ! maximum class number at calving source point
REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: tmp ! Temporary work space
REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: stored_ice ! Accumulated ice mass flux at calving locations [kg]
REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: stored_heat ! Heat content of stored ice [J]
END TYPE icebergs_gridded
TYPE, PUBLIC :: point !: properties of an individual iceberg (position, mass, size, etc...)
INTEGER :: year
REAL(wp) :: xi , yj ! iceberg coordinates in the (i,j) referential (global)
REAL(wp) :: e1 , e2 ! horizontal scale factors at the iceberg position
REAL(wp) :: lon, lat, day ! geographic position
REAL(wp) :: mass, thickness, width, length, uvel, vvel ! iceberg physical properties
REAL(wp) :: uo, vo, ui, vi, ua, va, ssh_x, ssh_y, sst, cn, hi ! properties of iceberg environment
REAL(wp) :: mass_of_bits, heat_density
END TYPE point
TYPE, PUBLIC :: iceberg !: linked list defining all the icebergs present in the model domain
TYPE(iceberg), POINTER :: prev=>NULL(), next=>NULL() ! pointers to previous and next unique icebergs in linked list
INTEGER, DIMENSION(nkounts) :: number ! variables which do not change for this iceberg
REAL(wp) :: mass_scaling ! - - - -
TYPE(point), POINTER :: current_point => NULL() ! variables which change with time are held in a separate type
END TYPE iceberg
TYPE(icebergs_gridded), POINTER :: berg_grid !: master instance of gridded iceberg type
TYPE(iceberg) , POINTER :: first_berg => NULL() !: master instance of linked list iceberg type
! !!! parameters controlling iceberg characteristics and modelling
REAL(wp) :: berg_dt !: Time-step between iceberg CALLs (should make adaptive?)
REAL(wp), DIMENSION(:), ALLOCATABLE :: first_width, first_length !:
LOGICAL :: l_restarted_bergs=.FALSE. ! Indicate whether we read state from a restart or not
! ! arbitrary numbers for diawri entry
REAL(wp), DIMENSION(nclasses), PUBLIC :: class_num=(/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
! Extra arrays with bigger halo, needed when interpolating forcing onto iceberg position
! particularly for MPP when iceberg can lie inside T grid but outside U, V, or f grid
REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: uo_e, vo_e
REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ff_e, tt_e, fr_e, hicth
REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ua_e, va_e
REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ssh_e
#if defined key_si3 || defined key_cice
REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ui_e, vi_e
#endif
!!gm almost all those PARAM ARE defined in NEMO
REAL(wp), PUBLIC, PARAMETER :: pp_rho_ice = 916.7_wp !: Density of fresh ice @ 0oC [kg/m^3]
REAL(wp), PUBLIC, PARAMETER :: pp_rho_water = 999.8_wp !: Density of fresh water @ 0oC [kg/m^3]
REAL(wp), PUBLIC, PARAMETER :: pp_rho_air = 1.1_wp !: Density of air @ 0oC [kg/m^3]
REAL(wp), PUBLIC, PARAMETER :: pp_rho_seawater = 1025._wp !: Approx. density of surface sea water @ 0oC [kg/m^3]
!!gm end
REAL(wp), PUBLIC, PARAMETER :: pp_Cd_av = 1.3_wp !: (Vertical) Drag coefficient between bergs and atmos
REAL(wp), PUBLIC, PARAMETER :: pp_Cd_ah = 0.0055_wp !: (lateral ) Drag coefficient between bergs and atmos
REAL(wp), PUBLIC, PARAMETER :: pp_Cd_wv = 0.9_wp !: (Vertical) Drag coefficient between bergs and ocean
REAL(wp), PUBLIC, PARAMETER :: pp_Cd_wh = 0.0012_wp !: (lateral ) Drag coefficient between bergs and ocean
REAL(wp), PUBLIC, PARAMETER :: pp_Cd_iv = 0.9_wp !: (Vertical) Drag coefficient between bergs and sea-ice
!TOM> no horizontal drag for sea ice! real, PARAMETER :: pp_Cd_ih=0.0012 ! (lateral) Drag coeff. between bergs and sea-ice
! !!* namberg namelist parameters (and defaults) **
LOGICAL , PUBLIC :: ln_bergdia !: Calculate budgets
INTEGER , PUBLIC :: nn_verbose_level !: Turn on debugging when level > 0
INTEGER , PUBLIC :: nn_test_icebergs !: Create icebergs in absence of a restart file from the supplied class nb
REAL(wp), PUBLIC, DIMENSION(4) :: rn_test_box !: lon1,lon2,lat1,lat2 box to create them in
LOGICAL , PUBLIC :: ln_use_calving !: Force use of calving data even with nn_test_icebergs > 0
! (default is not to use calving data with test bergs)
INTEGER , PUBLIC :: nn_sample_rate !: Timesteps between sampling of position for trajectory storage
INTEGER , PUBLIC :: nn_verbose_write !: timesteps between verbose messages
REAL(wp), PUBLIC :: rn_rho_bergs !: Density of icebergs
REAL(wp), PUBLIC :: rn_LoW_ratio !: Initial ratio L/W for newly calved icebergs
REAL(wp), PUBLIC :: rn_bits_erosion_fraction !: Fraction of erosion melt flux to divert to bergy bits
REAL(wp), PUBLIC :: rn_sicn_shift !: Shift of sea-ice concentration in erosion flux modulation (0 0 ) CALL ctl_warn('icb_alloc: allocation of arrays failed')
!
END FUNCTION icb_alloc
!!======================================================================
END MODULE icb_oce