Beispiel #1
0
def seawater_freezingpoint(sW, p=10.1325):
    """
	Parameters
	----------
		sW : array_like, number
			salinity of sea water in [PsU]
		p : array_like, number
			atmospheric pressure in [dbar]. atmospheric pressure at sea level by default p = 10.1325

	Returns
	----------
		sigma: ndarray
			conductivity of the brine in microsiemens/meter [ms/m]

		Valid for sW 4-40, and p up to 500
	"""
    p = icdt.make_array(p)
    sW = icdt.make_array(sW)

    ii_max = len(sW)

    t_fsw = []

    A = [-0.0575, +1.710523e-3, -2.154996e-4]
    B = [-7.53e-4]

    for ii in range(0, ii_max):
        t_fsw.append(A[0] * sW[ii] + A[1] * (sW[ii] * (3 / 2)) + A[2] * (sW[ii] ** 2) + B[0] * p)
    return t_fsw
Beispiel #2
0
def seaice_resistivity(t, s, rho_si=0.917):
    """
		Calculate the electric resistivity of sea ice for a given temperature and salinity

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
		s : array_like, number
			salinity in practical salinity unit [PsU]
		rho_si : optional, array_like, number
			density of the ice in gram per cubic centimeter [g cm^{-3}]. Defaults 0.917.

		Returns
		----------
		rhoel_si: ndarray
			resistiviy of seaice in microsiemens/meter [s/m]
	"""
    t = icdt.make_array(t)
    s = icdt.make_array(s)
    # Need to check if array is the same length as t and s otherway return error message
    rho_si = icdt.make_array(rho_si)

    sigma_b = brine_electricconductivity(t)
    vf_b = brine_volume_fraction(t, s, rho_si)

    rhoel_si = (sigma_b * (vf_b) ** 2) ** (-1)

    return rhoel_si
Beispiel #3
0
def seaice_latentheat(t, s, transformation='fusion'):
    """
		Calculate bulk latent heat from temperature and salinity during freezing ('f') or melting ('m')

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
			If t is an array, s should be an array of the same length
		s : array_like, number
			salinity in practical salinity unit [PsU]
			If s is an array, t should be an array of the same length
		transformation : optional, string
			direction of the phase transformation: solidification ('freezing') or fusion ('melting')
			default phase transformation is solidification

		Returns
		----------
		L_si: ndarray
			sea Ice latent heat of fusion

		sources
		----------
		Equation 2.28 and 2.29 in thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell

		from Equation (16) Ono, N. (1967). specific heat and heat of fusion of sea ice. In Physic of snow and Ice (H. Oura., Vol. 1, pp. 599–610).

	"""
    t = icdt.make_array(t)
    s = icdt.make_array(s)

    if len(t) > 1:
        if len(t) != len(s):
            print('t and s profile should be the same length')
            return 0

    # Pysical Constant
    L = 333.4  # [kJ kg^{-1}] latent heat of fusion of freshwater
    m_m = -0.05411  # [K]  slope of the liquid
    c_i = 2.11  # [kJ kg^{-1}K^{-1}] specific heat cpacity of ice @ 0°C
    c_w = 4.179  # [kJ kg^{-1}K^{-1}] specific heat cpacity of freshwater @ 0°C
    s_0 = 35  # [PsU] standard seawater salinity

    s00 = 'freezing'
    s01 = 'solidification'
    s10 = 'fusion'
    s11 = 'melting'

    if s00.startswith(transformation) or s01.startswith(transformation):
        L_si = L - c_i * t + c_i * m_m * s - m_m * L * (s / t) + c_w * m_m * (s_0 - s)
    elif s10.startswith(transformation) or s11.startswith(transformation):
        L_si = L - c_i * t + c_i * m_m * s - m_m * L * (s / t)
    return L_si
Beispiel #4
0
def seaice_electricconductivity(t, s, rho_si=0.917, flag_comment='n'):
    """
		Calculate the electric conductivity of sea ice for a given temperature and salinity

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
		s : array_like, number
			salinity in practical salinity unit [PsU]
		rho_si : optional, array_like, number
			density of the ice in gram per cubic centimeter [g cm^{-3}]. Defaults 0.917.

		Returns
		----------
		sigma_si: ndarray
			conductivity of seaice in microsiemens/meter [s/m]
	"""
    t = icdt.make_array(t)
    s = icdt.make_array(s)
    rho_si = icdt.make_array(rho_si)

    # todo improve this method by getting the length of the ice core
    if len(t) > 1:
        if len(t) != len(s):
            if flag_comment == 'y':
                print('Vb t and s profile should be the same length')
            delta_t = len(t) - len(s)
            if delta_t < 0:
                temp = np.empty((-delta_t))
                temp[:] = np.nan
                t = np.append(t, temp)
            elif delta_t > 0:
                # reinterpolation of t for the length of s
                # xs = np.linspace(0,1,len(s))
                # xt = np.linspace(0,1,len(t))
                # t = np.interp(xs, xt, t)
                # todo: interpolation is a good idea, but does not work as I wish it works better to add a marker for short core in the data.
                lent = len(t)
                t = t[0:len(s)]
                t[len(s):lent] = np.nan
                s[len(s):lent] = np.nan

    sigma_b = brine_electricconductivity(t, flag_comment='n')
    vf_b = brine_volume_fraction(t, s, rho_si, flag_comment='n')

    sigma_si = sigma_b * (vf_b) ** 2

    return sigma_si
Beispiel #5
0
def brine_electricconductivity(t, flag_comment='n'):
    """
		Calculate the electric conductivity of brine for a given temperature

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]

		Returns
		----------
		sigma: ndarray
			conductivity of the brine in microsiemens/meter [ms/m]

		Equation
		_________
			Fofonoff, Nick P., and Robert C. Millard. "Algorithms for computation of fundamental properties of seawater." (1983).
	"""
    import numpy as np

    t = icdt.make_array(t)
    ii_max = len(t)

    # Physical constant
    A = [0.08755, 0.5193]

    sigma_b = []
    for ii in range(0, ii_max):
        sigma_b.append(-t[ii] * np.exp(np.polyval(A, t[ii])))
    return np.array(sigma_b)
Beispiel #6
0
def brine_density(t):
    """
		Calculate the density of the brine in function of the temperature.

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]

		Returns
		----------
		rho_b: ndarray
			density of the brine in gram per cubic centimeters [g cm^{-3}]

		sources
		----------
		Equation 2.9 in thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell

		from equation (3) in Cox, G. F. N., & Weeks, W. F. (1986). Changes in the salinity and porosity of sea-ice samples during shipping and storage. J. Glaciol, 32(112)

		from Zubov, N.N. (1945), L'dy Arktiki [Arctic ice]. Moscow, Izdatel'stvo Glavsevmorputi.

	"""
    # Physical constant
    A = [8 * 10 ** (-4), 1]
    t = icdt.make_array(t)

    s_b = brine_salinity(t)
    rho_b = (A[1] + A[0] * s_b)

    return rho_b
Beispiel #7
0
def ice_density(t, flag_comment='y'):
    """
		Calculate the density of the pure water ice in function of the temperature

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
		flag_comment : {'y','n'}, optional
			Whether to display the commet or not. Default is 'y'

		Returns
		----------
		rho_i: ndarray
			density of the ice in gram per cubic centimeters [g cm^{-3}]

		sources
		----------
		Equation 2.7 in thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell

		from Pounder. E. R. 1965. the physics of ice. Oxford. etc .. Pergamon Press. (the Commonwealth and International Library. Geophysics Division.) Ringer.

	"""
    import numpy as np

    # Physical constant
    A = [-0.000117, 1]
    B = 0.917

    t = np.atleast_1d(t)
    t = icdt.make_array(t)
    ii_max = len(t)
    rho_ice = np.empty((ii_max))
    rho_ice[:] = np.nan

    rho_ice[np.where(t < 0)] = B * np.polyval(A, t[np.where(t < 0)])

    if flag_comment == 'y':
        if t > 0:
            print('temperature above 0°C : ice has melt')
        for ii in np.where(t >= 0)[0]:
            print('layer ' + str(ii + 1) + ' : t=' + str(t[ii]) + '°C')

    return rho_ice
Beispiel #8
0
def brine_thermal_conductivity(t, flag_comment='y'):
    """
		Calculate thermal conductivity of brine

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
			If t is an array, s should be an array of the same length

		Returns
		----------
		lambda_si ndarray
			Volume fraction of brine in the ice

		sources
		----------
		Equation 2.12 in Eicken, H. (2003). From the microscopic, to the macroscopic, to the regional scale: growth, microstructure and properties of sea ice. In thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell

		From Yen, Y. C., Cheng, K. C., and Fukusako, s. (1991) Review of intrinsic thermophysical properties of snow, ice, sea ice, and frost. In: Proceedings 3rd International symposium on Cold Regions Heat transfer, Fairbanks, AK, June 11-14, 1991. (Ed. by J. P. Zarling & s. L. Faussett), pp. 187-218, University of Alaska, Fairbanks
	"""
    import numpy as np

    # Physical constant
    A = [0.00014, 0.030, 1.25]
    B = 0.4184
    t = icdt.make_array(t)

    ii_max = len(t)
    lambda_b = np.empty((ii_max))
    lambda_b[:] = np.nan

    lambda_b[np.where(t < 0)] = B * np.polyval(A, t[np.where(t < 0)])

    if flag_comment == 'y':
        for ii in np.where(t >= 0)[0]:
            print('layer ' + str(ii + 1) + ' : t=' + str(t[ii]) + '°C, ice has melt')
    for ii in np.where(lambda_b < 0)[0]:
        lambda_b[ii] = np.nan
        if flag_comment == 'y':
            print('layer ' + str(ii + 1) + ' : conductivity not defined')
    return lambda_b
Beispiel #9
0
def seaice_permeability(t, s, rho_si='default', flag_comment='n'):
    """
		Calculate the volume fraction of brine in function of the temperature and salinity

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
			If t is an array, s should be an array of the same length
		s : array_like, number
			salinity in practical salinity unit [PsU]
			If s is an array, t should be an array of the same length
		rho_si : optional, array_like, number
			density of the ice in gram per cubic centimeter [g cm^{-3}]. Defautl is calculated for t,s value with a default air volume fraction set to 0.5‰.
			If rho_si is an array, t should be an array of the same length
		flag_comment : option, string
			toggle comment on/off

		Returns
		----------
		vf_b: ndarray
			Volume fraction of brine in the ice

		sources
		----------
		thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell
		from equation 5 and 15 in Cox, G. F. N., & Weeks, W. F. (1983). Equations for determining the gas and brine volumes in sea ice samples. Journal of Glaciology (Vol. 29, pp. 306–316).

	"""
    # check array lengths
    t = icdt.make_array(t)
    s = icdt.make_array(s)

    # todo improve this method by getting the length of the ice core
    if len(t) > 1:
        if len(t) != len(s):
            print('Vb t and s profile should be the same length')
            delta_t = len(t) - len(s)
            if delta_t < 0:
                temp = np.empty((-delta_t))
                temp[:] = np.nan
                t = np.append(t, temp)
            elif delta_t > 0:
                # reinterpolation of t for the length of s
                # xs = np.linspace(0,1,len(s))
                # xt = np.linspace(0,1,len(t))
                # t = np.interp(xs, xt, t)
                # t = np.interp(xs, xt, t)
                # todo: interpolation is a good idea, but does not work as I wish it works.
                lent = len(t)
                t = t[0:len(s)]
                t[len(s):lent] = np.nan
                s[len(s):lent] = np.nan
        else:
            t = t[0:len(s)]

    if rho_si == 'default':
        rho_si = seaice_density(t, s, flag_comment='n')
    else:
        rho_si = icdt.make_array(rho_si)
        if len(rho_si) != len(s) or len(rho_si) != 1:
            print('rho_si should be the same length as t and s')
            rho_si = np.ones(len(s))[:] * rho_si

    Vf_b = brine_volume_fraction(t, s, rho_si=rho_si, flag_comment='n')
    k = 3 * Vf_b ** 2 * 10 ** (-10)
    return k
Beispiel #10
0
def seaice_thermalConductivity(t, s, method='Maykut', flag_comment='y'):
    """
		Calculate bulk thermal conductivity of sea ice

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
			If t is an array, s should be an array of the same length
		s : array_like, number
			salinity in practical salinity unit [PsU]
			If s is an array, t should be an array of the same length
		method : optional, string
			thermal conductivity could be either calculated with Maykut or Pringle equation

		Returns
		----------
		lambda_si ndarray
			Volume fraction of brine in the ice

		sources
		----------
		Equation 2.14 and 2.16 in Eicken, H. (2003). From the microscopic, to the macroscopic, to the regional scale: growth, microstructure and properties of sea ice. In thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell

		Pringle method is describe in Pringle, D. J., Eicken, H., trodahl, H. J., & Backstrom, L. G. E. (2007). thermal conductivity of landfast Antarctic and Arctic sea ice. Journal of Geophysical Research, 112(C4), C04017. doi:10.1029/2006JC003641

		Maykut method is describe in Maykut, G. A. (1986). the surface heat and mass balance. In N. Understeiner (Ed.), the geophysics of sea ice (pp. 395–463). Dordrecht (NAtO AsI B146): Martinus Nijhoff Publishers.
	"""
    import numpy as np

    t = icdt.make_array(t)
    s = icdt.make_array(s)

    if len(t) > 1:
        if len(t) != len(s):
            print('t and s profile should be the same length')
            return 0

    ii_max = len(t)
    lambda_si = np.empty((ii_max))
    lambda_si[:] = np.nan

    if method == 'Maykut':
        # Physical constant
        A = 0.13

        lambda_si[np.where(t < 0)] = (
            ice_thermalConductivity(t[np.where(t < 0)]) + A * s[np.where(t < 0)] / t[np.where(t < 0)])

    elif method == 'Pringle':
        rho_si = seaice_density(t, s, flag_comment='n')
        rho_i = ice_density(t, flag_comment='n')

        lambda_si[np.where(t < 0)] = rho_si[np.where(t < 0)] / rho_i[np.where(t < 0)] * (
            2.11 - 0.011 * t[np.where(t < 0)] + 0.09 * s[np.where(t < 0)] / t[np.where(t < 0)] - (
                rho_si[np.where(t < 0)] - rho_i[np.where(t < 0)]) / 1000)

    if flag_comment == 'y':
        for ii in np.where(t >= 0)[0]:
            print('layer ' + str(ii + 1) + ' : t=' + str(t[ii]) + '°C, ice has melt')
    for ii in np.where(lambda_si < 0)[0]:
        lambda_si[ii] = np.nan
        if flag_comment == 'y':
            print('layer ' + str(ii + 1) + ' : conductivity not defined')

    return lambda_si
Beispiel #11
0
def brine_salinity(t, method='CW', flag_comment='y'):
    """
    Calculate the salinity of the brine in function of the temperature at equilibrium.

    Parameters
    ----------
    t : array_like, number
        temperature in degree Celsius [°C]
    method : {'As','CW'}, optional
        Whether to calculate the salinity with Assur model ('As') or with the equation of Cox & Weeks (1983) ('CW'). Default is 'CW'
    flag_comment:

    Returns
    ----------
    s_b: ndarray
        salinity of the brine in Practical salinity Unit [PsU]

    sources
    ----------
    'As' : Equation 2.8 in thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell
    'CW' : Equation 25 in Cox, G. F. N., & Weeks, W. F. (1986). Changes in the salinity and porosity of sea-ice samples during shipping and storage. J. Glaciol, 32(112), 371–375
"""
    import numpy as np

    t = icdt.make_array(t)

    ii_max = len(t)
    s_b = np.empty(ii_max)
    s_b[:] = np.nan

    if method == 'As':
        if t.all > -23:
            s_b = ((1 - 54.11 / t) ** (-1)) * 1000
        else:
            print('At least one temperature is inferior to -23[°C]. Cox & Weeks equation is used instead')
            brine_salinity(t, 'CW')
    else:
        # Physical constant
        A = np.empty((3, 4))
        # coefficient for -54<t<=-44
        A[0, :] = [-4442.1, -277.86, -5.501, -0.03669];

        # coefficient for -44<t<=-22.9
        A[1, :] = [206.24, -1.8907, -0.060868, -0.0010247];

        # coefficient for -22.9<t<=-2
        A[2, :] = [-3.9921, -22.700, -1.0015, -0.019956];

        for ii in range(0, ii_max):
            if np.isnan(t[ii]):
                if flag_comment == 'y':
                    print('layer ' + str(ii) + ' : temperature not defined')
            elif t[ii] < -54:
                if flag_comment == 'y':
                    print('layer ' + str(ii) + ' : t=' + str(t[ii]) + '<-54 : ice temperature is out of validity')
            elif 0 <= t[ii]:
                if flag_comment == 'y':
                    print('layer ' + str(ii) + ' : t=' + str(t[ii]) + '>0 : ice has alreay melt')
            else:
                if (-54 < t[ii]) & (t[ii] <= -44):
                    mm = 0
                elif (-44 < t[ii]) & (t[ii] <= -22.9):
                    mm = 1
                elif (-22.9 < t[ii]) & (t[ii] <= 0):
                    mm = 2

                P1 = [A[mm, 3], A[mm, 2], A[mm, 1], A[mm, 0]]

                s_b[ii] = (np.polyval(P1, t[ii]))
    return s_b
Beispiel #12
0
def seaice_density(t, s, vf_a='default', flag_comment='y'):
    """
		Calculate the density of seaice in function of the temperature and salinity

		Parameters
		----------
		t : array_like, number
			temperature in degree Celsius [°C]
			If t is an array, s must be an array of the same length
		s : array_like, number
			salinity in practical salinity unit [PsU]
			If s is an array, t must be an array of the same length
		vf_a : optional, array_like, number
			Air volume fraction, unitless [-].
			If air volume fraction is not defined, defaults value is set to 0.5‰. Usual value for first year sea ice, before spring warming.
			If Vf_a is an array, it tmust be the same length as t and s

		Returns
		----------
		rho_si: ndarray
			density of the brine in gram per cubic centimeters [g cm^{-3}]

		sources
		----------
		Equation 15 in Cox, G. F. N., & Weeks, W. F. (1983). Equations for determining the gas and brine volumes in sea ice samples. Journal of Glaciology (Vol. 29, pp. 306–316).

		Coefficient form Cox & Weeks (1983)  and Leppäranta & Manninen (1988) [Leppäranta, M. & Manninen, t. (1988), the brine an gas content of sea ice with attention to low salinities and high temperatures. Finnish Institute of Marien Research Internal Report 88-2, Helsinki.
	"""
    import numpy as np
    import warnings

    # check parameters
    t = icdt.make_array(t)
    s = icdt.make_array(s)

    if len(t) > 1:
        if len(t) != len(s):
            print('rho sI t and s profile should be the same length')
            delta_t = len(t) - len(s)
            if delta_t < 0:
                delta_t = len(t) - len(s)
                temp = np.empty((-delta_t))
                temp[:] = np.nan
                t = np.append(t, temp)
            elif delta_t > 0:
                lent = len(t)
                t = t[0:len(s)]
                t[len(s):lent] = np.nan
                s[len(s):lent] = np.nan

    if vf_a == 'default':
        vf_a = np.array([0.0005])
        warnings.warn('Air volume fraction is set to default value: Vf_a=0.5 ‰', UserWarning)
    else:
        vf_a = icdt.make_array(vf_a)
        if len(vf_a) != len(s) & len(vf_a) != 1:
            print('Vf_a should be the same length as t and s')
            return 0

    ii_max = len(t)
    rho_seaice = np.empty(ii_max)
    rho_seaice[:] = np.nan

    # Physical constant
    A = np.empty((4, 4, 2))

    # coefficient for t<=-22.9
    A[0, 0, :] = [-0.041221, 0.090312]
    A[0, 1, :] = [-18.407, -0.016111]
    A[0, 2, :] = [0.58402, 1.2291 * 10 ** (-4)]
    A[0, 3, :] = [0.21454, 1.3603 * 10 ** (-4)]

    # coefficient for -22.9<t<=-2
    A[1, 0, :] = [-4.732, 0.08903]
    A[1, 1, :] = [-22.45, -0.01763]
    A[1, 2, :] = [-0.6397, -5.330 * 10 ** (-4)]
    A[1, 3, :] = [-0.01074, -8.801 * 10 ** (-6)]

    # coefficient for -2<t<=0
    A[2, 0, :] = [9899, 8.547]
    A[2, 1, :] = [1309, 1.089]
    A[2, 2, :] = [55.27, 0.04518]
    A[2, 3, :] = [0.7160, 5.819 * 10 ** (-4)]

    rho_i = ice_density(t, 'n')
    rho_seaice = np.empty(ii_max)
    rho_seaice[:] = np.nan

    for ii in range(0, ii_max):
        t_temp = t[ii];
        s_temp = s[ii];
        if np.isnan(t_temp):
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : temperature not defined')
            rho_seaice[ii] = (np.nan)
        elif np.isnan(s_temp):
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : salinity not defined')
            rho_seaice[ii] = (np.nan)
        elif t_temp < -30:
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : t=' + str(t_temp) + '<-30 : ice temperature is out of validity')
        elif 0 <= t_temp:
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : t=' + str(t_temp) + '>0 : ice has alreay melt')
        else:
            if (-30 <= t_temp) & (t_temp <= -22.9):
                mm = 0
            elif (-22.9 < t_temp) & (t_temp <= -2):
                mm = 1
            elif (-2 < t_temp) & (t_temp <= 0):
                mm = 2

            P1 = [A[mm, 3, 0], A[mm, 2, 0], A[mm, 1, 0], A[mm, 0, 0]]
            P2 = [A[mm, 3, 1], A[mm, 2, 1], A[mm, 1, 1], A[mm, 0, 1]]

            F1 = np.polyval(P1, t_temp)
            F2 = np.polyval(P2, t_temp)

            rho_seaice[ii] = ((1 - vf_a) * (rho_i[ii] * F1 / (F1 - rho_i[ii] * s_temp * F2)));
    return rho_seaice
Beispiel #13
0
def brine_volume_fraction(t, s, rho_si='default', flag_comment='n'):
    """
    Calculate the volume fraction of brine in function of the temperature and salinity

    Parameters
    ----------
    t : array_like, number
        temperature in degree Celsius [°C]
        If t is an array, s should be an array of the same length
    s : array_like, number
        salinity in practical salinity unit [PsU]
        If s is an array, t should be an array of the same length
    rho_si : optional, array_like, number
        density of the ice in gram per cubic centimeter [g cm^{-3}]. Defautl is calculated for t,s value with a default air volume fraction set to 0.5‰.
        If rho_si is an array, t should be an array of the same length
    flag_comment : option, string
        toggle comment on/off

    Returns
    ----------
    vf_b: ndarray
        Volume fraction of brine in the ice

    sources
    ----------
    thomas, D. & G. s. Dieckmann, eds. (2010) sea ice. London: Wiley-Blackwell
    from equation 5 and 15 in Cox, G. F. N., & Weeks, W. F. (1983). Equations for determining the gas and brine volumes in sea ice samples. Journal of Glaciology (Vol. 29, pp. 306–316).
    """
    # check array lengths
    t = icdt.make_array(t)
    s = icdt.make_array(s)

    # todo improve this method by getting the length of the ice core
    if len(t) > 1:
        if len(t) != len(s):
            if flag_comment == 'y':
                print('Vb t and s profile should be the same length')
            delta_t = len(t) - len(s)
            if delta_t < 0:
                temp = np.empty((-delta_t))
                temp[:] = np.nan
                t = np.append(t, temp)
            elif delta_t > 0:
                # todo: interpolation is a good idea, but does not work as I wish it works.
                lent = len(t)
                t = t[0:len(s)]
                t[len(s):lent] = np.nan
                s[len(s):lent] = np.nan
        else:
            t = t[0:len(s)]

    if rho_si == 'default':
        rho_si = seaice_density(t, s, flag_comment='n')
    else:
        rho_si = icdt.make_array(rho_si)
        if len(rho_si) != len(s) or len(rho_si) != 1:
            if flag_comment == 'y':
                print('rho_si should be the same length as t and s')
            rho_si = np.ones(len(s))[:] * rho_si

    a = np.empty((4, 4, 2))

    # coefficient for -2<t<=0
    a[0, 0, :] = [-0.041221, 0.090312]
    a[0, 1, :] = [-18.407, -0.016111]
    a[0, 2, :] = [0.58402, 1.2291 * 10 ** (-4)]
    a[0, 3, :] = [0.21454, 1.3603 * 10 ** (-4)]

    # coefficient for -22.9<t<=-2
    a[1, 0, :] = [-4.732, 0.08903]
    a[1, 1, :] = [-22.45, -0.01763]
    a[1, 2, :] = [-0.6397, -5.330 * 10 ** (-4)]
    a[1, 3, :] = [-0.01074, -8.801 * 10 ** (-6)]

    # coefficient for t<=-22.9
    a[2, 0, :] = [9899, 8.547]
    a[2, 1, :] = [1309, 1.089]
    a[2, 2, :] = [55.27, 0.04518]
    a[2, 3, :] = [0.7160, 5.819 * 10 ** (-4)]

    ii_max = len(t)
    vf_b = np.empty(ii_max)
    vf_b[:] = np.nan

    vf_a = air_volumefraction(t, s, rho_si, flag_comment='n')

    for ii in np.arange(0, ii_max):
        t_temp = t[ii]
        s_temp = s[ii]
        vf_a_temp = vf_a[ii]
        if np.isnan(t_temp):
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : temperature not defined')
        elif np.isnan(s_temp):
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : salinity not defined')
        elif t_temp < -30:
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : t=' + str(t_temp) + '<-30 : ice temperature is out of validity')
        elif 0 <= t_temp:
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : t=' + str(t_temp) + '>0 : ice has alreay melt')
        else:
            if (-30 <= t_temp) & (t_temp <= -22.9):
                mm = 2
            elif (-22.9 < t_temp) & (t_temp <= -2):
                mm = 1
            elif (-2 < t_temp) & (t_temp <= 0):
                mm = 0

            p1 = [a[mm, 3, 0], a[mm, 2, 0], a[mm, 1, 0], a[mm, 0, 0]]
            p2 = [a[mm, 3, 1], a[mm, 2, 1], a[mm, 1, 1], a[mm, 0, 1]]

            f1 = np.polyval(p1, t_temp)
            f2 = np.polyval(p2, t_temp)

            rho_i = ice_density(t_temp, 'n')  # [0]

            vf_b[ii] = ((1 - vf_a_temp) * rho_i * s_temp / (f1 - rho_i * s_temp * f2))
    return vf_b
Beispiel #14
0
def air_volumefraction(t, s, rho_si=0.9, flag_comment='y'):
    """
    Calculate the volume fraction of air in function of the temperature and salinity

    Parameters
    ----------
    t : array_like, number
        temperature in degree Celsius [°C]
        If t is an array, s should be an array of the same length
    s : array_like, number
        salinity in practical salinity unit [PsU]
        If s is an array, t should be an array of the same length
    rho_si : optional, array_like, number
        density of the ice in gram per cubic centimeter [g cm^{-3}]. Defautl value is 0.9.
        If rho_si is an array, t should be an array of the same length
    flag_comment:


    Returns
    ----------
    vf_a: ndarray
        Volume fraction of air in the ice

    sources
    ----------
    Equation 14 in Cox, G. F. N., & Weeks, W. F. (1983). Equations for determining the gas and brine volumes in sea ice samples. Journal of Glaciology (Vol. 29, pp. 306–316).

	"""
    import numpy as np

    # check array lengths
    t = icdt.make_array(t)
    s = icdt.make_array(s)

    if len(t) > 1:
        if len(t) != len(s):
            print('rho sI t and s profile should be the same length')
            delta_t = len(t) - len(s)
            if delta_t < 0:
                delta_t = len(t) - len(s)
                temp = np.empty((-delta_t))
                temp[:] = np.nan
                t = np.append(t, temp)
            elif delta_t > 0:
                # todo: interpolation is a good idea, but does not work as I wish it works.
                lent = len(t)
                t = t[0:len(s)]
                t[len(s):lent] = np.nan
                s[len(s):lent] = np.nan

    rho_si = icdt.make_array(rho_si)
    if len(rho_si) != len(s) & len(rho_si) != 1:
        print('rho_si should be the same length as t and s')
        return 0

    ii_max = len(t)
    vf_a = np.empty(ii_max)
    vf_a[:] = np.nan

    # Physical constant
    A = np.empty((4, 4, 2))

    # coefficient for -2<t<=0
    A[0, 0, :] = [-0.041221, 0.090312]
    A[0, 1, :] = [-18.407, -0.016111]
    A[0, 2, :] = [0.58402, 1.2291 * 10 ** (-4)]
    A[0, 3, :] = [0.21454, 1.3603 * 10 ** (-4)]

    # coefficient for -22.9<t<=-2
    A[1, 0, :] = [-4.732, 0.08903]
    A[1, 1, :] = [-22.45, -0.01763]
    A[1, 2, :] = [-0.6397, -5.330 * 10 ** (-4)]
    A[1, 3, :] = [-0.01074, -8.801 * 10 ** (-6)]

    # coefficient for t<=-22.9
    A[2, 0, :] = [9899, 8.547]
    A[2, 1, :] = [1309, 1.089]
    A[2, 2, :] = [55.27, 0.04518]
    A[2, 3, :] = [0.7160, 5.819 * 10 ** (-4)]

    rho_i = ice_density(t, 'n')

    for ii in np.arange(0, ii_max):
        t_temp = t[ii];
        s_temp = s[ii];

        if len(rho_si) > 1:
            rho_si_temp = rho_si[ii]
        else:
            rho_si_temp = rho_si[0]

        if np.isnan(t_temp):
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : temperature not defined')
        elif np.isnan(s_temp):
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : salintiy not defined')
        elif t_temp < -30:
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : t=' + str(t_temp) + '<-30 : ice temperature is out of validity')
        elif 0 <= t_temp:
            if flag_comment == 'y':
                print('layer ' + str(ii) + ' : t=' + str(t_temp) + '>0 : ice has alreay melt')
        else:
            if (-30 <= t_temp) & (t_temp <= -22.9):
                mm = 2
            elif (-22.9 < t_temp) & (t_temp <= -2):
                mm = 1
            elif (-2 < t_temp) & (t_temp <= 0):
                mm = 0
            P1 = [A[mm, 3, 0], A[mm, 2, 0], A[mm, 1, 0], A[mm, 0, 0]]
            P2 = [A[mm, 3, 1], A[mm, 2, 1], A[mm, 1, 1], A[mm, 0, 1]]

            F1 = np.polyval(P1, t_temp)
            F2 = np.polyval(P2, t_temp)

            vf_a[ii] = ((1 - rho_si_temp / rho_i[ii] + rho_si_temp * s_temp * F2 / F1))
    return vf_a