Line data Source code
1 : !=======================================================================
2 :
3 : ! Routines to initialize the ice thickness distribution and
4 : ! utilities to redistribute ice among categories. These routines
5 : ! are not specific to a particular numerical implementation.
6 : !
7 : ! See Bitz, C.M., and W.H. Lipscomb, 1999:
8 : ! An energy-conserving thermodynamic model of sea ice,
9 : ! J. Geophys. Res., 104, 15,669--15,677.
10 : !
11 : ! See Bitz, C.M., M.M. Holland, A.J. Weaver, M. Eby, 2001:
12 : ! Simulating the ice-thickness distribution in a climate model,
13 : ! J. Geophys. Res., 106, 2441--2464.
14 : !
15 : ! authors: C. M. Bitz, UW
16 : ! William H. Lipscomb and Elizabeth C. Hunke, LANL
17 : !
18 : ! 2003: Vectorized by Clifford Chen (Fujitsu) and William Lipscomb
19 : !
20 : ! 2004 WHL: Added multiple snow layers, block structure, cleanup_itd
21 : ! 2006 ECH: Added WMO standard ice thickness categories as kcatbound=2
22 : ! Streamlined for efficiency
23 : ! Converted to free source form (F90)
24 : ! 2014 ECH: Converted to column package
25 :
26 : module icepack_itd
27 :
28 : use icepack_kinds
29 : use icepack_parameters, only: c0, c1, c2, c3, c15, c25, c100, p1, p01, p001, p5, puny
30 : use icepack_parameters, only: Lfresh, rhos, ice_ref_salinity, hs_min, cp_ice, Tocnfrz, rhoi
31 : use icepack_parameters, only: rhosi, sk_l, hs_ssl, min_salin
32 : use icepack_tracers, only: nt_Tsfc, nt_qice, nt_qsno, nt_aero, nt_isosno, nt_isoice
33 : use icepack_tracers, only: nt_apnd, nt_hpnd, nt_fbri, tr_brine, nt_bgc_S, bio_index
34 : use icepack_tracers, only: n_iso
35 : use icepack_tracers, only: tr_iso
36 : use icepack_tracers, only: icepack_compute_tracers
37 : use icepack_parameters, only: solve_zsal, skl_bgc, z_tracers
38 : use icepack_parameters, only: kcatbound, kitd
39 : use icepack_therm_shared, only: Tmin, hi_min
40 : use icepack_warnings, only: warnstr, icepack_warnings_add
41 : use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
42 : use icepack_zbgc_shared,only: zap_small_bgc
43 :
44 : implicit none
45 :
46 : private
47 : public :: aggregate_area, &
48 : shift_ice, & ! LCOV_EXCL_LINE
49 : column_sum, & ! LCOV_EXCL_LINE
50 : column_conservation_check, & ! LCOV_EXCL_LINE
51 : cleanup_itd, & ! LCOV_EXCL_LINE
52 : reduce_area, & ! LCOV_EXCL_LINE
53 : icepack_init_itd, & ! LCOV_EXCL_LINE
54 : icepack_init_itd_hist, & ! LCOV_EXCL_LINE
55 : icepack_aggregate
56 :
57 : !=======================================================================
58 :
59 : contains
60 :
61 : !=======================================================================
62 :
63 : ! Aggregate ice area (but not other state variables) over thickness
64 : ! categories.
65 : !
66 : ! authors: William H. Lipscomb, LANL
67 :
68 3153178741 : subroutine aggregate_area (ncat, aicen, aice, aice0)
69 :
70 : integer (kind=int_kind), intent(in) :: &
71 : ncat ! number of thickness categories
72 :
73 : real (kind=dbl_kind), dimension(:), intent(in) :: &
74 : aicen ! concentration of ice
75 :
76 : real (kind=dbl_kind), intent(inout) :: &
77 : aice, & ! concentration of ice ! LCOV_EXCL_LINE
78 : aice0 ! concentration of open water
79 :
80 : ! local variables
81 :
82 : integer (kind=int_kind) :: n
83 :
84 : character(len=*),parameter :: subname='(aggregate_area)'
85 :
86 : !-----------------------------------------------------------------
87 : ! Aggregate
88 : !-----------------------------------------------------------------
89 :
90 3153178741 : aice = c0
91 18849711660 : do n = 1, ncat
92 18849711660 : aice = aice + aicen(n)
93 : enddo ! n
94 :
95 : ! open water fraction
96 3153178741 : aice0 = max (c1 - aice, c0)
97 :
98 3153178741 : end subroutine aggregate_area
99 :
100 : !=======================================================================
101 :
102 : ! Rebins thicknesses into defined categories
103 : !
104 : ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL
105 :
106 505671827 : subroutine rebin (ntrcr, trcr_depend, &
107 : trcr_base, & ! LCOV_EXCL_LINE
108 : n_trcr_strata, & ! LCOV_EXCL_LINE
109 : nt_strata, & ! LCOV_EXCL_LINE
110 : aicen, trcrn, & ! LCOV_EXCL_LINE
111 : vicen, vsnon, & ! LCOV_EXCL_LINE
112 505671827 : ncat, hin_max )
113 :
114 : integer (kind=int_kind), intent(in) :: &
115 : ntrcr , & ! number of tracers in use ! LCOV_EXCL_LINE
116 : ncat ! number of thickness categories
117 :
118 : integer (kind=int_kind), dimension (:), intent(in) :: &
119 : trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon ! LCOV_EXCL_LINE
120 : n_trcr_strata ! number of underlying tracer layers
121 :
122 : real (kind=dbl_kind), dimension (:,:), intent(in) :: &
123 : trcr_base ! = 0 or 1 depending on tracer dependency
124 : ! argument 2: (1) aice, (2) vice, (3) vsno
125 :
126 : integer (kind=int_kind), dimension (:,:), intent(in) :: &
127 : nt_strata ! indices of underlying tracer layers
128 :
129 : real (kind=dbl_kind), dimension (ncat), intent(inout) :: &
130 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
131 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
132 : vsnon ! volume per unit area of snow (m)
133 :
134 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
135 : trcrn ! ice tracers
136 :
137 : real (kind=dbl_kind), dimension(0:ncat), intent(in) :: &
138 : hin_max ! category limits (m)
139 :
140 : ! local variables
141 :
142 : integer (kind=int_kind) :: &
143 : n ! category index
144 :
145 : logical (kind=log_kind) :: &
146 : shiftflag ! = .true. if ice must be shifted
147 :
148 : integer (kind=int_kind), dimension (ncat) :: &
149 1011343654 : donor ! donor category index
150 :
151 : real (kind=dbl_kind), dimension (ncat) :: &
152 : daice , & ! ice area transferred ! LCOV_EXCL_LINE
153 : dvice , & ! ice volume transferred ! LCOV_EXCL_LINE
154 843169648 : hicen ! ice thickness for each cat (m)
155 :
156 : character(len=*),parameter :: subname='(rebin)'
157 :
158 : !-----------------------------------------------------------------
159 : ! Initialize
160 : !-----------------------------------------------------------------
161 :
162 3022183168 : do n = 1, ncat
163 2516511341 : donor(n) = 0
164 2516511341 : daice(n) = c0
165 2516511341 : dvice(n) = c0
166 :
167 : !-----------------------------------------------------------------
168 : ! Compute ice thickness.
169 : !-----------------------------------------------------------------
170 3022183168 : if (aicen(n) > puny) then
171 2334975407 : hicen(n) = vicen(n) / aicen(n)
172 : else
173 181535934 : hicen(n) = c0
174 : endif
175 : enddo ! n
176 :
177 : !-----------------------------------------------------------------
178 : ! make sure thickness of cat 1 is at least hin_max(0)
179 : !-----------------------------------------------------------------
180 :
181 505671827 : if (aicen(1) > puny) then
182 504252163 : if (hicen(1) <= hin_max(0) .and. hin_max(0) > c0 ) then
183 2389668 : aicen(1) = vicen(1) / hin_max(0)
184 2389668 : hicen(1) = hin_max(0)
185 : endif
186 : endif
187 :
188 : !-----------------------------------------------------------------
189 : ! If a category thickness is not in bounds, shift the
190 : ! entire area, volume, and energy to the neighboring category
191 : !-----------------------------------------------------------------
192 :
193 : !-----------------------------------------------------------------
194 : ! Move thin categories up
195 : !-----------------------------------------------------------------
196 :
197 2516511341 : do n = 1, ncat-1 ! loop over category boundaries
198 :
199 : !-----------------------------------------------------------------
200 : ! identify thicknesses that are too big
201 : !-----------------------------------------------------------------
202 2010839514 : shiftflag = .false.
203 2234622217 : if (aicen(n) > puny .and. &
204 223782703 : hicen(n) > hin_max(n)) then
205 1367 : shiftflag = .true.
206 1367 : donor(n) = n
207 1367 : daice(n) = aicen(n)
208 1367 : dvice(n) = vicen(n)
209 : endif
210 :
211 2516511341 : if (shiftflag) then
212 :
213 : !-----------------------------------------------------------------
214 : ! shift ice between categories
215 : !-----------------------------------------------------------------
216 :
217 : call shift_ice (ntrcr, ncat, &
218 : trcr_depend, & ! LCOV_EXCL_LINE
219 : trcr_base, & ! LCOV_EXCL_LINE
220 : n_trcr_strata, & ! LCOV_EXCL_LINE
221 : nt_strata, & ! LCOV_EXCL_LINE
222 : aicen, trcrn, & ! LCOV_EXCL_LINE
223 : vicen, vsnon, & ! LCOV_EXCL_LINE
224 : hicen, donor, & ! LCOV_EXCL_LINE
225 1367 : daice, dvice )
226 1367 : if (icepack_warnings_aborted(subname)) return
227 :
228 : !-----------------------------------------------------------------
229 : ! reset shift parameters
230 : !-----------------------------------------------------------------
231 :
232 1367 : donor(n) = 0
233 1367 : daice(n) = c0
234 1367 : dvice(n) = c0
235 :
236 : endif ! shiftflag
237 :
238 : enddo ! n
239 :
240 : !-----------------------------------------------------------------
241 : ! Move thick categories down
242 : !-----------------------------------------------------------------
243 :
244 2516511341 : do n = ncat-1, 1, -1 ! loop over category boundaries
245 :
246 : !-----------------------------------------------------------------
247 : ! identify thicknesses that are too small
248 : !-----------------------------------------------------------------
249 :
250 2010839514 : shiftflag = .false.
251 2234622217 : if (aicen(n+1) > puny .and. &
252 223782703 : hicen(n+1) <= hin_max(n)) then
253 25458 : shiftflag = .true.
254 25458 : donor(n) = n+1
255 25458 : daice(n) = aicen(n+1)
256 25458 : dvice(n) = vicen(n+1)
257 : endif
258 :
259 2516511341 : if (shiftflag) then
260 :
261 : !-----------------------------------------------------------------
262 : ! shift ice between categories
263 : !-----------------------------------------------------------------
264 :
265 : call shift_ice (ntrcr, ncat, &
266 : trcr_depend, & ! LCOV_EXCL_LINE
267 : trcr_base, & ! LCOV_EXCL_LINE
268 : n_trcr_strata, & ! LCOV_EXCL_LINE
269 : nt_strata, & ! LCOV_EXCL_LINE
270 : aicen, trcrn, & ! LCOV_EXCL_LINE
271 : vicen, vsnon, & ! LCOV_EXCL_LINE
272 : hicen, donor, & ! LCOV_EXCL_LINE
273 25458 : daice, dvice )
274 25458 : if (icepack_warnings_aborted(subname)) return
275 :
276 : !-----------------------------------------------------------------
277 : ! reset shift parameters
278 : !-----------------------------------------------------------------
279 :
280 25458 : donor(n) = 0
281 25458 : daice(n) = c0
282 25458 : dvice(n) = c0
283 :
284 : endif ! shiftflag
285 :
286 : enddo ! n
287 :
288 : end subroutine rebin
289 :
290 : !=======================================================================
291 :
292 : ! Reduce area when ice melts for special case of ncat=1
293 : !
294 : ! Use CSM 1.0-like method of reducing ice area
295 : ! when melting occurs: assume only half the ice volume
296 : ! change goes to thickness decrease, the other half
297 : ! to reduction in ice fraction
298 : !
299 : ! authors: C. M. Bitz, UW
300 : ! modified by: Elizabeth C. Hunke, LANL
301 :
302 23057280 : subroutine reduce_area (hin_max, &
303 : aicen, vicen, & ! LCOV_EXCL_LINE
304 : aicen_init,vicen_init)
305 :
306 : real (kind=dbl_kind), intent(in) :: &
307 : hin_max ! lowest category boundary
308 :
309 : real (kind=dbl_kind), intent(inout) :: &
310 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
311 : vicen ! volume per unit area of ice (m)
312 :
313 : real (kind=dbl_kind), intent(in) :: &
314 : aicen_init, & ! old ice area for category 1 (m) ! LCOV_EXCL_LINE
315 : vicen_init ! old ice volume for category 1 (m)
316 :
317 : ! local variables
318 :
319 : real (kind=dbl_kind) :: &
320 : hi0 , & ! initial hi ! LCOV_EXCL_LINE
321 : hi1 , & ! current hi ! LCOV_EXCL_LINE
322 2882160 : dhi ! hi1 - hi0
323 :
324 : character(len=*),parameter :: subname='(reduce_area)'
325 :
326 23057280 : hi0 = c0
327 23057280 : if (aicen_init > c0) &
328 5333636 : hi0 = vicen_init / aicen_init
329 :
330 23057280 : hi1 = c0
331 23057280 : if (aicen > c0) &
332 5319283 : hi1 = vicen / aicen
333 :
334 : ! make sure thickness of cat 1 is at least hin_max(0)
335 23057280 : if (hi1 <= hin_max .and. hin_max > c0 ) then
336 0 : aicen = vicen / hin_max
337 0 : hi1 = hin_max
338 : endif
339 :
340 23057280 : if (aicen > c0) then
341 5319283 : dhi = hi1 - hi0
342 5319283 : if (dhi < c0) then
343 1848874 : hi1 = vicen / aicen
344 1848874 : aicen = c2 * vicen / (hi1 + hi0)
345 : endif
346 : endif
347 :
348 23057280 : end subroutine reduce_area
349 :
350 : !=======================================================================
351 :
352 : ! Shift ice across category boundaries, conserving area, volume, and
353 : ! energy.
354 : !
355 : ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL
356 :
357 207680044 : subroutine shift_ice (ntrcr, ncat, &
358 : trcr_depend, & ! LCOV_EXCL_LINE
359 : trcr_base, & ! LCOV_EXCL_LINE
360 : n_trcr_strata, & ! LCOV_EXCL_LINE
361 : nt_strata, & ! LCOV_EXCL_LINE
362 : aicen, trcrn, & ! LCOV_EXCL_LINE
363 : vicen, vsnon, & ! LCOV_EXCL_LINE
364 : hicen, donor, & ! LCOV_EXCL_LINE
365 207680044 : daice, dvice )
366 :
367 : integer (kind=int_kind), intent(in) :: &
368 : ncat , & ! number of thickness categories ! LCOV_EXCL_LINE
369 : ntrcr ! number of tracers in use
370 :
371 : integer (kind=int_kind), dimension (:), intent(in) :: &
372 : trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon ! LCOV_EXCL_LINE
373 : n_trcr_strata ! number of underlying tracer layers
374 :
375 : real (kind=dbl_kind), dimension (:,:), intent(in) :: &
376 : trcr_base ! = 0 or 1 depending on tracer dependency
377 : ! argument 2: (1) aice, (2) vice, (3) vsno
378 :
379 : integer (kind=int_kind), dimension (:,:), intent(in) :: &
380 : nt_strata ! indices of underlying tracer layers
381 :
382 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
383 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
384 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
385 : vsnon ! volume per unit area of snow (m)
386 :
387 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
388 : trcrn ! ice tracers
389 :
390 : ! NOTE: Third index of donor, daice, dvice should be ncat-1,
391 : ! except that compilers would have trouble when ncat = 1
392 : integer (kind=int_kind), dimension(:), intent(in) :: &
393 : donor ! donor category index
394 :
395 : real (kind=dbl_kind), dimension(:), intent(inout) :: &
396 : daice , & ! ice area transferred across boundary ! LCOV_EXCL_LINE
397 : dvice , & ! ice volume transferred across boundary ! LCOV_EXCL_LINE
398 : hicen ! ice thickness for each cat (m)
399 :
400 : ! local variables
401 :
402 : integer (kind=int_kind) :: &
403 : n , & ! thickness category index ! LCOV_EXCL_LINE
404 : nr , & ! receiver category ! LCOV_EXCL_LINE
405 : nd , & ! donor category ! LCOV_EXCL_LINE
406 : it , & ! tracer index ! LCOV_EXCL_LINE
407 : ntr , & ! tracer index ! LCOV_EXCL_LINE
408 : itl ! loop index
409 :
410 : real (kind=dbl_kind), dimension(ntrcr,ncat) :: &
411 2803835035 : atrcrn ! aicen*trcrn
412 :
413 : real (kind=dbl_kind) :: &
414 : dvsnow , & ! snow volume transferred ! LCOV_EXCL_LINE
415 18905233 : datrcr ! aicen*train transferred
416 :
417 : logical (kind=log_kind) :: &
418 : daice_negative , & ! true if daice < -puny ! LCOV_EXCL_LINE
419 : dvice_negative , & ! true if dvice < -puny ! LCOV_EXCL_LINE
420 : daice_greater_aicen, & ! true if daice > aicen ! LCOV_EXCL_LINE
421 : dvice_greater_vicen ! true if dvice > vicen
422 :
423 : real (kind=dbl_kind) :: &
424 18905233 : worka, workb
425 :
426 529639342 : real (kind=dbl_kind), dimension(ncat) :: aicen_init
427 491828876 : real (kind=dbl_kind), dimension(ncat) :: vicen_init
428 321959298 : real (kind=dbl_kind), dimension(ncat) :: vsnon_init
429 :
430 : character(len=*),parameter :: subname='(shift_ice)'
431 :
432 : !-----------------------------------------------------------------
433 : ! store initial snow and ice volume
434 : !-----------------------------------------------------------------
435 :
436 1261455370 : aicen_init(:) = aicen(:)
437 1261455370 : vicen_init(:) = vicen(:)
438 1261455370 : vsnon_init(:) = vsnon(:)
439 :
440 : !-----------------------------------------------------------------
441 : ! Define variables equal to aicen*trcrn, vicen*trcrn, vsnon*trcrn
442 : !-----------------------------------------------------------------
443 :
444 1261455370 : do n = 1, ncat
445 33489634106 : do it = 1, ntrcr
446 2312006159 : atrcrn(it,n) = trcrn(it,n)*(trcr_base(it,1) * aicen(n) &
447 : + trcr_base(it,2) * vicen(n) & ! LCOV_EXCL_LINE
448 32228178736 : + trcr_base(it,3) * vsnon(n))
449 33281954062 : if (n_trcr_strata(it) > 0) then
450 7662413888 : do itl = 1, n_trcr_strata(it)
451 4765655050 : ntr = nt_strata(it,itl)
452 7662413888 : atrcrn(it,n) = atrcrn(it,n) * trcrn(ntr,n)
453 : enddo
454 : endif
455 : enddo ! it
456 : enddo ! n
457 :
458 : !-----------------------------------------------------------------
459 : ! Check for daice or dvice out of range, allowing for roundoff error
460 : !-----------------------------------------------------------------
461 :
462 1053775326 : do n = 1, ncat-1
463 :
464 846095282 : daice_negative = .false.
465 846095282 : dvice_negative = .false.
466 846095282 : daice_greater_aicen = .false.
467 846095282 : dvice_greater_vicen = .false.
468 :
469 846095282 : if (donor(n) > 0) then
470 728709590 : nd = donor(n)
471 :
472 728709590 : if (daice(n) < c0) then
473 0 : if (daice(n) > -puny*aicen(nd)) then
474 0 : daice(n) = c0 ! shift no ice
475 0 : dvice(n) = c0
476 : else
477 0 : daice_negative = .true.
478 : endif
479 : endif
480 :
481 728709590 : if (dvice(n) < c0) then
482 0 : if (dvice(n) > -puny*vicen(nd)) then
483 0 : daice(n) = c0 ! shift no ice
484 0 : dvice(n) = c0
485 : else
486 0 : dvice_negative = .true.
487 : endif
488 : endif
489 :
490 728709590 : if (daice(n) > aicen(nd)*(c1-puny)) then
491 125498 : if (daice(n) < aicen(nd)*(c1+puny)) then
492 125498 : daice(n) = aicen(nd)
493 125498 : dvice(n) = vicen(nd)
494 : else
495 0 : daice_greater_aicen = .true.
496 : endif
497 : endif
498 :
499 728709590 : if (dvice(n) > vicen(nd)*(c1-puny)) then
500 125498 : if (dvice(n) < vicen(nd)*(c1+puny)) then
501 125498 : daice(n) = aicen(nd)
502 125498 : dvice(n) = vicen(nd)
503 : else
504 0 : dvice_greater_vicen = .true.
505 : endif
506 : endif
507 :
508 : endif ! donor > 0
509 :
510 : !-----------------------------------------------------------------
511 : ! error messages
512 : !-----------------------------------------------------------------
513 :
514 846095282 : if (daice_negative) then
515 0 : if (donor(n) > 0 .and. &
516 0 : daice(n) <= -puny*aicen(nd)) then
517 0 : write(warnstr,*) ' '
518 0 : call icepack_warnings_add(warnstr)
519 0 : write(warnstr,*) subname, 'shift_ice: negative daice'
520 0 : call icepack_warnings_add(warnstr)
521 0 : write(warnstr,*) subname, 'boundary, donor cat:', n, nd
522 0 : call icepack_warnings_add(warnstr)
523 0 : write(warnstr,*) subname, 'daice =', daice(n)
524 0 : call icepack_warnings_add(warnstr)
525 0 : write(warnstr,*) subname, 'dvice =', dvice(n)
526 0 : call icepack_warnings_add(warnstr)
527 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
528 0 : call icepack_warnings_add(subname//' shift_ice: negative daice')
529 : endif
530 : endif
531 846095282 : if (icepack_warnings_aborted(subname)) return
532 :
533 846095282 : if (dvice_negative) then
534 0 : if (donor(n) > 0 .and. &
535 0 : dvice(n) <= -puny*vicen(nd)) then
536 0 : write(warnstr,*) ' '
537 0 : call icepack_warnings_add(warnstr)
538 0 : write(warnstr,*) subname, 'shift_ice: negative dvice'
539 0 : call icepack_warnings_add(warnstr)
540 0 : write(warnstr,*) subname, 'boundary, donor cat:', n, nd
541 0 : call icepack_warnings_add(warnstr)
542 0 : write(warnstr,*) subname, 'daice =', daice(n)
543 0 : call icepack_warnings_add(warnstr)
544 0 : write(warnstr,*) subname, 'dvice =', dvice(n)
545 0 : call icepack_warnings_add(warnstr)
546 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
547 0 : call icepack_warnings_add(subname//' shift_ice: negative dvice')
548 : endif
549 : endif
550 846095282 : if (icepack_warnings_aborted(subname)) return
551 :
552 846095282 : if (daice_greater_aicen) then
553 0 : if (donor(n) > 0) then
554 0 : nd = donor(n)
555 0 : if (daice(n) >= aicen(nd)*(c1+puny)) then
556 0 : write(warnstr,*) ' '
557 0 : call icepack_warnings_add(warnstr)
558 0 : write(warnstr,*) subname, 'shift_ice: daice > aicen'
559 0 : call icepack_warnings_add(warnstr)
560 0 : write(warnstr,*) subname, 'boundary, donor cat:', n, nd
561 0 : call icepack_warnings_add(warnstr)
562 0 : write(warnstr,*) subname, 'daice =', daice(n)
563 0 : call icepack_warnings_add(warnstr)
564 0 : write(warnstr,*) subname, 'aicen =', aicen(nd)
565 0 : call icepack_warnings_add(warnstr)
566 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
567 0 : call icepack_warnings_add(subname//' shift_ice: daice > aicen')
568 : endif
569 : endif
570 : endif
571 846095282 : if (icepack_warnings_aborted(subname)) return
572 :
573 846095282 : if (dvice_greater_vicen) then
574 0 : if (donor(n) > 0) then
575 0 : nd = donor(n)
576 0 : if (dvice(n) >= vicen(nd)*(c1+puny)) then
577 0 : write(warnstr,*) ' '
578 0 : call icepack_warnings_add(warnstr)
579 0 : write(warnstr,*) subname, 'shift_ice: dvice > vicen'
580 0 : call icepack_warnings_add(warnstr)
581 0 : write(warnstr,*) subname, 'boundary, donor cat:', n, nd
582 0 : call icepack_warnings_add(warnstr)
583 0 : write(warnstr,*) subname, 'dvice =', dvice(n)
584 0 : call icepack_warnings_add(warnstr)
585 0 : write(warnstr,*) subname, 'vicen =', vicen(nd)
586 0 : call icepack_warnings_add(warnstr)
587 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
588 0 : call icepack_warnings_add(subname//' shift_ice: dvice > vicen')
589 : endif
590 : endif
591 : endif
592 1053775326 : if (icepack_warnings_aborted(subname)) return
593 : enddo ! boundaries, 1 to ncat-1
594 :
595 : !-----------------------------------------------------------------
596 : ! transfer volume and energy between categories
597 : !-----------------------------------------------------------------
598 :
599 1053775326 : do n = 1, ncat-1
600 :
601 1053775326 : if (daice(n) > c0) then ! daice(n) can be < puny
602 :
603 684671543 : nd = donor(n)
604 684671543 : if (nd == n) then
605 283036662 : nr = nd+1
606 : else ! nd = n+1
607 401634881 : nr = n
608 : endif
609 :
610 684671543 : aicen(nd) = aicen(nd) - daice(n)
611 684671543 : aicen(nr) = aicen(nr) + daice(n)
612 :
613 684671543 : vicen(nd) = vicen(nd) - dvice(n)
614 684671543 : vicen(nr) = vicen(nr) + dvice(n)
615 :
616 684671543 : worka = daice(n) / aicen_init(nd)
617 684671543 : dvsnow = vsnon_init(nd) * worka
618 684671543 : vsnon(nd) = vsnon(nd) - dvsnow
619 684671543 : vsnon(nr) = vsnon(nr) + dvsnow
620 684671543 : workb = dvsnow
621 :
622 21698671101 : do it = 1, ntrcr
623 21013999558 : nd = donor(n)
624 21013999558 : if (nd == n) then
625 7775669658 : nr = nd+1
626 : else ! nd = n+1
627 13238329900 : nr = n
628 : endif
629 :
630 1501298749 : datrcr = trcrn(it,nd)*(trcr_base(it,1) * daice(n) &
631 : + trcr_base(it,2) * dvice(n) & ! LCOV_EXCL_LINE
632 21013999558 : + trcr_base(it,3) * workb)
633 21013999558 : if (n_trcr_strata(it) > 0) then
634 5049105206 : do itl = 1, n_trcr_strata(it)
635 3138484127 : ntr = nt_strata(it,itl)
636 5049105206 : datrcr = datrcr * trcrn(ntr,nd)
637 : enddo
638 : endif
639 :
640 21013999558 : atrcrn(it,nd) = atrcrn(it,nd) - datrcr
641 21698671101 : atrcrn(it,nr) = atrcrn(it,nr) + datrcr
642 :
643 : enddo ! ntrcr
644 : endif ! daice
645 : enddo ! boundaries, 1 to ncat-1
646 :
647 : !-----------------------------------------------------------------
648 : ! Update ice thickness and tracers
649 : !-----------------------------------------------------------------
650 :
651 1261455370 : do n = 1, ncat
652 :
653 1053775326 : if (aicen(n) > puny) then
654 1003736597 : hicen(n) = vicen (n) / aicen(n)
655 : else
656 50038729 : hicen(n) = c0
657 : endif
658 :
659 : !-----------------------------------------------------------------
660 : ! Compute new tracers
661 : !-----------------------------------------------------------------
662 :
663 0 : call icepack_compute_tracers (ntrcr, trcr_depend, &
664 : atrcrn(:,n), aicen(n), & ! LCOV_EXCL_LINE
665 : vicen(n), vsnon(n), & ! LCOV_EXCL_LINE
666 : trcr_base, n_trcr_strata, & ! LCOV_EXCL_LINE
667 1149149347 : nt_strata, trcrn(:,n))
668 1261455370 : if (icepack_warnings_aborted(subname)) return
669 :
670 : enddo ! ncat
671 :
672 : end subroutine shift_ice
673 :
674 : !=======================================================================
675 :
676 : ! For each grid cell, sum field over all ice categories.
677 : !
678 : ! author: William H. Lipscomb, LANL
679 :
680 573887160 : subroutine column_sum (nsum, xin, xout)
681 :
682 : integer (kind=int_kind), intent(in) :: &
683 : nsum ! number of categories/layers
684 :
685 : real (kind=dbl_kind), dimension (nsum), &
686 : intent(in) :: & ! LCOV_EXCL_LINE
687 : xin ! input field
688 :
689 : real (kind=dbl_kind), intent(out) :: &
690 : xout ! output field
691 :
692 : ! local variables
693 :
694 : integer (kind=int_kind) :: &
695 : n ! category/layer index
696 :
697 : character(len=*),parameter :: subname='(column_sum)'
698 :
699 573887160 : xout = c0
700 3884750424 : do n = 1, nsum
701 3884750424 : xout = xout + xin(n)
702 : enddo ! n
703 :
704 573887160 : end subroutine column_sum
705 :
706 : !=======================================================================
707 :
708 : ! For each physical grid cell, check that initial and final values
709 : ! of a conserved field are equal to within a small value.
710 : !
711 : ! author: William H. Lipscomb, LANL
712 :
713 220713732 : subroutine column_conservation_check (fieldid, &
714 : x1, x2, & ! LCOV_EXCL_LINE
715 : max_err )
716 :
717 : real (kind=dbl_kind), intent(in) :: &
718 : x1 , & ! initial field ! LCOV_EXCL_LINE
719 : x2 ! final field
720 :
721 : real (kind=dbl_kind), intent(in) :: &
722 : max_err ! max allowed error
723 :
724 : character (len=char_len), intent(in) :: &
725 : fieldid ! field identifier
726 :
727 : character(len=*),parameter :: subname='(column_conservation_check)'
728 :
729 : ! local variables
730 :
731 220713732 : if (abs (x2-x1) > max_err) then
732 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
733 0 : write(warnstr,*) ' '
734 0 : call icepack_warnings_add(warnstr)
735 0 : write(warnstr,*) subname, 'Conservation error: ', trim(fieldid)
736 0 : call icepack_warnings_add(warnstr)
737 0 : write(warnstr,*) subname, ' Initial value = ', x1
738 0 : call icepack_warnings_add(warnstr)
739 0 : write(warnstr,*) subname, ' Final value = ', x2
740 0 : call icepack_warnings_add(warnstr)
741 0 : write(warnstr,*) subname, ' Difference = ', x2 - x1
742 0 : call icepack_warnings_add(warnstr)
743 : endif
744 :
745 220713732 : end subroutine column_conservation_check
746 :
747 : !=======================================================================
748 :
749 : ! Cleanup subroutine that rebins thickness categories if necessary,
750 : ! eliminates very small ice areas while conserving mass and energy,
751 : ! aggregates state variables, and does a boundary call.
752 : ! It is a good idea to call this subroutine after the thermodynamics
753 : ! (thermo_vertical/thermo_itd) and again after the dynamics
754 : ! (evp/transport/ridging).
755 : !
756 : ! author: William H. Lipscomb, LANL
757 :
758 1965715296 : subroutine cleanup_itd (dt, ntrcr, &
759 : nilyr, nslyr, & ! LCOV_EXCL_LINE
760 : ncat, hin_max, & ! LCOV_EXCL_LINE
761 : aicen, trcrn, & ! LCOV_EXCL_LINE
762 : vicen, vsnon, & ! LCOV_EXCL_LINE
763 : aice0, aice, & ! LCOV_EXCL_LINE
764 : n_aero, & ! LCOV_EXCL_LINE
765 : nbtrcr, nblyr, & ! LCOV_EXCL_LINE
766 : tr_aero, & ! LCOV_EXCL_LINE
767 : tr_pond_topo, & ! LCOV_EXCL_LINE
768 : heat_capacity, & ! LCOV_EXCL_LINE
769 : first_ice, & ! LCOV_EXCL_LINE
770 : trcr_depend, trcr_base, & ! LCOV_EXCL_LINE
771 : n_trcr_strata,nt_strata, & ! LCOV_EXCL_LINE
772 : fpond, fresh, & ! LCOV_EXCL_LINE
773 : fsalt, fhocn, & ! LCOV_EXCL_LINE
774 : faero_ocn, fiso_ocn, & ! LCOV_EXCL_LINE
775 : fzsal, & ! LCOV_EXCL_LINE
776 1965715296 : flux_bio, limit_aice_in)
777 :
778 : integer (kind=int_kind), intent(in) :: &
779 : ncat , & ! number of thickness categories ! LCOV_EXCL_LINE
780 : nilyr , & ! number of ice layers ! LCOV_EXCL_LINE
781 : nblyr , & ! number of bio layers ! LCOV_EXCL_LINE
782 : nslyr , & ! number of snow layers ! LCOV_EXCL_LINE
783 : ntrcr , & ! number of tracers in use ! LCOV_EXCL_LINE
784 : nbtrcr, & ! number of bio tracers in use ! LCOV_EXCL_LINE
785 : n_aero ! number of aerosol tracers
786 :
787 : real (kind=dbl_kind), intent(in) :: &
788 : dt ! time step
789 :
790 : real (kind=dbl_kind), dimension(0:ncat), intent(in) :: &
791 : hin_max ! category boundaries (m)
792 :
793 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
794 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
795 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
796 : vsnon ! volume per unit area of snow (m)
797 :
798 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
799 : trcrn ! ice tracers
800 :
801 : real (kind=dbl_kind), intent(inout) :: &
802 : aice , & ! total ice concentration ! LCOV_EXCL_LINE
803 : aice0 ! concentration of open water
804 :
805 : integer (kind=int_kind), dimension (:), intent(in) :: &
806 : trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon ! LCOV_EXCL_LINE
807 : n_trcr_strata ! number of underlying tracer layers
808 :
809 : real (kind=dbl_kind), dimension (:,:), intent(in) :: &
810 : trcr_base ! = 0 or 1 depending on tracer dependency
811 : ! argument 2: (1) aice, (2) vice, (3) vsno
812 :
813 : integer (kind=int_kind), dimension (:,:), intent(in) :: &
814 : nt_strata ! indices of underlying tracer layers
815 :
816 : logical (kind=log_kind), intent(in) :: &
817 : tr_aero, & ! aerosol flag ! LCOV_EXCL_LINE
818 : tr_pond_topo, & ! topo pond flag ! LCOV_EXCL_LINE
819 : heat_capacity ! if false, ice and snow have zero heat capacity
820 :
821 : logical (kind=log_kind), dimension(ncat), intent(inout) :: &
822 : first_ice ! For bgc and S tracers. set to true if zapping ice.
823 :
824 : ! ice-ocean fluxes (required for strict conservation)
825 :
826 : real (kind=dbl_kind), intent(inout), optional :: &
827 : fpond , & ! fresh water flux to ponds (kg/m^2/s) ! LCOV_EXCL_LINE
828 : fresh , & ! fresh water flux to ocean (kg/m^2/s) ! LCOV_EXCL_LINE
829 : fsalt , & ! salt flux to ocean (kg/m^2/s) ! LCOV_EXCL_LINE
830 : fhocn , & ! net heat flux to ocean (W/m^2) ! LCOV_EXCL_LINE
831 : fzsal ! net salt flux to ocean from zsalinity (kg/m^2/s)
832 :
833 : real (kind=dbl_kind), dimension (:), intent(inout), optional :: &
834 : flux_bio ! net tracer flux to ocean from biology (mmol/m^2/s)
835 :
836 : real (kind=dbl_kind), dimension (:), intent(inout), optional :: &
837 : faero_ocn ! aerosol flux to ocean (kg/m^2/s)
838 :
839 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
840 : fiso_ocn ! isotope flux to ocean (kg/m^2/s)
841 :
842 : logical (kind=log_kind), intent(in), optional :: &
843 : limit_aice_in ! if false, allow aice to be out of bounds
844 : ! may want to allow this for unit tests
845 :
846 : ! local variables
847 :
848 : integer (kind=int_kind) :: &
849 : n , & ! category index ! LCOV_EXCL_LINE
850 : it ! tracer index
851 :
852 : real (kind=dbl_kind) &
853 : dfpond , & ! zapped pond water flux (kg/m^2/s) ! LCOV_EXCL_LINE
854 : dfresh , & ! zapped fresh water flux (kg/m^2/s) ! LCOV_EXCL_LINE
855 : dfsalt , & ! zapped salt flux (kg/m^2/s) ! LCOV_EXCL_LINE
856 : dfhocn , & ! zapped energy flux ( W/m^2) ! LCOV_EXCL_LINE
857 195989088 : dfzsal ! zapped salt flux for zsalinity (kg/m^2/s)
858 :
859 : real (kind=dbl_kind), dimension (n_aero) :: &
860 4228105920 : dfaero_ocn ! zapped aerosol flux (kg/m^2/s)
861 :
862 : real (kind=dbl_kind), dimension (n_iso) :: &
863 3736594368 : dfiso_ocn ! zapped isotope flux (kg/m^2/s)
864 :
865 : real (kind=dbl_kind), dimension (ntrcr) :: &
866 6679700832 : dflux_bio ! zapped biology flux (mmol/m^2/s)
867 :
868 : logical (kind=log_kind) :: &
869 : limit_aice ! if true, check for aice out of bounds
870 :
871 : character(len=*),parameter :: subname='(cleanup_itd)'
872 :
873 : !-----------------------------------------------------------------
874 : ! Initialize
875 : !-----------------------------------------------------------------
876 :
877 1965715296 : if (present(limit_aice_in)) then
878 0 : limit_aice = limit_aice_in
879 : else
880 1965715296 : limit_aice = .true.
881 : endif
882 :
883 1965715296 : dfpond = c0
884 1965715296 : dfresh = c0
885 1965715296 : dfsalt = c0
886 1965715296 : dfhocn = c0
887 2891612832 : dfaero_ocn(:) = c0
888 2087918880 : dfiso_ocn (:) = c0
889 70554800448 : dflux_bio (:) = c0
890 1965715296 : dfzsal = c0
891 :
892 : !-----------------------------------------------------------------
893 : ! Compute total ice area.
894 : !-----------------------------------------------------------------
895 :
896 1965715296 : call aggregate_area (ncat, aicen, aice, aice0)
897 1965715296 : if (icepack_warnings_aborted(subname)) return
898 :
899 1965715296 : if (limit_aice) then ! check for aice out of bounds
900 1965715296 : if (aice > c1+puny .or. aice < -puny) then
901 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
902 0 : call icepack_warnings_add(subname//' aggregate ice area out of bounds')
903 0 : write(warnstr,*) subname, 'aice:', aice
904 0 : call icepack_warnings_add(warnstr)
905 0 : do n = 1, ncat
906 0 : write(warnstr,*) subname, 'n, aicen:', n, aicen(n)
907 0 : call icepack_warnings_add(warnstr)
908 : enddo
909 0 : return
910 : endif
911 : endif ! limit_aice
912 :
913 : !-----------------------------------------------------------------
914 : ! Identify grid cells with ice.
915 : !-----------------------------------------------------------------
916 :
917 1965715296 : if (aice > puny) then
918 :
919 : !-----------------------------------------------------------------
920 : ! Make sure ice in each category is within its thickness bounds.
921 : ! NOTE: The rebin subroutine is needed only in the rare cases
922 : ! when the linear_itd subroutine cannot transfer ice
923 : ! correctly (e.g., very fast ice growth).
924 : !-----------------------------------------------------------------
925 :
926 0 : call rebin (ntrcr, trcr_depend, &
927 : trcr_base, & ! LCOV_EXCL_LINE
928 : n_trcr_strata, & ! LCOV_EXCL_LINE
929 : nt_strata, & ! LCOV_EXCL_LINE
930 : aicen, trcrn, & ! LCOV_EXCL_LINE
931 : vicen, vsnon, & ! LCOV_EXCL_LINE
932 505671827 : ncat, hin_max )
933 505671827 : if (icepack_warnings_aborted(subname)) return
934 :
935 : endif ! aice > puny
936 :
937 : !-----------------------------------------------------------------
938 : ! Zero out ice categories with very small areas.
939 : !-----------------------------------------------------------------
940 :
941 1965715296 : if (limit_aice) then
942 : call zap_small_areas (dt, ntrcr, &
943 : ncat, & ! LCOV_EXCL_LINE
944 : n_aero, & ! LCOV_EXCL_LINE
945 : nblyr, & ! LCOV_EXCL_LINE
946 : nilyr, nslyr, & ! LCOV_EXCL_LINE
947 : aice, aice0, & ! LCOV_EXCL_LINE
948 : aicen, trcrn, & ! LCOV_EXCL_LINE
949 : vicen, vsnon, & ! LCOV_EXCL_LINE
950 : dfpond, & ! LCOV_EXCL_LINE
951 : dfresh, dfsalt, & ! LCOV_EXCL_LINE
952 : dfhocn, & ! LCOV_EXCL_LINE
953 : dfaero_ocn, dfiso_ocn, & ! LCOV_EXCL_LINE
954 : tr_aero, & ! LCOV_EXCL_LINE
955 : tr_pond_topo, & ! LCOV_EXCL_LINE
956 : first_ice, nbtrcr, & ! LCOV_EXCL_LINE
957 1965715296 : dfzsal, dflux_bio )
958 :
959 1965715296 : if (icepack_warnings_aborted(subname)) then
960 0 : write(warnstr,*) subname, 'aice:', aice
961 0 : call icepack_warnings_add(warnstr)
962 0 : do n = 1, ncat
963 0 : write(warnstr,*) subname, 'n, aicen:', n, aicen(n)
964 0 : call icepack_warnings_add(warnstr)
965 : enddo
966 0 : return
967 : endif
968 :
969 : endif ! l_limit_aice
970 :
971 : !-------------------------------------------------------------------
972 : ! Zap snow that has out of bounds temperatures
973 : !-------------------------------------------------------------------
974 :
975 : call zap_snow_temperature(dt, ncat, &
976 : heat_capacity, nblyr, & ! LCOV_EXCL_LINE
977 : nslyr, aicen, & ! LCOV_EXCL_LINE
978 : trcrn, vsnon, & ! LCOV_EXCL_LINE
979 : dfresh, dfhocn, & ! LCOV_EXCL_LINE
980 : dfaero_ocn, tr_aero, & ! LCOV_EXCL_LINE
981 : dfiso_ocn, & ! LCOV_EXCL_LINE
982 : dflux_bio, nbtrcr, & ! LCOV_EXCL_LINE
983 1965715296 : n_aero)
984 1965715296 : if (icepack_warnings_aborted(subname)) return
985 :
986 : !-------------------------------------------------------------------
987 : ! Update ice-ocean fluxes for strict conservation
988 : !-------------------------------------------------------------------
989 :
990 1965715296 : if (present(fpond)) &
991 1965715296 : fpond = fpond + dfpond
992 1965715296 : if (present(fresh)) &
993 1965715296 : fresh = fresh + dfresh
994 1965715296 : if (present(fsalt)) &
995 1965715296 : fsalt = fsalt + dfsalt
996 1965715296 : if (present(fhocn)) &
997 1965715296 : fhocn = fhocn + dfhocn
998 1965715296 : if (present(faero_ocn)) then
999 2891612832 : do it = 1, n_aero
1000 2891612832 : faero_ocn(it) = faero_ocn(it) + dfaero_ocn(it)
1001 : enddo
1002 : endif
1003 1965715296 : if (tr_iso) then
1004 162938112 : do it = 1, n_iso
1005 162938112 : fiso_ocn(it) = fiso_ocn(it) + dfiso_ocn(it)
1006 : enddo
1007 : endif
1008 1965715296 : if (present(flux_bio)) then
1009 5380396320 : do it = 1, nbtrcr
1010 5380396320 : flux_bio (it) = flux_bio(it) + dflux_bio(it)
1011 : enddo
1012 : endif
1013 1965715296 : if (present(fzsal)) &
1014 1965715296 : fzsal = fzsal + dfzsal
1015 :
1016 : !----------------------------------------------------------------
1017 : ! If using zero-layer model (no heat capacity), check that the
1018 : ! energy of snow and ice is correct.
1019 : !----------------------------------------------------------------
1020 :
1021 1965715296 : if ((.not. heat_capacity) .and. aice > puny) then
1022 : call zerolayer_check (ncat, nilyr, &
1023 : nslyr, aicen, & ! LCOV_EXCL_LINE
1024 : vicen, vsnon, & ! LCOV_EXCL_LINE
1025 93563017 : trcrn)
1026 93563017 : if (icepack_warnings_aborted(subname)) return
1027 : endif
1028 :
1029 : end subroutine cleanup_itd
1030 :
1031 : !=======================================================================
1032 :
1033 : ! For each ice category in each grid cell, remove ice if the fractional
1034 : ! area is less than puny.
1035 : !
1036 : ! author: William H. Lipscomb, LANL
1037 :
1038 1965715296 : subroutine zap_small_areas (dt, ntrcr, &
1039 : ncat, & ! LCOV_EXCL_LINE
1040 : n_aero, & ! LCOV_EXCL_LINE
1041 : nblyr, & ! LCOV_EXCL_LINE
1042 : nilyr, nslyr, & ! LCOV_EXCL_LINE
1043 : aice, aice0, & ! LCOV_EXCL_LINE
1044 : aicen, trcrn, & ! LCOV_EXCL_LINE
1045 : vicen, vsnon, & ! LCOV_EXCL_LINE
1046 : dfpond, & ! LCOV_EXCL_LINE
1047 : dfresh, dfsalt, & ! LCOV_EXCL_LINE
1048 : dfhocn, & ! LCOV_EXCL_LINE
1049 : dfaero_ocn, dfiso_ocn, & ! LCOV_EXCL_LINE
1050 : tr_aero, & ! LCOV_EXCL_LINE
1051 : tr_pond_topo, & ! LCOV_EXCL_LINE
1052 : first_ice, nbtrcr, & ! LCOV_EXCL_LINE
1053 1965715296 : dfzsal, dflux_bio )
1054 :
1055 : integer (kind=int_kind), intent(in) :: &
1056 : ncat , & ! number of thickness categories ! LCOV_EXCL_LINE
1057 : nilyr , & ! number of ice layers ! LCOV_EXCL_LINE
1058 : nblyr , & ! number of bio layers ! LCOV_EXCL_LINE
1059 : nslyr , & ! number of snow layers ! LCOV_EXCL_LINE
1060 : ntrcr , & ! number of tracers in use ! LCOV_EXCL_LINE
1061 : n_aero , & ! number of aerosol tracers ! LCOV_EXCL_LINE
1062 : nbtrcr ! number of biology tracers
1063 :
1064 : real (kind=dbl_kind), intent(in) :: &
1065 : dt ! time step
1066 :
1067 : real (kind=dbl_kind), intent(inout) :: &
1068 : aice , & ! total ice concentration ! LCOV_EXCL_LINE
1069 : aice0 ! concentration of open water
1070 :
1071 : real (kind=dbl_kind), dimension(:), intent(inout) :: &
1072 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
1073 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
1074 : vsnon ! volume per unit area of snow (m)
1075 :
1076 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
1077 : trcrn ! ice tracers
1078 :
1079 : real (kind=dbl_kind), intent(inout) :: &
1080 : dfpond , & ! zapped pond water flux (kg/m^2/s) ! LCOV_EXCL_LINE
1081 : dfresh , & ! zapped fresh water flux (kg/m^2/s) ! LCOV_EXCL_LINE
1082 : dfsalt , & ! zapped salt flux (kg/m^2/s) ! LCOV_EXCL_LINE
1083 : dfhocn , & ! zapped energy flux ( W/m^2) ! LCOV_EXCL_LINE
1084 : dfzsal ! zapped salt flux from zsalinity(kg/m^2/s)
1085 :
1086 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1087 : dfaero_ocn ! zapped aerosol flux (kg/m^2/s)
1088 :
1089 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1090 : dfiso_ocn ! zapped isotope flux (kg/m^2/s)
1091 :
1092 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1093 : dflux_bio ! zapped bio tracer flux from biology (mmol/m^2/s)
1094 :
1095 : logical (kind=log_kind), intent(in) :: &
1096 : tr_aero, & ! aerosol flag ! LCOV_EXCL_LINE
1097 : tr_pond_topo ! pond flag
1098 :
1099 : logical (kind=log_kind), dimension (:), intent(inout) :: &
1100 : first_ice ! For bgc tracers. Set to true if zapping ice
1101 :
1102 : ! local variables
1103 :
1104 : integer (kind=int_kind) :: &
1105 : n, k, it, & !counting indices ! LCOV_EXCL_LINE
1106 : blevels
1107 :
1108 195989088 : real (kind=dbl_kind) :: xtmp ! temporary variables
1109 391978176 : real (kind=dbl_kind) , dimension (1):: trcr_skl
1110 2763506016 : real (kind=dbl_kind) , dimension (nblyr+1):: bvol
1111 :
1112 : character(len=*),parameter :: subname='(zap_small_areas)'
1113 :
1114 : !-----------------------------------------------------------------
1115 : ! I. Zap categories with very small areas.
1116 : !-----------------------------------------------------------------
1117 1965715296 : dfzsal = c0
1118 :
1119 11737801440 : do n = 1, ncat
1120 :
1121 : !-----------------------------------------------------------------
1122 : ! Count categories to be zapped.
1123 : !-----------------------------------------------------------------
1124 :
1125 11737801440 : if (aicen(n) < -puny) then
1126 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1127 0 : call icepack_warnings_add(subname//' Zap ice: negative ice area')
1128 0 : return
1129 10735891488 : elseif (abs(aicen(n)) /= c0 .and. &
1130 963805344 : abs(aicen(n)) <= puny) then
1131 :
1132 : !-----------------------------------------------------------------
1133 : ! Account for tracers important for conservation
1134 : !-----------------------------------------------------------------
1135 :
1136 20161281 : if (tr_pond_topo) then
1137 187590 : xtmp = aicen(n) &
1138 1386557 : * trcrn(nt_apnd,n) * trcrn(nt_hpnd,n)
1139 1386557 : dfpond = dfpond - xtmp
1140 : endif
1141 :
1142 20161281 : if (tr_aero) then
1143 3345768 : do it = 1, n_aero
1144 377178 : xtmp = (vicen(n)*(trcrn(nt_aero+2+4*(it-1),n) &
1145 1861473 : + trcrn(nt_aero+3+4*(it-1),n)))/dt
1146 3345768 : dfaero_ocn(it) = dfaero_ocn(it) + xtmp
1147 : enddo
1148 : endif
1149 :
1150 20161281 : if (tr_iso) then
1151 425764 : do it = 1, n_iso
1152 319323 : xtmp = vicen(n)*trcrn(nt_isoice+it-1,n)/dt
1153 425764 : dfiso_ocn(it) = dfiso_ocn(it) + xtmp
1154 : enddo
1155 : endif
1156 :
1157 20161281 : if (solve_zsal) then
1158 2178912 : do it = 1, nblyr
1159 683466 : xtmp = rhosi*trcrn(nt_fbri,n)*vicen(n)*p001&
1160 : *trcrn(nt_bgc_S+it-1,n)/ & ! LCOV_EXCL_LINE
1161 1906548 : real(nblyr,kind=dbl_kind)/dt
1162 2178912 : dfzsal = dfzsal + xtmp
1163 : enddo ! n
1164 : endif
1165 :
1166 20161281 : if (skl_bgc .and. nbtrcr > 0) then
1167 1448519 : blevels = 1
1168 1448519 : bvol(1) = aicen(n)*sk_l
1169 1448519 : it = 1
1170 26073342 : do it = 1, nbtrcr
1171 23176304 : trcr_skl(1) = trcrn(bio_index(it),n)
1172 655056 : call zap_small_bgc(blevels, dflux_bio(it), &
1173 23176304 : dt, bvol(1:blevels), trcr_skl(blevels))
1174 24624823 : if (icepack_warnings_aborted(subname)) return
1175 : enddo
1176 18712762 : elseif (z_tracers .and. nbtrcr > 0) then
1177 1530401 : blevels = nblyr + 1
1178 13773609 : bvol(:) = vicen(n)/real(nblyr,kind=dbl_kind)*trcrn(nt_fbri,n)
1179 1530401 : bvol(1) = p5*bvol(1)
1180 1530401 : bvol(blevels) = p5*bvol(blevels)
1181 30608020 : do it = 1, nbtrcr
1182 777879 : call zap_small_bgc(blevels, dflux_bio(it), &
1183 29077619 : dt, bvol(1:blevels),trcrn(bio_index(it):bio_index(it)+blevels-1,n))
1184 30608020 : if (icepack_warnings_aborted(subname)) return
1185 : enddo
1186 : endif
1187 :
1188 : !-----------------------------------------------------------------
1189 : ! Zap ice energy and use ocean heat to melt ice
1190 : !-----------------------------------------------------------------
1191 :
1192 108224382 : do k = 1, nilyr
1193 11028244 : xtmp = trcrn(nt_qice+k-1,n) / dt &
1194 93577223 : * vicen(n)/real(nilyr,kind=dbl_kind) ! < 0
1195 88063101 : dfhocn = dfhocn + xtmp
1196 108224382 : trcrn(nt_qice+k-1,n) = c0
1197 : enddo ! k
1198 :
1199 : !-----------------------------------------------------------------
1200 : ! Zap ice and snow volume, add water and salt to ocean
1201 : !-----------------------------------------------------------------
1202 :
1203 20161281 : xtmp = (rhoi*vicen(n)) / dt
1204 20161281 : dfresh = dfresh + xtmp
1205 :
1206 20161281 : xtmp = rhoi*vicen(n)*ice_ref_salinity*p001 / dt
1207 20161281 : dfsalt = dfsalt + xtmp
1208 :
1209 20161281 : aice0 = aice0 + aicen(n)
1210 20161281 : aicen(n) = c0
1211 20161281 : vicen(n) = c0
1212 20161281 : trcrn(nt_Tsfc,n) = Tocnfrz
1213 :
1214 : !-----------------------------------------------------------------
1215 : ! Zap snow
1216 : !-----------------------------------------------------------------
1217 : call zap_snow(dt, nslyr, &
1218 : trcrn(:,n), vsnon(n), & ! LCOV_EXCL_LINE
1219 : dfresh, dfhocn, & ! LCOV_EXCL_LINE
1220 : dfaero_ocn, tr_aero, & ! LCOV_EXCL_LINE
1221 : dfiso_ocn, & ! LCOV_EXCL_LINE
1222 : dflux_bio, nbtrcr, & ! LCOV_EXCL_LINE
1223 : n_aero, & ! LCOV_EXCL_LINE
1224 21465599 : aicen(n), nblyr)
1225 20161281 : if (icepack_warnings_aborted(subname)) return
1226 :
1227 : !-----------------------------------------------------------------
1228 : ! Zap tracers
1229 : !-----------------------------------------------------------------
1230 :
1231 20161281 : if (ntrcr >= 2) then
1232 699160792 : do it = 2, ntrcr
1233 699160792 : if (tr_brine .and. it == nt_fbri) then
1234 3324786 : trcrn(it,n) = c1
1235 : else
1236 675674725 : trcrn(it,n) = c0
1237 : endif
1238 : enddo
1239 : endif
1240 20161281 : first_ice(n) = .true.
1241 :
1242 : endif ! aicen
1243 : enddo ! n
1244 :
1245 : !-----------------------------------------------------------------
1246 : ! II. Count cells with excess ice (aice > c1) due to roundoff errors.
1247 : ! Zap a little ice in each category so that aice = c1.
1248 : !-----------------------------------------------------------------
1249 :
1250 1965715296 : if (aice > (c1+puny)) then
1251 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1252 0 : call icepack_warnings_add(subname//' Zap ice: excess ice area')
1253 0 : return
1254 1965715296 : elseif (aice > c1 .and. aice < (c1+puny)) then
1255 :
1256 28348419 : do n = 1, ncat
1257 :
1258 : !-----------------------------------------------------------------
1259 : ! Account for tracers important for conservation
1260 : !-----------------------------------------------------------------
1261 :
1262 23652278 : if (tr_pond_topo) then
1263 9678 : xtmp = aicen(n) &
1264 : * trcrn(nt_apnd,n) * trcrn(nt_hpnd,n) & ! LCOV_EXCL_LINE
1265 74946 : * (aice-c1)/aice
1266 74946 : dfpond = dfpond - xtmp
1267 : endif
1268 :
1269 23652278 : if (tr_aero) then
1270 182582 : do it = 1, n_aero
1271 19856 : xtmp = (vsnon(n)*(trcrn(nt_aero +4*(it-1),n) &
1272 : + trcrn(nt_aero+1+4*(it-1),n)) & ! LCOV_EXCL_LINE
1273 : + vicen(n)*(trcrn(nt_aero+2+4*(it-1),n) & ! LCOV_EXCL_LINE
1274 : + trcrn(nt_aero+3+4*(it-1),n))) & ! LCOV_EXCL_LINE
1275 121075 : * (aice-c1)/aice / dt
1276 182582 : dfaero_ocn(it) = dfaero_ocn(it) + xtmp
1277 : enddo ! it
1278 : endif
1279 :
1280 23652278 : if (tr_iso) then
1281 1817720 : do it = 1, n_iso
1282 19830 : xtmp = (vsnon(n)*trcrn(nt_isosno+it-1,n) &
1283 : + vicen(n)*trcrn(nt_isoice+it-1,n)) & ! LCOV_EXCL_LINE
1284 1373205 : * (aice-c1)/aice / dt
1285 1817720 : dfiso_ocn(it) = dfiso_ocn(it) + xtmp
1286 : enddo ! it
1287 : endif
1288 :
1289 : !-----------------------------------------------------------------
1290 : ! Zap ice energy and use ocean heat to melt ice
1291 : !-----------------------------------------------------------------
1292 :
1293 186850294 : do k = 1, nilyr
1294 23674340 : xtmp = trcrn(nt_qice+k-1,n) &
1295 : * vicen(n)/real(nilyr,kind=dbl_kind) & ! LCOV_EXCL_LINE
1296 163198016 : * (aice-c1)/aice / dt ! < 0
1297 186850294 : dfhocn = dfhocn + xtmp
1298 : enddo ! k
1299 :
1300 : !-----------------------------------------------------------------
1301 : ! Zap snow energy and use ocean heat to melt snow
1302 : !-----------------------------------------------------------------
1303 :
1304 48418130 : do k = 1, nslyr
1305 3442108 : xtmp = trcrn(nt_qsno+k-1,n) &
1306 : * vsnon(n)/real(nslyr,kind=dbl_kind) & ! LCOV_EXCL_LINE
1307 24765852 : * (aice-c1)/aice / dt ! < 0
1308 48418130 : dfhocn = dfhocn + xtmp
1309 : enddo ! k
1310 :
1311 : !-----------------------------------------------------------------
1312 : ! Zap ice and snow volume, add water and salt to ocean
1313 : !-----------------------------------------------------------------
1314 :
1315 1708720 : xtmp = (rhoi*vicen(n) + rhos*vsnon(n)) &
1316 23652278 : * (aice-c1)/aice / dt
1317 23652278 : dfresh = dfresh + xtmp
1318 :
1319 1708720 : xtmp = rhoi*vicen(n)*ice_ref_salinity*p001 &
1320 23652278 : * (aice-c1)/aice / dt
1321 23652278 : dfsalt = dfsalt + xtmp
1322 :
1323 23652278 : if (solve_zsal) then
1324 176560 : do k = 1,nblyr
1325 47005 : xtmp = rhosi*trcrn(nt_fbri,n)*vicen(n)*p001&
1326 : /real(nblyr,kind=dbl_kind)*trcrn(nt_bgc_S+k-1,n) & ! LCOV_EXCL_LINE
1327 154490 : * (aice-c1)/aice /dt
1328 176560 : dfzsal = dfzsal + xtmp
1329 : enddo
1330 :
1331 22070 : if (vicen(n) > vicen(n)*trcrn(nt_fbri,n)) then
1332 6616 : xtmp = (vicen(n)-vicen(n)*trcrn(nt_fbri,n))*(aice-c1)/&
1333 21630 : aice*p001*rhosi*min_salin/dt
1334 21630 : dfzsal = dfzsal + xtmp
1335 : endif
1336 : endif ! solve_zsal
1337 :
1338 23652278 : aicen(n) = aicen(n) * (c1/aice)
1339 23652278 : vicen(n) = vicen(n) * (c1/aice)
1340 28348419 : vsnon(n) = vsnon(n) * (c1/aice)
1341 :
1342 : ! Note: Tracers are unchanged.
1343 :
1344 : enddo ! n
1345 :
1346 : !-----------------------------------------------------------------
1347 : ! Correct aice
1348 : !-----------------------------------------------------------------
1349 :
1350 4696141 : aice = c1
1351 4696141 : aice0 = c0
1352 :
1353 : endif ! aice
1354 :
1355 : end subroutine zap_small_areas
1356 :
1357 : !=======================================================================
1358 :
1359 20161281 : subroutine zap_snow(dt, nslyr, &
1360 : trcrn, vsnon, & ! LCOV_EXCL_LINE
1361 : dfresh, dfhocn, & ! LCOV_EXCL_LINE
1362 : dfaero_ocn, tr_aero, & ! LCOV_EXCL_LINE
1363 : dfiso_ocn, & ! LCOV_EXCL_LINE
1364 : dflux_bio, nbtrcr, & ! LCOV_EXCL_LINE
1365 : n_aero, & ! LCOV_EXCL_LINE
1366 : aicen, nblyr)
1367 :
1368 : integer (kind=int_kind), intent(in) :: &
1369 : nslyr , & ! number of snow layers ! LCOV_EXCL_LINE
1370 : n_aero , & ! number of aerosol tracers ! LCOV_EXCL_LINE
1371 : nblyr , & ! number of bio layers ! LCOV_EXCL_LINE
1372 : nbtrcr
1373 :
1374 : real (kind=dbl_kind), intent(in) :: &
1375 : dt ! time step
1376 :
1377 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1378 : trcrn ! ice tracers
1379 :
1380 : real (kind=dbl_kind), intent(in) :: &
1381 : aicen ! ice area fraction
1382 :
1383 : real (kind=dbl_kind), intent(inout) :: &
1384 : vsnon , & ! volume per unit area of snow (m) ! LCOV_EXCL_LINE
1385 : dfresh , & ! zapped fresh water flux (kg/m^2/s) ! LCOV_EXCL_LINE
1386 : dfhocn ! zapped energy flux ( W/m^2)
1387 :
1388 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1389 : dfaero_ocn ! zapped aerosol flux (kg/m^2/s)
1390 :
1391 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1392 : dfiso_ocn ! zapped isotope flux (kg/m^2/s)
1393 :
1394 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1395 : dflux_bio ! zapped bio tracer flux from biology (mmol/m^2/s)
1396 :
1397 : logical (kind=log_kind), intent(in) :: &
1398 : tr_aero ! aerosol flag
1399 :
1400 : ! local variables
1401 :
1402 : integer (kind=int_kind) :: &
1403 : k, it ! counting indices
1404 :
1405 1304318 : real (kind=dbl_kind) :: xtmp, dvssl, dvint
1406 :
1407 : character(len=*),parameter :: subname='(zap_snow)'
1408 :
1409 : ! aerosols
1410 20161281 : if (tr_aero) then
1411 3345768 : do it = 1, n_aero
1412 188589 : xtmp = (vsnon*(trcrn(nt_aero +4*(it-1)) &
1413 1861473 : + trcrn(nt_aero+1+4*(it-1))))/dt
1414 3345768 : dfaero_ocn(it) = dfaero_ocn(it) + xtmp
1415 : enddo ! it
1416 : endif ! tr_aero
1417 :
1418 : ! isotopes
1419 20161281 : if (tr_iso) then
1420 425764 : do it = 1, n_iso
1421 319323 : xtmp = vsnon*trcrn(nt_isosno+it-1)/dt
1422 425764 : dfiso_ocn(it) = dfiso_ocn(it) + xtmp
1423 : enddo ! it
1424 : endif ! tr_iso
1425 :
1426 20161281 : if (z_tracers) then
1427 1530401 : dvssl = min(p5*vsnon, hs_ssl*aicen) !snow surface layer
1428 1530401 : dvint = vsnon- dvssl !snow interior
1429 :
1430 30608020 : do it = 1, nbtrcr
1431 1555758 : xtmp = (trcrn(bio_index(it)+nblyr+1)*dvssl + &
1432 29855498 : trcrn(bio_index(it)+nblyr+2)*dvint)/dt
1433 30608020 : dflux_bio(it) = dflux_bio(it) + xtmp
1434 : enddo ! it
1435 :
1436 : endif ! z_tracers
1437 :
1438 : ! snow enthalpy tracer
1439 41832204 : do k = 1, nslyr
1440 1359530 : xtmp = trcrn(nt_qsno+k-1) / dt &
1441 21670923 : * vsnon/real(nslyr,kind=dbl_kind) ! < 0
1442 21670923 : dfhocn = dfhocn + xtmp
1443 41832204 : trcrn(nt_qsno+k-1) = c0
1444 : enddo ! k
1445 :
1446 : ! snow volume
1447 20161281 : xtmp = (rhos*vsnon) / dt
1448 20161281 : dfresh = dfresh + xtmp
1449 20161281 : vsnon = c0
1450 :
1451 20161281 : end subroutine zap_snow
1452 :
1453 : !=======================================================================
1454 :
1455 1965715296 : subroutine zap_snow_temperature(dt, ncat, &
1456 : heat_capacity, & ! LCOV_EXCL_LINE
1457 : nblyr, & ! LCOV_EXCL_LINE
1458 : nslyr, aicen, & ! LCOV_EXCL_LINE
1459 : trcrn, vsnon, & ! LCOV_EXCL_LINE
1460 : dfresh, dfhocn, & ! LCOV_EXCL_LINE
1461 : dfaero_ocn, tr_aero, & ! LCOV_EXCL_LINE
1462 : dfiso_ocn, & ! LCOV_EXCL_LINE
1463 : dflux_bio, nbtrcr, & ! LCOV_EXCL_LINE
1464 : n_aero )
1465 :
1466 : integer (kind=int_kind), intent(in) :: &
1467 : ncat , & ! number of thickness categories ! LCOV_EXCL_LINE
1468 : nslyr , & ! number of snow layers ! LCOV_EXCL_LINE
1469 : n_aero, & ! number of aerosol tracers ! LCOV_EXCL_LINE
1470 : nbtrcr, & ! number of z-tracers in use ! LCOV_EXCL_LINE
1471 : nblyr ! number of bio layers in ice
1472 :
1473 : real (kind=dbl_kind), intent(in) :: &
1474 : dt ! time step
1475 :
1476 : logical (kind=log_kind), intent(in) :: &
1477 : heat_capacity ! if false, ice and snow have zero heat capacity
1478 :
1479 : real (kind=dbl_kind), dimension (:), intent(in) :: &
1480 : aicen ! concentration of ice
1481 :
1482 : real (kind=dbl_kind), dimension(:), intent(inout) :: &
1483 : vsnon ! volume per unit area of snow (m)
1484 :
1485 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
1486 : trcrn ! ice tracers
1487 :
1488 : real (kind=dbl_kind), intent(inout) :: &
1489 : dfresh , & ! zapped fresh water flux (kg/m^2/s) ! LCOV_EXCL_LINE
1490 : dfhocn ! zapped energy flux ( W/m^2)
1491 :
1492 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1493 : dfaero_ocn ! zapped aerosol flux (kg/m^2/s)
1494 :
1495 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1496 : dfiso_ocn ! zapped isotope flux (kg/m^2/s)
1497 :
1498 : real (kind=dbl_kind), dimension (:),intent(inout) :: &
1499 : dflux_bio ! zapped biology flux (mmol/m^2/s)
1500 :
1501 : logical (kind=log_kind), intent(in) :: &
1502 : tr_aero ! aerosol flag
1503 :
1504 : ! local variables
1505 :
1506 : integer (kind=int_kind) :: &
1507 : n, k ! counting indices
1508 :
1509 : real (kind=dbl_kind) :: &
1510 : rnslyr , & ! real(nslyr) ! LCOV_EXCL_LINE
1511 : hsn , & ! snow thickness (m) ! LCOV_EXCL_LINE
1512 : zqsn , & ! snow layer enthalpy (J m-2) ! LCOV_EXCL_LINE
1513 : zTsn , & ! snow layer temperature (C) ! LCOV_EXCL_LINE
1514 195989088 : Tmax ! maximum allowed snow temperature
1515 :
1516 : logical :: &
1517 : l_zap ! logical whether zap snow
1518 :
1519 : character(len=*),parameter :: subname='(zap_snow_temperature)'
1520 :
1521 1965715296 : rnslyr = real(nslyr,kind=dbl_kind)
1522 :
1523 11737801440 : do n = 1, ncat
1524 :
1525 : !-----------------------------------------------------------------
1526 : ! Determine cells to zap
1527 : !-----------------------------------------------------------------
1528 :
1529 9772086144 : l_zap = .false.
1530 :
1531 9772086144 : if (aicen(n) > puny) then
1532 :
1533 : ! snow thickness
1534 2334948860 : hsn = vsnon(n) / aicen(n)
1535 :
1536 : ! check each snow layer - zap all if one is bad
1537 4800604972 : do k = 1, nslyr
1538 :
1539 : ! snow enthalpy and max temperature
1540 2465656112 : if (hsn > hs_min .and. heat_capacity) then
1541 : ! zqsn < 0
1542 1765501549 : zqsn = trcrn(nt_qsno+k-1,n)
1543 1765501549 : Tmax = -zqsn*puny*rnslyr / (rhos*cp_ice*vsnon(n))
1544 : else
1545 700154563 : zqsn = -rhos * Lfresh
1546 700154563 : Tmax = puny
1547 : endif
1548 :
1549 : ! snow temperature
1550 2465656112 : zTsn = (Lfresh + zqsn/rhos)/cp_ice
1551 :
1552 : ! check for zapping
1553 4800604972 : if (zTsn < Tmin .or. zTsn > Tmax) then
1554 0 : l_zap = .true.
1555 0 : write(warnstr,*) subname, "zap_snow_temperature: temperature out of bounds!"
1556 0 : call icepack_warnings_add(warnstr)
1557 0 : write(warnstr,*) subname, "k:" , k
1558 0 : call icepack_warnings_add(warnstr)
1559 0 : write(warnstr,*) subname, "zTsn:", zTsn
1560 0 : call icepack_warnings_add(warnstr)
1561 0 : write(warnstr,*) subname, "Tmin:", Tmin
1562 0 : call icepack_warnings_add(warnstr)
1563 0 : write(warnstr,*) subname, "Tmax:", Tmax
1564 0 : call icepack_warnings_add(warnstr)
1565 0 : write(warnstr,*) subname, "zqsn:", zqsn
1566 0 : call icepack_warnings_add(warnstr)
1567 : endif
1568 :
1569 : enddo ! k
1570 :
1571 : endif ! aicen > puny
1572 :
1573 : !-----------------------------------------------------------------
1574 : ! Zap the cells
1575 : !-----------------------------------------------------------------
1576 9772086144 : if (l_zap) &
1577 : call zap_snow(dt, nslyr, & ! LCOV_EXCL_LINE
1578 : trcrn(:,n), vsnon(n), & ! LCOV_EXCL_LINE
1579 : dfresh, dfhocn, & ! LCOV_EXCL_LINE
1580 : dfaero_ocn, tr_aero, & ! LCOV_EXCL_LINE
1581 : dfiso_ocn, & ! LCOV_EXCL_LINE
1582 : dflux_bio, nbtrcr, & ! LCOV_EXCL_LINE
1583 : n_aero, & ! LCOV_EXCL_LINE
1584 0 : aicen(n), nblyr)
1585 11737801440 : if (icepack_warnings_aborted(subname)) return
1586 :
1587 : enddo ! n
1588 :
1589 : end subroutine zap_snow_temperature
1590 :
1591 : !=======================================================================
1592 : ! Checks that the snow and ice energy in the zero layer thermodynamics
1593 : ! model still agrees with the snow and ice volume.
1594 : ! If there is an error, the model will abort.
1595 : ! This subroutine is only called if heat_capacity = .false.
1596 : !
1597 : ! author: Alison McLaren, Met Office
1598 : ! May 2010: ECH replaced eicen, esnon with trcrn but did not test
1599 : ! the changes. The loop below runs over n=1,ncat and I added loops
1600 : ! over k, making the test more stringent.
1601 :
1602 93563017 : subroutine zerolayer_check (ncat, nilyr, &
1603 : nslyr, aicen, & ! LCOV_EXCL_LINE
1604 : vicen, vsnon, & ! LCOV_EXCL_LINE
1605 93563017 : trcrn)
1606 :
1607 : integer (kind=int_kind), intent(in) :: &
1608 : ncat , & ! number of thickness categories ! LCOV_EXCL_LINE
1609 : nilyr , & ! number of ice layers ! LCOV_EXCL_LINE
1610 : nslyr ! number of snow layers
1611 :
1612 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
1613 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
1614 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
1615 : vsnon ! volume per unit area of snow (m)
1616 :
1617 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
1618 : trcrn ! ice tracers
1619 :
1620 : ! local variables
1621 :
1622 : integer (kind=int_kind) :: &
1623 : k , & ! vertical index ! LCOV_EXCL_LINE
1624 : n ! category index
1625 :
1626 : real (kind=dbl_kind) :: &
1627 19071791 : max_error ! max error in zero layer energy check
1628 : ! (so max volume error = puny)
1629 :
1630 : real (kind=dbl_kind), dimension (ncat) :: &
1631 301556780 : eicen ! energy of melting for each ice layer (J/m^2)
1632 :
1633 : real (kind=dbl_kind), dimension (ncat) :: &
1634 207993763 : esnon ! energy of melting for each snow layer (J/m^2)
1635 :
1636 : logical (kind=log_kind) :: &
1637 : ice_energy_correct , & ! zero layer ice energy check ! LCOV_EXCL_LINE
1638 : snow_energy_correct ! zero layer snow energy check
1639 :
1640 : real (kind=dbl_kind) :: &
1641 19071791 : worka, workb
1642 :
1643 : character(len=*),parameter :: subname='(zerolayer_check)'
1644 :
1645 : !-----------------------------------------------------------------
1646 : ! Initialize
1647 : !-----------------------------------------------------------------
1648 :
1649 93563017 : max_error = puny*Lfresh*rhos ! max error in zero layer energy check
1650 : ! (so max volume error = puny)
1651 :
1652 : !----------------------------------------------------------------
1653 : ! Calculate difference between ice and snow energies and the
1654 : ! energy values derived from the ice and snow volumes
1655 : !----------------------------------------------------------------
1656 :
1657 93563017 : ice_energy_correct = .true.
1658 93563017 : snow_energy_correct = .true.
1659 :
1660 93563017 : worka = c0
1661 93563017 : workb = c0
1662 :
1663 561378102 : do n = 1, ncat
1664 :
1665 467815085 : eicen(n) = c0
1666 935630170 : do k = 1, nilyr
1667 190717910 : eicen(n) = eicen(n) + trcrn(nt_qice+k-1,n) &
1668 1030989125 : * vicen(n) / real(nilyr,kind=dbl_kind)
1669 : enddo
1670 467815085 : worka = eicen(n) + rhoi * Lfresh * vicen(n)
1671 467815085 : esnon(n) = c0
1672 935630170 : do k = 1, nslyr
1673 190717910 : esnon(n) = esnon(n) + trcrn(nt_qsno+k-1,n) &
1674 1030989125 : * vsnon(n) / real(nslyr,kind=dbl_kind)
1675 : enddo
1676 467815085 : workb = esnon(n) + rhos * Lfresh * vsnon(n)
1677 :
1678 467815085 : if(abs(worka) > max_error) ice_energy_correct = .false.
1679 467815085 : if(abs(workb) > max_error) snow_energy_correct = .false.
1680 :
1681 : !----------------------------------------------------------------
1682 : ! If there is a problem, abort with error message
1683 : !----------------------------------------------------------------
1684 :
1685 467815085 : if (.not. ice_energy_correct) then
1686 :
1687 0 : if (abs(worka) > max_error) then
1688 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1689 0 : call icepack_warnings_add(subname//' zerolayer check - wrong ice energy')
1690 0 : write(warnstr,*) subname, 'n:', n
1691 0 : call icepack_warnings_add(warnstr)
1692 0 : write(warnstr,*) subname, 'eicen =', eicen(n)
1693 0 : call icepack_warnings_add(warnstr)
1694 0 : write(warnstr,*) subname, 'error=', worka
1695 0 : call icepack_warnings_add(warnstr)
1696 0 : write(warnstr,*) subname, 'vicen =', vicen(n)
1697 0 : call icepack_warnings_add(warnstr)
1698 0 : write(warnstr,*) subname, 'aicen =', aicen(n)
1699 0 : call icepack_warnings_add(warnstr)
1700 : endif
1701 :
1702 : endif
1703 467815085 : if (icepack_warnings_aborted(subname)) return
1704 :
1705 561378102 : if (.not. snow_energy_correct) then
1706 :
1707 0 : if (abs(workb) > max_error) then
1708 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1709 0 : call icepack_warnings_add(subname//' zerolayer check - wrong snow energy')
1710 0 : write(warnstr,*) subname, 'n:', n
1711 0 : call icepack_warnings_add(warnstr)
1712 0 : write(warnstr,*) subname, 'esnon =', esnon(n)
1713 0 : call icepack_warnings_add(warnstr)
1714 0 : write(warnstr,*) subname, 'error=', workb
1715 0 : call icepack_warnings_add(warnstr)
1716 0 : write(warnstr,*) subname, 'vsnon =', vsnon(n)
1717 0 : call icepack_warnings_add(warnstr)
1718 0 : write(warnstr,*) subname, 'aicen =', aicen(n)
1719 0 : call icepack_warnings_add(warnstr)
1720 0 : return
1721 : endif
1722 :
1723 : endif
1724 :
1725 : enddo ! ncat
1726 :
1727 : end subroutine zerolayer_check
1728 :
1729 : !=======================================================================
1730 : !autodocument_start icepack_init_itd
1731 : ! Initialize area fraction and thickness boundaries for the itd model
1732 : !
1733 : ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL
1734 : ! C. M. Bitz, UW
1735 :
1736 4138 : subroutine icepack_init_itd(ncat, hin_max)
1737 :
1738 : integer (kind=int_kind), intent(in) :: &
1739 : ncat ! number of thickness categories
1740 :
1741 : real (kind=dbl_kind), intent(out) :: &
1742 : hin_max(0:ncat) ! category limits (m)
1743 :
1744 : !autodocument_end
1745 :
1746 : ! local variables
1747 :
1748 : integer (kind=int_kind) :: &
1749 : n ! thickness category index
1750 :
1751 : real (kind=dbl_kind) :: &
1752 : cc1, cc2, cc3, & ! parameters for kcatbound = 0 ! LCOV_EXCL_LINE
1753 : x1 , & ! LCOV_EXCL_LINE
1754 : rn , & ! real(n) ! LCOV_EXCL_LINE
1755 : rncat , & ! real(ncat) ! LCOV_EXCL_LINE
1756 : d1 , & ! parameters for kcatbound = 1 (m) ! LCOV_EXCL_LINE
1757 : d2 , & ! ! LCOV_EXCL_LINE
1758 : b1 , & ! parameters for kcatbound = 3 ! LCOV_EXCL_LINE
1759 : b2 , & ! ! LCOV_EXCL_LINE
1760 723 : b3
1761 :
1762 : real (kind=dbl_kind), dimension(5) :: wmo5 ! data for wmo itd
1763 : real (kind=dbl_kind), dimension(6) :: wmo6 ! data for wmo itd
1764 : real (kind=dbl_kind), dimension(7) :: wmo7 ! data for wmo itd
1765 :
1766 : character(len=*),parameter :: subname='(icepack_init_itd)'
1767 :
1768 : ! thinnest 3 categories combined
1769 : data wmo5 / 0.30_dbl_kind, 0.70_dbl_kind, &
1770 : 1.20_dbl_kind, 2.00_dbl_kind, & ! LCOV_EXCL_LINE
1771 : 999._dbl_kind /
1772 : ! thinnest 2 categories combined
1773 : data wmo6 / 0.15_dbl_kind, &
1774 : 0.30_dbl_kind, 0.70_dbl_kind, & ! LCOV_EXCL_LINE
1775 : 1.20_dbl_kind, 2.00_dbl_kind, & ! LCOV_EXCL_LINE
1776 : 999._dbl_kind /
1777 : !echmod wmo6a
1778 : ! data wmo6 /0.30_dbl_kind, 0.70_dbl_kind, &
1779 : ! 1.20_dbl_kind, 2.00_dbl_kind, & ! LCOV_EXCL_LINE
1780 : ! 4.56729_dbl_kind, & ! LCOV_EXCL_LINE
1781 : ! 999._dbl_kind /
1782 : ! all thickness categories
1783 : data wmo7 / 0.10_dbl_kind, 0.15_dbl_kind, &
1784 : 0.30_dbl_kind, 0.70_dbl_kind, & ! LCOV_EXCL_LINE
1785 : 1.20_dbl_kind, 2.00_dbl_kind, & ! LCOV_EXCL_LINE
1786 : 999._dbl_kind /
1787 :
1788 4138 : rncat = real(ncat, kind=dbl_kind)
1789 4138 : d1 = 3.0_dbl_kind / rncat
1790 4138 : d2 = 0.5_dbl_kind / rncat
1791 4138 : b1 = p1 ! asymptotic category width (m)
1792 4138 : b2 = c3 ! thickness for which participation function is small (m)
1793 4138 : b3 = max(rncat*(rncat-1), c2*b2/b1)
1794 :
1795 4138 : hi_min = p01 ! minimum ice thickness allowed (m) for thermo
1796 : ! note hi_min is reset to 0.1 for kitd=0, below
1797 :
1798 : !-----------------------------------------------------------------
1799 : ! Choose category boundaries based on one of four options.
1800 : !
1801 : ! The first formula (kcatbound = 0) was used in Lipscomb (2001)
1802 : ! and in CICE versions 3.0 and 3.1.
1803 : !
1804 : ! The second formula is more user-friendly in the sense that it
1805 : ! is easy to obtain round numbers for category boundaries:
1806 : !
1807 : ! H(n) = n * [d1 + d2*(n-1)]
1808 : !
1809 : ! Default values are d1 = 300/ncat, d2 = 50/ncat.
1810 : ! For ncat = 5, boundaries in cm are 60, 140, 240, 360, which are
1811 : ! close to the standard values given by the first formula.
1812 : ! For ncat = 10, boundaries in cm are 30, 70, 120, 180, 250, 330,
1813 : ! 420, 520, 630.
1814 : !
1815 : ! The third option provides support for World Meteorological
1816 : ! Organization classification based on thickness. The full
1817 : ! WMO thickness distribution is used if ncat = 7; if ncat=5
1818 : ! or ncat = 6, some of the thinner categories are combined.
1819 : ! For ncat = 5, boundaries are 30, 70, 120, 200, >200 cm.
1820 : ! For ncat = 6, boundaries are 15, 30, 70, 120, 200, >200 cm.
1821 : ! For ncat = 7, boundaries are 10, 15, 30, 70, 120, 200, >200 cm.
1822 : !
1823 : ! The fourth formula asymptotes to a particular category width as
1824 : ! the number of categories increases, given by the parameter b1.
1825 : ! The parameter b3 is computed so that the category boundaries
1826 : ! are even numbers.
1827 : !
1828 : ! H(n) = b1 * [n + b3*n*(n+1)/(2*N*(N-1))] for N=ncat
1829 : !
1830 : ! kcatbound=-1 is available only for 1-category runs, with
1831 : ! boundaries 0 and 100 m.
1832 : !-----------------------------------------------------------------
1833 :
1834 4138 : if (kcatbound == -1) then ! single category
1835 350 : hin_max(0) = c0
1836 350 : hin_max(1) = c100
1837 :
1838 3788 : elseif (kcatbound == 0) then ! original scheme
1839 :
1840 3071 : if (kitd == 1) then
1841 : ! linear remapping itd category limits
1842 2947 : cc1 = c3/rncat
1843 2947 : cc2 = c15*cc1
1844 2947 : cc3 = c3
1845 :
1846 2947 : hin_max(0) = c0 ! minimum ice thickness, m
1847 : else
1848 : ! delta function itd category limits
1849 : #ifndef CESMCOUPLED
1850 124 : hi_min = p1 ! minimum ice thickness allowed (m) for thermo
1851 : #endif
1852 124 : cc1 = max(1.1_dbl_kind/rncat,hi_min)
1853 124 : cc2 = c25*cc1
1854 124 : cc3 = 2.25_dbl_kind
1855 :
1856 : ! hin_max(0) should not be zero
1857 : ! use some caution in making it less than 0.10
1858 124 : hin_max(0) = hi_min ! minimum ice thickness, m
1859 : endif ! kitd
1860 :
1861 18426 : do n = 1, ncat
1862 15355 : x1 = real(n-1,kind=dbl_kind) / rncat
1863 6610 : hin_max(n) = hin_max(n-1) &
1864 21731 : + cc1 + cc2*(c1 + tanh(cc3*(x1-c1)))
1865 : enddo
1866 :
1867 717 : elseif (kcatbound == 1) then ! new scheme
1868 :
1869 178 : hin_max(0) = c0
1870 1068 : do n = 1, ncat
1871 890 : rn = real(n, kind=dbl_kind)
1872 1068 : hin_max(n) = rn * (d1 + (rn-c1)*d2)
1873 : enddo
1874 :
1875 539 : elseif (kcatbound == 2) then ! WMO standard
1876 :
1877 299 : if (ncat == 5) then
1878 7 : hin_max(0) = c0
1879 42 : do n = 1, ncat
1880 42 : hin_max(n) = wmo5(n)
1881 : enddo
1882 292 : elseif (ncat == 6) then
1883 292 : hin_max(0) = c0
1884 2044 : do n = 1, ncat
1885 2044 : hin_max(n) = wmo6(n)
1886 : enddo
1887 0 : elseif (ncat == 7) then
1888 0 : hin_max(0) = c0
1889 0 : do n = 1, ncat
1890 0 : hin_max(n) = wmo7(n)
1891 : enddo
1892 : else
1893 0 : call icepack_warnings_add(subname//' kcatbound=2 (WMO) must have ncat=5, 6 or 7')
1894 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1895 0 : return
1896 : endif
1897 :
1898 240 : elseif (kcatbound == 3) then ! asymptotic scheme
1899 :
1900 240 : hin_max(0) = c0
1901 1920 : do n = 1, ncat
1902 1680 : rn = real(n, kind=dbl_kind)
1903 1920 : hin_max(n) = b1 * (rn + b3*rn*(rn+c1)/(c2*rncat*(rncat-c1)))
1904 : enddo
1905 :
1906 : endif ! kcatbound
1907 :
1908 : end subroutine icepack_init_itd
1909 :
1910 : !=======================================================================
1911 : !autodocument_start icepack_init_itd_hist
1912 : ! Initialize area fraction and thickness boundaries for the itd model
1913 : !
1914 : ! authors: William H. Lipscomb and Elizabeth C. Hunke, LANL
1915 : ! C. M. Bitz, UW
1916 :
1917 334 : subroutine icepack_init_itd_hist (ncat, hin_max, c_hi_range)
1918 :
1919 : integer (kind=int_kind), intent(in) :: &
1920 : ncat ! number of thickness categories
1921 :
1922 : real (kind=dbl_kind), intent(in) :: &
1923 : hin_max(0:ncat) ! category limits (m)
1924 :
1925 : character (len=35), intent(out) :: &
1926 : c_hi_range(ncat) ! string for history output
1927 :
1928 : !autodocument_end
1929 :
1930 : ! local variables
1931 :
1932 : integer (kind=int_kind) :: &
1933 : n ! thickness category index
1934 :
1935 : character(len=8) :: c_hinmax1,c_hinmax2
1936 : character(len=2) :: c_nc
1937 :
1938 : character(len=*),parameter :: subname='(icepack_init_itd_hist)'
1939 :
1940 334 : write(warnstr,*) ' '
1941 334 : call icepack_warnings_add(warnstr)
1942 334 : write(warnstr,*) subname
1943 334 : call icepack_warnings_add(warnstr)
1944 334 : write(warnstr,*) 'hin_max(n-1) < Cat n < hin_max(n)'
1945 334 : call icepack_warnings_add(warnstr)
1946 1987 : do n = 1, ncat
1947 1653 : write(warnstr,*) hin_max(n-1),' < Cat ',n, ' < ',hin_max(n)
1948 1653 : call icepack_warnings_add(warnstr)
1949 : ! Write integer n to character string
1950 1653 : write (c_nc, '(i2)') n
1951 :
1952 : ! Write hin_max to character string
1953 1653 : write (c_hinmax1, '(f6.3)') hin_max(n-1)
1954 1653 : write (c_hinmax2, '(f6.3)') hin_max(n)
1955 :
1956 : ! Save character string to write to history file
1957 1987 : c_hi_range(n)=c_hinmax1//'m < hi Cat '//c_nc//' < '//c_hinmax2//'m'
1958 : enddo
1959 :
1960 334 : write(warnstr,*) ' '
1961 334 : call icepack_warnings_add(warnstr)
1962 :
1963 334 : end subroutine icepack_init_itd_hist
1964 :
1965 : !=======================================================================
1966 : !autodocument_start icepack_aggregate
1967 : ! Aggregate ice state variables over thickness categories.
1968 : !
1969 : ! authors: C. M. Bitz, UW
1970 : ! W. H. Lipscomb, LANL
1971 :
1972 3632132060 : subroutine icepack_aggregate (ncat, &
1973 : aicen, trcrn, & ! LCOV_EXCL_LINE
1974 : vicen, vsnon, & ! LCOV_EXCL_LINE
1975 : aice, trcr, & ! LCOV_EXCL_LINE
1976 : vice, vsno, & ! LCOV_EXCL_LINE
1977 : aice0, & ! LCOV_EXCL_LINE
1978 : ntrcr, & ! LCOV_EXCL_LINE
1979 : trcr_depend, & ! LCOV_EXCL_LINE
1980 : trcr_base, & ! LCOV_EXCL_LINE
1981 : n_trcr_strata, & ! LCOV_EXCL_LINE
1982 3632132060 : nt_strata)
1983 :
1984 : integer (kind=int_kind), intent(in) :: &
1985 : ncat , & ! number of thickness categories ! LCOV_EXCL_LINE
1986 : ntrcr ! number of tracers in use
1987 :
1988 : real (kind=dbl_kind), dimension (:), intent(in) :: &
1989 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
1990 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
1991 : vsnon ! volume per unit area of snow (m)
1992 :
1993 : real (kind=dbl_kind), dimension (:,:), intent(inout) :: &
1994 : trcrn ! ice tracers
1995 :
1996 : integer (kind=int_kind), dimension (:), intent(in) :: &
1997 : trcr_depend, & ! = 0 for aicen tracers, 1 for vicen, 2 for vsnon ! LCOV_EXCL_LINE
1998 : n_trcr_strata ! number of underlying tracer layers
1999 :
2000 : real (kind=dbl_kind), dimension (:,:), intent(in) :: &
2001 : trcr_base ! = 0 or 1 depending on tracer dependency
2002 : ! argument 2: (1) aice, (2) vice, (3) vsno
2003 :
2004 : integer (kind=int_kind), dimension (:,:), intent(in) :: &
2005 : nt_strata ! indices of underlying tracer layers
2006 :
2007 : real (kind=dbl_kind), intent(out) :: &
2008 : aice , & ! concentration of ice ! LCOV_EXCL_LINE
2009 : vice , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
2010 : vsno , & ! volume per unit area of snow (m) ! LCOV_EXCL_LINE
2011 : aice0 ! concentration of open water
2012 :
2013 : real (kind=dbl_kind), dimension (:), intent(out) :: &
2014 : trcr ! ice tracers
2015 :
2016 : !autodocument_end
2017 :
2018 : ! local variables
2019 :
2020 : integer (kind=int_kind) :: &
2021 : n, it, itl, & ! loop indices ! LCOV_EXCL_LINE
2022 : ntr ! tracer index
2023 :
2024 : real (kind=dbl_kind), dimension (:), allocatable :: &
2025 3632132060 : atrcr ! sum of aicen*trcrn or vicen*trcrn or vsnon*trcrn
2026 :
2027 : real (kind=dbl_kind) :: &
2028 368639626 : atrcrn ! category value
2029 :
2030 : character(len=*),parameter :: subname='(icepack_aggregate)'
2031 :
2032 : !-----------------------------------------------------------------
2033 : ! Initialize
2034 : !-----------------------------------------------------------------
2035 :
2036 3632132060 : aice0 = c1
2037 3632132060 : aice = c0
2038 3632132060 : vice = c0
2039 3632132060 : vsno = c0
2040 :
2041 3632132060 : allocate (atrcr(ntrcr))
2042 :
2043 : !-----------------------------------------------------------------
2044 : ! Aggregate
2045 : !-----------------------------------------------------------------
2046 :
2047 >12926*10^7 : atrcr(:) = c0
2048 :
2049 21665885656 : do n = 1, ncat
2050 :
2051 18033753596 : aice = aice + aicen(n)
2052 18033753596 : vice = vice + vicen(n)
2053 18033753596 : vsno = vsno + vsnon(n)
2054 :
2055 >64834*10^7 : do it = 1, ntrcr
2056 42522224627 : atrcrn = trcrn(it,n)*(trcr_base(it,1) * aicen(n) &
2057 : + trcr_base(it,2) * vicen(n) & ! LCOV_EXCL_LINE
2058 >62667*10^7 : + trcr_base(it,3) * vsnon(n))
2059 >62667*10^7 : if (n_trcr_strata(it) > 0) then ! additional tracer layers
2060 >13214*10^7 : do itl = 1, n_trcr_strata(it)
2061 82197825489 : ntr = nt_strata(it,itl)
2062 >13214*10^7 : atrcrn = atrcrn * trcrn(ntr,n)
2063 : enddo
2064 : endif
2065 >64471*10^7 : atrcr(it) = atrcr(it) + atrcrn
2066 : enddo ! ntrcr
2067 : enddo ! ncat
2068 :
2069 : ! Open water fraction
2070 3632132060 : aice0 = max (c1 - aice, c0)
2071 :
2072 : ! Tracers
2073 0 : call icepack_compute_tracers (ntrcr, trcr_depend, &
2074 : atrcr, aice, & ! LCOV_EXCL_LINE
2075 : vice , vsno, & ! LCOV_EXCL_LINE
2076 : trcr_base, n_trcr_strata, & ! LCOV_EXCL_LINE
2077 3632132060 : nt_strata, trcr)
2078 3632132060 : if (icepack_warnings_aborted(subname)) return
2079 :
2080 3632132060 : deallocate (atrcr)
2081 :
2082 3632132060 : end subroutine icepack_aggregate
2083 :
2084 : !=======================================================================
2085 :
2086 : end module icepack_itd
2087 :
2088 : !=======================================================================
2089 :
2090 :
2091 :
2092 :
2093 :
2094 :
2095 :
2096 :
2097 :
|