Line data Source code
1 : !=======================================================================
2 :
3 : module icepack_therm_mushy
4 :
5 : use icepack_kinds
6 : use icepack_parameters, only: c0, c1, c2, c8, c10
7 : use icepack_parameters, only: p01, p05, p1, p2, p5, pi, bignum, puny
8 : use icepack_parameters, only: viscosity_dyn, rhow, rhoi, rhos, cp_ocn, cp_ice, Lfresh, gravit
9 : use icepack_parameters, only: hs_min
10 : use icepack_parameters, only: a_rapid_mode, Rac_rapid_mode
11 : use icepack_parameters, only: aspect_rapid_mode, dSdt_slow_mode, phi_c_slow_mode
12 : use icepack_mushy_physics, only: icepack_mushy_density_brine, enthalpy_brine, enthalpy_snow
13 : use icepack_mushy_physics, only: enthalpy_mush_liquid_fraction
14 : use icepack_mushy_physics, only: icepack_mushy_temperature_mush, icepack_mushy_liquid_fraction
15 : use icepack_mushy_physics, only: temperature_snow, temperature_mush_liquid_fraction
16 : use icepack_mushy_physics, only: liquidus_brine_salinity_mush, liquidus_temperature_mush
17 : use icepack_mushy_physics, only: conductivity_mush_array, conductivity_snow_array
18 : use icepack_tracers, only: tr_pond
19 : use icepack_therm_shared, only: surface_heat_flux, dsurface_heat_flux_dTsf
20 : use icepack_therm_shared, only: ferrmax
21 : use icepack_warnings, only: warnstr, icepack_warnings_add
22 : use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
23 :
24 : implicit none
25 :
26 : private
27 : public :: &
28 : temperature_changes_salinity, &
29 : permeability
30 :
31 : real(kind=dbl_kind), parameter :: &
32 : dTemp_errmax = 5.0e-4_dbl_kind ! max allowed change in temperature
33 : ! between iterations
34 :
35 : !=======================================================================
36 :
37 : contains
38 :
39 : !=======================================================================
40 :
41 609317819 : subroutine temperature_changes_salinity(dt, &
42 : nilyr, nslyr, &
43 : rhoa, flw, &
44 : potT, Qa, &
45 : shcoef, lhcoef, &
46 : fswsfc, fswint, &
47 609317819 : Sswabs, Iswabs, &
48 : hilyr, hslyr, &
49 : apond, hpond, &
50 1218635638 : zqin, zTin, &
51 1218635638 : zqsn, zTsn, &
52 609317819 : zSin, &
53 : Tsf, Tbot, &
54 : sss, &
55 : fsensn, flatn, &
56 : flwoutn, fsurfn, &
57 : fcondtop, fcondbot, &
58 : fadvheat, snoice)
59 :
60 : ! solve the enthalpy and bulk salinity of the ice for a single column
61 :
62 : integer (kind=int_kind), intent(in) :: &
63 : nilyr , & ! number of ice layers
64 : nslyr ! number of snow layers
65 :
66 : real (kind=dbl_kind), intent(in) :: &
67 : dt ! time step (s)
68 :
69 : real (kind=dbl_kind), intent(in) :: &
70 : rhoa , & ! air density (kg/m^3)
71 : flw , & ! incoming longwave radiation (W/m^2)
72 : potT , & ! air potential temperature (K)
73 : Qa , & ! specific humidity (kg/kg)
74 : shcoef , & ! transfer coefficient for sensible heat
75 : lhcoef , & ! transfer coefficient for latent heat
76 : Tbot , & ! ice bottom surfce temperature (deg C)
77 : sss ! sea surface salinity (PSU)
78 :
79 : real (kind=dbl_kind), intent(inout) :: &
80 : fswsfc , & ! SW absorbed at ice/snow surface (W m-2)
81 : fswint ! SW absorbed in ice interior below surface (W m-2)
82 :
83 : real (kind=dbl_kind), intent(inout) :: &
84 : hilyr , & ! ice layer thickness (m)
85 : hslyr , & ! snow layer thickness (m)
86 : apond , & ! melt pond area fraction
87 : hpond ! melt pond depth (m)
88 :
89 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
90 : Sswabs , & ! SW radiation absorbed in snow layers (W m-2)
91 : Iswabs ! SW radiation absorbed in ice layers (W m-2)
92 :
93 : real (kind=dbl_kind), intent(inout):: &
94 : fsurfn , & ! net flux to top surface, excluding fcondtopn
95 : fcondtop , & ! downward cond flux at top surface (W m-2)
96 : fsensn , & ! surface downward sensible heat (W m-2)
97 : flatn , & ! surface downward latent heat (W m-2)
98 : flwoutn ! upward LW at surface (W m-2)
99 :
100 : real (kind=dbl_kind), intent(out):: &
101 : fcondbot , & ! downward cond flux at bottom surface (W m-2)
102 : fadvheat , & ! flow of heat to ocean due to advection (W m-2)
103 : snoice ! snow ice formation
104 :
105 : real (kind=dbl_kind), intent(inout):: &
106 : Tsf ! ice/snow surface temperature (C)
107 :
108 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
109 : zqin , & ! ice layer enthalpy (J m-3)
110 : zTin , & ! internal ice layer temperatures
111 : zSin , & ! internal ice layer salinities
112 : zqsn , & ! snow layer enthalpy (J m-3)
113 : zTsn ! internal snow layer temperatures
114 :
115 : ! local variables
116 : real(kind=dbl_kind), dimension(1:nilyr) :: &
117 1413344656 : zqin0 , & ! ice layer enthalpy (J m-3) at start of timestep
118 1413344656 : zSin0 , & ! internal ice layer salinities (ppt) at start of timestep
119 1413344656 : phi , & ! liquid fraction
120 1413344656 : km , & ! ice conductivity (W m-1 K-1)
121 1478247662 : dSdt ! gravity drainage desalination rate for slow mode (ppt s-1)
122 :
123 : real(kind=dbl_kind), dimension(1:nilyr+1) :: &
124 1445796159 : Sbr , & ! brine salinity (ppt)
125 1445796159 : qbr ! brine enthalpy (J m-3)
126 :
127 : real(kind=dbl_kind), dimension(0:nilyr) :: &
128 1445796159 : q ! upward interface vertical Darcy flow (m s-1)
129 :
130 : real(kind=dbl_kind), dimension(1:nslyr) :: &
131 1218635638 : zqsn0 , & ! snow layer enthalpy (J m-3) at start of timestep
132 706672328 : ks ! snow conductivity (W m-1 K-1)
133 :
134 : real(kind=dbl_kind) :: &
135 32451503 : Tsf0 , & ! ice/snow surface temperature (C) at start of timestep
136 32451503 : hin , & ! ice thickness (m)
137 32451503 : hsn , & ! snow thickness (m)
138 32451503 : hslyr_min , & ! minimum snow layer thickness (m)
139 32451503 : w , & ! vertical flushing Darcy velocity (m/s)
140 32451503 : qocn , & ! ocean brine enthalpy (J m-3)
141 32451503 : qpond , & ! melt pond brine enthalpy (J m-3)
142 32451503 : Spond ! melt pond salinity (ppt)
143 :
144 : integer(kind=int_kind) :: &
145 : k ! ice/snow layer index
146 :
147 : logical(kind=log_kind) :: &
148 : lsnow ! snow presence: T: has snow, F: no snow
149 :
150 : character(len=*),parameter :: subname='(temperature_changes_salinity)'
151 :
152 609317819 : fadvheat = c0
153 609317819 : snoice = c0
154 :
155 609317819 : Tsf0 = Tsf
156 1218635638 : zqsn0 = zqsn
157 4874542552 : zqin0 = zqin
158 4874542552 : zSin0 = zSin
159 :
160 609317819 : Spond = c0
161 609317819 : qpond = enthalpy_brine(c0)
162 :
163 609317819 : hslyr_min = hs_min / real(nslyr, dbl_kind)
164 :
165 609317819 : lsnow = (hslyr > hslyr_min)
166 :
167 609317819 : hin = hilyr * real(nilyr,dbl_kind)
168 :
169 609317819 : qocn = enthalpy_brine(Tbot)
170 :
171 609317819 : if (lsnow) then
172 531599226 : hsn = hslyr * real(nslyr,dbl_kind)
173 : else
174 77718593 : hsn = c0
175 : endif
176 :
177 4874542552 : do k = 1, nilyr
178 4874542552 : phi(k) = icepack_mushy_liquid_fraction(icepack_mushy_temperature_mush(zqin(k),zSin(k)),zSin(k))
179 : enddo ! k
180 :
181 : ! calculate vertical bulk darcy flow
182 0 : call flushing_velocity(zTin, &
183 0 : phi, nilyr, &
184 : hin, hsn, &
185 : hilyr, &
186 : hpond, apond, &
187 609317819 : dt, w)
188 609317819 : if (icepack_warnings_aborted(subname)) return
189 :
190 : ! calculate quantities related to drainage
191 0 : call explicit_flow_velocities(nilyr, zSin, &
192 0 : zTin, Tsf, &
193 : Tbot, q, &
194 0 : dSdt, Sbr, &
195 0 : qbr, dt, &
196 : sss, qocn, &
197 609317819 : hilyr, hin)
198 609317819 : if (icepack_warnings_aborted(subname)) return
199 :
200 : ! calculate the conductivities
201 609317819 : call conductivity_mush_array(nilyr, zqin0, zSin0, km)
202 609317819 : if (icepack_warnings_aborted(subname)) return
203 :
204 609317819 : if (lsnow) then
205 : ! case with snow
206 :
207 : ! calculate the snow conductivities
208 531599226 : call conductivity_snow_array(ks)
209 531599226 : if (icepack_warnings_aborted(subname)) return
210 :
211 : ! run the two stage solver
212 : call two_stage_solver_snow(nilyr, nslyr, &
213 : Tsf, Tsf0, &
214 0 : zqsn, zqsn0, &
215 0 : zqin, zqin0, &
216 0 : zSin, zSin0, &
217 0 : zTsn, &
218 0 : zTin, &
219 0 : phi, Tbot, &
220 0 : km, ks, &
221 0 : q, dSdt, &
222 : w, dt, &
223 : fswint, fswsfc, &
224 : rhoa, flw, &
225 : potT, Qa, &
226 : shcoef, lhcoef, &
227 0 : Iswabs, Sswabs, &
228 : qpond, qocn, &
229 : Spond, sss, &
230 : hilyr, hslyr, &
231 : fcondtop, fcondbot, &
232 : fadvheat, &
233 : flwoutn, fsensn, &
234 531599226 : flatn, fsurfn )
235 :
236 531599226 : if (icepack_warnings_aborted(subname)) then
237 0 : write(warnstr,*) subname, "temperature_changes_salinity: Picard solver non-convergence (snow)"
238 0 : call icepack_warnings_add(warnstr)
239 0 : return
240 : endif
241 :
242 : ! given the updated enthalpy and bulk salinity calculate other quantities
243 1063198452 : do k = 1, nslyr
244 1063198452 : zTsn(k) = temperature_snow(zqsn(k))
245 : enddo ! k
246 :
247 4252793808 : do k = 1, nilyr
248 3721194582 : zTin(k) = temperature_mush_liquid_fraction(zqin(k), phi(k))
249 3721194582 : Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
250 4252793808 : qbr(k) = enthalpy_brine(zTin(k))
251 : enddo ! k
252 :
253 : else
254 : ! case without snow
255 :
256 : ! run the two stage solver
257 : call two_stage_solver_nosnow(nilyr, nslyr, &
258 : Tsf, Tsf0, &
259 0 : zqsn, &
260 0 : zqin, zqin0, &
261 0 : zSin, zSin0, &
262 0 : zTsn, &
263 0 : zTin, &
264 0 : phi, Tbot, &
265 0 : km, ks, &
266 0 : q, dSdt, &
267 : w, dt, &
268 : fswint, fswsfc, &
269 : rhoa, flw, &
270 : potT, Qa, &
271 : shcoef, lhcoef, &
272 0 : Iswabs, Sswabs, &
273 : qpond, qocn, &
274 : Spond, sss, &
275 : hilyr, hslyr, &
276 : fcondtop, fcondbot, &
277 : fadvheat, &
278 : flwoutn, fsensn, &
279 77718593 : flatn, fsurfn )
280 :
281 77718593 : if (icepack_warnings_aborted(subname)) then
282 0 : write(warnstr,*) subname, "temperature_changes_salinity: Picard solver non-convergence (no snow)"
283 0 : call icepack_warnings_add(warnstr)
284 0 : return
285 : endif
286 :
287 : ! given the updated enthalpy and bulk salinity calculate other quantities
288 621748744 : do k = 1, nilyr
289 544030151 : zTin(k) = temperature_mush_liquid_fraction(zqin(k), phi(k))
290 544030151 : Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
291 621748744 : qbr(k) = enthalpy_brine(zTin(k))
292 : enddo ! k
293 :
294 : endif
295 :
296 : ! drain ponds from flushing
297 609317819 : call flush_pond(w, hpond, apond, dt)
298 609317819 : if (icepack_warnings_aborted(subname)) return
299 :
300 : ! flood snow ice
301 : call flood_ice(hsn, hin, &
302 : nslyr, nilyr, &
303 : hslyr, hilyr, &
304 0 : zqsn, zqin, &
305 0 : phi, dt, &
306 0 : zSin, Sbr, &
307 : sss, qocn, &
308 609317819 : snoice, fadvheat)
309 609317819 : if (icepack_warnings_aborted(subname)) return
310 :
311 : end subroutine temperature_changes_salinity
312 :
313 : !=======================================================================
314 :
315 531599226 : subroutine two_stage_solver_snow(nilyr, nslyr, &
316 : Tsf, Tsf0, &
317 1063198452 : zqsn, zqsn0, &
318 1063198452 : zqin, zqin0, &
319 1063198452 : zSin, zSin0, &
320 531599226 : zTsn, &
321 531599226 : zTin, &
322 531599226 : phi, Tbot, &
323 531599226 : km, ks, &
324 531599226 : q, dSdt, &
325 : w, dt, &
326 : fswint, fswsfc, &
327 : rhoa, flw, &
328 : potT, Qa, &
329 : shcoef, lhcoef, &
330 531599226 : Iswabs, Sswabs, &
331 : qpond, qocn, &
332 : Spond, sss, &
333 : hilyr, hslyr, &
334 : fcondtop, fcondbot, &
335 : fadvheat, &
336 : flwoutn, fsensn, &
337 : flatn, fsurfn )
338 :
339 : ! solve the vertical temperature and salt change for case with snow
340 : ! 1) determine what type of surface condition existed previously - cold or melting
341 : ! 2) solve the system assuming this condition persists
342 : ! 3) check the consistency of the surface condition of the solution
343 : ! 4) If the surface condition is inconsistent resolve for the other surface condition
344 : ! 5) If neither solution is consistent the resolve the inconsistency
345 :
346 : integer (kind=int_kind), intent(in) :: &
347 : nilyr , & ! number of ice layers
348 : nslyr ! number of snow layers
349 :
350 : real(kind=dbl_kind), intent(inout) :: &
351 : Tsf ! snow surface temperature (C)
352 :
353 : real(kind=dbl_kind), intent(out) :: &
354 : fcondtop , & ! downward cond flux at top surface (W m-2)
355 : fcondbot , & ! downward cond flux at bottom surface (W m-2)
356 : flwoutn , & ! upward LW at surface (W m-2)
357 : fsensn , & ! surface downward sensible heat (W m-2)
358 : flatn , & ! surface downward latent heat (W m-2)
359 : fsurfn , & ! net flux to top surface, excluding fcondtop
360 : fadvheat ! flow of heat to ocean due to advection (W m-2)
361 :
362 : real(kind=dbl_kind), intent(in) :: &
363 : Tsf0 ! snow surface temperature (C) at beginning of timestep
364 :
365 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
366 : zqsn , & ! snow layer enthalpy (J m-3)
367 : zTsn ! snow layer temperature (C)
368 :
369 : real(kind=dbl_kind), dimension(:), intent(in) :: &
370 : zqsn0 , & ! snow layer enthalpy (J m-3) at beginning of timestep
371 : ks , & ! snow conductivity (W m-1 K-1)
372 : Sswabs ! SW radiation absorbed in snow layers (W m-2)
373 :
374 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
375 : zqin , & ! ice layer enthalpy (J m-3)
376 : zSin , & ! ice layer bulk salinity (ppt)
377 : zTin , & ! ice layer temperature (C)
378 : phi ! ice layer liquid fraction
379 :
380 : real(kind=dbl_kind), dimension(:), intent(in) :: &
381 : zqin0 , & ! ice layer enthalpy (J m-3) at beginning of timestep
382 : zSin0 , & ! ice layer bulk salinity (ppt) at beginning of timestep
383 : km , & ! ice conductivity (W m-1 K-1)
384 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
385 : dSdt ! gravity drainage desalination rate for slow mode (ppt s-1)
386 :
387 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
388 : q ! upward interface vertical Darcy flow (m s-1)
389 :
390 : real(kind=dbl_kind), intent(in) :: &
391 : dt , & ! time step (s)
392 : Tbot , & ! ice bottom surfce temperature (deg C)
393 : hilyr , & ! ice layer thickness (m)
394 : hslyr , & ! snow layer thickness (m)
395 : fswint , & ! SW absorbed in ice interior below surface (W m-2)
396 : fswsfc , & ! SW absorbed at ice/snow surface (W m-2)
397 : rhoa , & ! air density (kg/m^3)
398 : flw , & ! incoming longwave radiation (W/m^2)
399 : potT , & ! air potential temperature (K)
400 : Qa , & ! specific humidity (kg/kg)
401 : shcoef , & ! transfer coefficient for sensible heat
402 : lhcoef , & ! transfer coefficient for latent heat
403 : w , & ! vertical flushing Darcy velocity (m/s)
404 : qpond , & ! melt pond brine enthalpy (J m-3)
405 : qocn , & ! ocean brine enthalpy (J m-3)
406 : Spond , & ! melt pond salinity (ppt)
407 : sss ! sea surface salinity (PSU)
408 :
409 : real(kind=dbl_kind) :: &
410 30172660 : fcondtop1 , & ! first stage downward cond flux at top surface (W m-2)
411 30172660 : fsurfn1 , & ! first stage net flux to top surface, excluding fcondtop
412 30172660 : Tsf1 ! first stage ice surface temperature (C)
413 :
414 : character(len=*),parameter :: subname='(two_stage_solver_snow)'
415 :
416 :
417 : ! determine if surface is initially cold or melting
418 531599226 : if (Tsf < c0) then
419 :
420 : ! initially cold
421 :
422 : ! solve the system for cold and snow
423 : call picard_solver(nilyr, nslyr, &
424 : .true., .true., &
425 0 : Tsf, zqsn, &
426 0 : zqin, zSin, &
427 0 : zTin, zTsn, &
428 0 : phi, dt, &
429 : hilyr, hslyr, &
430 0 : km, ks, &
431 0 : Iswabs, Sswabs, &
432 : Tbot, &
433 : fswint, fswsfc, &
434 : rhoa, flw, &
435 : potT, Qa, &
436 : shcoef, lhcoef, &
437 : fcondtop, fcondbot, &
438 : fadvheat, &
439 : flwoutn, fsensn, &
440 : flatn, fsurfn, &
441 : qpond, qocn, &
442 : Spond, sss, &
443 0 : q, dSdt, &
444 511866832 : w )
445 1043466058 : if (icepack_warnings_aborted(subname)) return
446 :
447 : ! halt if solver failed
448 511866832 : if (icepack_warnings_aborted(subname)) return
449 :
450 : ! check if solution is consistent - surface should still be cold
451 511866832 : if (Tsf < dTemp_errmax) then
452 :
453 : ! solution is consistent - have solution so finish
454 477647204 : return
455 :
456 : else
457 :
458 : ! solution is inconsistent - surface is warmer than melting
459 : ! resolve assuming surface is melting
460 34219628 : Tsf1 = Tsf
461 :
462 : ! reset the solution to initial values
463 34219628 : Tsf = c0
464 68439256 : zqsn = zqsn0
465 273757024 : zqin = zqin0
466 273757024 : zSin = zSin0
467 :
468 : ! solve the system for melting and snow
469 : call picard_solver(nilyr, nslyr, &
470 : .true., .false., &
471 0 : Tsf, zqsn, &
472 0 : zqin, zSin, &
473 0 : zTin, zTsn, &
474 0 : phi, dt, &
475 : hilyr, hslyr, &
476 0 : km, ks, &
477 0 : Iswabs, Sswabs, &
478 : Tbot, &
479 : fswint, fswsfc, &
480 : rhoa, flw, &
481 : potT, Qa, &
482 : shcoef, lhcoef, &
483 : fcondtop, fcondbot, &
484 : fadvheat, &
485 : flwoutn, fsensn, &
486 : flatn, fsurfn, &
487 : qpond, qocn, &
488 : Spond, sss, &
489 0 : q, dSdt, &
490 34219628 : w )
491 34219628 : if (icepack_warnings_aborted(subname)) return
492 :
493 : ! halt if solver failed
494 34219628 : if (icepack_warnings_aborted(subname)) return
495 :
496 : ! check if solution is consistent
497 : ! surface conductive heat flux should be less than
498 : ! incoming surface heat flux
499 34219628 : if (fcondtop - fsurfn < ferrmax) then
500 :
501 : ! solution is consistent - have solution so finish
502 34219628 : return
503 :
504 : else
505 :
506 : ! solution is inconsistent
507 0 : call two_stage_inconsistency(1, Tsf1, c0, fcondtop, fsurfn)
508 0 : if (icepack_warnings_aborted(subname)) return
509 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
510 0 : call icepack_warnings_add(subname//" two_stage_solver_snow: two_stage_inconsistency: cold" )
511 0 : return
512 :
513 : endif ! surface flux consistency
514 :
515 : endif ! surface temperature consistency
516 :
517 : else
518 :
519 : ! initially melting
520 19732394 : Tsf = c0
521 :
522 : ! solve the system for melting and snow
523 : call picard_solver(nilyr, nslyr, &
524 : .true., .false., &
525 0 : Tsf, zqsn, &
526 0 : zqin, zSin, &
527 0 : zTin, zTsn, &
528 0 : phi, dt, &
529 : hilyr, hslyr, &
530 0 : km, ks, &
531 0 : Iswabs, Sswabs, &
532 : Tbot, &
533 : fswint, fswsfc, &
534 : rhoa, flw, &
535 : potT, Qa, &
536 : shcoef, lhcoef, &
537 : fcondtop, fcondbot, &
538 : fadvheat, &
539 : flwoutn, fsensn, &
540 : flatn, fsurfn, &
541 : qpond, qocn, &
542 : Spond, sss, &
543 0 : q, dSdt, &
544 19732394 : w )
545 :
546 19732394 : if (icepack_warnings_aborted(subname)) return
547 :
548 : ! halt if solver failed
549 19732394 : if (icepack_warnings_aborted(subname)) return
550 :
551 : ! check if solution is consistent
552 : ! surface conductive heat flux should be less than
553 : ! incoming surface heat flux
554 19732394 : if (fcondtop - fsurfn < ferrmax) then
555 :
556 : ! solution is consistent - have solution so finish
557 19082042 : return
558 :
559 : else
560 :
561 : ! solution is inconsistent - resolve assuming other surface condition
562 : ! assume surface is cold
563 650352 : fcondtop1 = fcondtop
564 650352 : fsurfn1 = fsurfn
565 :
566 : ! reset the solution to initial values
567 650352 : Tsf = Tsf0
568 1300704 : zqsn = zqsn0
569 5202816 : zqin = zqin0
570 5202816 : zSin = zSin0
571 :
572 : ! solve the system for cold and snow
573 : call picard_solver(nilyr, nslyr, &
574 : .true., .true., &
575 0 : Tsf, zqsn, &
576 0 : zqin, zSin, &
577 0 : zTin, zTsn, &
578 0 : phi, dt, &
579 : hilyr, hslyr, &
580 0 : km, ks, &
581 0 : Iswabs, Sswabs, &
582 : Tbot, &
583 : fswint, fswsfc, &
584 : rhoa, flw, &
585 : potT, Qa, &
586 : shcoef, lhcoef, &
587 : fcondtop, fcondbot, &
588 : fadvheat, &
589 : flwoutn, fsensn, &
590 : flatn, fsurfn, &
591 : qpond, qocn, &
592 : Spond, sss, &
593 0 : q, dSdt, &
594 650352 : w )
595 650352 : if (icepack_warnings_aborted(subname)) return
596 :
597 : ! halt if solver failed
598 650352 : if (icepack_warnings_aborted(subname)) return
599 :
600 : ! check if solution is consistent - surface should be cold
601 650352 : if (Tsf < dTemp_errmax) then
602 :
603 : ! solution is consistent - have solution so finish
604 650352 : return
605 :
606 : else
607 :
608 : ! solution is inconsistent
609 : ! failed to find a solution so need to refine solutions until consistency found
610 0 : call two_stage_inconsistency(2, Tsf, c0, fcondtop1, fsurfn1)
611 0 : if (icepack_warnings_aborted(subname)) return
612 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
613 0 : call icepack_warnings_add(subname//" two_stage_solver_snow: two_stage_inconsistency: melting" )
614 0 : return
615 :
616 : endif ! surface temperature consistency
617 :
618 : endif ! surface flux consistency
619 :
620 : endif
621 :
622 : end subroutine two_stage_solver_snow
623 :
624 : !=======================================================================
625 :
626 77718593 : subroutine two_stage_solver_nosnow(nilyr, nslyr, &
627 : Tsf, Tsf0, &
628 77718593 : zqsn, &
629 155437186 : zqin, zqin0, &
630 155437186 : zSin, zSin0, &
631 77718593 : zTsn, &
632 77718593 : zTin, &
633 77718593 : phi, Tbot, &
634 77718593 : km, ks, &
635 77718593 : q, dSdt, &
636 : w, dt, &
637 : fswint, fswsfc, &
638 : rhoa, flw, &
639 : potT, Qa, &
640 : shcoef, lhcoef, &
641 77718593 : Iswabs, Sswabs, &
642 : qpond, qocn, &
643 : Spond, sss, &
644 : hilyr, hslyr, &
645 : fcondtop, fcondbot, &
646 : fadvheat, &
647 : flwoutn, fsensn, &
648 : flatn, fsurfn )
649 :
650 : ! solve the vertical temperature and salt change for case with no snow
651 : ! 1) determine what type of surface condition existed previously - cold or melting
652 : ! 2) solve the system assuming this condition persists
653 : ! 3) check the consistency of the surface condition of the solution
654 : ! 4) If the surface condition is inconsistent resolve for the other surface condition
655 : ! 5) If neither solution is consistent the resolve the inconsistency
656 :
657 : integer (kind=int_kind), intent(in) :: &
658 : nilyr , & ! number of ice layers
659 : nslyr ! number of snow layers
660 :
661 : real(kind=dbl_kind), intent(inout) :: &
662 : Tsf ! ice surface temperature (C)
663 :
664 : real(kind=dbl_kind), intent(out) :: &
665 : fcondtop , & ! downward cond flux at top surface (W m-2)
666 : fcondbot , & ! downward cond flux at bottom surface (W m-2)
667 : flwoutn , & ! upward LW at surface (W m-2)
668 : fsensn , & ! surface downward sensible heat (W m-2)
669 : flatn , & ! surface downward latent heat (W m-2)
670 : fsurfn , & ! net flux to top surface, excluding fcondtop
671 : fadvheat ! flow of heat to ocean due to advection (W m-2)
672 :
673 : real(kind=dbl_kind), intent(in) :: &
674 : Tsf0 ! ice surface temperature (C) at beginning of timestep
675 :
676 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
677 : zqsn , & ! snow layer enthalpy (J m-3)
678 : zTsn ! snow layer temperature (C)
679 :
680 : real(kind=dbl_kind), dimension(:), intent(in) :: &
681 : ks , & ! snow conductivity (W m-1 K-1)
682 : Sswabs ! SW radiation absorbed in snow layers (W m-2)
683 :
684 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
685 : zqin , & ! ice layer enthalpy (J m-3)
686 : zSin , & ! ice layer bulk salinity (ppt)
687 : zTin , & ! ice layer temperature (C)
688 : phi ! ice layer liquid fraction
689 :
690 : real(kind=dbl_kind), dimension(:), intent(in) :: &
691 : zqin0 , & ! ice layer enthalpy (J m-3) at beginning of timestep
692 : zSin0 , & ! ice layer bulk salinity (ppt) at beginning of timestep
693 : km , & ! ice conductivity (W m-1 K-1)
694 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
695 : dSdt ! gravity drainage desalination rate for slow mode (ppt s-1)
696 :
697 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
698 : q ! upward interface vertical Darcy flow (m s-1)
699 :
700 : real(kind=dbl_kind), intent(in) :: &
701 : dt , & ! time step (s)
702 : hilyr , & ! ice layer thickness (m)
703 : hslyr , & ! snow layer thickness (m)
704 : Tbot , & ! ice bottom surfce temperature (deg C)
705 : fswint , & ! SW absorbed in ice interior below surface (W m-2)
706 : fswsfc , & ! SW absorbed at ice/snow surface (W m-2)
707 : rhoa , & ! air density (kg/m^3)
708 : flw , & ! incoming longwave radiation (W/m^2)
709 : potT , & ! air potential temperature (K)
710 : Qa , & ! specific humidity (kg/kg)
711 : shcoef , & ! transfer coefficient for sensible heat
712 : lhcoef , & ! transfer coefficient for latent heat
713 : w , & ! vertical flushing Darcy velocity (m/s)
714 : qpond , & ! melt pond brine enthalpy (J m-3)
715 : qocn , & ! ocean brine enthalpy (J m-3)
716 : Spond , & ! melt pond salinity (ppt)
717 : sss ! sea surface salinity (PSU)
718 :
719 : real(kind=dbl_kind) :: &
720 2278843 : Tmlt , & ! upper ice layer melting temperature (C)
721 2278843 : fcondtop1 , & ! first stage downward cond flux at top surface (W m-2)
722 2278843 : fsurfn1 , & ! first stage net flux to top surface, excluding fcondtop
723 2278843 : Tsf1 ! first stage ice surface temperature (C)
724 :
725 : character(len=*),parameter :: subname='(two_stage_solver_nosnow)'
726 :
727 : ! initial surface melting temperature
728 77718593 : Tmlt = liquidus_temperature_mush(zSin0(1))
729 :
730 : ! determine if surface is initially cold or melting
731 77718593 : if (Tsf < Tmlt) then
732 :
733 : ! initially cold
734 :
735 : ! solve the system for cold and no snow
736 : call picard_solver(nilyr, nslyr, &
737 : .false., .true., &
738 0 : Tsf, zqsn, &
739 0 : zqin, zSin, &
740 0 : zTin, zTsn, &
741 0 : phi, dt, &
742 : hilyr, hslyr, &
743 0 : km, ks, &
744 0 : Iswabs, Sswabs, &
745 : Tbot, &
746 : fswint, fswsfc, &
747 : rhoa, flw, &
748 : potT, Qa, &
749 : shcoef, lhcoef, &
750 : fcondtop, fcondbot, &
751 : fadvheat, &
752 : flwoutn, fsensn, &
753 : flatn, fsurfn, &
754 : qpond, qocn, &
755 : Spond, sss, &
756 0 : q, dSdt, &
757 62331792 : w )
758 140050385 : if (icepack_warnings_aborted(subname)) return
759 :
760 : ! halt if solver failed
761 62331792 : if (icepack_warnings_aborted(subname)) return
762 :
763 : ! check if solution is consistent - surface should still be cold
764 62331792 : if (Tsf < Tmlt + dTemp_errmax) then
765 :
766 : ! solution is consistent - have solution so finish
767 41135217 : return
768 :
769 : else
770 : ! solution is inconsistent - surface is warmer than melting
771 : ! resolve assuming surface is melting
772 21196575 : Tsf1 = Tsf
773 :
774 : ! reset the solution to initial values
775 21196575 : Tsf = liquidus_temperature_mush(zSin0(1))
776 169572600 : zqin = zqin0
777 169572600 : zSin = zSin0
778 :
779 : ! solve the system for melt and no snow
780 : call picard_solver(nilyr, nslyr, &
781 : .false., .false., &
782 0 : Tsf, zqsn, &
783 0 : zqin, zSin, &
784 0 : zTin, zTsn, &
785 0 : phi, dt, &
786 : hilyr, hslyr, &
787 0 : km, ks, &
788 0 : Iswabs, Sswabs, &
789 : Tbot, &
790 : fswint, fswsfc, &
791 : rhoa, flw, &
792 : potT, Qa, &
793 : shcoef, lhcoef, &
794 : fcondtop, fcondbot, &
795 : fadvheat, &
796 : flwoutn, fsensn, &
797 : flatn, fsurfn, &
798 : qpond, qocn, &
799 : Spond, sss, &
800 0 : q, dSdt, &
801 21196575 : w )
802 21196575 : if (icepack_warnings_aborted(subname)) return
803 :
804 : ! halt if solver failed
805 21196575 : if (icepack_warnings_aborted(subname)) return
806 :
807 : ! check if solution is consistent
808 : ! surface conductive heat flux should be less than
809 : ! incoming surface heat flux
810 21196575 : if (fcondtop - fsurfn < ferrmax) then
811 :
812 : ! solution is consistent - have solution so finish
813 21196575 : return
814 :
815 : else
816 :
817 : ! solution is inconsistent
818 0 : call two_stage_inconsistency(3, Tsf1, Tmlt, fcondtop, fsurfn)
819 0 : if (icepack_warnings_aborted(subname)) return
820 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
821 0 : call icepack_warnings_add(subname//" two_stage_solver_nosnow: two_stage_inconsistency: cold" )
822 0 : return
823 :
824 : endif
825 :
826 : endif
827 :
828 : else
829 : ! initially melting
830 :
831 : ! solve the system for melt and no snow
832 15386801 : Tsf = Tmlt
833 :
834 : call picard_solver(nilyr, nslyr, &
835 : .false., .false., &
836 0 : Tsf, zqsn, &
837 0 : zqin, zSin, &
838 0 : zTin, zTsn, &
839 0 : phi, dt, &
840 : hilyr, hslyr, &
841 0 : km, ks, &
842 0 : Iswabs, Sswabs, &
843 : Tbot, &
844 : fswint, fswsfc, &
845 : rhoa, flw, &
846 : potT, Qa, &
847 : shcoef, lhcoef, &
848 : fcondtop, fcondbot, &
849 : fadvheat, &
850 : flwoutn, fsensn, &
851 : flatn, fsurfn, &
852 : qpond, qocn, &
853 : Spond, sss, &
854 0 : q, dSdt, &
855 15386801 : w )
856 15386801 : if (icepack_warnings_aborted(subname)) return
857 :
858 : ! halt if solver failed
859 15386801 : if (icepack_warnings_aborted(subname)) return
860 :
861 : ! check if solution is consistent
862 : ! surface conductive heat flux should be less than
863 : ! incoming surface heat flux
864 15386801 : if (fcondtop - fsurfn < ferrmax) then
865 :
866 : ! solution is consistent - have solution so finish
867 15223802 : return
868 :
869 : else
870 :
871 : ! solution is inconsistent - resolve assuming other surface condition
872 : ! assume surface is cold
873 162999 : fcondtop1 = fcondtop
874 162999 : fsurfn1 = fsurfn
875 :
876 : ! reset the solution to initial values
877 162999 : Tsf = Tsf0
878 1303992 : zqin = zqin0
879 1303992 : zSin = zSin0
880 :
881 : ! solve the system for cold and no snow
882 : call picard_solver(nilyr, nslyr, &
883 : .false., .true., &
884 0 : Tsf, zqsn, &
885 0 : zqin, zSin, &
886 0 : zTin, zTsn, &
887 0 : phi, dt, &
888 : hilyr, hslyr, &
889 0 : km, ks, &
890 0 : Iswabs, Sswabs, &
891 : Tbot, &
892 : fswint, fswsfc, &
893 : rhoa, flw, &
894 : potT, Qa, &
895 : shcoef, lhcoef, &
896 : fcondtop, fcondbot, &
897 : fadvheat, &
898 : flwoutn, fsensn, &
899 : flatn, fsurfn, &
900 : qpond, qocn, &
901 : Spond, sss, &
902 0 : q, dSdt, &
903 162999 : w )
904 162999 : if (icepack_warnings_aborted(subname)) return
905 :
906 : ! halt if solver failed
907 162999 : if (icepack_warnings_aborted(subname)) return
908 :
909 : ! check if solution is consistent - surface should be cold
910 162999 : if (Tsf < Tmlt + dTemp_errmax) then
911 :
912 : ! solution is consistent - have solution so finish
913 162999 : return
914 :
915 : else
916 :
917 : ! solution is inconsistent
918 0 : call two_stage_inconsistency(4, Tsf, Tmlt, fcondtop1, fsurfn1)
919 0 : if (icepack_warnings_aborted(subname)) return
920 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
921 0 : call icepack_warnings_add(subname//" two_stage_solver_nosnow: two_stage_inconsistency: melting" )
922 0 : return
923 :
924 : endif
925 :
926 : endif
927 :
928 : endif
929 :
930 : end subroutine two_stage_solver_nosnow
931 :
932 : !=======================================================================
933 :
934 0 : subroutine two_stage_inconsistency(type, Tsf, Tmlt, fcondtop, fsurfn)
935 :
936 : integer (kind=int_kind), intent(in) :: &
937 : type
938 :
939 : real(kind=dbl_kind), intent(in) :: &
940 : Tsf, &
941 : Tmlt, &
942 : fcondtop, &
943 : fsurfn
944 :
945 : character(len=*),parameter :: subname='(two_stage_inconsistency)'
946 :
947 0 : write(warnstr,*) subname, "icepack_therm_mushy: two stage inconsistency"
948 0 : call icepack_warnings_add(warnstr)
949 0 : write(warnstr,*) subname, "type:", type
950 0 : call icepack_warnings_add(warnstr)
951 :
952 0 : if (type == 1) then
953 :
954 0 : write(warnstr,*) subname, "First stage : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
955 0 : call icepack_warnings_add(warnstr)
956 0 : write(warnstr,*) subname, " :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
957 0 : call icepack_warnings_add(warnstr)
958 0 : write(warnstr,*) subname, "Second stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
959 0 : call icepack_warnings_add(warnstr)
960 0 : write(warnstr,*) subname, " :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
961 0 : call icepack_warnings_add(warnstr)
962 :
963 0 : else if (type == 2) then
964 :
965 0 : write(warnstr,*) subname, "First stage : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
966 0 : call icepack_warnings_add(warnstr)
967 0 : write(warnstr,*) subname, " :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
968 0 : call icepack_warnings_add(warnstr)
969 0 : write(warnstr,*) subname, "Second stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
970 0 : call icepack_warnings_add(warnstr)
971 0 : write(warnstr,*) subname, " :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
972 0 : call icepack_warnings_add(warnstr)
973 :
974 0 : else if (type == 3) then
975 :
976 0 : write(warnstr,*) subname, "First stage : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
977 0 : call icepack_warnings_add(warnstr)
978 0 : write(warnstr,*) subname, " :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
979 0 : call icepack_warnings_add(warnstr)
980 0 : write(warnstr,*) subname, "Second stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
981 0 : call icepack_warnings_add(warnstr)
982 0 : write(warnstr,*) subname, " :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
983 0 : call icepack_warnings_add(warnstr)
984 :
985 0 : else if (type == 4) then
986 :
987 0 : write(warnstr,*) subname, "First stage : fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax"
988 0 : call icepack_warnings_add(warnstr)
989 0 : write(warnstr,*) subname, " :", fcondtop, fsurfn, ferrmax, fcondtop - fsurfn - ferrmax
990 0 : call icepack_warnings_add(warnstr)
991 0 : write(warnstr,*) subname, "Second stage : Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax"
992 0 : call icepack_warnings_add(warnstr)
993 0 : write(warnstr,*) subname, " :", Tsf, Tmlt, dTemp_errmax, Tsf - Tmlt - dTemp_errmax
994 0 : call icepack_warnings_add(warnstr)
995 :
996 : endif
997 :
998 0 : end subroutine two_stage_inconsistency
999 :
1000 : !=======================================================================
1001 : ! Picard/TDMA based solver
1002 : !=======================================================================
1003 :
1004 665547373 : subroutine prep_picard(nilyr, nslyr, &
1005 665547373 : lsnow, zqsn, &
1006 665547373 : zqin, zSin, &
1007 : hilyr, hslyr, &
1008 665547373 : km, ks, &
1009 1331094746 : zTin, zTsn, &
1010 665547373 : Sbr, phi, &
1011 1331094746 : dxp, kcstar, &
1012 : einit)
1013 :
1014 : integer (kind=int_kind), intent(in) :: &
1015 : nilyr , & ! number of ice layers
1016 : nslyr ! number of snow layers
1017 :
1018 : logical, intent(in) :: &
1019 : lsnow ! snow presence: T: has snow, F: no snow
1020 :
1021 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1022 : zqin , & ! ice layer enthalpy (J m-3)
1023 : zSin , & ! ice layer bulk salinity (ppt)
1024 : km , & ! ice conductivity (W m-1 K-1)
1025 : zqsn , & ! snow layer enthalpy (J m-3)
1026 : ks ! snow conductivity (W m-1 K-1)
1027 :
1028 : real(kind=dbl_kind), intent(in) :: &
1029 : hilyr , & ! ice layer thickness (m)
1030 : hslyr ! snow layer thickness (m)
1031 :
1032 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1033 : zTin , & ! ice layer temperature (C)
1034 : Sbr , & ! ice layer brine salinity (ppt)
1035 : phi , & ! ice layer liquid fraction
1036 : zTsn , & ! snow layer temperature (C)
1037 : dxp , & ! distances between grid points (m)
1038 : kcstar ! interface conductivities (W m-1 K-1)
1039 :
1040 : real(kind=dbl_kind), intent(out) :: &
1041 : einit ! initial total energy (J)
1042 :
1043 : integer(kind=int_kind) :: k
1044 :
1045 : character(len=*),parameter :: subname='(prep_picard)'
1046 :
1047 : ! calculate initial ice temperatures
1048 5324378984 : do k = 1, nilyr
1049 4658831611 : zTin(k) = icepack_mushy_temperature_mush(zqin(k), zSin(k))
1050 4658831611 : Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
1051 5324378984 : phi(k) = icepack_mushy_liquid_fraction(zTin(k), zSin(k))
1052 : enddo ! k
1053 :
1054 665547373 : if (lsnow) then
1055 :
1056 1132938412 : do k = 1, nslyr
1057 1132938412 : zTsn(k) = temperature_snow(zqsn(k))
1058 : enddo ! k
1059 :
1060 : endif ! lsnow
1061 :
1062 : ! interface distances
1063 665547373 : call calc_intercell_thickness(nilyr, nslyr, lsnow, hilyr, hslyr, dxp)
1064 665547373 : if (icepack_warnings_aborted(subname)) return
1065 :
1066 : ! interface conductivities
1067 : call calc_intercell_conductivity(lsnow, nilyr, nslyr, &
1068 665547373 : km, ks, hilyr, hslyr, kcstar)
1069 665547373 : if (icepack_warnings_aborted(subname)) return
1070 :
1071 : ! total energy content
1072 : call total_energy_content(lsnow, &
1073 : nilyr, nslyr, &
1074 0 : zqin, zqsn, &
1075 : hilyr, hslyr, &
1076 665547373 : einit)
1077 665547373 : if (icepack_warnings_aborted(subname)) return
1078 :
1079 : end subroutine prep_picard
1080 :
1081 : !=======================================================================
1082 :
1083 665547373 : subroutine picard_solver(nilyr, nslyr, &
1084 : lsnow, lcold, &
1085 665547373 : Tsf, zqsn, &
1086 665547373 : zqin, zSin, &
1087 665547373 : zTin, zTsn, &
1088 665547373 : phi, dt, &
1089 : hilyr, hslyr, &
1090 665547373 : km, ks, &
1091 665547373 : Iswabs, Sswabs, &
1092 : Tbot, &
1093 : fswint, fswsfc, &
1094 : rhoa, flw, &
1095 : potT, Qa, &
1096 : shcoef, lhcoef, &
1097 : fcondtop, fcondbot, &
1098 : fadvheat, &
1099 : flwoutn, fsensn, &
1100 : flatn, fsurfn, &
1101 : qpond, qocn, &
1102 : Spond, sss, &
1103 1331094746 : q, dSdt, &
1104 : w )
1105 :
1106 : integer (kind=int_kind), intent(in) :: &
1107 : nilyr , & ! number of ice layers
1108 : nslyr ! number of snow layers
1109 :
1110 : logical, intent(in) :: &
1111 : lsnow , & ! snow presence: T: has snow, F: no snow
1112 : lcold ! surface cold: T: surface is cold, F: surface is melting
1113 :
1114 : real(kind=dbl_kind), intent(inout) :: &
1115 : Tsf ! snow surface temperature (C)
1116 :
1117 : real(kind=dbl_kind), intent(out) :: &
1118 : fcondtop , & ! downward cond flux at top surface (W m-2)
1119 : fcondbot , & ! downward cond flux at bottom surface (W m-2)
1120 : fadvheat ! flow of heat to ocean due to advection (W m-2)
1121 :
1122 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1123 : zqin , & ! ice layer enthalpy (J m-3)
1124 : zSin , & ! ice layer bulk salinity (ppt)
1125 : zTin , & ! ice layer temperature (C)
1126 : phi , & ! ice layer liquid fraction
1127 : zqsn , & ! snow layer enthalpy (J m-3)
1128 : zTsn ! snow layer temperature (C)
1129 :
1130 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1131 : km , & ! ice conductivity (W m-1 K-1)
1132 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
1133 : dSdt ! gravity drainage desalination rate for slow mode (ppt s-1)
1134 :
1135 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
1136 : q ! upward interface vertical Darcy flow (m s-1)
1137 :
1138 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1139 : ks , & ! snow conductivity (W m-1 K-1)
1140 : Sswabs ! SW radiation absorbed in snow layers (W m-2)
1141 :
1142 : real(kind=dbl_kind), intent(out) :: &
1143 : flwoutn , & ! upward LW at surface (W m-2)
1144 : fsensn , & ! surface downward sensible heat (W m-2)
1145 : flatn , & ! surface downward latent heat (W m-2)
1146 : fsurfn ! net flux to top surface, excluding fcondtop
1147 :
1148 : real(kind=dbl_kind), intent(in) :: &
1149 : dt , & ! time step (s)
1150 : hilyr , & ! ice layer thickness (m)
1151 : hslyr , & ! snow layer thickness (m)
1152 : Tbot , & ! ice bottom surfce temperature (deg C)
1153 : fswint , & ! SW absorbed in ice interior below surface (W m-2)
1154 : fswsfc , & ! SW absorbed at ice/snow surface (W m-2)
1155 : rhoa , & ! air density (kg/m^3)
1156 : flw , & ! incoming longwave radiation (W/m^2)
1157 : potT , & ! air potential temperature (K)
1158 : Qa , & ! specific humidity (kg/kg)
1159 : shcoef , & ! transfer coefficient for sensible heat
1160 : lhcoef , & ! transfer coefficient for latent heat
1161 : qpond , & ! melt pond brine enthalpy (J m-3)
1162 : qocn , & ! ocean brine enthalpy (J m-3)
1163 : Spond , & ! melt pond salinity (ppt)
1164 : sss , & ! sea surface salinity (ppt)
1165 : w ! vertical flushing Darcy velocity (m/s)
1166 :
1167 : real(kind=dbl_kind), dimension(nilyr) :: &
1168 1551935642 : Sbr , & ! ice layer brine salinity (ppt)
1169 1551935642 : qbr , & ! ice layer brine enthalpy (J m-3)
1170 1551935642 : zTin0 , & ! ice layer temperature (C) at start of timestep
1171 1551935642 : zqin0 , & ! ice layer enthalpy (J m-3) at start of timestep
1172 1551935642 : zSin0 , & ! ice layer bulk salinity (ppt) at start of timestep
1173 1551935642 : zTin_prev ! ice layer temperature at previous iteration
1174 :
1175 : real(kind=dbl_kind), dimension(nslyr) :: &
1176 1331094746 : zqsn0 , & ! snow layer enthalpy (J m-3) at start of timestep
1177 1331094746 : zTsn0 , & ! snow layer temperature (C) at start of timestep
1178 1331094746 : zTsn_prev ! snow layer temperature at previous iteration
1179 :
1180 : real(kind=dbl_kind), dimension(nslyr+nilyr+1) :: &
1181 1699162906 : dxp , & ! distances between grid points (m)
1182 1070422349 : kcstar ! interface conductivities (W m-1 K-1)
1183 :
1184 : real(kind=dbl_kind) :: &
1185 36806816 : Tsf0 , & ! snow surface temperature (C) at start of timestep
1186 36806816 : dfsurfn_dTsf , & ! derivative of net flux to top surface, excluding fcondtopn
1187 36806816 : dflwoutn_dTsf , & ! derivative of longwave flux wrt surface temperature
1188 36806816 : dfsensn_dTsf , & ! derivative of sensible heat flux wrt surface temperature
1189 36806816 : dflatn_dTsf , & ! derivative of latent heat flux wrt surface temperature
1190 36806816 : Tsf_prev , & ! snow surface temperature at previous iteration
1191 36806816 : einit , & ! initial total energy (J)
1192 36806816 : fadvheat_nit ! heat to ocean due to advection (W m-2) during iteration
1193 :
1194 : logical :: &
1195 : lconverged ! has Picard solver converged?
1196 :
1197 : integer :: &
1198 : nit ! Picard iteration count
1199 :
1200 : integer, parameter :: &
1201 : nit_max = 100 ! maximum number of Picard iterations
1202 :
1203 : character(len=*),parameter :: subname='(picard_solver)'
1204 :
1205 665547373 : lconverged = .false.
1206 :
1207 : ! prepare quantities for picard iteration
1208 : call prep_picard(nilyr, nslyr, &
1209 0 : lsnow, zqsn, &
1210 0 : zqin, zSin, &
1211 : hilyr, hslyr, &
1212 0 : km, ks, &
1213 0 : zTin, zTsn, &
1214 0 : Sbr, phi, &
1215 0 : dxp, kcstar, &
1216 665547373 : einit)
1217 665547373 : if (icepack_warnings_aborted(subname)) return
1218 :
1219 665547373 : Tsf0 = Tsf
1220 5324378984 : zqin0 = zqin
1221 1331094746 : zqsn0 = zqsn
1222 5324378984 : zTin0 = zTin
1223 1331094746 : zTsn0 = zTsn
1224 5324378984 : zSin0 = zSin
1225 :
1226 : ! set prev variables
1227 665547373 : Tsf_prev = Tsf
1228 1331094746 : zTsn_prev = zTsn
1229 5324378984 : zTin_prev = zTin
1230 :
1231 : ! picard iteration
1232 1490253356 : picard: do nit = 1, nit_max
1233 :
1234 : ! surface heat flux
1235 : call surface_heat_flux(Tsf, fswsfc, &
1236 : rhoa, flw, &
1237 : potT, Qa, &
1238 : shcoef, lhcoef, &
1239 : flwoutn, fsensn, &
1240 1490253356 : flatn, fsurfn)
1241 1490253356 : if (icepack_warnings_aborted(subname)) return
1242 :
1243 : ! derivative of heat flux with respect to surface temperature
1244 : call dsurface_heat_flux_dTsf(Tsf, rhoa, &
1245 : shcoef, lhcoef, &
1246 : dfsurfn_dTsf, dflwoutn_dTsf, &
1247 1490253356 : dfsensn_dTsf, dflatn_dTsf)
1248 1490253356 : if (icepack_warnings_aborted(subname)) return
1249 :
1250 : ! tridiagonal solve of new temperatures
1251 : call solve_heat_conduction(lsnow, lcold, &
1252 : nilyr, nslyr, &
1253 : Tsf, Tbot, &
1254 0 : zqin0, zqsn0, &
1255 0 : phi, dt, &
1256 : qpond, qocn, &
1257 : q, w, &
1258 : hilyr, hslyr, &
1259 0 : dxp, kcstar, &
1260 0 : Iswabs, Sswabs, &
1261 : fsurfn, dfsurfn_dTsf, &
1262 1490253356 : zTin, zTsn)
1263 1490253356 : if (icepack_warnings_aborted(subname)) return
1264 :
1265 : ! update brine enthalpy
1266 1490253356 : call picard_updates_enthalpy(nilyr, zTin, qbr)
1267 1490253356 : if (icepack_warnings_aborted(subname)) return
1268 :
1269 : ! drainage fluxes
1270 : call picard_drainage_fluxes(fadvheat_nit, q, &
1271 0 : qbr, qocn, &
1272 1490253356 : nilyr)
1273 1490253356 : if (icepack_warnings_aborted(subname)) return
1274 :
1275 : ! flushing fluxes
1276 : call picard_flushing_fluxes(nilyr, &
1277 : fadvheat_nit, w, &
1278 0 : qbr, &
1279 1490253356 : qpond)
1280 1490253356 : if (icepack_warnings_aborted(subname)) return
1281 :
1282 : ! perform convergence check
1283 : call check_picard_convergence(nilyr, nslyr, &
1284 : lsnow, &
1285 : lconverged, &
1286 : Tsf, Tsf_prev, &
1287 0 : zTin, zTin_prev,&
1288 0 : zTsn, zTsn_prev,&
1289 0 : phi, Tbot, &
1290 0 : zqin, zqsn, &
1291 0 : km, ks, &
1292 : hilyr, hslyr, &
1293 : fswint, &
1294 : einit, dt, &
1295 : fcondtop, fcondbot, &
1296 1490253356 : fadvheat_nit)
1297 1490253356 : if (icepack_warnings_aborted(subname)) return
1298 :
1299 1490253356 : if (lconverged) exit
1300 :
1301 824705983 : Tsf_prev = Tsf
1302 1649411966 : zTsn_prev = zTsn
1303 7263195237 : zTin_prev = zTin
1304 :
1305 : enddo picard
1306 :
1307 665547373 : fadvheat = fadvheat_nit
1308 :
1309 : ! update the picard iterants
1310 0 : call picard_updates(nilyr, zTin, &
1311 665547373 : Sbr, qbr)
1312 665547373 : if (icepack_warnings_aborted(subname)) return
1313 :
1314 : ! solve for the salinity
1315 0 : call solve_salinity(zSin, Sbr, &
1316 : Spond, sss, &
1317 0 : q, dSdt, &
1318 : w, hilyr, &
1319 665547373 : dt, nilyr)
1320 665547373 : if (icepack_warnings_aborted(subname)) return
1321 :
1322 : ! final surface heat flux
1323 : call surface_heat_flux(Tsf, fswsfc, &
1324 : rhoa, flw, &
1325 : potT, Qa, &
1326 : shcoef, lhcoef, &
1327 : flwoutn, fsensn, &
1328 665547373 : flatn, fsurfn)
1329 665547373 : if (icepack_warnings_aborted(subname)) return
1330 :
1331 : ! if not converged
1332 665547373 : if (.not. lconverged) then
1333 :
1334 : call picard_nonconvergence(nilyr, nslyr,&
1335 : Tsf0, Tsf, &
1336 0 : zTsn0, zTsn, &
1337 0 : zTin0, zTin, &
1338 0 : zSin0, zSin, &
1339 0 : zqsn0, zqsn, &
1340 0 : zqin0, zqin, &
1341 0 : phi)
1342 0 : if (icepack_warnings_aborted(subname)) return
1343 0 : call icepack_warnings_add(subname//" picard_solver: Picard solver non-convergence" )
1344 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1345 0 : if (icepack_warnings_aborted(subname)) return
1346 :
1347 : endif
1348 :
1349 : end subroutine picard_solver
1350 :
1351 : !=======================================================================
1352 :
1353 0 : subroutine picard_nonconvergence(nilyr, nslyr,&
1354 : Tsf0, Tsf, &
1355 0 : zTsn0, zTsn, &
1356 0 : zTin0, zTin, &
1357 0 : zSin0, zSin, &
1358 0 : zqsn0, zqsn, &
1359 0 : zqin0, zqin, phi)
1360 :
1361 : integer (kind=int_kind), intent(in) :: &
1362 : nilyr , & ! number of ice layers
1363 : nslyr ! number of snow layers
1364 :
1365 : real(kind=dbl_kind), intent(in) :: &
1366 : Tsf0 , & ! snow surface temperature (C) at beginning of timestep
1367 : Tsf ! snow surface temperature (C)
1368 :
1369 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1370 : zTsn0 , & ! snow layer temperature (C) at beginning of timestep
1371 : zTsn , & ! snow layer temperature (C)
1372 : zqsn0 , &
1373 : zqsn , &
1374 : zTin0 , & ! ice layer temperature (C)
1375 : zTin , & ! ice layer temperature (C)
1376 : zSin0 , & ! ice layer bulk salinity (ppt)
1377 : zSin , & ! ice layer bulk salinity (ppt)
1378 : zqin0 , &
1379 : zqin , &
1380 : phi ! ice layer liquid fraction
1381 :
1382 : integer :: &
1383 : k ! vertical layer index
1384 :
1385 : character(len=*),parameter :: subname='(picard_nonconvergence)'
1386 :
1387 0 : write(warnstr,*) subname, "-------------------------------------"
1388 0 : call icepack_warnings_add(warnstr)
1389 :
1390 0 : write(warnstr,*) subname, "picard convergence failed!"
1391 0 : call icepack_warnings_add(warnstr)
1392 0 : write(warnstr,*) subname, 0, Tsf0, Tsf
1393 0 : call icepack_warnings_add(warnstr)
1394 :
1395 0 : do k = 1, nslyr
1396 0 : write(warnstr,*) subname, k, zTsn0(k), zTsn(k), zqsn(k), zqsn0(k)
1397 0 : call icepack_warnings_add(warnstr)
1398 : enddo ! k
1399 :
1400 0 : do k = 1, nilyr
1401 0 : write(warnstr,*) subname, k, zTin0(k), zTin(k), zSin0(k), zSin(k), phi(k), zqin(k), zqin0(k)
1402 0 : call icepack_warnings_add(warnstr)
1403 : enddo ! k
1404 :
1405 0 : write(warnstr,*) subname, "-------------------------------------"
1406 0 : call icepack_warnings_add(warnstr)
1407 :
1408 0 : end subroutine picard_nonconvergence
1409 :
1410 : !=======================================================================
1411 :
1412 1490253356 : subroutine check_picard_convergence(nilyr, nslyr, &
1413 : lsnow, &
1414 : lconverged, &
1415 : Tsf, Tsf_prev, &
1416 2980506712 : zTin, zTin_prev,&
1417 2980506712 : zTsn, zTsn_prev,&
1418 1490253356 : phi, Tbot, &
1419 1490253356 : zqin, zqsn, &
1420 1490253356 : km, ks, &
1421 : hilyr, hslyr, &
1422 : fswint, &
1423 : einit, dt, &
1424 : fcondtop, fcondbot, &
1425 : fadvheat)
1426 :
1427 : integer (kind=int_kind), intent(in) :: &
1428 : nilyr , & ! number of ice layers
1429 : nslyr ! number of snow layers
1430 :
1431 : logical, intent(inout) :: &
1432 : lconverged ! has Picard solver converged?
1433 :
1434 : logical, intent(in) :: &
1435 : lsnow ! snow presence: T: has snow, F: no snow
1436 :
1437 : real(kind=dbl_kind), intent(in) :: &
1438 : dt , & ! time step (s)
1439 : Tsf , & ! snow surface temperature (C)
1440 : Tsf_prev , & ! snow surface temperature at previous iteration
1441 : hilyr , & ! ice layer thickness (m)
1442 : hslyr , & ! snow layer thickness (m)
1443 : fswint , & ! SW absorbed in ice interior below surface (W m-2)
1444 : einit , & ! initial total energy (J)
1445 : Tbot , & ! ice bottom surfce temperature (deg C)
1446 : fadvheat ! flow of heat to ocean due to advection (W m-2)
1447 :
1448 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1449 : zTin , & ! ice layer temperature (C)
1450 : zTin_prev, & ! ice layer temperature at previous iteration
1451 : phi , & ! ice layer liquid fraction
1452 : km ! ice conductivity (W m-1 K-1)
1453 :
1454 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1455 : zqin ! ice layer enthalpy (J m-3)
1456 :
1457 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1458 : zTsn , & ! snow layer temperature (C)
1459 : zTsn_prev, & ! snow layer temperature at previous iteration
1460 : ks ! snow conductivity (W m-1 K-1)
1461 :
1462 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1463 : zqsn ! snow layer enthalpy (J m-3)
1464 :
1465 : real(kind=dbl_kind), intent(out) :: &
1466 : fcondtop , & ! downward cond flux at top surface (W m-2)
1467 : fcondbot ! downward cond flux at bottom surface (W m-2)
1468 :
1469 : real(kind=dbl_kind) :: &
1470 82004691 : ferr , & ! energy flux error
1471 82004691 : efinal , & ! initial total energy (J) at iteration
1472 82004691 : dzTsn , & ! change in snow temperature (C) between iterations
1473 82004691 : dzTin , & ! change in ice temperature (C) between iterations
1474 82004691 : dTsf ! change in surface temperature (C) between iterations
1475 :
1476 : character(len=*),parameter :: subname='(check_picard_convergence)'
1477 :
1478 : call picard_final(lsnow, &
1479 : nilyr, nslyr, &
1480 0 : zqin, zqsn, &
1481 0 : zTin, zTsn, &
1482 1490253356 : phi)
1483 1490253356 : if (icepack_warnings_aborted(subname)) return
1484 :
1485 : call total_energy_content(lsnow, &
1486 : nilyr, nslyr, &
1487 0 : zqin, zqsn, &
1488 : hilyr, hslyr, &
1489 1490253356 : efinal)
1490 1490253356 : if (icepack_warnings_aborted(subname)) return
1491 :
1492 : call maximum_variables_changes(lsnow, &
1493 : Tsf, Tsf_prev, dTsf, &
1494 0 : zTsn, zTsn_prev, dzTsn, &
1495 1490253356 : zTin, zTin_prev, dzTin)
1496 1490253356 : if (icepack_warnings_aborted(subname)) return
1497 :
1498 1490253356 : fcondbot = c2 * km(nilyr) * ((zTin(nilyr) - Tbot) / hilyr)
1499 :
1500 1490253356 : if (lsnow) then
1501 1267640144 : fcondtop = c2 * ks(1) * ((Tsf - zTsn(1)) / hslyr)
1502 : else
1503 222613212 : fcondtop = c2 * km(1) * ((Tsf - zTin(1)) / hilyr)
1504 : endif
1505 :
1506 1490253356 : ferr = (efinal - einit) / dt - (fcondtop - fcondbot + fswint - fadvheat)
1507 :
1508 : lconverged = (dTsf < dTemp_errmax .and. &
1509 : dzTsn < dTemp_errmax .and. &
1510 : dzTin < dTemp_errmax .and. &
1511 1490253356 : abs(ferr) < 0.9_dbl_kind*ferrmax)
1512 :
1513 : end subroutine check_picard_convergence
1514 :
1515 : !=======================================================================
1516 :
1517 1490253356 : subroutine picard_drainage_fluxes(fadvheat, q, &
1518 1490253356 : qbr, qocn, &
1519 : nilyr)
1520 :
1521 : integer (kind=int_kind), intent(in) :: &
1522 : nilyr ! number of ice layers
1523 :
1524 : real(kind=dbl_kind), intent(out) :: &
1525 : fadvheat ! flow of heat to ocean due to advection (W m-2)
1526 :
1527 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
1528 : q ! upward interface vertical Darcy flow (m s-1)
1529 :
1530 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1531 : qbr ! ice layer brine enthalpy (J m-3)
1532 :
1533 : real(kind=dbl_kind), intent(in) :: &
1534 : qocn ! ocean brine enthalpy (J m-3)
1535 :
1536 : integer :: &
1537 : k ! vertical layer index
1538 :
1539 : character(len=*),parameter :: subname='(picard_drainage_fluxes)'
1540 :
1541 1490253356 : fadvheat = c0
1542 :
1543 : ! calculate fluxes from base upwards
1544 10431773492 : do k = 1, nilyr-1
1545 :
1546 10431773492 : fadvheat = fadvheat - q(k) * (qbr(k+1) - qbr(k))
1547 :
1548 : enddo ! k
1549 :
1550 1490253356 : k = nilyr
1551 :
1552 1490253356 : fadvheat = fadvheat - q(k) * (qocn - qbr(k))
1553 :
1554 1490253356 : end subroutine picard_drainage_fluxes
1555 :
1556 : !=======================================================================
1557 :
1558 1490253356 : subroutine picard_flushing_fluxes(nilyr, &
1559 : fadvheat, w, &
1560 1490253356 : qbr, &
1561 : qpond)
1562 :
1563 : integer (kind=int_kind), intent(in) :: &
1564 : nilyr ! number of ice layers
1565 :
1566 : real(kind=dbl_kind), intent(inout) :: &
1567 : fadvheat ! flow of heat to ocean due to advection (W m-2)
1568 :
1569 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1570 : qbr ! ice layer brine enthalpy (J m-3)
1571 :
1572 : real(kind=dbl_kind), intent(in) :: &
1573 : w , & ! vertical flushing Darcy velocity (m/s)
1574 : qpond ! melt pond brine enthalpy (J m-3)
1575 :
1576 : character(len=*),parameter :: subname='(picard_flushing_fluxes)'
1577 :
1578 1490253356 : fadvheat = fadvheat + w * (qbr(nilyr) - qpond)
1579 :
1580 1490253356 : end subroutine picard_flushing_fluxes
1581 :
1582 : !=======================================================================
1583 :
1584 1490253356 : subroutine maximum_variables_changes(lsnow, &
1585 : Tsf, Tsf_prev, dTsf, &
1586 1490253356 : zTsn, zTsn_prev, dzTsn, &
1587 1490253356 : zTin, zTin_prev, dzTin)
1588 :
1589 : logical, intent(in) :: &
1590 : lsnow ! snow presence: T: has snow, F: no snow
1591 :
1592 : real(kind=dbl_kind), intent(in) :: &
1593 : Tsf , & ! snow surface temperature (C)
1594 : Tsf_prev ! snow surface temperature at previous iteration
1595 :
1596 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1597 : zTsn , & ! snow layer temperature (C)
1598 : zTsn_prev, & ! snow layer temperature at previous iteration
1599 : zTin , & ! ice layer temperature (C)
1600 : zTin_prev ! ice layer temperature at previous iteration
1601 :
1602 : real(kind=dbl_kind), intent(out) :: &
1603 : dTsf , & ! change in surface temperature (C) between iterations
1604 : dzTsn , & ! change in snow temperature (C) between iterations
1605 : dzTin ! change in surface temperature (C) between iterations
1606 :
1607 : character(len=*),parameter :: subname='(maximum_variables_changes)'
1608 :
1609 1490253356 : dTsf = abs(Tsf - Tsf_prev)
1610 :
1611 1490253356 : if (lsnow) then
1612 2535280288 : dzTsn = maxval(abs(zTsn - zTsn_prev))
1613 : else ! lsnow
1614 222613212 : dzTsn = c0
1615 : endif ! lsnow
1616 :
1617 11922026848 : dzTin = maxval(abs(zTin - zTin_prev))
1618 :
1619 1490253356 : end subroutine maximum_variables_changes
1620 :
1621 : !=======================================================================
1622 :
1623 2155800729 : subroutine total_energy_content(lsnow, &
1624 : nilyr, nslyr, &
1625 2155800729 : zqin, zqsn, &
1626 : hilyr, hslyr, &
1627 : energy)
1628 :
1629 : logical, intent(in) :: &
1630 : lsnow ! snow presence: T: has snow, F: no snow
1631 :
1632 : integer (kind=int_kind), intent(in) :: &
1633 : nilyr , & ! number of ice layers
1634 : nslyr ! number of snow layers
1635 :
1636 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1637 : zqin , & ! ice layer enthalpy (J m-3)
1638 : zqsn ! snow layer enthalpy (J m-3)
1639 :
1640 : real(kind=dbl_kind), intent(in) :: &
1641 : hilyr , & ! ice layer thickness (m)
1642 : hslyr ! snow layer thickness (m)
1643 :
1644 : real(kind=dbl_kind), intent(out) :: &
1645 : energy ! total energy of ice and snow
1646 :
1647 : integer :: &
1648 : k ! vertical layer index
1649 :
1650 : character(len=*),parameter :: subname='(total_energy_content)'
1651 :
1652 2155800729 : energy = c0
1653 :
1654 2155800729 : if (lsnow) then
1655 :
1656 3668218700 : do k = 1, nslyr
1657 :
1658 3668218700 : energy = energy + hslyr * zqsn(k)
1659 :
1660 : enddo ! k
1661 :
1662 : endif ! lsnow
1663 :
1664 17246405832 : do k = 1, nilyr
1665 :
1666 17246405832 : energy = energy + hilyr * zqin(k)
1667 :
1668 : enddo ! k
1669 :
1670 2155800729 : end subroutine total_energy_content
1671 :
1672 : !=======================================================================
1673 :
1674 665547373 : subroutine picard_updates(nilyr, zTin, &
1675 1331094746 : Sbr, qbr)
1676 :
1677 : ! update brine salinity and liquid fraction based on new temperatures
1678 :
1679 : integer (kind=int_kind), intent(in) :: &
1680 : nilyr ! number of ice layers
1681 :
1682 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1683 : zTin ! ice layer temperature (C)
1684 :
1685 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1686 : Sbr , & ! ice layer brine salinity (ppt)
1687 : qbr ! ice layer brine enthalpy (J m-3)
1688 :
1689 : integer :: &
1690 : k ! vertical layer index
1691 :
1692 : character(len=*),parameter :: subname='(picard_updates)'
1693 :
1694 5324378984 : do k = 1, nilyr
1695 :
1696 4658831611 : Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
1697 5324378984 : qbr(k) = enthalpy_brine(zTin(k))
1698 :
1699 : enddo ! k
1700 :
1701 665547373 : end subroutine picard_updates
1702 :
1703 : !=======================================================================
1704 :
1705 1490253356 : subroutine picard_updates_enthalpy(nilyr, zTin, qbr)
1706 :
1707 : ! update brine salinity and liquid fraction based on new temperatures
1708 :
1709 : integer (kind=int_kind), intent(in) :: &
1710 : nilyr ! number of ice layers
1711 :
1712 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1713 : zTin ! ice layer temperature (C)
1714 :
1715 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1716 : qbr ! ice layer brine enthalpy (J m-3)
1717 :
1718 : integer :: &
1719 : k ! vertical layer index
1720 :
1721 : character(len=*),parameter :: subname='(picard_updates_enthalpy)'
1722 :
1723 11922026848 : do k = 1, nilyr
1724 :
1725 11922026848 : qbr(k) = enthalpy_brine(zTin(k))
1726 :
1727 : enddo ! k
1728 :
1729 1490253356 : end subroutine picard_updates_enthalpy
1730 :
1731 : !=======================================================================
1732 :
1733 1490253356 : subroutine picard_final(lsnow, &
1734 : nilyr, nslyr, &
1735 2980506712 : zqin, zqsn, &
1736 2980506712 : zTin, zTsn, &
1737 1490253356 : phi)
1738 :
1739 : integer (kind=int_kind), intent(in) :: &
1740 : nilyr, & ! number of ice layers
1741 : nslyr ! number of snow layers
1742 :
1743 : logical, intent(in) :: &
1744 : lsnow ! snow presence: T: has snow, F: no snow
1745 :
1746 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1747 : zqin, & ! ice layer enthalpy (J m-3)
1748 : zqsn ! snow layer enthalpy (J m-3)
1749 :
1750 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1751 : zTin, & ! ice layer temperature (C)
1752 : phi , & ! ice layer liquid fraction
1753 : zTsn ! snow layer temperature (C)
1754 :
1755 : integer :: &
1756 : k ! vertical layer index
1757 :
1758 : character(len=*),parameter :: subname='(picard_final)'
1759 :
1760 11922026848 : do k = 1, nilyr
1761 11922026848 : zqin(k) = enthalpy_mush_liquid_fraction(zTin(k), phi(k))
1762 : enddo ! k
1763 :
1764 1490253356 : if (lsnow) then
1765 :
1766 2535280288 : do k = 1, nslyr
1767 2535280288 : zqsn(k) = enthalpy_snow(zTsn(k))
1768 : enddo ! k
1769 :
1770 : endif ! lsnow
1771 :
1772 1490253356 : end subroutine picard_final
1773 :
1774 : !=======================================================================
1775 :
1776 665547373 : subroutine calc_intercell_thickness(nilyr, nslyr, lsnow, hilyr, hslyr, dxp)
1777 :
1778 : integer (kind=int_kind), intent(in) :: &
1779 : nilyr, & ! number of ice layers
1780 : nslyr ! number of snow layers
1781 :
1782 : logical, intent(in) :: &
1783 : lsnow ! snow presence: T: has snow, F: no snow
1784 :
1785 : real(kind=dbl_kind), intent(in) :: &
1786 : hilyr , & ! ice layer thickness (m)
1787 : hslyr ! snow layer thickness (m)
1788 :
1789 : real(kind=dbl_kind), dimension(:), intent(out) :: &
1790 : dxp ! distances between grid points (m)
1791 :
1792 : integer :: &
1793 : l ! vertical index
1794 :
1795 : character(len=*),parameter :: subname='(calc_intercell_thickness)'
1796 :
1797 665547373 : if (lsnow) then
1798 :
1799 566469206 : dxp(1) = hslyr / c2
1800 :
1801 566469206 : do l = 2, nslyr
1802 :
1803 566469206 : dxp(l) = hslyr
1804 :
1805 : enddo ! l
1806 :
1807 566469206 : dxp(nslyr+1) = (hilyr + hslyr) / c2
1808 :
1809 3965284442 : do l = nslyr+2, nilyr+nslyr
1810 :
1811 3965284442 : dxp(l) = hilyr
1812 :
1813 : enddo ! l
1814 :
1815 566469206 : dxp(nilyr+nslyr+1) = hilyr / c2
1816 :
1817 : else ! lsnow
1818 :
1819 99078167 : dxp(1) = hilyr / c2
1820 :
1821 693547169 : do l = 2, nilyr
1822 :
1823 693547169 : dxp(l) = hilyr
1824 :
1825 : enddo ! l
1826 :
1827 99078167 : dxp(nilyr+1) = hilyr / c2
1828 :
1829 198156334 : do l = nilyr+2, nilyr+nslyr+1
1830 :
1831 198156334 : dxp(l) = c0
1832 :
1833 : enddo ! l
1834 :
1835 : endif ! lsnow
1836 :
1837 665547373 : end subroutine calc_intercell_thickness
1838 :
1839 : !=======================================================================
1840 :
1841 665547373 : subroutine calc_intercell_conductivity(lsnow, &
1842 : nilyr, nslyr, &
1843 665547373 : km, ks, &
1844 : hilyr, hslyr, &
1845 665547373 : kcstar)
1846 :
1847 : integer (kind=int_kind), intent(in) :: &
1848 : nilyr, & ! number of ice layers
1849 : nslyr ! number of snow layers
1850 :
1851 : logical, intent(in) :: &
1852 : lsnow ! snow presence: T: has snow, F: no snow
1853 :
1854 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1855 : km , & ! ice conductivity (W m-1 K-1)
1856 : ks ! snow conductivity (W m-1 K-1)
1857 :
1858 : real(kind=dbl_kind), intent(in) :: &
1859 : hilyr , & ! ice layer thickness (m)
1860 : hslyr ! snow layer thickness (m)
1861 :
1862 : real(kind=dbl_kind), dimension(:), intent(out) :: &
1863 : kcstar ! interface conductivities (W m-1 K-1)
1864 :
1865 : real(kind=dbl_kind) :: &
1866 36806816 : fe ! distance fraction at interface
1867 :
1868 : integer :: &
1869 : k, & ! vertical layer index
1870 : l ! vertical index
1871 :
1872 : character(len=*),parameter :: subname='(calc_intercell_conductivity)'
1873 :
1874 665547373 : if (lsnow) then
1875 :
1876 566469206 : kcstar(1) = ks(1)
1877 :
1878 566469206 : do l = 2, nslyr
1879 :
1880 0 : k = l
1881 566469206 : kcstar(l) = (c2 * ks(k) * ks(k-1)) / (ks(k) + ks(k-1))
1882 :
1883 : enddo ! l
1884 :
1885 566469206 : fe = hilyr / (hilyr + hslyr)
1886 566469206 : kcstar(nslyr+1) = c1 / ((c1 - fe) / ks(nslyr) + fe / km(1))
1887 :
1888 3965284442 : do k = 2, nilyr
1889 :
1890 3398815236 : l = k + nslyr
1891 3965284442 : kcstar(l) = (c2 * km(k) * km(k-1)) / (km(k) + km(k-1))
1892 :
1893 : enddo ! k
1894 :
1895 566469206 : kcstar(nilyr+nslyr+1) = km(nilyr)
1896 :
1897 : else ! lsnow
1898 :
1899 99078167 : kcstar(1) = km(1)
1900 :
1901 693547169 : do k = 2, nilyr
1902 :
1903 594469002 : l = k
1904 693547169 : kcstar(l) = (c2 * km(k) * km(k-1)) / (km(k) + km(k-1))
1905 :
1906 : enddo ! k
1907 :
1908 99078167 : kcstar(nilyr+1) = km(nilyr)
1909 :
1910 198156334 : do l = nilyr+2, nilyr+nslyr+1
1911 :
1912 198156334 : kcstar(l) = c0
1913 :
1914 : enddo ! l
1915 :
1916 : endif ! lsnow
1917 :
1918 665547373 : end subroutine calc_intercell_conductivity
1919 :
1920 : !=======================================================================
1921 :
1922 1490253356 : subroutine solve_heat_conduction(lsnow, lcold, &
1923 : nilyr, nslyr, &
1924 : Tsf, Tbot, &
1925 1490253356 : zqin0, zqsn0, &
1926 1490253356 : phi, dt, &
1927 : qpond, qocn, &
1928 1490253356 : q, w, &
1929 : hilyr, hslyr, &
1930 1490253356 : dxp, kcstar, &
1931 1490253356 : Iswabs, Sswabs, &
1932 : fsurfn, dfsurfn_dTsf, &
1933 1490253356 : zTin, zTsn)
1934 :
1935 : logical, intent(in) :: &
1936 : lsnow , & ! snow presence: T: has snow, F: no snow
1937 : lcold ! surface cold: T: surface is cold, F: surface is melting
1938 :
1939 : integer (kind=int_kind), intent(in) :: &
1940 : nilyr, & ! number of ice layers
1941 : nslyr ! number of snow layers
1942 :
1943 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1944 : zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep
1945 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
1946 : phi , & ! ice layer liquid fraction
1947 : zqsn0 , & ! snow layer enthalpy (J m-3) at start of timestep
1948 : Sswabs ! SW radiation absorbed in snow layers (W m-2)
1949 :
1950 : real(kind=dbl_kind), intent(inout) :: &
1951 : Tsf ! snow surface temperature (C)
1952 :
1953 : real(kind=dbl_kind), intent(in) :: &
1954 : dt , & ! timestep (s)
1955 : hilyr , & ! ice layer thickness (m)
1956 : hslyr , & ! snow layer thickness (m)
1957 : Tbot , & ! ice bottom surfce temperature (deg C)
1958 : qpond , & ! melt pond brine enthalpy (J m-3)
1959 : qocn , & ! ocean brine enthalpy (J m-3)
1960 : w , & ! vertical flushing Darcy velocity (m/s)
1961 : fsurfn , & ! net flux to top surface, excluding fcondtop
1962 : dfsurfn_dTsf ! derivative of net flux to top surface, excluding fcondtopn
1963 :
1964 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
1965 : q ! upward interface vertical Darcy flow (m s-1)
1966 :
1967 : real(kind=dbl_kind), dimension(:), intent(in) :: &
1968 : dxp , & ! distances between grid points (m)
1969 : kcstar ! interface conductivities (W m-1 K-1)
1970 :
1971 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1972 : zTin ! ice layer temperature (C)
1973 :
1974 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
1975 : zTsn ! snow layer temperature (C)
1976 :
1977 : real(kind=dbl_kind), dimension(nilyr+nslyr+1) :: &
1978 3636544240 : Ap , & ! diagonal of tridiagonal matrix
1979 3636544240 : As , & ! lower off-diagonal of tridiagonal matrix
1980 3800553622 : An , & ! upper off-diagonal of tridiagonal matrix
1981 3636544240 : b , & ! right hand side of matrix solve
1982 2310300266 : T ! ice and snow temperatures
1983 :
1984 : integer :: &
1985 : nyn ! matrix size
1986 :
1987 : character(len=*),parameter :: subname='(solve_heat_conduction)'
1988 :
1989 : ! set up matrix and right hand side - snow
1990 1490253356 : if (lsnow) then
1991 :
1992 1267640144 : if (lcold) then
1993 :
1994 0 : call matrix_elements_snow_cold(Ap, As, An, b, nyn, &
1995 : nilyr, nslyr, &
1996 : Tsf, Tbot, &
1997 0 : zqin0, zqsn0, &
1998 : qpond, qocn, &
1999 0 : phi, q, &
2000 : w, &
2001 : hilyr, hslyr, &
2002 0 : dxp, kcstar, &
2003 0 : Iswabs, Sswabs, &
2004 : fsurfn, dfsurfn_dTsf, &
2005 1159736259 : dt)
2006 1159736259 : if (icepack_warnings_aborted(subname)) return
2007 :
2008 : else ! lcold
2009 :
2010 0 : call matrix_elements_snow_melt(Ap, As, An, b, nyn, &
2011 : nilyr, nslyr, &
2012 : Tsf, Tbot, &
2013 0 : zqin0, zqsn0, &
2014 : qpond, qocn, &
2015 0 : phi, q, &
2016 : w, &
2017 : hilyr, hslyr, &
2018 0 : dxp, kcstar, &
2019 0 : Iswabs, Sswabs, &
2020 107903885 : dt)
2021 107903885 : if (icepack_warnings_aborted(subname)) return
2022 :
2023 : endif ! lcold
2024 :
2025 : else ! lsnow
2026 :
2027 222613212 : if (lcold) then
2028 :
2029 0 : call matrix_elements_nosnow_cold(Ap, As, An, b, nyn, &
2030 : nilyr, &
2031 : Tsf, Tbot, &
2032 0 : zqin0, &
2033 : qpond, qocn, &
2034 0 : phi, q, &
2035 : w, &
2036 : hilyr, &
2037 0 : dxp, kcstar, &
2038 0 : Iswabs, &
2039 : fsurfn, dfsurfn_dTsf, &
2040 149447219 : dt)
2041 149447219 : if (icepack_warnings_aborted(subname)) return
2042 :
2043 : else ! lcold
2044 :
2045 0 : call matrix_elements_nosnow_melt(Ap, As, An, b, nyn, &
2046 : nilyr, &
2047 : Tsf, Tbot, &
2048 0 : zqin0, &
2049 : qpond, qocn, &
2050 0 : phi, q, &
2051 : w, &
2052 : hilyr, &
2053 0 : dxp, kcstar, &
2054 0 : Iswabs, &
2055 73165993 : dt)
2056 73165993 : if (icepack_warnings_aborted(subname)) return
2057 :
2058 : endif ! lcold
2059 :
2060 : endif ! lsnow
2061 :
2062 : ! tridiag to get new temperatures
2063 : call tdma_solve_sparse(nilyr, nslyr, &
2064 1490253356 : An(1:nyn), Ap(1:nyn), As(1:nyn), b(1:nyn), T(1:nyn), nyn)
2065 1490253356 : if (icepack_warnings_aborted(subname)) return
2066 :
2067 : call update_temperatures(lsnow, lcold, &
2068 : nilyr, nslyr, &
2069 0 : T, Tsf, &
2070 1490253356 : zTin, zTsn)
2071 1490253356 : if (icepack_warnings_aborted(subname)) return
2072 :
2073 : end subroutine solve_heat_conduction
2074 :
2075 : !=======================================================================
2076 :
2077 1490253356 : subroutine update_temperatures(lsnow, lcold, &
2078 : nilyr, nslyr, &
2079 1490253356 : T, Tsf, &
2080 1490253356 : zTin, zTsn)
2081 :
2082 : logical, intent(in) :: &
2083 : lsnow , & ! snow presence: T: has snow, F: no snow
2084 : lcold ! surface cold: T: surface is cold, F: surface is melting
2085 :
2086 : integer (kind=int_kind), intent(in) :: &
2087 : nilyr , & ! number of ice layers
2088 : nslyr ! number of snow layers
2089 :
2090 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2091 : T ! matrix solution vector
2092 :
2093 : real(kind=dbl_kind), intent(inout) :: &
2094 : Tsf ! snow surface temperature (C)
2095 :
2096 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
2097 : zTin , & ! ice layer temperature (C)
2098 : zTsn ! snow layer temperature (C)
2099 :
2100 : integer :: &
2101 : l , & ! vertical index
2102 : k ! vertical layer index
2103 :
2104 : character(len=*),parameter :: subname='(update_temperatures)'
2105 :
2106 1490253356 : if (lsnow) then
2107 :
2108 1267640144 : if (lcold) then
2109 :
2110 1159736259 : Tsf = T(1)
2111 :
2112 2319472518 : do k = 1, nslyr
2113 1159736259 : l = k + 1
2114 2319472518 : zTsn(k) = T(l)
2115 : enddo ! k
2116 :
2117 9277890072 : do k = 1, nilyr
2118 8118153813 : l = k + nslyr + 1
2119 9277890072 : zTin(k) = T(l)
2120 : enddo ! k
2121 :
2122 : else ! lcold
2123 :
2124 215807770 : do k = 1, nslyr
2125 107903885 : l = k
2126 215807770 : zTsn(k) = T(l)
2127 : enddo ! k
2128 :
2129 863231080 : do k = 1, nilyr
2130 755327195 : l = k + nslyr
2131 863231080 : zTin(k) = T(l)
2132 : enddo ! k
2133 :
2134 : endif ! lcold
2135 :
2136 : else ! lsnow
2137 :
2138 222613212 : if (lcold) then
2139 :
2140 149447219 : Tsf = T(1)
2141 :
2142 1195577752 : do k = 1, nilyr
2143 1046130533 : l = k + 1
2144 1195577752 : zTin(k) = T(l)
2145 : enddo ! k
2146 :
2147 : else ! lcold
2148 :
2149 585327944 : do k = 1, nilyr
2150 512161951 : l = k
2151 585327944 : zTin(k) = T(l)
2152 : enddo ! k
2153 :
2154 : endif ! lcold
2155 :
2156 : endif ! lsnow
2157 :
2158 1490253356 : end subroutine update_temperatures
2159 :
2160 : !=======================================================================
2161 :
2162 146331986 : subroutine matrix_elements_nosnow_melt(Ap, As, An, b, nyn, &
2163 : nilyr, &
2164 : Tsf, Tbot, &
2165 73165993 : zqin0, &
2166 : qpond, qocn, &
2167 73165993 : phi, q, &
2168 : w, &
2169 : hilyr, &
2170 73165993 : dxp, kcstar, &
2171 73165993 : Iswabs, &
2172 : dt)
2173 :
2174 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2175 : Ap , & ! diagonal of tridiagonal matrix
2176 : As , & ! lower off-diagonal of tridiagonal matrix
2177 : An , & ! upper off-diagonal of tridiagonal matrix
2178 : b ! right hand side of matrix solve
2179 :
2180 : integer, intent(out) :: &
2181 : nyn ! matrix size
2182 :
2183 : integer (kind=int_kind), intent(in) :: &
2184 : nilyr ! number of ice layers
2185 :
2186 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2187 : zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep
2188 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
2189 : phi ! ice layer liquid fraction
2190 :
2191 : real(kind=dbl_kind), intent(in) :: &
2192 : Tsf , & ! snow surface temperature (C)
2193 : dt , & ! timestep (s)
2194 : hilyr , & ! ice layer thickness (m)
2195 : Tbot , & ! ice bottom surfce temperature (deg C)
2196 : qpond , & ! melt pond brine enthalpy (J m-3)
2197 : qocn , & ! ocean brine enthalpy (J m-3)
2198 : w ! downwards vertical flushing Darcy velocity (m/s)
2199 :
2200 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
2201 : q ! upward interface vertical Darcy flow (m s-1)
2202 :
2203 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2204 : dxp , & ! distances between grid points (m)
2205 : kcstar ! interface conductivities (W m-1 K-1)
2206 :
2207 : integer :: &
2208 : k , & ! vertical layer index
2209 : l ! vertical index
2210 :
2211 : character(len=*),parameter :: subname='(matrix_elements_nosnow_melt)'
2212 :
2213 : ! surface layer
2214 73165993 : k = 1
2215 73165993 : l = k
2216 :
2217 4403370 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2218 8806740 : kcstar(k+1) / dxp(k+1) + &
2219 4403370 : kcstar(k) / dxp(k) + &
2220 4403370 : q(k) * cp_ocn * rhow + &
2221 77569363 : w * cp_ocn * rhow
2222 13210110 : As(l) = -kcstar(k+1) / dxp(k+1) - &
2223 81972733 : q(k) * cp_ocn * rhow
2224 73165993 : An(l) = c0
2225 4403370 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2226 4403370 : (kcstar(k) / dxp(k)) * Tsf + &
2227 73165993 : w * qpond
2228 :
2229 : ! interior ice layers
2230 438995958 : do k = 2, nilyr-1
2231 :
2232 365829965 : l = k
2233 :
2234 22016850 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2235 44033700 : kcstar(k+1) / dxp(k+1) + &
2236 22016850 : kcstar(k) / dxp(k) + &
2237 22016850 : q(k) * cp_ocn * rhow + &
2238 387846815 : w * cp_ocn * rhow
2239 66050550 : As(l) = -kcstar(k+1) / dxp(k+1) - &
2240 409863665 : q(k) * cp_ocn * rhow
2241 22016850 : An(l) = -kcstar(k) / dxp(k) - &
2242 365829965 : w * cp_ocn * rhow
2243 438995958 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
2244 :
2245 : enddo ! k
2246 :
2247 : ! bottom layer
2248 73165993 : k = nilyr
2249 73165993 : l = k
2250 :
2251 4403370 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2252 8806740 : kcstar(k+1) / dxp(k+1) + &
2253 4403370 : kcstar(k) / dxp(k) + &
2254 4403370 : q(k) * cp_ocn * rhow + &
2255 77569363 : w * cp_ocn * rhow
2256 73165993 : As(l) = c0
2257 4403370 : An(l) = -kcstar(k) / dxp(k) - &
2258 73165993 : w * cp_ocn * rhow
2259 4403370 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2260 8806740 : (kcstar(k+1) * Tbot) / dxp(k+1) + &
2261 81972733 : q(k) * qocn
2262 :
2263 73165993 : nyn = nilyr
2264 :
2265 73165993 : end subroutine matrix_elements_nosnow_melt
2266 :
2267 : !=======================================================================
2268 :
2269 298894438 : subroutine matrix_elements_nosnow_cold(Ap, As, An, b, nyn, &
2270 : nilyr, &
2271 : Tsf, Tbot, &
2272 149447219 : zqin0, &
2273 : qpond, qocn, &
2274 149447219 : phi, q, &
2275 : w, &
2276 : hilyr, &
2277 149447219 : dxp, kcstar, &
2278 149447219 : Iswabs, &
2279 : fsurfn, dfsurfn_dTsf, &
2280 : dt)
2281 :
2282 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2283 : Ap , & ! diagonal of tridiagonal matrix
2284 : As , & ! lower off-diagonal of tridiagonal matrix
2285 : An , & ! upper off-diagonal of tridiagonal matrix
2286 : b ! right hand side of matrix solve
2287 :
2288 : integer, intent(out) :: &
2289 : nyn ! matrix size
2290 :
2291 : integer (kind=int_kind), intent(in) :: &
2292 : nilyr ! number of ice layers
2293 :
2294 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2295 : zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep
2296 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
2297 : phi ! ice layer liquid fraction
2298 :
2299 : real(kind=dbl_kind), intent(in) :: &
2300 : Tsf , & ! snow surface temperature (C)
2301 : dt , & ! timestep (s)
2302 : hilyr , & ! ice layer thickness (m)
2303 : Tbot , & ! ice bottom surfce temperature (deg C)
2304 : qpond , & ! melt pond brine enthalpy (J m-3)
2305 : qocn , & ! ocean brine enthalpy (J m-3)
2306 : w , & ! downwards vertical flushing Darcy velocity (m/s)
2307 : fsurfn , & ! net flux to top surface, excluding fcondtop
2308 : dfsurfn_dTsf ! derivative of net flux to top surface, excluding fcondtopn
2309 :
2310 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
2311 : q ! upward interface vertical Darcy flow (m s-1)
2312 :
2313 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2314 : dxp , & ! distances between grid points (m)
2315 : kcstar ! interface conductivities (W m-1 K-1)
2316 :
2317 : integer :: &
2318 : k , & ! vertical layer index
2319 : l ! vertical index
2320 :
2321 : character(len=*),parameter :: subname='(matrix_elements_nosnow_cold)'
2322 :
2323 : ! surface temperature
2324 149447219 : l = 1
2325 149447219 : Ap(l) = dfsurfn_dTsf - kcstar(1) / dxp(1)
2326 149447219 : As(l) = kcstar(1) / dxp(1)
2327 149447219 : An(l) = c0
2328 149447219 : b (l) = dfsurfn_dTsf * Tsf - fsurfn
2329 :
2330 : ! surface layer
2331 149447219 : k = 1
2332 149447219 : l = k + 1
2333 :
2334 3722439 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2335 7444878 : kcstar(k+1) / dxp(k+1) + &
2336 3722439 : kcstar(k) / dxp(k) + &
2337 3722439 : q(k) * cp_ocn * rhow + &
2338 153169658 : w * cp_ocn * rhow
2339 11167317 : As(l) = -kcstar(k+1) / dxp(k+1) - &
2340 156892097 : q(k) * cp_ocn * rhow
2341 149447219 : An(l) = -kcstar(k) / dxp(k)
2342 3722439 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2343 149447219 : w * qpond
2344 :
2345 : ! interior ice layers
2346 896683314 : do k = 2, nilyr-1
2347 :
2348 747236095 : l = k + 1
2349 :
2350 18612195 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2351 37224390 : kcstar(k+1) / dxp(k+1) + &
2352 18612195 : kcstar(k) / dxp(k) + &
2353 18612195 : q(k) * cp_ocn * rhow + &
2354 765848290 : w * cp_ocn * rhow
2355 55836585 : As(l) = -kcstar(k+1) / dxp(k+1) - &
2356 784460485 : q(k) * cp_ocn * rhow
2357 18612195 : An(l) = -kcstar(k) / dxp(k) - &
2358 747236095 : w * cp_ocn * rhow
2359 896683314 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
2360 :
2361 : enddo ! k
2362 :
2363 : ! bottom layer
2364 149447219 : k = nilyr
2365 149447219 : l = k + 1
2366 :
2367 3722439 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2368 7444878 : kcstar(k+1) / dxp(k+1) + &
2369 3722439 : kcstar(k) / dxp(k) + &
2370 3722439 : q(k) * cp_ocn * rhow + &
2371 153169658 : w * cp_ocn * rhow
2372 149447219 : As(l) = c0
2373 3722439 : An(l) = -kcstar(k) / dxp(k) - &
2374 149447219 : w * cp_ocn * rhow
2375 3722439 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2376 7444878 : (kcstar(k+1) * Tbot) / dxp(k+1) + &
2377 156892097 : q(k) * qocn
2378 :
2379 149447219 : nyn = nilyr + 1
2380 :
2381 149447219 : end subroutine matrix_elements_nosnow_cold
2382 :
2383 : !=======================================================================
2384 :
2385 215807770 : subroutine matrix_elements_snow_melt(Ap, As, An, b, nyn, &
2386 : nilyr, nslyr, &
2387 : Tsf, Tbot, &
2388 215807770 : zqin0, zqsn0, &
2389 : qpond, qocn, &
2390 107903885 : phi, q, &
2391 : w, &
2392 : hilyr, hslyr, &
2393 107903885 : dxp, kcstar, &
2394 215807770 : Iswabs, Sswabs, &
2395 : dt)
2396 :
2397 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2398 : Ap , & ! diagonal of tridiagonal matrix
2399 : As , & ! lower off-diagonal of tridiagonal matrix
2400 : An , & ! upper off-diagonal of tridiagonal matrix
2401 : b ! right hand side of matrix solve
2402 :
2403 : integer, intent(out) :: &
2404 : nyn ! matrix size
2405 :
2406 : integer (kind=int_kind), intent(in) :: &
2407 : nilyr , & ! number of ice layers
2408 : nslyr ! number of snow layers
2409 :
2410 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2411 : zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep
2412 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
2413 : phi , & ! ice layer liquid fraction
2414 : zqsn0 , & ! snow layer enthalpy (J m-3) at start of timestep
2415 : Sswabs ! SW radiation absorbed in snow layers (W m-2)
2416 :
2417 : real(kind=dbl_kind), intent(in) :: &
2418 : Tsf , & ! snow surface temperature (C)
2419 : dt , & ! timestep (s)
2420 : hilyr , & ! ice layer thickness (m)
2421 : hslyr , & ! snow layer thickness (m)
2422 : Tbot , & ! ice bottom surfce temperature (deg C)
2423 : qpond , & ! melt pond brine enthalpy (J m-3)
2424 : qocn , & ! ocean brine enthalpy (J m-3)
2425 : w ! downwards vertical flushing Darcy velocity (m/s)
2426 :
2427 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
2428 : q ! upward interface vertical Darcy flow (m s-1)
2429 :
2430 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2431 : dxp , & ! distances between grid points (m)
2432 : kcstar ! interface conductivities (W m-1 K-1)
2433 :
2434 : integer :: &
2435 : k , & ! vertical layer index
2436 : l ! vertical index
2437 :
2438 : character(len=*),parameter :: subname='(matrix_elements_snow_melt)'
2439 :
2440 : ! surface layer
2441 107903885 : k = 1
2442 107903885 : l = k
2443 :
2444 9898576 : Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
2445 19797152 : kcstar(l+1) / dxp(l+1) + &
2446 127701037 : kcstar(l) / dxp(l)
2447 107903885 : As(l) = -kcstar(l+1) / dxp(l+1)
2448 107903885 : An(l) = c0
2449 9898576 : b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k) + &
2450 107903885 : (kcstar(l) * Tsf) / dxp(l)
2451 :
2452 : ! interior snow layers
2453 107903885 : do k = 2, nslyr
2454 :
2455 0 : l = k
2456 :
2457 0 : Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
2458 0 : kcstar(l+1) / dxp(l+1) + &
2459 0 : kcstar(l) / dxp(l)
2460 0 : As(l) = -kcstar(l+1) / dxp(l+1)
2461 0 : An(l) = -kcstar(l) / dxp(l)
2462 107903885 : b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k)
2463 :
2464 : enddo ! k
2465 :
2466 : ! top ice layer
2467 107903885 : k = 1
2468 107903885 : l = nslyr + k
2469 :
2470 9898576 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2471 19797152 : kcstar(l+1) / dxp(l+1) + &
2472 9898576 : kcstar(l) / dxp(l) + &
2473 9898576 : q(k) * cp_ocn * rhow + &
2474 117802461 : w * cp_ocn * rhow
2475 29695728 : As(l) = -kcstar(l+1) / dxp(l+1) - &
2476 127701037 : q(k) * cp_ocn * rhow
2477 107903885 : An(l) = -kcstar(l) / dxp(l)
2478 9898576 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2479 107903885 : w * qpond
2480 :
2481 : ! interior ice layers
2482 647423310 : do k = 2, nilyr-1
2483 :
2484 539519425 : l = nslyr + k
2485 :
2486 49492880 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2487 98985760 : kcstar(l+1) / dxp(l+1) + &
2488 49492880 : kcstar(l) / dxp(l) + &
2489 49492880 : q(k) * cp_ocn * rhow + &
2490 589012305 : w * cp_ocn * rhow
2491 148478640 : As(l) = -kcstar(l+1) / dxp(l+1) - &
2492 638505185 : q(k) * cp_ocn * rhow
2493 49492880 : An(l) = -kcstar(l) / dxp(l) - &
2494 539519425 : w * cp_ocn * rhow
2495 647423310 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
2496 :
2497 : enddo ! k
2498 :
2499 : ! bottom layer
2500 107903885 : k = nilyr
2501 107903885 : l = nilyr + nslyr
2502 :
2503 9898576 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2504 19797152 : kcstar(l+1) / dxp(l+1) + &
2505 9898576 : kcstar(l) / dxp(l) + &
2506 9898576 : q(k) * cp_ocn * rhow + &
2507 117802461 : w * cp_ocn * rhow
2508 107903885 : As(l) = c0
2509 9898576 : An(l) = -kcstar(l) / dxp(l) - &
2510 107903885 : w * cp_ocn * rhow
2511 9898576 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2512 19797152 : (kcstar(l+1) * Tbot) / dxp(l+1) + &
2513 127701037 : q(k) * qocn
2514 :
2515 107903885 : nyn = nilyr + nslyr
2516 :
2517 107903885 : end subroutine matrix_elements_snow_melt
2518 :
2519 : !=======================================================================
2520 :
2521 2319472518 : subroutine matrix_elements_snow_cold(Ap, As, An, b, nyn, &
2522 : nilyr, nslyr, &
2523 : Tsf, Tbot, &
2524 2319472518 : zqin0, zqsn0, &
2525 : qpond, qocn, &
2526 1159736259 : phi, q, &
2527 : w, &
2528 : hilyr, hslyr, &
2529 1159736259 : dxp, kcstar, &
2530 2319472518 : Iswabs, Sswabs, &
2531 : fsurfn, dfsurfn_dTsf, &
2532 : dt)
2533 :
2534 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2535 : Ap , & ! diagonal of tridiagonal matrix
2536 : As , & ! lower off-diagonal of tridiagonal matrix
2537 : An , & ! upper off-diagonal of tridiagonal matrix
2538 : b ! right hand side of matrix solve
2539 :
2540 : integer, intent(out) :: &
2541 : nyn ! matrix size
2542 :
2543 : integer (kind=int_kind), intent(in) :: &
2544 : nilyr , & ! number of ice layers
2545 : nslyr ! number of snow layers
2546 :
2547 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2548 : zqin0 , & ! ice layer enthalpy (J m-3) at beggining of timestep
2549 : Iswabs , & ! SW radiation absorbed in ice layers (W m-2)
2550 : phi , & ! ice layer liquid fraction
2551 : zqsn0 , & ! snow layer enthalpy (J m-3) at start of timestep
2552 : Sswabs ! SW radiation absorbed in snow layers (W m-2)
2553 :
2554 : real(kind=dbl_kind), intent(in) :: &
2555 : Tsf , & ! snow surface temperature (C)
2556 : dt , & ! timestep (s)
2557 : hilyr , & ! ice layer thickness (m)
2558 : hslyr , & ! snow layer thickness (m)
2559 : Tbot , & ! ice bottom surfce temperature (deg C)
2560 : qpond , & ! melt pond brine enthalpy (J m-3)
2561 : qocn , & ! ocean brine enthalpy (J m-3)
2562 : w , & ! downwards vertical flushing Darcy velocity (m/s)
2563 : fsurfn , & ! net flux to top surface, excluding fcondtop
2564 : dfsurfn_dTsf ! derivative of net flux to top surface, excluding fcondtopn
2565 :
2566 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
2567 : q ! upward interface vertical Darcy flow (m s-1)
2568 :
2569 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2570 : dxp , & ! distances between grid points (m)
2571 : kcstar ! interface conductivities (W m-1 K-1)
2572 :
2573 : integer :: &
2574 : k , & ! vertical layer index
2575 : l , & ! matrix index
2576 : m ! vertical index
2577 :
2578 : character(len=*),parameter :: subname='(matrix_elements_snow_cold)'
2579 :
2580 : ! surface temperature
2581 1159736259 : l = 1
2582 1159736259 : Ap(l) = dfsurfn_dTsf - kcstar(1) / dxp(1)
2583 1159736259 : As(l) = kcstar(1) / dxp(1)
2584 1159736259 : An(l) = c0
2585 1159736259 : b (l) = dfsurfn_dTsf * Tsf - fsurfn
2586 :
2587 : ! surface layer
2588 1159736259 : k = 1
2589 1159736259 : l = k + 1
2590 1159736259 : m = 1
2591 :
2592 63980306 : Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
2593 127960612 : kcstar(m+1) / dxp(m+1) + &
2594 1287696871 : kcstar(m) / dxp(m)
2595 1159736259 : As(l) = -kcstar(m+1) / dxp(m+1)
2596 1159736259 : An(l) = -kcstar(m) / dxp(m)
2597 1159736259 : b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k)
2598 :
2599 : ! interior snow layers
2600 1159736259 : do k = 2, nslyr
2601 :
2602 0 : l = k + 1
2603 0 : m = k
2604 :
2605 0 : Ap(l) = ((rhos * cp_ice) / dt) * hslyr + &
2606 0 : kcstar(m+1) / dxp(m+1) + &
2607 0 : kcstar(m) / dxp(m)
2608 0 : As(l) = -kcstar(m+1) / dxp(m+1)
2609 0 : An(l) = -kcstar(m) / dxp(m)
2610 1159736259 : b (l) = ((rhos * Lfresh + zqsn0(k)) / dt) * hslyr + Sswabs(k)
2611 :
2612 : enddo ! k
2613 :
2614 : ! top ice layer
2615 1159736259 : k = 1
2616 1159736259 : l = nslyr + k + 1
2617 1159736259 : m = k + nslyr
2618 :
2619 63980306 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2620 127960612 : kcstar(m+1) / dxp(m+1) + &
2621 63980306 : kcstar(m) / dxp(m) + &
2622 63980306 : q(k) * cp_ocn * rhow + &
2623 1223716565 : w * cp_ocn * rhow
2624 191940918 : As(l) = -kcstar(m+1) / dxp(m+1) - &
2625 1287696871 : q(k) * cp_ocn * rhow
2626 1159736259 : An(l) = -kcstar(m) / dxp(m)
2627 63980306 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2628 1159736259 : w * qpond
2629 :
2630 : ! interior ice layers
2631 6958417554 : do k = 2, nilyr-1
2632 :
2633 5798681295 : l = nslyr + k + 1
2634 5798681295 : m = k + nslyr
2635 :
2636 319901530 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2637 639803060 : kcstar(m+1) / dxp(m+1) + &
2638 319901530 : kcstar(m) / dxp(m) + &
2639 319901530 : q(k) * cp_ocn * rhow + &
2640 6118582825 : w * cp_ocn * rhow
2641 959704590 : As(l) = -kcstar(m+1) / dxp(m+1) - &
2642 6438484355 : q(k) * cp_ocn * rhow
2643 319901530 : An(l) = -kcstar(m) / dxp(m) - &
2644 5798681295 : w * cp_ocn * rhow
2645 6958417554 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k)
2646 :
2647 : enddo ! k
2648 :
2649 : ! bottom layer
2650 1159736259 : k = nilyr
2651 1159736259 : l = nilyr + nslyr + 1
2652 1159736259 : m = k + nslyr
2653 :
2654 63980306 : Ap(l) = ((phi(k) * (cp_ocn * rhow - cp_ice * rhoi) + rhoi * cp_ice) / dt) * hilyr + &
2655 127960612 : kcstar(m+1) / dxp(m+1) + &
2656 63980306 : kcstar(m) / dxp(m) + &
2657 63980306 : q(k) * cp_ocn * rhow + &
2658 1223716565 : w * cp_ocn * rhow
2659 1159736259 : As(l) = c0
2660 63980306 : An(l) = -kcstar(m) / dxp(m) - &
2661 1159736259 : w * cp_ocn * rhow
2662 63980306 : b (l) = (((c1 - phi(k)) * rhoi * Lfresh + zqin0(k)) / dt) * hilyr + Iswabs(k) + &
2663 127960612 : (kcstar(m+1) * Tbot) / dxp(m+1) + &
2664 1287696871 : q(k) * qocn
2665 :
2666 1159736259 : nyn = nilyr + nslyr + 1
2667 :
2668 1159736259 : end subroutine matrix_elements_snow_cold
2669 :
2670 : !=======================================================================
2671 :
2672 1331094746 : subroutine solve_salinity(zSin, Sbr, &
2673 : Spond, sss, &
2674 1331094746 : q, dSdt, &
2675 : w, hilyr, &
2676 : dt, nilyr)
2677 :
2678 : integer (kind=int_kind), intent(in) :: &
2679 : nilyr ! number of ice layers
2680 :
2681 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
2682 : zSin ! ice layer bulk salinity (ppt)
2683 :
2684 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2685 : Sbr , & ! ice layer brine salinity (ppt)
2686 : dSdt ! gravity drainage desalination rate for slow mode (ppt s-1)
2687 :
2688 : real(kind=dbl_kind), dimension(0:nilyr), intent(in) :: &
2689 : q ! upward interface vertical Darcy flow (m s-1)
2690 :
2691 : real(kind=dbl_kind), intent(in) :: &
2692 : Spond , & ! melt pond salinity (ppt)
2693 : sss , & ! sea surface salinity (ppt)
2694 : w , & ! vertical flushing Darcy velocity (m/s)
2695 : hilyr , & ! ice layer thickness (m)
2696 : dt ! timestep (s)
2697 :
2698 : integer :: &
2699 : k ! vertical layer index
2700 :
2701 : real(kind=dbl_kind), parameter :: &
2702 : S_min = p01
2703 :
2704 : real(kind=dbl_kind), dimension(nilyr) :: &
2705 960001901 : zSin0
2706 :
2707 : character(len=*),parameter :: subname='(solve_salinity)'
2708 :
2709 5324378984 : zSin0 = zSin
2710 :
2711 665547373 : k = 1
2712 36806816 : zSin(k) = zSin(k) + max(S_min - zSin(k), &
2713 73613632 : ((q(k) * (Sbr(k+1) - Sbr(k))) / hilyr + &
2714 36806816 : dSdt(k) + &
2715 702354189 : (w * (Spond - Sbr(k))) / hilyr) * dt)
2716 :
2717 3993284238 : do k = 2, nilyr-1
2718 :
2719 184034080 : zSin(k) = zSin(k) + max(S_min - zSin(k), &
2720 368068160 : ((q(k) * (Sbr(k+1) - Sbr(k))) / hilyr + &
2721 184034080 : dSdt(k) + &
2722 4177318318 : (w * (Sbr(k-1) - Sbr(k))) / hilyr) * dt)
2723 :
2724 : enddo ! k
2725 :
2726 665547373 : k = nilyr
2727 36806816 : zSin(k) = zSin(k) + max(S_min - zSin(k), &
2728 36806816 : ((q(k) * (sss - Sbr(k))) / hilyr + &
2729 36806816 : dSdt(k) + &
2730 665547373 : (w * (Sbr(k-1) - Sbr(k))) / hilyr) * dt)
2731 :
2732 :
2733 5324378984 : if (minval(zSin) < c0) then
2734 :
2735 :
2736 0 : write(warnstr,*) subname, (q(k) * (Sbr(k+1) - Sbr(k))) / hilyr, &
2737 0 : dSdt(k) , &
2738 0 : (w * (Spond - Sbr(k))) / hilyr
2739 0 : call icepack_warnings_add(warnstr)
2740 :
2741 0 : do k = 1, nilyr
2742 :
2743 0 : write(warnstr,*) subname, k, zSin(k), zSin0(k)
2744 0 : call icepack_warnings_add(warnstr)
2745 :
2746 : enddo
2747 :
2748 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
2749 0 : return
2750 :
2751 : endif
2752 :
2753 : end subroutine solve_salinity
2754 :
2755 : !=======================================================================
2756 :
2757 1490253356 : subroutine tdma_solve_sparse(nilyr, nslyr, a, b, c, d, x, n)
2758 :
2759 : ! perform a tri-diagonal solve with TDMA using a sparse tridiagoinal matrix
2760 :
2761 : integer (kind=int_kind), intent(in) :: &
2762 : nilyr, & ! number of ice layers
2763 : nslyr ! number of snow layers
2764 :
2765 : integer(kind=int_kind), intent(in) :: &
2766 : n ! matrix size
2767 :
2768 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2769 : a , & ! matrix lower off-diagonal
2770 : b , & ! matrix diagonal
2771 : c , & ! matrix upper off-diagonal
2772 : d ! right hand side vector
2773 :
2774 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2775 : x ! solution vector
2776 :
2777 : real(kind=dbl_kind), dimension(nilyr+nslyr+1) :: &
2778 3636544240 : cp , & ! modified upper off-diagonal vector
2779 3636544240 : dp ! modified right hand side vector
2780 :
2781 : integer(kind=int_kind) :: &
2782 : i ! vector index
2783 :
2784 : character(len=*),parameter :: subname='(tdma_solve_sparse)'
2785 :
2786 : ! forward sweep
2787 1490253356 : cp(1) = c(1) / b(1)
2788 11518343758 : do i = 2, n-1
2789 11518343758 : cp(i) = c(i) / (b(i) - cp(i-1)*a(i))
2790 : enddo
2791 :
2792 1490253356 : dp(1) = d(1) / b(1)
2793 13008597114 : do i = 2, n
2794 13008597114 : dp(i) = (d(i) - dp(i-1)*a(i)) / (b(i) - cp(i-1)*a(i))
2795 : enddo
2796 :
2797 : ! back substitution
2798 1490253356 : x(n) = dp(n)
2799 13008597114 : do i = n-1,1,-1
2800 13008597114 : x(i) = dp(i) - cp(i)*x(i+1)
2801 : enddo
2802 :
2803 1490253356 : end subroutine tdma_solve_sparse
2804 :
2805 : !=======================================================================
2806 : ! Effect of salinity
2807 : !=======================================================================
2808 :
2809 8493988986 : function permeability(phi) result(perm)
2810 :
2811 : ! given the liquid fraction calculate the permeability
2812 : ! See Golden et al. 2007
2813 :
2814 : real(kind=dbl_kind), intent(in) :: &
2815 : phi ! liquid fraction
2816 :
2817 : real(kind=dbl_kind) :: &
2818 : perm ! permeability (m2)
2819 :
2820 : real(kind=dbl_kind), parameter :: &
2821 : phic = p05 ! critical liquid fraction for impermeability
2822 :
2823 : character(len=*),parameter :: subname='(permeability)'
2824 :
2825 8493988986 : perm = 3.0e-8_dbl_kind * max(phi - phic, c0)**3
2826 :
2827 8493988986 : end function permeability
2828 :
2829 : !=======================================================================
2830 :
2831 609317819 : subroutine explicit_flow_velocities(nilyr, zSin, &
2832 609317819 : zTin, Tsf, &
2833 609317819 : Tbot, q, &
2834 1218635638 : dSdt, Sbr, &
2835 609317819 : qbr, dt, &
2836 : sss, qocn, &
2837 : hilyr, hin)
2838 :
2839 : ! calculate the rapid gravity drainage mode Darcy velocity and the
2840 : ! slow mode drainage rate
2841 :
2842 : integer (kind=int_kind), intent(in) :: &
2843 : nilyr ! number of ice layers
2844 :
2845 : real(kind=dbl_kind), dimension(:), intent(in) :: &
2846 : zSin, & ! ice layer bulk salinity (ppt)
2847 : zTin ! ice layer temperature (C)
2848 :
2849 : real(kind=dbl_kind), intent(in) :: &
2850 : Tsf , & ! ice/snow surface temperature (C)
2851 : Tbot , & ! ice bottom temperature (C)
2852 : dt , & ! time step (s)
2853 : sss , & ! sea surface salinty (ppt)
2854 : qocn , & ! ocean enthalpy (J m-3)
2855 : hilyr , & ! ice layer thickness (m)
2856 : hin ! ice thickness (m)
2857 :
2858 : real(kind=dbl_kind), dimension(0:nilyr), intent(out) :: &
2859 : q ! rapid mode upward interface vertical Darcy flow (m s-1)
2860 :
2861 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2862 : dSdt ! slow mode drainage rate (ppt s-1)
2863 :
2864 : real(kind=dbl_kind), dimension(:), intent(out) :: &
2865 : Sbr , & ! ice layer brine salinity (ppt)
2866 : qbr ! ice layer brine enthalpy (J m-3)
2867 :
2868 : real(kind=dbl_kind), parameter :: &
2869 : kappal = 8.824e-8_dbl_kind, & ! heat diffusivity of liquid
2870 : fracmax = p2 , & ! limiting advective layer fraction
2871 : zSin_min = p1 , & ! minimum bulk salinity (ppt)
2872 : safety_factor = c10 ! to prevent negative salinities
2873 :
2874 : real(kind=dbl_kind), dimension(1:nilyr) :: &
2875 1413344656 : phi ! ice layer liquid fraction
2876 :
2877 : real(kind=dbl_kind), dimension(0:nilyr) :: &
2878 1445796159 : rho ! ice layer brine density (kg m-3)
2879 :
2880 : real(kind=dbl_kind) :: &
2881 32451503 : rho_ocn , & ! ocean density (kg m-3)
2882 32451503 : perm_min , & ! minimum permeability from layer to ocean (m2)
2883 32451503 : perm_harm , & ! harmonic mean of permeability from layer to ocean (m2)
2884 32451503 : rho_sum , & ! sum of the brine densities from layer to ocean (kg m-3)
2885 32451503 : rho_pipe , & ! density of the brine in the channel (kg m-3)
2886 32451503 : z , & ! distance to layer from top surface (m)
2887 32451503 : perm , & ! ice layer permeability (m2)
2888 32451503 : drho , & ! brine density difference between layer and ocean (kg m-3)
2889 32451503 : Ra , & ! local mush Rayleigh number
2890 32451503 : rn , & ! real value of number of layers considered
2891 32451503 : L , & ! thickness of the layers considered (m)
2892 32451503 : dx , & ! horizontal size of convective flow (m)
2893 32451503 : dx2 , & ! square of the horizontal size of convective flow (m2)
2894 32451503 : Am , & ! A parameter for mush
2895 32451503 : Bm , & ! B parameter for mush
2896 32451503 : Ap , & ! A parameter for channel
2897 32451503 : Bp , & ! B parameter for channel
2898 32451503 : qlimit , & ! limit to vertical Darcy flow for numerical stability
2899 32451503 : dS_guess , & ! expected bulk salinity without limits
2900 32451503 : alpha , & ! desalination limiting factor
2901 32451503 : ra_constants ! for Rayleigh number
2902 :
2903 : integer(kind=int_kind) :: &
2904 : k ! ice layer index
2905 :
2906 : character(len=*),parameter :: subname='(explicit_flow_velocities)'
2907 :
2908 : ! initial downward sweep - determine derived physical quantities
2909 4874542552 : do k = 1, nilyr
2910 :
2911 4265224733 : Sbr(k) = liquidus_brine_salinity_mush(zTin(k))
2912 4265224733 : phi(k) = icepack_mushy_liquid_fraction(zTin(k), zSin(k))
2913 4265224733 : qbr(k) = enthalpy_brine(zTin(k))
2914 4874542552 : rho(k) = icepack_mushy_density_brine(Sbr(k))
2915 :
2916 : enddo ! k
2917 :
2918 609317819 : rho(0) = rho(1)
2919 :
2920 : ! ocean conditions
2921 609317819 : Sbr(nilyr+1) = sss
2922 609317819 : qbr(nilyr+1) = qocn
2923 609317819 : rho_ocn = icepack_mushy_density_brine(sss)
2924 :
2925 : ! initialize accumulated quantities
2926 609317819 : perm_min = bignum
2927 609317819 : perm_harm = c0
2928 609317819 : rho_sum = c0
2929 :
2930 : ! limit to q for numerical stability
2931 609317819 : qlimit = (fracmax * hilyr) / dt
2932 :
2933 : ! no flow through ice top surface
2934 609317819 : q(0) = c0
2935 :
2936 609317819 : ra_constants = gravit / (viscosity_dyn * kappal)
2937 : ! first iterate over layers going up
2938 4874542552 : do k = nilyr, 1, -1
2939 :
2940 : ! vertical position from ice top surface
2941 4265224733 : z = ((real(k, dbl_kind) - p5) / real(nilyr, dbl_kind)) * hin
2942 :
2943 : ! permeabilities
2944 4265224733 : perm = permeability(phi(k))
2945 4265224733 : perm_min = min(perm_min,perm)
2946 4265224733 : perm_harm = perm_harm + (c1 / max(perm,1.0e-30_dbl_kind))
2947 :
2948 : ! densities
2949 4265224733 : rho_sum = rho_sum + rho(k)
2950 : !rho_pipe = rho(k)
2951 4265224733 : rho_pipe = p5 * (rho(k) + rho(k-1))
2952 4265224733 : drho = max(rho(k) - rho_ocn, c0)
2953 :
2954 : ! mush Rayleigh number
2955 4265224733 : Ra = drho * (hin-z) * perm_min * ra_constants
2956 :
2957 : ! height of mush layer to layer k
2958 4265224733 : rn = real(nilyr-k+1,dbl_kind)
2959 4265224733 : L = rn * hilyr
2960 :
2961 : ! horizontal size of convection
2962 4265224733 : dx = L * c2 * aspect_rapid_mode
2963 4265224733 : dx2 = dx**2
2964 :
2965 : ! determine vertical Darcy flow
2966 4265224733 : Am = (dx2 * rn) / (viscosity_dyn * perm_harm)
2967 4265224733 : Bm = (-gravit * rho_sum) / rn
2968 :
2969 4265224733 : Ap = (pi * a_rapid_mode**4) / (c8 * viscosity_dyn)
2970 4265224733 : Bp = -rho_pipe * gravit
2971 :
2972 4265224733 : q(k) = max((Am / dx2) * ((-Ap*Bp - Am*Bm) / (Am + Ap) + Bm), 1.0e-30_dbl_kind)
2973 :
2974 : ! modify by Rayleigh number and advection limit
2975 4265224733 : q(k) = min(q(k) * (max(Ra - Rac_rapid_mode, c0) / (Ra+puny)), qlimit)
2976 :
2977 : ! late stage drainage
2978 227160521 : dSdt(k) = dSdt_slow_mode * (max((zSin(k) - phi_c_slow_mode*Sbr(k)), c0) &
2979 4265224733 : * max((Tbot - Tsf), c0)) / (hin + 0.001_dbl_kind)
2980 :
2981 4265224733 : dSdt(k) = max(dSdt(k), (-zSin(k) * 0.5_dbl_kind) / dt)
2982 :
2983 : ! restrict flows to prevent too much salt loss
2984 4265224733 : dS_guess = (((q(k) * (Sbr(k+1) - Sbr(k))) / hilyr + dSdt(k)) * dt) * safety_factor
2985 :
2986 4265224733 : if (abs(dS_guess) < puny) then
2987 1863561863 : alpha = c1
2988 : else
2989 2401662870 : alpha = (zSin_min - zSin(k)) / dS_guess
2990 : endif
2991 :
2992 4265224733 : if (alpha < c0 .or. alpha > c1) alpha = c1
2993 :
2994 4265224733 : q(k) = q(k) * alpha
2995 4874542552 : dSdt(k) = dSdt(k) * alpha
2996 :
2997 : enddo ! k
2998 :
2999 609317819 : end subroutine explicit_flow_velocities
3000 :
3001 : !=======================================================================
3002 : ! Flushing
3003 : !=======================================================================
3004 :
3005 609317819 : subroutine flushing_velocity(zTin, &
3006 609317819 : phi, nilyr, &
3007 : hin, hsn, &
3008 : hilyr, &
3009 : hpond, apond, &
3010 : dt, w)
3011 :
3012 : ! calculate the vertical flushing Darcy velocity (positive downward)
3013 :
3014 : integer (kind=int_kind), intent(in) :: &
3015 : nilyr ! number of ice layers
3016 :
3017 : real(kind=dbl_kind), dimension(:), intent(in) :: &
3018 : zTin , & ! ice layer temperature (C)
3019 : phi ! ice layer liquid fraction
3020 :
3021 : real(kind=dbl_kind), intent(in) :: &
3022 : hilyr , & ! ice layer thickness (m)
3023 : hpond , & ! melt pond thickness (m)
3024 : apond , & ! melt pond area (-)
3025 : hsn , & ! snow thickness (m)
3026 : hin , & ! ice thickness (m)
3027 : dt ! time step (s)
3028 :
3029 : real(kind=dbl_kind), intent(out) :: &
3030 : w ! vertical flushing Darcy flow rate (m s-1)
3031 :
3032 : real(kind=dbl_kind), parameter :: &
3033 : advection_limit = 0.005_dbl_kind ! limit to fraction of brine in
3034 : ! any layer that can be advected
3035 :
3036 : real(kind=dbl_kind) :: &
3037 32451503 : perm , & ! ice layer permeability (m2)
3038 32451503 : ice_mass , & ! mass of ice (kg m-2)
3039 32451503 : perm_harm , & ! harmonic mean of ice permeability (m2)
3040 32451503 : hocn , & ! ocean surface height above ice base (m)
3041 32451503 : hbrine , & ! brine surface height above ice base (m)
3042 32451503 : w_down_max , & ! maximum downward flushing Darcy flow rate (m s-1)
3043 32451503 : phi_min , & ! minimum porosity in the mush
3044 32451503 : wlimit , & ! limit to w to avoid advecting all brine in layer
3045 32451503 : dhhead ! hydraulic head (m)
3046 :
3047 : integer(kind=int_kind) :: &
3048 : k ! ice layer index
3049 :
3050 : character(len=*),parameter :: subname='(flushing_velocity)'
3051 :
3052 : ! initialize
3053 609317819 : w = c0
3054 :
3055 : ! only flush if ponds are active
3056 609317819 : if (tr_pond) then
3057 :
3058 604109179 : ice_mass = c0
3059 604109179 : perm_harm = c0
3060 604109179 : phi_min = c1
3061 :
3062 4832873432 : do k = 1, nilyr
3063 :
3064 : ! liquid fraction
3065 : !phi = icepack_mushy_liquid_fraction(zTin(k), zSin(k))
3066 4228764253 : phi_min = min(phi_min,phi(k))
3067 :
3068 : ! permeability
3069 4228764253 : perm = permeability(phi(k))
3070 :
3071 : ! ice mass
3072 222602961 : ice_mass = ice_mass + phi(k) * icepack_mushy_density_brine(liquidus_brine_salinity_mush(zTin(k))) + &
3073 4228764253 : (c1 - phi(k)) * rhoi
3074 :
3075 : ! permeability harmonic mean
3076 4832873432 : perm_harm = perm_harm + c1 / (perm + 1e-30_dbl_kind)
3077 :
3078 : enddo ! k
3079 :
3080 604109179 : ice_mass = ice_mass * hilyr
3081 :
3082 604109179 : perm_harm = real(nilyr,dbl_kind) / perm_harm
3083 :
3084 : ! calculate ocean surface height above bottom of ice
3085 604109179 : hocn = (ice_mass + hpond * apond * rhow + hsn * rhos) / rhow
3086 :
3087 : ! calculate brine height above bottom of ice
3088 604109179 : hbrine = hin + hpond
3089 :
3090 : ! pressure head
3091 604109179 : dhhead = max(hbrine - hocn,c0)
3092 :
3093 : ! darcy flow through ice
3094 604109179 : w = (perm_harm * rhow * gravit * (dhhead / hin)) / viscosity_dyn
3095 :
3096 : ! maximum down flow to drain pond
3097 604109179 : w_down_max = (hpond * apond) / dt
3098 :
3099 : ! limit flow
3100 604109179 : w = min(w,w_down_max)
3101 :
3102 : ! limit amount of brine that can be advected out of any particular layer
3103 604109179 : wlimit = (advection_limit * phi_min * hilyr) / dt
3104 :
3105 604109179 : if (abs(w) > puny) then
3106 127192674 : w = w * max(min(abs(wlimit/w),c1),c0)
3107 : else
3108 476916505 : w = c0
3109 : endif
3110 :
3111 604109179 : w = max(w, c0)
3112 :
3113 : endif
3114 :
3115 609317819 : end subroutine flushing_velocity
3116 :
3117 : !=======================================================================
3118 :
3119 609317819 : subroutine flush_pond(w, hpond, apond, dt)
3120 :
3121 : ! given a flushing velocity drain the meltponds
3122 :
3123 : real(kind=dbl_kind), intent(in) :: &
3124 : w , & ! vertical flushing Darcy flow rate (m s-1)
3125 : apond , & ! melt pond area (-)
3126 : dt ! time step (s)
3127 :
3128 : real(kind=dbl_kind), intent(inout) :: &
3129 : hpond ! melt pond thickness (m)
3130 :
3131 : real(kind=dbl_kind), parameter :: &
3132 : lambda_pond = c1 / (10.0_dbl_kind * 24.0_dbl_kind * 3600.0_dbl_kind), &
3133 : hpond0 = 0.01_dbl_kind
3134 :
3135 : character(len=*),parameter :: subname='(flush_pond)'
3136 :
3137 609317819 : if (tr_pond) then
3138 604109179 : if (apond > c0 .and. hpond > c0) then
3139 :
3140 : ! flush pond through mush
3141 386503755 : hpond = hpond - w * dt / apond
3142 :
3143 386503755 : hpond = max(hpond, c0)
3144 :
3145 : ! exponential decay of pond
3146 386503755 : hpond = hpond - lambda_pond * dt * (hpond + hpond0)
3147 :
3148 386503755 : hpond = max(hpond, c0)
3149 :
3150 : endif
3151 : endif
3152 :
3153 609317819 : end subroutine flush_pond
3154 :
3155 : !=======================================================================
3156 :
3157 609317819 : subroutine flood_ice(hsn, hin, &
3158 : nslyr, nilyr, &
3159 : hslyr, hilyr, &
3160 609317819 : zqsn, zqin, &
3161 609317819 : phi, dt, &
3162 1218635638 : zSin, Sbr, &
3163 : sss, qocn, &
3164 : snoice, fadvheat)
3165 :
3166 : ! given upwards flushing brine flow calculate amount of snow ice and
3167 : ! convert snow to ice with appropriate properties
3168 :
3169 : integer (kind=int_kind), intent(in) :: &
3170 : nilyr , & ! number of ice layers
3171 : nslyr ! number of snow layers
3172 :
3173 : real(kind=dbl_kind), intent(in) :: &
3174 : dt , & ! time step (s)
3175 : hsn , & ! snow thickness (m)
3176 : hin , & ! ice thickness (m)
3177 : sss , & ! sea surface salinity (ppt)
3178 : qocn ! ocean brine enthalpy (J m-2)
3179 :
3180 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
3181 : zqsn , & ! snow layer enthalpy (J m-2)
3182 : zqin , & ! ice layer enthalpy (J m-2)
3183 : zSin , & ! ice layer bulk salinity (ppt)
3184 : phi ! ice liquid fraction
3185 :
3186 : real(kind=dbl_kind), dimension(:), intent(in) :: &
3187 : Sbr ! ice layer brine salinity (ppt)
3188 :
3189 : real(kind=dbl_kind), intent(inout) :: &
3190 : hslyr , & ! snow layer thickness (m)
3191 : hilyr ! ice layer thickness (m)
3192 :
3193 : real(kind=dbl_kind), intent(out) :: &
3194 : snoice ! snow ice formation
3195 :
3196 : real(kind=dbl_kind), intent(inout) :: &
3197 : fadvheat ! advection heat flux to ocean
3198 :
3199 : real(kind=dbl_kind) :: &
3200 32451503 : hin2 , & ! new ice thickness (m)
3201 32451503 : hsn2 , & ! new snow thickness (m)
3202 32451503 : hilyr2 , & ! new ice layer thickness (m)
3203 32451503 : hslyr2 , & ! new snow layer thickness (m)
3204 32451503 : dh , & ! thickness of snowice formation (m)
3205 32451503 : phi_snowice , & ! liquid fraction of new snow ice
3206 32451503 : rho_snowice , & ! density of snowice (kg m-3)
3207 32451503 : zSin_snowice , & ! bulk salinity of new snowice (ppt)
3208 32451503 : zqin_snowice , & ! ice enthalpy of new snowice (J m-2)
3209 32451503 : zqsn_snowice , & ! snow enthalpy of snow thats becoming snowice (J m-2)
3210 32451503 : freeboard_density , & ! negative of ice surface freeboard times the ocean density (kg m-2)
3211 32451503 : ice_mass , & ! mass of the ice (kg m-2)
3212 32451503 : rho_ocn , & ! density of the ocean (kg m-3)
3213 32451503 : ice_density , & ! density of ice layer (kg m-3)
3214 32451503 : hadded , & ! thickness rate of water used from ocean (m/s)
3215 32451503 : wadded , & ! mass rate of water used from ocean (kg/m^2/s)
3216 32451503 : eadded ! energy rate of water used from ocean (W/m^2)
3217 :
3218 : ! real(kind=dbl_kind) :: &
3219 : ! sadded ! salt rate of water used from ocean (kg/m^2/s)
3220 :
3221 : integer :: &
3222 : k ! vertical index
3223 :
3224 : character(len=*),parameter :: subname='(flood_ice)'
3225 :
3226 609317819 : snoice = c0
3227 :
3228 : ! check we have snow
3229 609317819 : if (hsn > puny) then
3230 :
3231 531599226 : rho_ocn = icepack_mushy_density_brine(sss)
3232 :
3233 : ! ice mass
3234 531599226 : ice_mass = c0
3235 4252793808 : do k = 1, nilyr
3236 3721194582 : ice_density = min(phi(k) * icepack_mushy_density_brine(Sbr(k)) + (c1 - phi(k)) * rhoi,rho_ocn)
3237 4252793808 : ice_mass = ice_mass + ice_density
3238 : enddo ! k
3239 531599226 : ice_mass = ice_mass * hilyr
3240 :
3241 : ! negative freeboard times ocean density
3242 531599226 : freeboard_density = max(ice_mass + hsn * rhos - hin * rho_ocn, c0)
3243 :
3244 : ! check if have flooded ice
3245 531599226 : if (freeboard_density > c0) then
3246 :
3247 : ! sea ice fraction of newly formed snow ice
3248 51963859 : phi_snowice = (c1 - rhos / rhoi)
3249 :
3250 : ! density of newly formed snowice
3251 51963859 : rho_snowice = phi_snowice * rho_ocn + (c1 - phi_snowice) * rhoi
3252 :
3253 : ! calculate thickness of new ice added
3254 51963859 : dh = freeboard_density / (rho_ocn - rho_snowice + rhos)
3255 51963859 : dh = max(min(dh,hsn),c0)
3256 :
3257 : ! enthalpy of snow that becomes snowice
3258 51963859 : call enthalpy_snow_snowice(nslyr, dh, hsn, zqsn, zqsn_snowice)
3259 51963859 : if (icepack_warnings_aborted(subname)) return
3260 :
3261 : ! change thicknesses
3262 51963859 : hin2 = hin + dh
3263 51963859 : hsn2 = hsn - dh
3264 :
3265 51963859 : hilyr2 = hin2 / real(nilyr,dbl_kind)
3266 51963859 : hslyr2 = hsn2 / real(nslyr,dbl_kind)
3267 :
3268 : ! properties of new snow ice
3269 51963859 : zSin_snowice = phi_snowice * sss
3270 51963859 : zqin_snowice = phi_snowice * qocn + zqsn_snowice
3271 :
3272 : ! change snow properties
3273 51963859 : call update_vertical_tracers_snow(nslyr, zqsn, hslyr, hslyr2)
3274 51963859 : if (icepack_warnings_aborted(subname)) return
3275 :
3276 : ! change ice properties
3277 0 : call update_vertical_tracers_ice(nilyr, zqin, hilyr, hilyr2, &
3278 51963859 : hin, hin2, zqin_snowice)
3279 51963859 : if (icepack_warnings_aborted(subname)) return
3280 0 : call update_vertical_tracers_ice(nilyr, zSin, hilyr, hilyr2, &
3281 51963859 : hin, hin2, zSin_snowice)
3282 51963859 : if (icepack_warnings_aborted(subname)) return
3283 0 : call update_vertical_tracers_ice(nilyr, phi, hilyr, hilyr2, &
3284 51963859 : hin, hin2, phi_snowice)
3285 51963859 : if (icepack_warnings_aborted(subname)) return
3286 :
3287 : ! change thicknesses
3288 51963859 : hilyr = hilyr2
3289 51963859 : hslyr = hslyr2
3290 51963859 : snoice = dh
3291 :
3292 51963859 : hadded = (dh * phi_snowice) / dt
3293 51963859 : wadded = hadded * rhoi
3294 51963859 : eadded = hadded * qocn
3295 : ! sadded = wadded * ice_ref_salinity * p001
3296 :
3297 : ! conservation
3298 51963859 : fadvheat = fadvheat - eadded
3299 :
3300 : endif
3301 :
3302 : endif
3303 :
3304 : end subroutine flood_ice
3305 :
3306 : !=======================================================================
3307 :
3308 51963859 : subroutine enthalpy_snow_snowice(nslyr, dh, hsn, zqsn, zqsn_snowice)
3309 :
3310 : ! determine enthalpy of the snow being converted to snow ice
3311 :
3312 : integer (kind=int_kind), intent(in) :: &
3313 : nslyr ! number of snow layers
3314 :
3315 : real(kind=dbl_kind), intent(in) :: &
3316 : dh , & ! thickness of new snowice formation (m)
3317 : hsn ! initial snow thickness
3318 :
3319 : real(kind=dbl_kind), dimension(:), intent(in) :: &
3320 : zqsn ! snow layer enthalpy (J m-2)
3321 :
3322 : real(kind=dbl_kind), intent(out) :: &
3323 : zqsn_snowice ! enthalpy of snow becoming snowice (J m-2)
3324 :
3325 : real(kind=dbl_kind) :: &
3326 4452112 : rnlyr ! real value of number of snow layers turning to snowice
3327 :
3328 : integer(kind=int_kind) :: &
3329 : nlyr , & ! no of snow layers completely converted to snowice
3330 : k ! snow layer index
3331 :
3332 : character(len=*),parameter :: subname='(enthalpy_snow_snowice)'
3333 :
3334 51963859 : zqsn_snowice = c0
3335 :
3336 : ! snow depth and snow layers affected by snowice formation
3337 51963859 : if (hsn > puny) then
3338 51963859 : rnlyr = (dh / hsn) * nslyr
3339 51963859 : nlyr = min(floor(rnlyr),nslyr-1) ! nlyr=0 if nslyr=1
3340 :
3341 : ! loop over full snow layers affected
3342 : ! not executed if nlyr=0
3343 51963859 : do k = nslyr, nslyr-nlyr+1, -1
3344 51963859 : zqsn_snowice = zqsn_snowice + zqsn(k) / rnlyr
3345 : enddo ! k
3346 :
3347 : ! partially converted snow layer
3348 : zqsn_snowice = zqsn_snowice + &
3349 51963859 : ((rnlyr - real(nlyr,dbl_kind)) / rnlyr) * zqsn(nslyr-nlyr)
3350 : endif
3351 :
3352 51963859 : end subroutine enthalpy_snow_snowice
3353 :
3354 : !=======================================================================
3355 :
3356 51963859 : subroutine update_vertical_tracers_snow(nslyr, trc, hlyr1, hlyr2)
3357 :
3358 : ! given some snow ice formation regrid snow layers
3359 :
3360 : integer (kind=int_kind), intent(in) :: &
3361 : nslyr ! number of snow layers
3362 :
3363 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
3364 : trc ! vertical tracer
3365 :
3366 : real(kind=dbl_kind), intent(in) :: &
3367 : hlyr1 , & ! old cell thickness
3368 : hlyr2 ! new cell thickness
3369 :
3370 : real(kind=dbl_kind), dimension(1:nslyr) :: &
3371 103927718 : trc2 ! temporary array for updated tracer
3372 :
3373 : ! vertical indexes for old and new grid
3374 : integer(kind=int_kind) :: &
3375 : k1 , & ! vertical index for old grid
3376 : k2 ! vertical index for new grid
3377 :
3378 : real(kind=dbl_kind) :: &
3379 4452112 : z1a , & ! lower boundary of old cell
3380 4452112 : z1b , & ! upper boundary of old cell
3381 4452112 : z2a , & ! lower boundary of new cell
3382 4452112 : z2b , & ! upper boundary of new cell
3383 4452112 : overlap ! overlap between old and new cell
3384 :
3385 : character(len=*),parameter :: subname='(update_vertical_tracers_snow)'
3386 :
3387 : ! loop over new grid cells
3388 103927718 : do k2 = 1, nslyr
3389 :
3390 : ! initialize new tracer
3391 51963859 : trc2(k2) = c0
3392 :
3393 : ! calculate upper and lower boundary of new cell
3394 51963859 : z2a = (k2 - 1) * hlyr2
3395 51963859 : z2b = k2 * hlyr2
3396 :
3397 : ! loop over old grid cells
3398 103927718 : do k1 = 1, nslyr
3399 :
3400 : ! calculate upper and lower boundary of old cell
3401 51963859 : z1a = (k1 - 1) * hlyr1
3402 51963859 : z1b = k1 * hlyr1
3403 :
3404 : ! calculate overlap between old and new cell
3405 51963859 : overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
3406 :
3407 : ! aggregate old grid cell contribution to new cell
3408 103927718 : trc2(k2) = trc2(k2) + overlap * trc(k1)
3409 :
3410 : enddo ! k1
3411 :
3412 : ! renormalize new grid cell
3413 103927718 : trc2(k2) = trc2(k2) / hlyr2
3414 :
3415 : enddo ! k2
3416 :
3417 : ! update vertical tracer array with the adjusted tracer
3418 103927718 : trc = trc2
3419 :
3420 51963859 : end subroutine update_vertical_tracers_snow
3421 :
3422 : !=======================================================================
3423 :
3424 155891577 : subroutine update_vertical_tracers_ice(nilyr, trc, hlyr1, hlyr2, &
3425 : h1, h2, trc0)
3426 :
3427 : ! given some snow ice formation regrid ice layers
3428 :
3429 : integer (kind=int_kind), intent(in) :: &
3430 : nilyr ! number of ice layers
3431 :
3432 : real(kind=dbl_kind), dimension(:), intent(inout) :: &
3433 : trc ! vertical tracer
3434 :
3435 : real(kind=dbl_kind), intent(in) :: &
3436 : hlyr1 , & ! old cell thickness
3437 : hlyr2 , & ! new cell thickness
3438 : h1 , & ! old total thickness
3439 : h2 , & ! new total thickness
3440 : trc0 ! tracer value of added snow ice on ice top
3441 :
3442 : real(kind=dbl_kind), dimension(1:nilyr) :: &
3443 391921170 : trc2 ! temporary array for updated tracer
3444 :
3445 : integer(kind=int_kind) :: &
3446 : k1 , & ! vertical indexes for old grid
3447 : k2 ! vertical indexes for new grid
3448 :
3449 : real(kind=dbl_kind) :: &
3450 13356336 : z1a , & ! lower boundary of old cell
3451 13356336 : z1b , & ! upper boundary of old cell
3452 13356336 : z2a , & ! lower boundary of new cell
3453 13356336 : z2b , & ! upper boundary of new cell
3454 13356336 : overlap ! overlap between old and new cell
3455 :
3456 : character(len=*),parameter :: subname='(update_vertical_tracers_ice)'
3457 :
3458 : ! loop over new grid cells
3459 1247132616 : do k2 = 1, nilyr
3460 :
3461 : ! initialize new tracer
3462 1091241039 : trc2(k2) = c0
3463 :
3464 : ! calculate upper and lower boundary of new cell
3465 1091241039 : z2a = (k2 - 1) * hlyr2
3466 1091241039 : z2b = k2 * hlyr2
3467 :
3468 : ! calculate upper and lower boundary of added snow ice at top
3469 1091241039 : z1a = c0
3470 1091241039 : z1b = h2 - h1
3471 :
3472 : ! calculate overlap between added ice and new cell
3473 1091241039 : overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
3474 :
3475 : ! aggregate added ice contribution to new cell
3476 1091241039 : trc2(k2) = trc2(k2) + overlap * trc0
3477 :
3478 : ! loop over old grid cells
3479 8729928312 : do k1 = 1, nilyr
3480 :
3481 : ! calculate upper and lower boundary of old cell
3482 7638687273 : z1a = (k1 - 1) * hlyr1 + h2 - h1
3483 7638687273 : z1b = k1 * hlyr1 + h2 - h1
3484 :
3485 : ! calculate overlap between old and new cell
3486 7638687273 : overlap = max(min(z1b, z2b) - max(z1a, z2a), c0)
3487 :
3488 : ! aggregate old grid cell contribution to new cell
3489 8729928312 : trc2(k2) = trc2(k2) + overlap * trc(k1)
3490 :
3491 : enddo ! k1
3492 :
3493 : ! renormalize new grid cell
3494 1247132616 : trc2(k2) = trc2(k2) / hlyr2
3495 :
3496 : enddo ! k2
3497 :
3498 : ! update vertical tracer array with the adjusted tracer
3499 1247132616 : trc = trc2
3500 :
3501 155891577 : end subroutine update_vertical_tracers_ice
3502 :
3503 : !=======================================================================
3504 :
3505 : end module icepack_therm_mushy
3506 :
3507 : !=======================================================================
|