1 | MODULE 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 :: first_width, first_length |
---|
91 | LOGICAL :: l_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 :: pp_rho_ice = 916.7_wp ! Density of fresh ice @ 0oC (kg/m^3) |
---|
110 | REAL(wp), PUBLIC, PARAMETER :: pp_rho_water = 999.8_wp ! Density of fresh water @ 0oC (kg/m^3) |
---|
111 | REAL(wp), PUBLIC, PARAMETER :: pp_rho_air = 1.1_wp ! Density of air @ 0oC (kg/m^3) ??? |
---|
112 | REAL(wp), PUBLIC, PARAMETER :: pp_rho_seawater = 1025._wp ! Approx. density of surface sea water @ 0oC (kg/m^3) |
---|
113 | !!gm end |
---|
114 | REAL(wp), PUBLIC, PARAMETER :: pp_Cd_av = 1.3_wp ! (Vertical) Drag coefficient between bergs and atmos (?) |
---|
115 | REAL(wp), PUBLIC, PARAMETER :: pp_Cd_ah = 0.0055_wp ! (Horizontal) Drag coefficient between bergs and atmos (?) |
---|
116 | REAL(wp), PUBLIC, PARAMETER :: pp_Cd_wv = 0.9_wp ! (Vertical) Drag coefficient between bergs and ocean (?) |
---|
117 | REAL(wp), PUBLIC, PARAMETER :: pp_Cd_wh = 0.0012_wp ! (Horizontal) Drag coefficient between bergs and ocean (?) |
---|
118 | REAL(wp), PUBLIC, PARAMETER :: pp_Cd_iv = 0.9_wp ! (Vertical) Drag coefficient between bergs and sea-ice (?) |
---|
119 | !TOM> no horizontal drag for sea ice! real, PARAMETER :: pp_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(:,:) :: src_calving, src_calving_hflx |
---|
150 | INTEGER , PUBLIC, SAVE :: numicb |
---|
151 | INTEGER , PUBLIC, SAVE, DIMENSION(nkounts) :: num_bergs |
---|
152 | INTEGER , PUBLIC, SAVE :: nicbdi, nicbei, nicbdj, nicbej |
---|
153 | REAL(wp) , PUBLIC, SAVE :: ricb_left, ricb_right |
---|
154 | INTEGER , PUBLIC, SAVE :: nicbpack |
---|
155 | INTEGER , PUBLIC, SAVE :: nktberg, nknberg |
---|
156 | INTEGER, ALLOCATABLE , PUBLIC, SAVE, DIMENSION(:) :: nicbfldpts |
---|
157 | INTEGER, ALLOCATABLE , PUBLIC, SAVE, DIMENSION(:) :: nicbflddest |
---|
158 | INTEGER, ALLOCATABLE , PUBLIC, SAVE, DIMENSION(:) :: nicbfldproc |
---|
159 | |
---|
160 | TYPE(FLD), ALLOCATABLE, PUBLIC , DIMENSION(:) :: sf_icb ! structure: file information, fields read |
---|
161 | |
---|
162 | END MODULE icb_oce |
---|