Esempio n. 1
0
def heatDiff(self,iii):
    '''
    Heat diffusion function

    :param z:
    :param dz:
    :param Ts:
    :param rho:

    :returns self.Tz:
    :returns self.T10m:

    thermal diffusivity: alpha = K_firn / (rho*c_firn)
    '''

    nz_P            = len(self.z)
    nz_fv           = nz_P - 2
    nt              = 1

    z_edges_vec1 = self.z[0:-1] + np.diff(self.z) / 2
    z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec1, [self.z[-1]]))
    z_P_vec     = self.z

    phi_s           = self.Tz[0]
    phi_0           = self.Tz

    K_ice           = 9.828 * np.exp(-0.0057 * phi_0) # thermal conductivity, Cuffey and Paterson, eq. 9.2 (Yen 1981)
    c_firn          = 152.5 + 7.122 * phi_0 # specific heat, Cuffey and Paterson, eq. 9.1 (page 400)
    # c_firn        = CP_I # If you prefer a constant specific heat.

    K_firn = firnConductivity(self,iii,K_ice) # thermal conductivity

    if self.c['MELT']:
        try:
            if self.c['LWCheat']=='lowK':
                K_firn[self.LWC>0]=K_firn[self.LWC>0]/1.e4
        except:
            pass

    Gamma_P         = K_firn
    tot_rho         = self.rho
    c_vol           = self.rho * c_firn

    self.Tz         = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt[iii], Gamma_P, phi_0, nz_P, nz_fv, phi_s, tot_rho, c_vol)

    self.T10m       = self.Tz[np.where(self.z>=10.0)[0][0]]

    if self.c['MELT']:
        if self.c['LWCheat']=='effectiveT':
            pass

        elif np.any(self.Tz>273.15):
            print('WARNING: TEMPERATURE EXCEEDS MELTING TEMPERATURE')
            print('Maximum temperature was:',np.max(self.Tz),' at layers:',np.where(self.Tz == np.max(self.Tz)))
            print('WARM TEMPERATURES HAVE BEEN SET TO 273.15; MODEL RUN IS CONTINUING')
            self.Tz[self.Tz>=273.15]=273.15

    return self.Tz, self.T10m
Esempio n. 2
0
def heatDiff(self, iii):
    '''
    Heat diffusion function

    :param z:
    :param dz:
    :param Ts:
    :param rho:

    :returns self.Tz:
    :returns self.T10m:
    '''

    nz_P = len(self.z)
    nz_fv = nz_P - 2
    nt = 1

    z_edges_vec = self.z[1:-2] + self.dz[2:-1] / 2
    z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec, [self.z[-1]]))
    z_P_vec = self.z
    # phi_s = self.Ts[iii]
    phi_s = self.Tz[0]
    phi_0 = self.Tz

    # K_ice = 9.828 * np.exp(-0.0057 * phi_0)
    # K_firn = K_ice * (self.rho / 1000) ** (2 - 0.5 * (self.rho / 1000))
    K_firn = 0.021 + 2.5 * (self.rho / 1000.)**2
    c_firn = 152.5 + 7.122 * phi_0
    Gamma_P = K_firn / (c_firn * self.rho)

    self.Tz = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, Gamma_P,
                                 phi_0, nz_P, nz_fv, phi_s)
    self.Tz = np.concatenate(([self.Ts[iii]], self.Tz[:-1]))

    fT10m = interpolate.interp1d(self.z, self.Tz)  # temp at 10m depth
    self.T10m = fT10m(10)

    return self.Tz, self.T10m
def isoDiff(self,iii):
    '''
    Isotope diffusion function

    :param iter:
    :param z:
    :param dz:
    :param rho:
    :param iso:

    :returns self.phi_t:
    '''
    
    nz_P        = len(self.z)                                           # number of nodes in z
    nz_fv       = nz_P - 2                                              # number of finite volumes in z
    nt          = 1                                                     # number of time steps

    # z_edges_vec = self.z[1:-2] + self.dz[2:-1] / 2                        # uniform edge spacing of volume edges
    # z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec, [self.z[-1]]))
    # z_P_vec   = self.z

    z_edges_vec1 = self.z[0:-1] + np.diff(self.z) / 2
    z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec1, [self.z[-1]]))
    z_P_vec     = self.z

    ### Node positions
    phi_s       = self.del_z[0]                                         # isotope value at surface
    phi_0       = self.del_z                                            # initial isotope profile

    ### Define diffusivity for each isotopic species
    ### Establish values needed for diffusivity calculation
    m           = 0.018                                                 # kg/mol; molar mass of water
    pz          = 3.454 * np.power(10, 12) * np.exp(-6133 / self.Tz)    # Pa; saturation vapor pressure over ice

    alpha_18_z  = 0.9722 * np.exp(11.839 / self.Tz)                     # fractionation factor for 18_O
    # alpha_18_z    = np.exp(11.839/Tz-28.224*np.power(10,-3))          # alternate formulation from Eric's python code
    alpha_D_z   = 0.9098 * np.exp(16288 / np.power(self.Tz, 2))         # fractionation factor for D
    Po          = 1.0                                                   # reference pressure in atm
    P           = 1.0

    ### Set diffusivity in air (units of m^2/s)
    # Da        = 2.1 * np.power(10.0, -5.) * np.power(self.Tz / 273.15, 1.94) * (Po / P)
    Da          = 2.1 * 1.0e-5 * (self.Tz / 273.15)**1.94 * (Po / P)
    Da_18       = Da / 1.0285               # account for fractionation factor for 18_O, fixed Johnsen typo
    Da_D        = Da / 1.0251               # account for fractionation factor for D, fixed Johnsen typo

    ### Calculate tortuosity
    invtau      = np.zeros(int(len(self.dz)))
    b           = 0.25                                                                  # Tortuosity parameter
    invtau[self.rho < RHO_I / np.sqrt(b)]   = 1.0 - (b * (self.rho[self.rho < RHO_I / np.sqrt(b)] / RHO_I)) ** 2
    invtau[self.rho >= RHO_I / np.sqrt(b)]  = 0.0

    ### Set diffusivity for each isotope
    if self.c['iso'] == '18':
        D           = m * pz * invtau * Da_18 * (1 / self.rho - 1 / RHO_I) / (R * self.Tz * alpha_18_z)
        D           = D + 1.5e-15
        self.del_z  = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, D, phi_0, nz_P, nz_fv, phi_s, self.rho)
    elif self.c['iso'] == 'D':
        D           = m * pz * invtau * Da_D * (1 / self.rho - 1 / RHO_I) / (R * self.Tz * alpha_D_z)
        D[D<=0.0]   = 1.0e-20
        self.del_z  = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, D, phi_0, nz_P, nz_fv, phi_s, self.rho)
    elif self.c['iso'] == 'NoDiffusion':
        pass
        
    ### Solve for vertical isotope profile at this time step i
    self.del_z = np.concatenate(([self.del_s[iii]], self.del_z[:-1]))

    return self.del_z
def heatDiff(self,iii):
    '''
    Heat diffusion function

    :param z:
    :param dz:
    :param Ts:
    :param rho:

    :returns self.Tz:
    :returns self.T10m:
    # thermal diffusivity: alpha = K_firn / (rho*c_firn)
    '''

    nz_P            = len(self.z)
    nz_fv           = nz_P - 2
    nt              = 1

    # z_edges_vec   = self.z[1:-2] + self.dz[2:-1] / 2
    # z_edges_vec   = np.concatenate(([self.z[0]], z_edges_vec, [self.z[-1]]))
    # z_P_vec       = self.z

    z_edges_vec1 = self.z[0:-1] + np.diff(self.z) / 2
    z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec1, [self.z[-1]]))
    z_P_vec     = self.z
    
    phi_s           = self.Tz[0]
    phi_0           = self.Tz

    K_ice           = 9.828 * np.exp(-0.0057 * phi_0) # thermal conductivity, Cuffey and Paterson, eq. 9.2 (Yen 1981)
    # c_firn          = 152.5 + 7.122 * phi_0 # specific heat, Cuffey and Paterson, eq. 9.1 (page 400)
    c_firn        = CP_I # If you prefer a constant specific heat.

    ### Conductivity. Choose your favorite! ###
    # References are provided at the end of this script.

    # alpha_DAVIDCS_m2s = 18.3 / S_PER_YEAR # special for work Max was doing for David Clemens-Sewell

    # K_firn = alpha_DAVIDCS_m2s * self.rho * c_firn
    # K_firn[self.z>=20.0]    = K_ice[self.z>=20.0] * (self.rho[self.z>=20.0]/RHO_I) ** (2 - 0.5 * (self.rho[self.z>=20.0]/RHO_I))    # Schwander 1997, eq. A11

    # K_firn    = K_ice * (self.rho/RHO_I) ** (2 - 0.5 * (self.rho/RHO_I))    # Schwander 1997, eq. A11
    # K_firn    = 2.22362 * (self.rho / 1000)**1.885                          # Yen 1981, eq 34 w/ fixed K_ice (original)
    # K_firn    = K_ice * (self.rho / 1000)**1.885                            # Yen 1981, modified for variable K_ice
    # K_firn    = 0.021 + 2.5 * (self.rho/1000.)**2                           # Anderson (1976)
    # K_firn    = 0.0688 * np.exp(0.0088*phi_0 + 4.6682*self.rho)             # Yen 1981, eq. 35.
    # K_firn    = 0.138 - 1.01*(self.rho/1000) + 3.233*(self.rho/1000)**2     # Sturm, 1997.; rho < 0.6
    # K_firn    = 2.1e-2 + 4.2e-4 * self.rho + 2.2e-9 * (self.rho)**3         # Van Dusen 1929 (via C&P)
    K_firn    = (2 * K_ice * self.rho) / (3*RHO_I - self.rho)               # Schwerdtfeger (via C&P)
    # K_firn    = 3.e-6 * self.rho**2 - 1.06e-5 * self.rho + 0.024            # Riche and Schneebeli 2013 eq. 10
    # k_firn    = 0.0784 + 2.697 * (self.rho/1000.)**2                        # Jiawen 1991 eq. 3
    
    Gamma_P         = K_firn # (new)
 
    # Gamma_P         = K_firn / (c_firn) # old)
    tot_rho         = self.rho
    c_vol = self.rho * c_firn
    # print('c_vol',c_vol)

    self.Tz         = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, Gamma_P, phi_0, nz_P, nz_fv, phi_s, tot_rho, c_vol)

    fT10m           = interpolate.interp1d(self.z, self.Tz)                                 # temp at 10m depth
    self.T10m       = fT10m(10)

    if np.any(self.Tz>273.17):
        print('WARNING: TEMPERATURE EXCEEDS MELTING TEMPERATURE')
        print('Maximal temperature was:',np.max(self.Tz),' at layers:',np.where(self.Tz == np.max(self.Tz)))
        print('WARM TEMPERATURES HAVE BEEN SET TO 273.15; MODEL RUN IS CONTINUING')
        self.Tz[self.Tz>=273.15]=273.15

    return self.Tz, self.T10m
Esempio n. 5
0
    def isoDiff(self, IsoParams, iii):
        '''
        Isotope diffusion function

        :param iter:
        :param z:
        :param dz:
        :param rho:
        :param iso:

        :returns self.phi_t:
        '''

        for k, v in list(IsoParams.items()):
            setattr(self, k, v)

        nz_P = len(self.z)  # number of nodes in z
        nz_fv = nz_P - 2  # number of finite volumes in z
        nt = 1  # number of time steps

        # z_edges_vec = self.z[1:-2] + self.dz[2:-1] / 2                        # uniform edge spacing of volume edges
        # z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec, [self.z[-1]]))
        # z_P_vec   = self.z

        z_edges_vec1 = self.z[0:-1] + np.diff(self.z) / 2
        z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec1, [self.z[-1]]))
        z_P_vec = self.z

        ### Node positions
        phi_s = self.del_z[0]  # isotope value at surface
        # phi_s       = self.del_z[1] # isotope value at surface
        # if iii==0:
        #     print('Caution! line 121, isotopeDiffusion.py')
        phi_0 = self.del_z  # initial isotope profile

        ### Define diffusivity for each isotopic species
        ### Establish values needed for diffusivity calculation
        m = 0.018  # kg/mol; molar mass of water
        pz = 3.454e12 * np.exp(
            -6133 / self.Tz)  # Pa; saturation vapor pressure over ice

        alpha_18_z = 0.9722 * np.exp(
            11.839 / self.Tz)  # fractionation factor for 18_O
        # alpha_18_z    = np.exp(11.839/Tz-28.224*np.power(10,-3))          # alternate formulation from Eric's python code
        alpha_D_z = 0.9098 * np.exp(16288 /
                                    (self.Tz**2))  # fractionation factor for D
        Po = 1.0  # reference pressure in atm
        # P         = 1.0
        P = self.c[
            'site_pressure'] / 1013.25  # Pressure at WAIS from Christo's thesis.

        ### Set diffusivity in air (units of m^2/s)
        Da = 2.11e-5 * (self.Tz / 273.15)**1.94 * (Po / P)

        ### Calculate tortuosity
        invtau = np.zeros(int(len(self.dz)))
        b = 1.3  # Tortuosity parameter (Johnsen 2000)
        invtau[self.rho < RHO_I / np.sqrt(b)] = 1.0 - (
            b * (self.rho[self.rho < RHO_I / np.sqrt(b)] / RHO_I)**2)
        # b           = 0.25 # Tortuosity parameter (Emma's value), effective b = 0.0625 (taken outside of squared term)
        # invtau[self.rho < RHO_I / np.sqrt(b)]   = 1.0 - (b * (self.rho[self.rho < RHO_I / np.sqrt(b)] / RHO_I))**2 #Emma
        invtau[self.rho >= RHO_I / np.sqrt(b)] = 0.0

        ### Set diffusivity for each isotope
        c_vol = np.ones_like(
            self.rho)  # Just a filler here to make the diffusion work.
        if ((self.isotope == '18') or (self.isotope == 'd18O')):
            Da_18 = Da / 1.0285  # account for fractionation factor for 18_O, fixed Johnsen typo
            D = m * pz * invtau * Da_18 * (1 / self.rho - 1 / RHO_I) / (
                R * self.Tz * alpha_18_z)
            D = D + 1.5e-15  # Emma added - not sure why? prevent negative?
            self.del_z = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt,
                                            D, phi_0, nz_P, nz_fv, phi_s,
                                            self.rho, c_vol)

        elif ((self.isotope == 'D') or (self.isotope == 'dD')):
            Da_D = Da / 1.0251  # account for fractionation factor for D, fixed Johnsen typo
            D = m * pz * invtau * Da_D * (1 / self.rho - 1 / RHO_I) / (
                R * self.Tz * alpha_D_z)
            D[D <= 0.0] = 1.0e-20
            self.del_z = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt,
                                            D, phi_0, nz_P, nz_fv, phi_s,
                                            self.rho, c_vol)

        elif ((self.isotope == 'NoDiffusion') or (self.isotope == 'ND')):
            D = np.zeros_like(self.z)

        dsig2_dt = 2 * (-1 * self.drho_dt / self.rho) * self.iso_sig2_z + 2 * D
        self.iso_sig2_z = self.iso_sig2_z + dsig2_dt * self.dt

        # Advect profile down
        if self.bdot > 0.0:
            self.del_z = np.concatenate(([self.del_s[iii]], self.del_z[:-1]))
            self.iso_sig2_z = np.concatenate(
                ([self.iso_sig2_s[iii]], self.iso_sig2_z[:-1]))
        else:
            pass

        # self.del_z[0] = self.del_z[1]
        # print('Caution!!! You are altering the upper isotope value! Line 173, isotopeDiffusion.py')

        return self.del_z, self.iso_sig2_z
Esempio n. 6
0
    def firn_air_diffusion(self, AirParams, iii):
        '''
        Solve the diffusion equation.
        Calls solver.py
        '''

        for k, v in list(AirParams.items()):
            setattr(self, k, v)

        nz_P = len(self.z)
        nz_fv = nz_P - 2
        nt = 1

        z_edges1 = self.z[0:-1] + np.diff(self.z) / 2
        z_edges = np.concatenate(([self.z[0]], z_edges1, [self.z[-1]]))
        z_P_vec = self.z
        # if (iii>100 and iii<110):
        #     print('z_P',z_P_vec[0:5])
        #     print('len p', len(z_P_vec))
        #     print('edges',z_edges[0:5])
        #     print('len edges',len(z_edges))
        # input('enter')
        # phi_s     = self.Ts[iii]
        phi_s = self.Gz[0]
        phi_0 = self.Gz

        # K_ice     = 9.828 * np.exp(-0.0057 * phi_0)
        # K_firn    = K_ice * (self.rho / 1000) ** (2 - 0.5 * (self.rho / 1000))

        self.rho_co, self.por_co, self.por_tot, self.por_cl, self.por_op, self.bcoRho, self.LIDRho = self.porosity(
        )

        # self.air_pressure_old     = np.copy(self.air_pressure)
        porosity_old = (RHO_I - self.rho_old) / RHO_I

        por_co1 = 1 - self.rho_co / RHO_I  # Porosity at close-off
        alpha = 0.37  # constant determined in Goujon
        por_cl1 = np.zeros_like(porosity_old)
        por_cl1[porosity_old > 0] = alpha * porosity_old[porosity_old > 0] * (
            porosity_old[porosity_old > 0] / por_co1)**(-7.6)
        ind = por_cl1 > porosity_old
        por_cl1[ind] = porosity_old[ind]
        por_op_old = porosity_old - por_cl1  # Open Porosity

        self.air_volume_old = por_op_old * self.dz_old
        # self.air_volume_old   = np.copy(self.air_volume)

        self.air_volume = self.por_op * self.dz
        volfrac = self.air_volume_old / self.air_volume
        # volfrac = np.concatenate(([volfrac[0]],volfrac))
        self.air_pressure = (self.p_a * np.exp(
            M_AIR * GRAVITY * self.z / (R * self.Tz))) * volfrac - (
                self.p_a * np.exp(M_AIR * GRAVITY * self.z / (R * self.Tz))
            )  # assume air pressure is atmos in entire column

        self.pressure_grad = np.gradient(self.air_pressure, self.z)
        self.z_co = min(self.z[self.rho >= (
            self.bcoRho)])  #close-off depth; bcoRho is mean close off density
        # self.z_co               = min(self.z[self.rho>=(self.rho_co)]) #close-off depth; bcoRho is close off density
        # self.z_co               = self.z[np.where(self.rho>=self.rho_co)[0][0]] #close-off depth; bcoRho is close off density
        self.LID = min(self.z[self.rho >= (
            self.LIDRho)])  #lock in depth; LIDRho is lock-in density
        # print(self.LID)
        self.bdot_t = self.bdot[iii]

        self.diffu, self.d_eddy = self.diffusivity()
        # ij = np.where(self.diffu<=1e-20)[0][0]
        # print('Diffu zero',self.z[ij])

        airdict = {
            'd_eddy': self.d_eddy,
            'por_op': self.por_op,
            'Tz': self.Tz,
            'deltaM': self.deltaM,
            'omega': self.omega,
            'dz': self.dz,
            'rho': self.rho,
            'gravity': self.cg['gravity'],
            'thermal': self.cg['thermal'],
            'air_pressure': self.air_pressure,
            'pressure_grad': self.pressure_grad,
            'z': self.z,
            'dt': self.dt,
            'z_co': self.z_co,
            'p_a': self.p_a,
            'por_tot': self.por_tot,
            'por_cl': self.por_cl,
            'w_firn': self.w_firn,
            'advection_type': self.cg['advection_type'],
            'iii': iii,
            'gaschoice': self.gaschoice
        }

        msk = np.where(self.z > self.z_co)[0][0]
        c_vol = np.ones_like(
            self.rho)  # Just a filler here to make the diffusion work.

        self.Gz, w_p = transient_solve_TR(z_edges, z_P_vec, nt, self.dt,
                                          self.diffu, phi_0, nz_P, nz_fv,
                                          phi_s, self.rho, c_vol, airdict)
        self.Gz = np.concatenate(([self.Gs[iii]], self.Gz[:-1]))

        ind_LID = np.where(self.z >= self.LID)[0]
        self.gas_age[self.gas_age >
                     0] = self.gas_age[self.gas_age > 0] + self.dt / S_PER_YEAR
        self.gas_age = np.concatenate(([0], self.gas_age[:-1]))
        self.gas_age[ind_LID[0]] = 15.0
        ii2 = np.where((self.z > self.LID) & (self.gas_age == 0))[0]
        self.gas_age[ii2] = 15

        # print('diffu',self.diffu[0:10])

        return self.Gz, self.diffu, w_p, self.gas_age
Esempio n. 7
0
def isoDiff(self, iii):
    '''
    Isotope diffusion function

    :param iter:
    :param z:
    :param dz:
    :param rho:
    :param iso:

    :returns self.phi_t:
    '''

    nz_P = len(self.z)  # number of nodes in z
    nz_fv = nz_P - 2  # number of finite volumes in z
    nt = 1  # number of time steps

    # z_edges_vec = self.z[1:-2] + self.dz[2:-1] / 2                        # uniform edge spacing of volume edges
    # z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec, [self.z[-1]]))
    # z_P_vec   = self.z

    z_edges_vec1 = self.z[0:-1] + np.diff(self.z) / 2
    z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec1, [self.z[-1]]))
    z_P_vec = self.z

    ### Node positions
    phi_s = self.del_z[0]  # isotope value at surface
    phi_0 = self.del_z  # initial isotope profile

    ### Define diffusivity for each isotopic species
    ### Establish values needed for diffusivity calculation
    m = 0.018  # kg/mol; molar mass of water
    pz = 3.454 * np.power(10, 12) * np.exp(
        -6133 / self.Tz)  # Pa; saturation vapor pressure over ice

    alpha_18_z = 0.9722 * np.exp(
        11.839 / self.Tz)  # fractionation factor for 18_O
    # alpha_18_z    = np.exp(11.839/Tz-28.224*np.power(10,-3))          # alternate formulation from Eric's python code
    alpha_D_z = 0.9098 * np.exp(
        16288 / np.power(self.Tz, 2))  # fractionation factor for D
    Po = 1.0  # reference pressure in atm
    P = 1.0

    ### Set diffusivity in air (units of m^2/s)
    # Da        = 2.1 * np.power(10.0, -5.) * np.power(self.Tz / 273.15, 1.94) * (Po / P)
    Da = 2.1 * 1.0e-5 * (self.Tz / 273.15)**1.94 * (Po / P)
    Da_18 = Da / 1.0285  # account for fractionation factor for 18_O, fixed Johnsen typo
    Da_D = Da / 1.0251  # account for fractionation factor for D, fixed Johnsen typo

    ### Calculate tortuosity
    invtau = np.zeros(int(len(self.dz)))
    b = 0.25  # Tortuosity parameter
    invtau[self.rho < RHO_I / np.sqrt(b)] = 1.0 - (
        b * (self.rho[self.rho < RHO_I / np.sqrt(b)] / RHO_I))**2
    invtau[self.rho >= RHO_I / np.sqrt(b)] = 0.0

    ### Set diffusivity for each isotope
    if self.c['iso'] == '18':
        D = m * pz * invtau * Da_18 * (1 / self.rho -
                                       1 / RHO_I) / (R * self.Tz * alpha_18_z)
        D = D + 1.5e-15
        self.del_z = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, D,
                                        phi_0, nz_P, nz_fv, phi_s, self.rho)
    elif self.c['iso'] == 'D':
        D = m * pz * invtau * Da_D * (1 / self.rho -
                                      1 / RHO_I) / (R * self.Tz * alpha_D_z)
        D[D <= 0.0] = 1.0e-20
        self.del_z = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, D,
                                        phi_0, nz_P, nz_fv, phi_s, self.rho)
    elif self.c['iso'] == 'NoDiffusion':
        pass

    ### Solve for vertical isotope profile at this time step i
    self.del_z = np.concatenate(([self.del_s[iii]], self.del_z[:-1]))

    return self.del_z
Esempio n. 8
0
def heatDiff(self, iii):
    '''
    Heat diffusion function

    :param z:
    :param dz:
    :param Ts:
    :param rho:

    :returns self.Tz:
    :returns self.T10m:
    # thermal diffusivity: alpha = K_firn / (rho*c_firn)
    '''

    nz_P = len(self.z)
    nz_fv = nz_P - 2
    nt = 1

    # z_edges_vec   = self.z[1:-2] + self.dz[2:-1] / 2
    # z_edges_vec   = np.concatenate(([self.z[0]], z_edges_vec, [self.z[-1]]))
    # z_P_vec       = self.z

    z_edges_vec1 = self.z[0:-1] + np.diff(self.z) / 2
    z_edges_vec = np.concatenate(([self.z[0]], z_edges_vec1, [self.z[-1]]))
    z_P_vec = self.z

    phi_s = self.Tz[0]
    phi_0 = self.Tz

    K_ice = 9.828 * np.exp(
        -0.0057 *
        phi_0)  # thermal conductivity, Cuffey and Paterson, eq. 9.2 (Yen 1981)
    # c_firn          = 152.5 + 7.122 * phi_0 # specific heat, Cuffey and Paterson, eq. 9.1 (page 400)
    c_firn = CP_I  # If you prefer a constant specific heat.

    ### Conductivity. Choose your favorite! ###
    # References are provided at the end of this script.

    # alpha_DAVIDCS_m2s = 18.3 / S_PER_YEAR

    # K_firn = alpha_DAVIDCS_m2s * self.rho * c_firn
    # K_firn[self.z>=20.0]    = K_ice[self.z>=20.0] * (self.rho[self.z>=20.0]/RHO_I) ** (2 - 0.5 * (self.rho[self.z>=20.0]/RHO_I))    # Schwander 1997, eq. A11

    # K_firn    = K_ice * (self.rho/RHO_I) ** (2 - 0.5 * (self.rho/RHO_I))    # Schwander 1997, eq. A11
    # K_firn    = 2.22362 * (self.rho / 1000)**1.885                          # Yen 1981, eq 34 w/ fixed K_ice (original)
    K_firn = K_ice * (self.rho /
                      1000)**1.885  # Yen 1981, modified for variable K_ice
    # K_firn    = 0.021 + 2.5 * (self.rho/1000.)**2                           # Anderson (1976)
    # K_firn    = 0.0688 * np.exp(0.0088*phi_0 + 4.6682*self.rho)             # Yen 1981, eq. 35.
    # K_firn    = 0.138 - 1.01*(self.rho/1000) + 3.233*(self.rho/1000)**2     # Sturm, 1997.; rho < 0.6
    # K_firn    = 2.1e-2 + 4.2e-4 * self.rho + 2.2e-9 * (self.rho)**3         # Van Dusen 1929 (via C&P)
    # K_firn    = (2 * K_ice * self.rho) / (3*RHO_I - self.rho)               # Schwerdtfeger (via C&P)
    # K_firn    = 3.e-6 * self.rho**2 - 1.06e-5 * self.rho + 0.024            # Riche and Schneebeli 2013 eq. 10
    # k_firn    = 0.0784 + 2.697 * (self.rho/1000.)**2                        # Jiawen 1991 eq. 3

    Gamma_P = K_firn  # (new)
    # print('K_firn',K_firn)
    # Gamma_P         = K_firn / (c_firn) # old)
    tot_rho = self.rho
    c_vol = self.rho * c_firn
    # print('c_vol',c_vol)

    self.Tz = transient_solve_TR(z_edges_vec, z_P_vec, nt, self.dt, Gamma_P,
                                 phi_0, nz_P, nz_fv, phi_s, tot_rho, c_vol)

    fT10m = interpolate.interp1d(self.z, self.Tz)  # temp at 10m depth
    self.T10m = fT10m(10)

    if np.any(self.Tz > 273.17):
        print('WARNING: TEMPERATURE EXCEEDS MELTING TEMPERATURE')
        print('Maximal temperature was:', np.max(self.Tz), ' at layers:',
              np.where(self.Tz == np.max(self.Tz)))
        print(
            'WARM TEMPERATURES HAVE BEEN SET TO 273.15; MODEL RUN IS CONTINUING'
        )
        self.Tz[self.Tz >= 273.15] = 273.15

    return self.Tz, self.T10m
    def firn_air_diffusion(self,AirParams,iii):

        for k,v in list(AirParams.items()):
            setattr(self,k,v)

        nz_P        = len(self.z)
        nz_fv       = nz_P - 2
        nt          = 1

        z_edges1 = self.z[0:-1] + np.diff(self.z) / 2
        z_edges = np.concatenate(([self.z[0]], z_edges1, [self.z[-1]]))
        z_P_vec     = self.z
        # if (iii>100 and iii<110):
        #     print('z_P',z_P_vec[0:5])
        #     print('len p', len(z_P_vec))
        #     print('edges',z_edges[0:5])
        #     print('len edges',len(z_edges))
        # input('enter')
        # phi_s     = self.Ts[iii]
        phi_s       = self.Gz[0]
        phi_0       = self.Gz

        # K_ice     = 9.828 * np.exp(-0.0057 * phi_0)
        # K_firn    = K_ice * (self.rho / 1000) ** (2 - 0.5 * (self.rho / 1000))

        self.rho_co, self.por_co, self.por_tot, self.por_cl, self.por_op, self.bcoRho, self.LIDRho = self.porosity()
        
        # self.air_pressure_old     = np.copy(self.air_pressure)
        porosity_old            = (RHO_I-self.rho_old)/RHO_I

        por_co1              = 1 - self.rho_co/RHO_I # Porosity at close-off
        alpha               = 0.37 # constant determined in Goujon
        por_cl1              = np.zeros_like(porosity_old)
        por_cl1[porosity_old>0] = alpha*porosity_old[porosity_old>0]*(porosity_old[porosity_old>0]/por_co1)**(-7.6)
        ind                 = por_cl1>porosity_old
        por_cl1[ind]         = porosity_old[ind]
        por_op_old          = porosity_old - por_cl1 # Open Porosity

        self.air_volume_old     = por_op_old * self.dz_old
        # self.air_volume_old   = np.copy(self.air_volume)

        self.air_volume         = self.por_op * self.dz
        volfrac = self.air_volume_old / self.air_volume
        # volfrac = np.concatenate(([volfrac[0]],volfrac))
        self.air_pressure       = (self.p_a*np.exp(M_AIR*GRAVITY*self.z/(R*self.Tz))) * volfrac - (self.p_a*np.exp(M_AIR*GRAVITY*self.z/(R*self.Tz))) # assume air pressure is atmos in entire column


        self.pressure_grad      = np.gradient(self.air_pressure,self.z) 
        self.z_co               = min(self.z[self.rho>=(self.bcoRho)]) #close-off depth; bcoRho is mean close off density
        # self.z_co               = min(self.z[self.rho>=(self.rho_co)]) #close-off depth; bcoRho is close off density
        # self.z_co               = self.z[np.where(self.rho>=self.rho_co)[0][0]] #close-off depth; bcoRho is close off density
        self.LID                = min(self.z[self.rho>=(self.LIDRho)]) #lock in depth; LIDRho is lock-in density
        print(self.LID)
        self.bdot_t = self.bdot[iii]

        self.diffu, self.d_eddy = self.diffusivity()
        # ij = np.where(self.diffu<=1e-20)[0][0]
        # print('Diffu zero',self.z[ij])

        airdict = {
            'd_eddy':           self.d_eddy,
            'por_op':           self.por_op,
            'Tz':               self.Tz,
            'deltaM':           self.deltaM,
            'omega':            self.omega,
            'dz':               self.dz,
            'rho':              self.rho,
            'gravity':          self.cg['gravity'],
            'thermal':          self.cg['thermal'],
            'air_pressure':     self.air_pressure,
            'pressure_grad':    self.pressure_grad,
            'z':                self.z, 
            'dt':               self.dt,
            'z_co':             self.z_co,
            'p_a':              self.p_a,
            'por_tot':          self.por_tot,
            'por_cl':           self.por_cl,
            'w_firn':           self.w_firn,
            'advection_type':   self.cg['advection_type'],
            'iii': iii,
            'gaschoice': self.gaschoice
            }

        msk = np.where(self.z>self.z_co)[0][0]
        self.Gz, w_p = transient_solve_TR(z_edges, z_P_vec, nt, self.dt, self.diffu, phi_0, nz_P, nz_fv, phi_s, self.rho, airdict)
        self.Gz = np.concatenate(([self.Gs[iii]], self.Gz[:-1]))

        ind_LID = np.where(self.z>=self.LID)[0]
        self.gas_age[self.gas_age>0] = self.gas_age[self.gas_age>0] + self.dt/S_PER_YEAR
        self.gas_age = np.concatenate(([0], self.gas_age[:-1]))
        self.gas_age[ind_LID[0]] = 15.0
        ii2 = np.where((self.z>self.LID) & (self.gas_age==0))[0]
        self.gas_age[ii2] = 15

        # print('diffu',self.diffu[0:10])

        return self.Gz, self.diffu, w_p, self.gas_age