Line data Source code
1 : module icepack_mushy_physics
2 :
3 : use icepack_kinds
4 : use icepack_parameters, only: c0, c1, c2, c4, c1000
5 : use icepack_parameters, only: puny
6 : use icepack_parameters, only: rhow, rhoi, rhos, cp_ocn, cp_ice, Lfresh
7 : use icepack_parameters, only: ksno
8 : use icepack_tracers, only: nilyr
9 : use icepack_warnings, only: warnstr, icepack_warnings_add
10 : use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
11 :
12 : implicit none
13 :
14 : private
15 : public :: &
16 : conductivity_mush_array, &
17 : conductivity_snow_array, &
18 : icepack_enthalpy_snow, &
19 : enthalpy_brine, &
20 : icepack_enthalpy_mush, &
21 : enthalpy_mush_liquid_fraction, &
22 : enthalpy_of_melting, &
23 : temperature_snow, &
24 : icepack_mushy_temperature_mush, &
25 : temperature_mush_liquid_fraction, &
26 : liquidus_brine_salinity_mush, &
27 : liquidus_temperature_mush, &
28 : icepack_mushy_liquid_fraction, &
29 : icepack_mushy_density_brine
30 :
31 : !-----------------------------------------------------------------
32 : ! Constants for Liquidus relation from Assur (1958)
33 : !-----------------------------------------------------------------
34 :
35 : ! liquidus relation - higher temperature region
36 : real(kind=dbl_kind), parameter :: &
37 : az1_liq = -18.48_dbl_kind, &
38 : bz1_liq = 0.0_dbl_kind
39 :
40 : ! liquidus relation - lower temperature region
41 : real(kind=dbl_kind), parameter :: &
42 : az2_liq = -10.3085_dbl_kind, &
43 : bz2_liq = 62.4_dbl_kind
44 :
45 : ! liquidus break
46 : real(kind=dbl_kind), parameter :: &
47 : Tb_liq = -7.6362968855167352_dbl_kind, & ! temperature of liquidus break
48 : Sb_liq = 123.66702800276086_dbl_kind ! salinity of liquidus break
49 :
50 : ! basic liquidus relation constants
51 : real(kind=dbl_kind), parameter :: &
52 : az1p_liq = az1_liq / c1000, &
53 : bz1p_liq = bz1_liq / c1000, &
54 : az2p_liq = az2_liq / c1000, &
55 : bz2p_liq = bz2_liq / c1000
56 :
57 : !-----------------------------------------------------------------
58 : ! Other parameters
59 : !-----------------------------------------------------------------
60 :
61 : real(kind=dbl_kind), parameter :: &
62 : ki = 2.3_dbl_kind , & ! fresh ice conductivity (W m-1 K-1)
63 : kb = 0.5375_dbl_kind ! brine conductivity (W m-1 K-1)
64 :
65 : !=======================================================================
66 :
67 : contains
68 :
69 : !=======================================================================
70 : ! Physical Quantities
71 : !=======================================================================
72 : ! Detemine the conductivity of the mush from enthalpy and salinity
73 :
74 7258715 : subroutine conductivity_mush_array(zqin, zSin, km)
75 :
76 : real(kind=dbl_kind), dimension(:), intent(in) :: &
77 : zqin, & ! ice layer enthalpy (J m-3)
78 : zSin ! ice layer bulk salinity (ppt)
79 :
80 : real(kind=dbl_kind), dimension(:), intent(out) :: &
81 : km ! ice layer conductivity (W m-1 K-1)
82 :
83 : integer(kind=int_kind) :: &
84 : k ! ice layer index
85 :
86 : real(kind=dbl_kind) :: Tmush
87 :
88 : character(len=*),parameter :: subname='(conductivity_mush_array)'
89 :
90 58069720 : do k = 1, nilyr
91 :
92 50811005 : Tmush = icepack_mushy_temperature_mush(zqin(k), zSin(k))
93 :
94 58069720 : km(k) = heat_conductivity(Tmush, zSin(k))
95 :
96 : enddo ! k
97 :
98 7258715 : end subroutine conductivity_mush_array
99 :
100 : !=======================================================================
101 : !autodocument_start icepack_mushy_density_brine
102 : ! Compute density of brine from brine salinity
103 :
104 156664773 : function icepack_mushy_density_brine(Sbr) result(rho)
105 :
106 : real(kind=dbl_kind), intent(in) :: &
107 : Sbr ! brine salinity (ppt)
108 :
109 : real(kind=dbl_kind) :: &
110 : rho ! brine density (kg m-3)
111 :
112 : !autodocument_end
113 :
114 : real(kind=dbl_kind), parameter :: &
115 : a = 1000.3_dbl_kind , & ! zeroth empirical coefficient
116 : b = 0.78237_dbl_kind , & ! linear empirical coefficient
117 : c = 2.8008e-4_dbl_kind ! quadratic empirical coefficient
118 :
119 : character(len=*),parameter :: subname='(icepack_mushy_density_brine)'
120 :
121 156664773 : rho = a + b * Sbr + c * Sbr**2
122 :
123 156664773 : end function icepack_mushy_density_brine
124 :
125 : !=======================================================================
126 : ! Snow
127 : !=======================================================================
128 : ! Heat conductivity of the snow
129 :
130 5973006 : subroutine conductivity_snow_array(ks)
131 :
132 : real(kind=dbl_kind), dimension(:), intent(out) :: &
133 : ks ! snow layer conductivity (W m-1 K-1)
134 :
135 : character(len=*),parameter :: subname='(conductivity_snow_array)'
136 :
137 15128400 : ks = ksno
138 :
139 5973006 : end subroutine conductivity_snow_array
140 :
141 : !=======================================================================
142 : !autodocument_start icepack_enthalpy_snow
143 : ! Enthalpy of snow from snow temperature
144 :
145 18781915 : function icepack_enthalpy_snow(zTsn) result(zqsn)
146 :
147 : real(kind=dbl_kind), intent(in) :: &
148 : zTsn ! snow layer temperature (C)
149 :
150 : real(kind=dbl_kind) :: &
151 : zqsn ! snow layer enthalpy (J m-3)
152 :
153 : !autodocument_end
154 :
155 : character(len=*),parameter :: subname='(icepack_enthalpy_snow)'
156 :
157 18781915 : zqsn = -rhos * (-cp_ice * zTsn + Lfresh)
158 :
159 18781915 : end function icepack_enthalpy_snow
160 :
161 : !=======================================================================
162 : ! Temperature of snow from the snow enthalpy
163 :
164 18365656 : function temperature_snow(zqsn) result(zTsn)
165 :
166 : real(kind=dbl_kind), intent(in) :: &
167 : zqsn ! snow layer enthalpy (J m-3)
168 :
169 : real(kind=dbl_kind) :: &
170 : zTsn, & ! snow layer temperature (C)
171 : A, B
172 :
173 : character(len=*),parameter :: subname='(temperature_snow)'
174 :
175 18365656 : A = c1 / (rhos * cp_ice)
176 18365656 : B = Lfresh / cp_ice
177 18365656 : zTsn = A * zqsn + B
178 :
179 18365656 : end function temperature_snow
180 :
181 : !=======================================================================
182 : ! Mushy Layer Formulation - Assur (1958) liquidus
183 : !=======================================================================
184 : ! Liquidus relation: equilibrium brine salinity as function of temperature
185 : ! based on empirical data from Assur (1958)
186 :
187 479450973 : function liquidus_brine_salinity_mush(zTin) result(Sbr)
188 :
189 : real(kind=dbl_kind), intent(in) :: &
190 : zTin ! ice layer temperature (C)
191 :
192 : real(kind=dbl_kind) :: &
193 : Sbr ! ice brine salinity (ppt)
194 :
195 : real(kind=dbl_kind) :: &
196 : t_high , & ! mask for high temperature liquidus region
197 : lsubzero ! mask for sub-zero temperatures
198 :
199 : real(kind=dbl_kind) :: &
200 : J1_liq, K1_liq, L1_liq, & ! temperature to brine salinity
201 : J2_liq, K2_liq, L2_liq
202 :
203 : character(len=*),parameter :: subname='(liquidus_brine_salinty_mush)'
204 :
205 : ! temperature to brine salinity
206 479450973 : J1_liq = bz1_liq / az1_liq
207 479450973 : K1_liq = c1 / c1000
208 479450973 : L1_liq = (c1 + bz1p_liq) / az1_liq
209 479450973 : J2_liq = bz2_liq / az2_liq
210 479450973 : K2_liq = c1 / c1000
211 479450973 : L2_liq = (c1 + bz2p_liq) / az2_liq
212 :
213 479450973 : t_high = merge(c1, c0, (zTin > Tb_liq))
214 479450973 : lsubzero = merge(c1, c0, (zTin <= c0))
215 :
216 : Sbr = ((zTin + J1_liq) / (K1_liq * zTin + L1_liq)) * t_high + &
217 479450973 : ((zTin + J2_liq) / (K2_liq * zTin + L2_liq)) * (c1 - t_high)
218 :
219 479450973 : Sbr = Sbr * lsubzero
220 :
221 479450973 : end function liquidus_brine_salinity_mush
222 :
223 : !=======================================================================
224 : ! Liquidus relation: equilibrium temperature as function of brine salinity
225 : ! based on empirical data from Assur (1958)
226 :
227 115036954 : function liquidus_temperature_mush(Sbr) result(zTin)
228 :
229 : real(kind=dbl_kind), intent(in) :: &
230 : Sbr ! ice brine salinity (ppt)
231 :
232 : real(kind=dbl_kind) :: &
233 : zTin ! ice layer temperature (C)
234 :
235 : real(kind=dbl_kind) :: &
236 : t_high ! mask for high temperature liquidus region
237 :
238 : real(kind=dbl_kind) :: &
239 : M1_liq, &! brine salinity to temperature
240 : N1_liq, &
241 : O1_liq, &
242 : M2_liq, &
243 : N2_liq, &
244 : O2_liq
245 :
246 : character(len=*),parameter :: subname='(liquidus_temperature_mush)'
247 :
248 : ! brine salinity to temperature
249 115036954 : M1_liq = az1_liq
250 115036954 : N1_liq = -az1p_liq
251 115036954 : O1_liq = -bz1_liq / az1_liq
252 115036954 : M2_liq = az2_liq
253 115036954 : N2_liq = -az2p_liq
254 115036954 : O2_liq = -bz2_liq / az2_liq
255 :
256 115036954 : t_high = merge(c1, c0, (Sbr <= Sb_liq))
257 :
258 : zTin = ((Sbr / (M1_liq + N1_liq * Sbr)) + O1_liq) * t_high + &
259 115036954 : ((Sbr / (M2_liq + N2_liq * Sbr)) + O2_liq) * (c1 - t_high)
260 :
261 115036954 : end function liquidus_temperature_mush
262 :
263 : !=======================================================================
264 : !autodocument_start icepack_enthalpy_mush
265 : ! Enthalpy of mush from mush temperature and bulk salinity
266 :
267 8451871 : function icepack_enthalpy_mush(zTin, zSin) result(zqin)
268 :
269 : real(kind=dbl_kind), intent(in) :: &
270 : zTin, & ! ice layer temperature (C)
271 : zSin ! ice layer bulk salinity (ppt)
272 :
273 : real(kind=dbl_kind) :: &
274 : zqin ! ice layer enthalpy (J m-3)
275 :
276 : !autodocument_end
277 :
278 : real(kind=dbl_kind) :: &
279 : phi ! ice liquid fraction
280 :
281 : character(len=*),parameter :: subname='(icepack_enthalpy_mush)'
282 :
283 8451871 : phi = icepack_mushy_liquid_fraction(zTin, zSin)
284 :
285 : zqin = phi * (cp_ocn * rhow - cp_ice * rhoi) * zTin + &
286 8451871 : rhoi * cp_ice * zTin - (c1 - phi) * rhoi * Lfresh
287 :
288 8451871 : end function icepack_enthalpy_mush
289 :
290 : !=======================================================================
291 : ! Enthalpy of mush from mush temperature and liquid fraction
292 :
293 111131806 : function enthalpy_mush_liquid_fraction(zTin, phi) result(zqin)
294 :
295 : real(kind=dbl_kind), intent(in) :: &
296 : zTin, & ! ice layer temperature (C)
297 : phi ! liquid fraction
298 :
299 : real(kind=dbl_kind) :: &
300 : zqin ! ice layer enthalpy (J m-3)
301 :
302 : character(len=*),parameter :: subname='(enthalpy_mush_liquid_fraction)'
303 :
304 : zqin = phi * (cp_ocn * rhow - cp_ice * rhoi) * zTin + &
305 111131806 : rhoi * cp_ice * zTin - (c1 - phi) * rhoi * Lfresh
306 :
307 111131806 : end function enthalpy_mush_liquid_fraction
308 :
309 : !=======================================================================
310 : ! Enthalpy of melting of mush from bulk salinity
311 : ! Energy needed to fully melt mush (T < 0)
312 :
313 58069720 : function enthalpy_of_melting(zSin) result(qm)
314 :
315 : real(kind=dbl_kind), intent(in) :: &
316 : zSin ! ice layer bulk salinity (ppt)
317 :
318 : real(kind=dbl_kind) :: &
319 : qm ! melting ice enthalpy (J m-3)
320 :
321 : character(len=*),parameter :: subname='(enthalpy_of_melting)'
322 :
323 58069720 : qm = cp_ocn * rhow * liquidus_temperature_mush(zSin)
324 :
325 58069720 : end function enthalpy_of_melting
326 :
327 : !=======================================================================
328 : ! Enthalpy of brine (fully liquid) from temperature
329 :
330 281106874 : function enthalpy_brine(zTin) result(qbr)
331 :
332 : real(kind=dbl_kind), intent(in) :: &
333 : zTin ! ice layer temperature (C)
334 :
335 : real(kind=dbl_kind) :: &
336 : qbr ! brine enthalpy (J m-3)
337 :
338 : character(len=*),parameter :: subname='(enthalpy_brine)'
339 :
340 281106874 : qbr = cp_ocn * rhow * zTin
341 :
342 281106874 : end function enthalpy_brine
343 :
344 : !=======================================================================
345 : !autodocument_start icepack_mushy_temperature_mush
346 : ! Temperature of mush from mush enthalpy and bulk salinity
347 :
348 211780162 : function icepack_mushy_temperature_mush(zqin, zSin) result(zTin)
349 :
350 : real(kind=dbl_kind), intent(in) :: &
351 : zqin , & ! ice enthalpy (J m-3)
352 : zSin ! ice layer bulk salinity (ppt)
353 :
354 : real(kind=dbl_kind) :: &
355 : zTin ! ice layer temperature (C)
356 :
357 : !autodocument_end
358 :
359 : real(kind=dbl_kind) :: &
360 : qb , & ! liquidus break enthalpy
361 : q0 , & ! fully melted enthalpy
362 : A , & ! quadratic equation A parameter
363 : B , & ! quadratic equation B parameter
364 : C , & ! quadratic equation C parameter
365 : S_low , & ! mask for salinity less than the liquidus break salinity
366 : t_high , & ! mask for high temperature liquidus region
367 : t_low , & ! mask for low temperature liquidus region
368 : q_melt ! mask for all mush melted
369 :
370 : ! quadratic constants - higher temperature region
371 : real(kind=dbl_kind) :: &
372 : AS1_liq, AC1_liq, & ! quadratic constants - higher temperature region
373 : BS1_liq, BC1_liq, BQ1_liq, & ! "
374 : CS1_liq, CC1_liq, CQ1_liq, & ! "
375 : AS2_liq, AC2_liq, & ! quadratic constants - lower temperature region
376 : BS2_liq, BC2_liq, BQ2_liq, & ! "
377 : CS2_liq, CC2_liq, CQ2_liq, & ! "
378 : D_liq, E_liq, & ! break enthalpy constants
379 : F1_liq, G1_liq, H1_liq, & ! just fully melted enthapy constants
380 : F2_liq, G2_liq, H2_liq, & ! "
381 : I_liq ! warmer than fully melted constants
382 :
383 : character(len=*),parameter :: subname='(icepack_mushy_temperature_mush)'
384 :
385 : !--------------------------------------------------------
386 :
387 : ! quadratic constants - higher temperature region
388 211780162 : AS1_liq = az1p_liq * (rhow * cp_ocn - rhoi * cp_ice)
389 211780162 : AC1_liq = rhoi * cp_ice * az1_liq
390 : BS1_liq = (c1 + bz1p_liq) * (rhow * cp_ocn - rhoi * cp_ice) &
391 211780162 : + rhoi * Lfresh * az1p_liq
392 211780162 : BQ1_liq = -az1_liq
393 211780162 : BC1_liq = rhoi * cp_ice * bz1_liq - rhoi * Lfresh * az1_liq
394 211780162 : CS1_liq = rhoi * Lfresh * (c1 + bz1p_liq)
395 211780162 : CQ1_liq = -bz1_liq
396 211780162 : CC1_liq = -rhoi * Lfresh * bz1_liq
397 :
398 : ! quadratic constants - lower temperature region
399 211780162 : AS2_liq = az2p_liq * (rhow * cp_ocn - rhoi * cp_ice)
400 211780162 : AC2_liq = rhoi * cp_ice * az2_liq
401 : BS2_liq = (c1 + bz2p_liq) * (rhow * cp_ocn - rhoi * cp_ice) &
402 211780162 : + rhoi * Lfresh * az2p_liq
403 211780162 : BQ2_liq = -az2_liq
404 211780162 : BC2_liq = rhoi * cp_ice * bz2_liq - rhoi * Lfresh * az2_liq
405 211780162 : CS2_liq = rhoi * Lfresh * (c1 + bz2p_liq)
406 211780162 : CQ2_liq = -bz2_liq
407 211780162 : CC2_liq = -rhoi * Lfresh * bz2_liq
408 :
409 : ! break enthalpy constants
410 : D_liq = ((c1 + az1p_liq*Tb_liq + bz1p_liq) &
411 : / ( az1_liq*Tb_liq + bz1_liq)) &
412 211780162 : * ((cp_ocn*rhow - cp_ice*rhoi)*Tb_liq + Lfresh*rhoi)
413 211780162 : E_liq = cp_ice*rhoi*Tb_liq - Lfresh*rhoi
414 :
415 : ! just fully melted enthapy constants
416 211780162 : F1_liq = ( -c1000 * cp_ocn * rhow) / az1_liq
417 211780162 : G1_liq = -c1000
418 211780162 : H1_liq = (-bz1_liq * cp_ocn * rhow) / az1_liq
419 211780162 : F2_liq = ( -c1000 * cp_ocn * rhow) / az2_liq
420 211780162 : G2_liq = -c1000
421 211780162 : H2_liq = (-bz2_liq * cp_ocn * rhow) / az2_liq
422 :
423 : ! warmer than fully melted constants
424 211780162 : I_liq = c1 / (cp_ocn * rhow)
425 :
426 : ! just melted enthalpy
427 211780162 : S_low = merge(c1, c0, (zSin < Sb_liq))
428 : q0 = ((F1_liq * zSin) / (G1_liq + zSin) + H1_liq) * S_low + &
429 211780162 : ((F2_liq * zSin) / (G2_liq + zSin) + H2_liq) * (c1 - S_low)
430 211780162 : q_melt = merge(c1, c0, (zqin > q0))
431 :
432 : ! break enthalpy
433 211780162 : qb = D_liq * zSin + E_liq
434 211780162 : t_high = merge(c1, c0, (zqin > qb))
435 211780162 : t_low = c1 - t_high
436 :
437 : ! quadratic values
438 : A = (AS1_liq * zSin + AC1_liq) * t_high + &
439 211780162 : (AS2_liq * zSin + AC2_liq) * t_low
440 :
441 : B = (BS1_liq * zSin + BQ1_liq * zqin + BC1_liq) * t_high + &
442 211780162 : (BS2_liq * zSin + BQ2_liq * zqin + BC2_liq) * t_low
443 :
444 : C = (CS1_liq * zSin + CQ1_liq * zqin + CC1_liq) * t_high + &
445 211780162 : (CS2_liq * zSin + CQ2_liq * zqin + CC2_liq) * t_low
446 :
447 211780162 : zTin = (-B + sqrt(max(B**2 - c4 * A * C,puny))) / (c2 * A)
448 :
449 : ! change T if all melted
450 211780162 : zTin = q_melt * zqin * I_liq + (c1 - q_melt) * zTin
451 :
452 211780162 : end function icepack_mushy_temperature_mush
453 :
454 : !=======================================================================
455 : ! Temperature of mush from mush enthalpy and liquid fraction
456 :
457 50811005 : function temperature_mush_liquid_fraction(zqin, phi) result(zTin)
458 :
459 : real(kind=dbl_kind), intent(in) :: &
460 : zqin , & ! ice enthalpy (J m-3)
461 : phi ! liquid fraction
462 :
463 : real(kind=dbl_kind) :: &
464 : zTin ! ice layer temperature (C)
465 :
466 : character(len=*),parameter :: subname='(temperature_mush_liquid_fraction)'
467 :
468 : zTin = (zqin + (c1 - phi) * rhoi * Lfresh) / &
469 50811005 : (phi * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice)
470 :
471 50811005 : end function temperature_mush_liquid_fraction
472 :
473 : !=======================================================================
474 : ! Mush heat conductivity from mush temperature and bulk salinity
475 :
476 50811005 : function heat_conductivity(zTin, zSin) result(km)
477 :
478 : real(kind=dbl_kind), intent(in) :: &
479 : zTin , & ! ice layer temperature (C)
480 : zSin ! ice layer bulk salinity (ppt)
481 :
482 : real(kind=dbl_kind) :: &
483 : km ! ice layer conductivity (W m-1 K-1)
484 :
485 : real(kind=dbl_kind) :: &
486 : phi ! liquid fraction
487 :
488 : character(len=*),parameter :: subname='(heat_conductivity)'
489 :
490 50811005 : phi = icepack_mushy_liquid_fraction(zTin, zSin)
491 :
492 50811005 : km = phi * (kb - ki) + ki
493 :
494 50811005 : end function heat_conductivity
495 :
496 : !=======================================================================
497 : !autodocument_start icepack_mushy_liquid_fraction
498 : ! Liquid fraction of mush from mush temperature and bulk salinity
499 :
500 219346702 : function icepack_mushy_liquid_fraction(zTin, zSin) result(phi)
501 :
502 : real(kind=dbl_kind), intent(in) :: &
503 : zTin, & ! ice layer temperature (C)
504 : zSin ! ice layer bulk salinity (ppt)
505 :
506 : real(kind=dbl_kind) :: &
507 : phi ! liquid fraction
508 :
509 : !autodocument_end
510 :
511 : real(kind=dbl_kind) :: &
512 : Sbr ! brine salinity (ppt)
513 :
514 : character(len=*),parameter :: subname='(icepack_mushy_liquid_fraction)'
515 :
516 219346702 : Sbr = max(liquidus_brine_salinity_mush(zTin),puny)
517 219346702 : phi = zSin / max(Sbr, zSin)
518 :
519 219346702 : end function icepack_mushy_liquid_fraction
520 :
521 : !=======================================================================
522 :
523 : end module icepack_mushy_physics
|