# fcts_snowpackflow.py

This script contains all the functions required to make the pereferential flow scheme of snowpack work https://models.slf.ch/p/snowpack/source/tree/HEAD/branches/dev/snowpack/snowpackCore/ReSolver1d.cc

`fcts_snowpackflow.``Micedryer`(dz, rho, Mtheta, Mtheta_sat, crtn_theta, rhoimp, totrunoff)

  This works the same as satexcess but in order to make sure that layers at pore close-off density (rho>rhoimp) are dry in MFdom.

`fcts_snowpackflow.``Mrefreezing`(dz, zstep, rho, grain, Tz, Mthetar_old, Mlwc, lwc_min_fr, Ptheta, PeffSat, Plwc, h_e, bigF, mu, crtn_theta, rhoimp, totrefrozen_lwc, refrozenlay, totrunoff)

  Proceed to refreezing according to cold content of every layer. Adjust porosity and hydraulic properties accordingly. Verify that we don’t oversaturate PFdom. If so, we call for Psatexcess

`fcts_snowpackflow.``Msatexcess`(dz, rho, Mtheta, Mtheta_sat, crtn_theta, rhoimp, totrunoff)

  For MFdom In case the water content of some layers exceeds the water content at saturation, we move the water to the layers below (in priority) and in the layers above (if there is not enough pore space in all the layers below)

`fcts_snowpackflow.``NPtrid`(a, b, c, d)

  function to solve tridiagonal matrix –> find x matrix in Ax=d equation

  a,b,c,d are arrays, should be made of floats, not integer a and c are 1 index shorter than b and d - [b0 c0 0. 0. …] - [a0 b1 c1 0. …] A = [……………] - [. 0. 0. an-1 bn]

`fcts_snowpackflow.``PFleave`(dz, rho, Tz, Mtheta, Mthetar, Mthetar_old, MeffSat, Mtheta_sat, Mlwc, Ptheta, PeffSat, Plwc, Ptheta_sat, crtn_theta, rhoimp, aquif, PSatlim)

  When the saturation in the PF domain reaches a threshold value (PSatlim), backflow towards MFdom occurs. First we transfer as much water as the cold content of the layer can accomodate Second, if PSatlim is still exceeded, we equalise saturations in both domains Note that at the end, saturation might not be the same if we equalise because Mthetar can change subsequently

`fcts_snowpackflow.``PFleaveheat`(dz, rho, Tz, Mtheta, Mthetar, Mthetar_old, MeffSat, Mtheta_sat, Mlwc, Ptheta, PeffSat, Plwc, Ptheta_sat, crtn_theta, kth, bigF, bigN, aquif, rhoimp, deltatime)

  This mimics refreezing in the PF domain by transferring water back to the MF dom depending on how much heat would be lost by water in PFdom (see paragraph 2.3 of Wever 2016) It depends on the tuning parameter bigN which represents number of preferential flow paths per unit area Based on equations (6) and (7) of Wever 2016 but caution, misformulation in (7)

`fcts_snowpackflow.``Picedryer`(dz, rho, Ptheta, Ptheta_sat, crtn_theta, rhoPdr, totrunoff)

  This works the same as satexcess but in order to make sure that layers at pore close-off density (rho>rhoimp) are dry in MFdom.

`fcts_snowpackflow.``Prefreezing`(dz, rho, grain, Tz, Mthetar_old, Mtheta, Mlwc, lwc_min_fr, Ptheta, PeffSat, Plwc, bigF, h_e, mu, crtn_theta, dryfront, totrefrozen_lwc, refrozenlay, rhoimp, totrunoff)

  Not used in preferential flow scheme of Wever 2016 but might be a good idea to use. Proceed to refreezing of Plwc until dryfront according to cold content of every layer. Adjust porosity and hydraulic properties accordingly. Also needs the variables Mtheta and dryfront as input parameters (vs refreezing())

`fcts_snowpackflow.``Psatexcess`(dz, rho, Ptheta, Ptheta_sat, crtn_theta, rhoimp, totrunoff)

  This works the same as Msatexcess but for PFdom In case the water content of some layers exceeds the water content at saturation, we move the water to the layers below (in priority) and in the layers above (if there is not enough pore space in all the layers below)

`fcts_snowpackflow.``TDMAsolver`(a, b, c, d)

  Way faster than NPtrid!!

  TDMA solver –> find x matrix in Ax=d equation a,b,c,d are arrays, should be made of floats, not integer a and c are 1 index shorter than b and d - [b0 c0 0. 0. …] - [a0 b1 c1 0. …] A = [……………] - [. 0. 0. an-1 bn] A is nxn tridiagonal matrix with a - b - c as diagonals, x is nx1 matrix, d is nx1 matrix Sources: https://gist.github.com/cbellei/8ab3ab8551b8dfc8b081c518ccd9ada9 https://en.wikibooks.org/wiki/Algorithm_Implementation/Linear_Algebra/Tridiagonal_matrix_algorithm#Python

`fcts_snowpackflow.``combineCFM`(split_list, rhoF, dzF, TzF, massF, lwcF, Plwc_memF, r2F, refrozenF)

  F for fine grid C for coarse grid Here, we need the vectors that are outputs of the flow routine: - combine them back to reintegrate these to the CFM - Note that we also need the split_list ! (nb of sublayers into which every CFM layer was split by the split function) - Normally, RE routine (including freezing) should not affect dz and r2 variables but only use them -> not necessary to combine them and to give them back to CFM (which can keep its own self.dz and self.r2)

`fcts_snowpackflow.``entrysuction`(dz, Mtheta, Mthetar, Mthetar_old, MeffSat, Mtheta_sat, Mlwc, Ptheta, PeffSat, Plwc, Ptheta_sat, crtn_theta, aquif, MSat_westag)

  When the pressure exceeds the water entry suction of layer below, water penetrates from MFdom layer to PFdom of layer below We convert water entry suction in more intuitive saturation value If after transfer, saturation of the layer below in PFdom is still inferior to saturation in layer above in MFdom, we equalise saturations

`fcts_snowpackflow.``layerequaliser_eq`(dz, Mtheta, Mthetar, Mthetar_old, MeffSat, Mtheta_sat, Mlwc, Ptheta, PeffSat, Plwc, Ptheta_sat, crtn_theta, aquif)

  Whenever the effective saturation in the MFdom exceeds the saturation in the PFdom within a same layer, we equalise saturations Not sure this is physically realistic but that is what is written in Wever 2016 https://models.slf.ch/p/snowpack/source/tree/HEAD/branches/dev/snowpack/snowpackCore/ReSolver1d.cc + confirmed by Nander Wever, email 27 Sept 2018

`fcts_snowpackflow.``lengthendom`(self, rho_short, dz_short, Tz_short, mass_short, lwc_short, Plwc_mem_short, r2_short)

  After having solved the flow, we concatenate back new values with deep values that were not taken into account during the flow routine (because all their rho values was above rhoimp from a certain depth). !! This function has to be called before the flow routine but AFTER the melting !!

`fcts_snowpackflow.``restrictdom`(self)

  Limit the domain to reduce computational time of flow solving Spot the deepest layer below pore close-off density (rhoimp). The bottom of the domain will be the next layer. Thus, we do not take all the column where rho is constantly above pore close-off density (rhoimp). But we make sure not to exclude any layer that has liquid water

`fcts_snowpackflow.``runoff`(dz, rho, Mhead, Mtheta, Mthetar, Mthetar_old, MeffSat, Mlwc, Mtheta_sat, theta_min_fr, crtn_theta, slope, rhoimp, aquif, deltatime, totrunoff)

  This is the Greenland specific runoff function of Zuo and Oerlemans 1996 (21) We proceed to runoff only for layers of which water content is above theta_min_fr. CAUTION: this might be changed!! We don’t apply runoff in the aquifer

`fcts_snowpackflow.``splitCFM`(rhoC, dzC, TzC, massC, lwcC, Plwc_memC, r2C, vert_res)

  F for fine grid C for coarse grid We split the layers of the CFM in layers of a certain maximal thickness. Maximal thickness must be specified in vert_res. With the implementation of upstream weighted mean for K at interfaces, we can take large vert_res value!