New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
icb_oce.F90 in branches/2012/dev_r3337_NOCS10_ICB/NEMOGCM/NEMO/OPA_SRC/ICB – NEMO

source: branches/2012/dev_r3337_NOCS10_ICB/NEMOGCM/NEMO/OPA_SRC/ICB/icb_oce.F90 @ 3339

Last change on this file since 3339 was 3339, checked in by sga, 12 years ago

NEMO branch dev_r3337_NOCS10_ICB: add new iceberg sub-directory ICB

File size: 10.9 KB
Line 
1MODULE icb_oce
2
3   !!======================================================================
4   !!                       ***  MODULE  icb_oce  ***
5   !! Ocean physics:  declare variables for iceberg tracking
6   !!======================================================================
7   !! History : 3.3.1 !  2010-01  (Martin&Adcroft) Original code
8   !!            -    !  2011-03  (Madec)          Part conversion to NEMO form
9   !!            -    !                            Removal of mapping from another grid
10   !!            -    !  2011-04  (Alderson)       Extensive rewrite
11   !!            -    !                            Split into separate modules
12   !!----------------------------------------------------------------------
13   !!
14   !! Track Icebergs as Lagrangian objects within the model domain
15   !! Interaction with the other model variables through 'icebergs_gridded'
16   !!
17   !! A single iceberg is held as an instance of type 'iceberg'
18   !! This type defines a linked list, so each instance contains a pointer to the previous and next
19   !! icebergs in the list
20   !!
21   !! Type 'icebergs' is a convenience container for all relevant arrays
22   !! It contains one pointer to an 'iceberg' instance representing all icebergs in the processor
23   !!
24   !! Each iceberg has a position represented as a real cartesian coordinate which is fractional
25   !! grid cell, centred on T points; so an iceberg position of (1.0,1.0) lies exactly on the first
26   !! T point and the T cell spans 0.5 to 1.5 in each direction
27   !!
28   !! Each iceberg is assigned a unique id even in MPI
29   !! This consists of an array of integers: the first element is used to label, the second and
30   !! subsequent elements are used to count the number of times the first element wraps around
31   !! all possible values within the valid size for this datatype.
32   !! Labelling is done by starting the first label in each processor (even when only one)
33   !! as narea, and then incrementing by jpnij (i.e. the total number of processors.
34   !! This means that the source processor for each iceberg can be identified by arithmetic
35   !! modulo jpnij.
36   !!
37   !!----------------------------------------------------------------------
38
39   USE par_oce         ! ocean parameters
40   USE fldread
41
42   IMPLICIT NONE
43   PUBLIC
44
45   ! Global constants
46   INTEGER, PUBLIC, PARAMETER :: nclasses = 10 ! Number of ice bergs classes
47   INTEGER, PUBLIC, PARAMETER :: nkounts  =  3 ! Number of integers combined for unique naming
48
49   !! icebergs_gridded type allows for interaction between the set of icebergs and the model grid
50   TYPE, PUBLIC :: icebergs_gridded
51      REAL(wp), DIMENSION(:,:)  , POINTER :: calving => NULL()     ! Calving mass rate [frozen runoff] (kg/s) (into stored ice)
52      REAL(wp), DIMENSION(:,:)  , POINTER :: calving_hflx=>NULL()  ! Calving heat flux [heat content of calving] (W/m2)
53      REAL(wp), DIMENSION(:,:)  , POINTER :: floating_melt=>NULL() ! Net melting rate to icebergs + bits (kg/s/m^2)
54      INTEGER , DIMENSION(:,:)  , POINTER :: maxclass=>NULL()      ! maximum class number at calving source point
55      REAL(wp), DIMENSION(:,:)  , POINTER :: tmp=>NULL()           ! Temporary work space
56      REAL(wp), DIMENSION(:,:,:), POINTER :: stored_ice=>NULL()    ! Accumulated ice mass flux at calving locations (kg)
57      REAL(wp), DIMENSION(:,:)  , POINTER :: stored_heat=>NULL()   ! Heat content of stored ice (J)
58   END TYPE icebergs_gridded
59
60   !! point type is just a convenience storage type for properties of an individual iceberg
61   TYPE, PUBLIC ::   point
62      INTEGER  :: year
63      REAL(wp) :: xi, yj              ! iceberg coordinates in the (i,j) referential (global)
64      REAL(wp) :: e1, e2              ! horizontal scale factors at the iceberg position
65      REAL(wp) :: lon, lat, day
66      REAL(wp) :: mass, thickness, width, length, uvel, vvel
67      REAL(wp) :: uo, vo, ui, vi, ua, va, ssh_x, ssh_y, sst, cn, hi
68      REAL(wp) :: mass_of_bits, heat_density
69   END TYPE point
70
71   !! iceberg type is really just a linked list
72   TYPE, PUBLIC :: iceberg
73      ! pointers to previous and next unique icebergs in linked list
74      TYPE(iceberg), POINTER      :: prev=>NULL(), next=>NULL()
75      ! variables which do not change for this iceberg
76      INTEGER, DIMENSION(nkounts) :: number
77      REAL(wp)                    :: mass_scaling
78      ! variables which change with time are held in a separate type
79      TYPE(point), POINTER        :: current_point => NULL()
80   END TYPE iceberg
81
82   !! master instances of gridded and linked list iceberg types
83   TYPE(icebergs_gridded), POINTER ::   berg_grid
84   TYPE(iceberg)         , POINTER ::   first_berg   => NULL()
85
86   !! parameters controlling iceberg characteristics and modelling
87   REAL(wp)                        ::   berg_dt                    ! Time-step between iceberg CALLs (should make adaptive?)
88   INTEGER                         ::   current_year
89   REAL(wp)                        ::   current_yearday            ! 1.00-365.99
90   REAL(wp), DIMENSION(:), POINTER ::   initial_width, initial_length
91   LOGICAL                         ::   restarted_bergs=.false.          ! Indicate whether we read state from a restart or not
92   !                                                           ! arbitrary numbers for diawri entry
93   REAL(wp), DIMENSION(nclasses), PUBLIC ::   class_num=(/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
94
95   ! Extra arrays with bigger halo, needed when interpolating forcing onto iceberg position
96   ! particularly for MPP when iceberg can lie inside T grid but outside U, V, or f grid
97   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: uo_e
98   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: vo_e
99   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ff_e
100   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ua_e
101   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: va_e
102#if defined key_lim2 || defined key_lim3
103   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ui_e
104   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: vi_e
105   REAL(wp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ssh_e
106#endif
107
108   !!gm almost all those PARAM ARE defined in NEMO
109   REAL(wp), PUBLIC, PARAMETER :: rho_ice      = 916.7_wp   ! Density of fresh ice @ 0oC (kg/m^3)
110   REAL(wp), PUBLIC, PARAMETER :: rho_water    = 999.8_wp   ! Density of fresh water @ 0oC (kg/m^3)
111   REAL(wp), PUBLIC, PARAMETER :: rho_air      = 1.1_wp     ! Density of air @ 0oC (kg/m^3) ???
112   REAL(wp), PUBLIC, PARAMETER :: rho_seawater = 1025._wp   ! Approx. density of surface sea water @ 0oC (kg/m^3)
113   !!gm end
114   REAL(wp), PUBLIC, PARAMETER :: Cd_av = 1.3_wp      ! (Vertical) Drag coefficient between bergs and atmos (?)
115   REAL(wp), PUBLIC, PARAMETER :: Cd_ah = 0.0055_wp   ! (Horizontal) Drag coefficient between bergs and atmos (?)
116   REAL(wp), PUBLIC, PARAMETER :: Cd_wv = 0.9_wp      ! (Vertical) Drag coefficient between bergs and ocean (?)
117   REAL(wp), PUBLIC, PARAMETER :: Cd_wh = 0.0012_wp   ! (Horizontal) Drag coefficient between bergs and ocean (?)
118   REAL(wp), PUBLIC, PARAMETER :: Cd_iv = 0.9_wp      ! (Vertical) Drag coefficient between bergs and sea-ice (?)
119   !TOM> no horizontal drag for sea ice! real, PARAMETER :: Cd_ih=0.0012 ! (Horizontal) Drag coefficient between bergs and sea-ice (?)
120
121   !                                           !** namberg namelist parameters (and defaults) **
122   LOGICAL,  PUBLIC  ::   ln_bergdia        = .true.    ! Calculate budgets
123   INTEGER,  PUBLIC  ::   nn_verbose_level       = 0         ! Turn on debugging when level > 0
124   INTEGER,  PUBLIC  ::   nn_test_icebergs = 0    ! Create icebergs in absence of a restart file from the supplied class number
125   REAL(wp), PUBLIC, DIMENSION(4) ::   rn_test_box = (/ 0._wp, 1._wp, 0._wp, 1._wp /)
126                                                         ! lon1,lon2,lat1,lat2 box to create them in
127   INTEGER,   PUBLIC ::   nn_sample_rate           = 0       ! Timesteps between sampling of position for trajectory storage
128   INTEGER,   PUBLIC ::   nn_verbose_write              = 15      ! timesteps between verbose messages
129   REAL(wp),  PUBLIC ::   rn_rho_bergs                  = 850._wp ! Density of icebergs
130   REAL(wp),  PUBLIC ::   rn_LoW_ratio                  = 1.5_wp  ! Initial ratio L/W for newly calved icebergs
131   REAL(wp),  PUBLIC ::   rn_bits_erosion_fraction = 0.      ! Fraction of erosion melt flux to divert to bergy bits
132   REAL(wp),  PUBLIC ::   rn_sicn_shift                 = 0._wp   ! Shift of sea-ice concentration in erosion flux modulation (0<sicn_shift<1)
133   LOGICAL,   PUBLIC ::   ln_operator_splitting     = .true.  ! Use first order operator splitting for thermodynamics
134   LOGICAL,   PUBLIC ::   ln_passive_mode               = .false. ! iceberg - ocean decoupling
135   LOGICAL,   PUBLIC ::   ln_time_average_weight        = .false. ! Time average the weight on the ocean        !!gm I don't understand that !
136   REAL(wp),  PUBLIC ::   rn_speed_limit                = 0._wp   ! CFL speed limit for a berg
137   !
138   !                                                           ! Mass thresholds between iceberg classes (kg)
139   REAL(wp), DIMENSION(nclasses), PUBLIC ::   rn_initial_mass=(/8.8e7, 4.1e8, 3.3e9, 1.8e10, 3.8e10, 7.5e10, 1.2e11, &
140                                                             2.2e11, 3.9e11, 7.4e11/)
141   !                                              ! Fraction of calving to apply to this class (non-dim)
142   REAL(wp), DIMENSION(nclasses), PUBLIC ::   rn_distribution=(/0.25, 0.12, 0.15, 0.18, 0.12, 0.07, 0.03, 0.03, 0.03, 0.02/)
143   !                                              ! Ratio between effective and real iceberg mass (non-dim)
144   REAL(wp), DIMENSION(nclasses), PUBLIC ::   rn_mass_scaling=(/2000, 200, 50, 20, 10, 5, 2, 1, 1, 1/)
145   !                                              ! Total thickness of newly calved bergs (m)
146   REAL(wp), DIMENSION(nclasses), PUBLIC ::   rn_initial_thickness=(/40., 67., 133., 175., 250., 250., 250., 250., 250., 250./)
147
148   ! Single instance of an icebergs type initialised in icebergs_init and updated in icebergs_run
149   REAL(wp), ALLOCATABLE, PUBLIC, SAVE, DIMENSION(:,:)     ::   p_calving, p_calving_hflx
150   INTEGER              , PUBLIC, SAVE                     ::   numicb 
151   INTEGER              , PUBLIC, SAVE, DIMENSION(nkounts) ::   kount_bergs
152   INTEGER              , PUBLIC, SAVE                     ::   icbdi, icbei, icbdj, icbej
153   REAL(wp)             , PUBLIC, SAVE                     ::   icb_left, icb_right
154   INTEGER              , PUBLIC, SAVE                     ::   icbpack
155   INTEGER              , PUBLIC, SAVE                     ::   ktberg, knberg
156   INTEGER, ALLOCATABLE , PUBLIC, SAVE, DIMENSION(:)       ::   icbfldpts
157   INTEGER, ALLOCATABLE , PUBLIC, SAVE, DIMENSION(:)       ::   icbflddest
158   INTEGER, ALLOCATABLE , PUBLIC, SAVE, DIMENSION(:)       ::   icbfldproc
159
160   TYPE(FLD), ALLOCATABLE, PUBLIC     , DIMENSION(:)       ::   sf_icb       ! structure: file information, fields read
161
162END MODULE icb_oce
Note: See TracBrowser for help on using the repository browser.