Ejemplo n.º 1
0
 def setUp(self):
     self.phase = ct.DustyGas('h2o2.xml')
     self.phase.TPX = 500.0, ct.one_atm, "O2:2.0, H2:1.0, H2O:1.0"
     self.phase.porosity = 0.2
     self.phase.tortuosity = 0.3
     self.phase.mean_pore_radius = 1e-4
     self.phase.mean_particle_diameter = 5e-4
     self.Dref = self.phase.multi_diff_coeffs
def DGM (Por, Tau, RPo, Dia, PTR, PTL, TL, TR, PL, PR, YL, YR):
	# solve the dusty gas model
	
	# set the transport manager to the dusty gas model
	dg = ct.DustyGas(FileCanteraGas)
	dg.porosity = Por
	dg.tortuosity = Tau
	dg.mean_pore_radius = RPo
	dg.mean_particle_diameter = Dia
	
	DGMFlux = np.zeros((Kgas,))
	Dist = PTR - PTL
	
	# setup properties on the left side
	gas.TPY = (TL, PL, YL)
	XMOLL = gas.X
	DENSL = gas.density
	CONCL = gas.density * XMOLL
	ENTHL = gas.standard_enthalpies_RT * ct.gas_constant * TL
		
	# setup properties on the right side
	gas.TPY = (TR, PR, YR)
	XMOLR = gas.X
	DENSR = gas.density
	CONCR = gas.density * XMOLR
	ENTHR = gas.standard_enthalpies_RT * ct.gas_constant * TR
	
	DGMFlux = dg.molar_fluxes(TL, TR, DENSL, DENSR, YL, YR, Dist)
	
	DGMHeat = 0.0
	for k in range (1,Kgas - 1):
		if DGMFlux[k] >= 0:
			DGMHeat = DGMHeat + ENTHL[k] * DGMFlux[k]
		else:
			DGMHeat = DGMHeat + ENTHR[k] * DGMFlux[k]
	
	# convert molar fluxes from DGM to mass fluxes
	for k in range (1,Kgas - 1):
		DGMFlux [k] = W[k] * DGMFlux[k]
		
	return(DGMFlux, DGMHeat)
Ejemplo n.º 3
0
        t = datetime.now()
        dtStr = t.strftime('%m_%d_%Y_%H%M')

        save_string = (membrane_params['name']+'_'+str(int(row_temp['Feed Temp [C]']))+'_'+str(int(row_temp['Perm Temp [C]']))+'_'+dtStr)
        print(save_string)
        i_tau=-1
        for tau_g in tau_g_vec:
            i_tau += 1
            print('Tortusity factor = ',tau_g)
            tic = timeit.default_timer()
            if DGM:

                # Transport flag: 0 for DGM, 1 for Fickean
                trans_flag = 0

                gas = ct.DustyGas(ctifile)
                gas.porosity = membrane_params['eps_g']
                gas.tortuosity = tau_g
                gas.mean_pore_radius = 2.*membrane_params['r_p']
                gas.mean_particle_diameter = membrane_params['d_p']


                liq = ct.Solution(ctifile,liqphase)
                liq_int = ct.Interface(ctifile,intphase,[gas,liq])

                params['sdot_gas_ptr'] = np.arange(int_ord_gas,int_ord_gas+gas.n_species)

                from oneD_membrane_sim import load_model, run_model

                SV_0, params = load_model(gas, membrane_params, params, temp_data.loc[i_temp,:], n_points)
Ejemplo n.º 4
0
"""
Dusty Gas transport model.

The Dusty Gas model is a multicomponent transport model for gas transport
through the pores of a stationary porous medium. This example shows how to
create a transport manager that implements the Dusty Gas model and use it to
compute the multicomponent diffusion coefficients.
"""

import cantera as ct

# create a gas-phase object to represent the gas in the pores, with a
# dusty gas transport manager
g = ct.DustyGas('h2o2.cti')

# set the gas state
g.TPX = 500.0, ct.one_atm, "OH:1, H:2, O2:3, O:1.0E-8, H2:1.0E-8, H2O:1.0E-8, H2O2:1.0E-8, HO2:1.0E-8, AR:1.0E-8"

# set its parameters
g.porosity = 0.2
g.tortuosity = 4.0
g.mean_pore_radius = 1.5e-7
g.mean_particle_diameter = 1.5e-6  # lengths in meters

# print the multicomponent diffusion coefficients
print(g.multi_diff_coeffs)

# compute molar species fluxes
T1, rho1, Y1 = g.TDY

g.TP = g.T, 1.2 * ct.one_atm
Ejemplo n.º 5
0
cwd = os.getcwd()
gas_path = ct.__path__[0]
copy2(os.path.basename(__file__), folder_name)
if os.path.exists(gas_file):
    copy2(gas_file, folder_name)
else:
    copy2(gas_path + '/data/' + gas_file, folder_name)

# Tortuosity calculation via Bruggeman correlation:
tau_g = phi_g**(-0.5)

# Call cantera for gas-phase:
if Diff_Mod == 1:
    gas = ct.Solution(gas_file)
elif Diff_Mod == 2:
    gas = ct.DustyGas(gas_file)
    gas.porosity = phi_g
    gas.tortuosity = tau_g
    gas.mean_pore_radius = r_p
    gas.mean_particle_diameter = d_p

# Initialize solution vector:
Nspecies = gas.n_species
SV_0 = np.zeros(Nx * Ny * Nspecies)

# Given constants:
F = ct.faraday  # Faraday Constant [s-A/kmol]
R = ct.gas_constant  # Universal gas constant [J/kmol-K]

Temp = Temp + 273.15  # convert temperature from [C] -> [K]
gas.TP = Temp, Press  # set gas state via temperature and pressure
Ejemplo n.º 6
0
Calculate transport properties in a porous medium using the dusty gas transport model.

The Dusty Gas model is a multicomponent transport model for gas transport
through the pores of a stationary porous medium. This example shows how to
create a transport manager that implements the Dusty Gas model and use it to
compute the multicomponent diffusion coefficients and thermal conductivity.

Requires:  cantera >= 2.6.0
Keywords: transport, multicomponent transport
"""

import cantera as ct

# create a gas-phase object to represent the gas in the pores, with a
# dusty gas transport manager
g = ct.DustyGas('h2o2.yaml')

# set the gas state
composition = {
    "OH": 1,
    "H": 2,
    "O2": 3,
    "O": 1.0E-8,
    "H2": 1.0E-8,
    "H2O": 1.0E-8,
    "H2O2": 1.0E-8,
    "HO2": 1.0E-8,
    "AR": 1.0E-8
}
g.TPX = 500.0, ct.one_atm, composition
Ejemplo n.º 7
0
def initialize(membrane, tau_g, transport, feed_temp, permeate_temp):
    """ 
    Initialize variables, parameters, and Cantera objects for the simulation.

    - Reads user inputs from membrane_distillation_inputs.yaml
    - Creates necessary Cantera objects.
    - Reads and stores necessary parameters.
    - Initializes the solution vector


    Returns: 
    - Initial solution vector SV_0
    - Dictionary of cantera objects obj
    - Dictionary of paramters params
    """
    import numpy as np
    from ruamel.yaml import YAML
    from pathlib import Path
    import cantera as ct

    #===========================================================================
    #   READ IN INPUTS
    #===========================================================================
    input_file = 'membrane_distillation_inputs.yaml'
    path = Path(input_file)
    yaml = YAML(typ='safe')
    inputs = yaml.load(path)

    #===========================================================================
    #   READ OUT MEMBRANE PROPERTIES
    #===========================================================================
    # Read out the selected membrane.  Specification via command-line overrides #   all other input.  If no command-line input is provided, look in the
    #   input file.  Otherwise, raise an exception:
    if membrane is None:
        if 'membrane' in inputs['simulation-params']:
            membrane = inputs['simulation-params']['membrane']
        else:
            raise ValueError(
                'Please specify a membrane for your simulation'
                'either via command line (--membrane=[name string]) or as a'
                ' field in membrane_distillation_inputs.yaml:simulation-params'
            )
    # print(membrane)
    # This tracks whether or not the named membrane was found in the list of
    #   parameters in the input file.  Initialize to "not found":
    found = 0
    for mem in inputs['membrane-data']:
        if mem['name'] == str(membrane):
            if found:
                # More than one set of membrane params has that name.
                #   Throw an error.
                raise ValueError('There were two or more membranes with the'
                                 ' name ' + membrane +
                                 ' in your input file. Pleease edit.')

            membrane_params = mem
            found = 1
    if not found:
        raise ValueError('Specified membrane ' + membrane + ' not found in' +
                         ' membrane_distillation_inputs.yaml. Pleease edit.')
    #===========================================================================
    #   LOAD PARAMETERS INTO 'param' DICT
    #===========================================================================
    # Create dictionary of parameters, 'params'
    params = {}
    params['n_y'] = inputs['simulation-params']['n_y']
    params['dyInv'] = params['n_y'] / membrane_params['thickness']
    params['dy'] = 1. / params['dyInv']
    params['eps_g'] = membrane_params['porosity']
    params['r_pore'] = 0.5 * membrane_params['pore-diameter']
    params['d_part'] = membrane_params['particle-diameter']
    params['kappa_membrane'] = membrane_params['thermal-conductivity']
    params['c_v_membrane'] = membrane_params['const-vol-specific-heat']
    params['rho_membrane'] = membrane_params['solid-phase-density']
    params['h_fg_feed'] = inputs['temp-data']['h_fg_feed']
    params['h_fg_permeate'] = inputs['temp-data']['h_fg_permeate']

    #===========================================================================
    #   LOAD PARAMETERS THAT CAN COME FROM EITHER INPUT FILE OR COMMAND LINE:
    #===========================================================================
    # Load the transport model:
    if transport:
        params['transport'] = transport
    elif 'transport-model' in inputs['simulation-params']:
        params['transport'] = inputs['simulation-params']['transport-model']
    else:
        raise ValueError('Please select a transport model: DGM or Fick.')

    # Load the tortuosity:
    if tau_g:
        params['tau_g'] = float(tau_g)
    elif 'tau_g' in membrane_params:
        params['tau_g'] = membrane_params['tau_g']
    else:
        raise ValueError('Please specify a tortuosity tau_g, either via the '
                         'command line (--tau_g=[value]) or as a field in '
                         'membrane_distillation_inputs.yaml:membrane-params')

    # For the Fick model, we manually store the membrane permeability:
    if params['transport'] == 'Fick':
        params['K_g'] = (4. * params['d_part']**2 * params['eps_g']**3 /
                         (72. * params['tau_g']**2 *
                          (1. - params['eps_g'])**2))

    Press = 101325.0  # Initial gas pressure [Pa]
    # Read out the feed flow temperature and convert to K:
    if feed_temp is not None:
        params['T_feed'] = 273.15 + feed_temp
    elif 'T_feed' in inputs['temp-data']:
        params['T_feed'] = 273.15 + inputs['temp-data']['T_feed']
    else:
        raise ValueError('Please specify a feed temperature, either via the'
                         ' command line (--feed_temp=[temp]) or as a field in '
                         'membrane_distillation_inputs.yaml:temp-data')

    # Read out the permeate flow temperature and convert to K:
    if permeate_temp is not None:
        params['T_permeate'] = 273.15 + permeate_temp
    elif 'T_permeate' in inputs['temp-data']:
        params['T_permeate'] = 273.15 + inputs['temp-data']['T_permeate']
    else:
        raise ValueError(
            'Please specify a permeate temperature, either via '
            'the command line (--permeate_temp=[temp]) or as a field in '
            'membrane_distillation_inputs.yaml:temp-data')

    #===========================================================================
    #   CHECK FOR AND LOAD INTEGRATOR PARAMETERS:
    #===========================================================================
    # If tolerances are not specified, load in the defaults:
    if 'rtol' not in params:
        params['rtol'] = 1e-3
    if 'atol' not in params:
        params['atol'] = 1e-6

    # If a final simulation time is not specified, load the default:
    if 't final' not in params:
        params['t final'] = 1000  # seconds

    # If an integrator method is not specified, load BDF:
    if 'method' not in params:
        params['method'] = 'BDF'

    #===========================================================================
    #   Create Cantera objects and store in 'obj' dict:
    #===========================================================================
    if params['transport'] == 'Fick':
        gas = ct.Solution(input_file, inputs['phase-names']['gas'])
    elif params['transport'] == 'DGM':
        gas = ct.DustyGas(input_file, inputs['phase-names']['gas'])
        gas.tortuosity = params['tau_g']
        gas.porosity = params['eps_g']
        gas.mean_pore_radius = params['r_pore']
        gas.mean_particle_diameter = params['d_part']

    liquid = ct.Solution(input_file, inputs['phase-names']['liquid'])
    interface = ct.Interface(input_file, inputs['phase-names']['interface'],
                             [gas, liquid])
    obj = {'gas': gas, 'liquid': liquid, 'interface': interface}

    #===========================================================================
    #   POINTERS TO SOLUTION VECTOR LOCATIONS
    #===========================================================================
    # Each volume has n_species + 1 variables (the extra being temperature)
    params['n_vars'] = gas.n_species + 1
    size_SV = params['n_y'] * params['n_vars']
    SV_0 = np.zeros(size_SV)

    params['ptr_temp'] = range(0, size_SV, params['n_vars'])
    params['ptr_rho_k'] = np.ndarray(shape=(params['n_y'], gas.n_species),
                                     dtype='int')
    for j in range(params['n_y']):
        params['ptr_rho_k'][j, :] = range(
            1 + j * params['n_vars'], 1 + j * params['n_vars'] + gas.n_species)

    #===========================================================================
    #   INITIALIZE THE SOLUTION VECTOR
    #===========================================================================
    # Calculate the mole fraction of water vapor at the feed side, assuming
    #   saturation.
    # Generic string for gas-phase mole fractions:
    comp_string = 'N2:{},H2O:{}'
    X_h2o = inputs['temp-data']['P_H2O_feed'] / Press
    X_k_feed = comp_string.format(1. - X_h2o, X_h2o)

    # Calculate the mole fraction of water vapor at the permeate side,
    #   assuming saturation:
    X_h2o = inputs['temp-data']['P_H2O_permeate'] / Press
    X_k_permeate = comp_string.format(1. - X_h2o, X_h2o)

    # Use cantera gas object to calcualte species mass densities:
    # Feed side:
    gas.TPX = params['T_feed'], Press, X_k_feed
    rho_k_feed = gas.density * gas.Y

    # Permeate side:
    gas.TPX = params['T_permeate'], Press, X_k_permeate
    rho_k_permeate = gas.density * gas.Y

    # Starting guess assumes linear gradients:
    SV_0[params['ptr_temp']] = np.linspace(params['T_feed'],
                                           params['T_permeate'], params['n_y'])
    for k in np.arange(gas.n_species):
        SV_0[params['ptr_rho_k'][:, k]] = np.linspace(rho_k_feed[k],
                                                      rho_k_permeate[k],
                                                      params['n_y'])

    return SV_0, obj, params