コード例 #1
0
ファイル: test_convert.py プロジェクト: minhbau/cantera-1
    def test_sofc(self):
        gas_a, anode_bulk, oxide_a = ct.import_phases(
            'sofc.cti', ['gas', 'metal', 'oxide_bulk'])

        self.assertNear(gas_a.P, ct.one_atm)
        self.assertNear(anode_bulk['electron'].X, 1.0)
        self.assertNear(oxide_a.density, 700)
コード例 #2
0
ファイル: test_equilibrium.py プロジェクト: Althenor/Cantera
 def setUp(self):
     self.phases = ct.import_phases('KOH.xml', [
         'K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid',
         'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water',
         'KOH_plasma'
     ])
     self.mix = ct.Mixture(self.phases)
コード例 #3
0
ファイル: test_convert.py プロジェクト: hkmoffat/cantera
    def test_sofc(self):
        gas_a, anode_bulk, oxide_a = ct.import_phases(
            "../../interfaces/cython/cantera/examples/surface_chemistry/sofc.cti", ["gas", "metal", "oxide_bulk"]
        )

        self.assertNear(gas_a.P, ct.one_atm)
        self.assertNear(anode_bulk["electron"].X, 1.0)
        self.assertNear(oxide_a.density, 700)
コード例 #4
0
ファイル: test_convert.py プロジェクト: kyleniemeyer/cantera
    def test_sofc(self):
        gas_a, anode_bulk, oxide_a = ct.import_phases(
            'sofc.cti',
            ['gas', 'metal', 'oxide_bulk'])

        self.assertNear(gas_a.P, ct.one_atm)
        self.assertNear(anode_bulk['electron'].X, 1.0)
        self.assertNear(oxide_a.density, 700)
コード例 #5
0
ファイル: test_convert.py プロジェクト: parkerclayton/Cantera
    def test_sofc(self):
        gas_a, anode_bulk, oxide_a = ct.import_phases(
            '../../interfaces/cython/cantera/examples/surface_chemistry/sofc.cti',
            ['gas', 'metal', 'oxide_bulk'])

        self.assertNear(gas_a.P, ct.one_atm)
        self.assertNear(anode_bulk['electron'].X, 1.0)
        self.assertNear(oxide_a.density, 700)
コード例 #6
0
ファイル: test_convert.py プロジェクト: pwcnorthrop/cantera
    def test_sofc(self):
        gas_a, anode_bulk, oxide_a = ct.import_phases(
            '../../interfaces/cython/cantera/examples/surface_chemistry/sofc.cti',
            ['gas', 'metal', 'oxide_bulk'])

        self.assertNear(gas_a.P, ct.one_atm)
        self.assertNear(anode_bulk['electron'].X, 1.0)
        self.assertNear(oxide_a.density, 700)
コード例 #7
0
ファイル: test_kinetics.py プロジェクト: thomasfiala/cantera
    def test_sofc(self):
        mech = 'sofc-test.xml'
        T = 1073.15  # T in K
        P = ct.one_atm
        TPB_length_per_area = 1.0e7  # TPB length per unit area [1/m]

        def newton_solve(f, xstart, C=0.0):
            """ Solve f(x) = C by Newton iteration. """
            x0 = xstart
            dx = 1.0e-6

            n = 0
            while True:
                n += 1
                f0 = f(x0) - C
                x0 -= f0/(f(x0 + dx) - C - f0)*dx
                if n > 1000:
                    raise Exception('No convergence in Newton solve')
                if abs(f0) < 0.00001:
                    return x0

        # Anode-side phases
        gas_a, anode_bulk, oxide_a = ct.import_phases(mech,
                                                      ['gas', 'metal', 'oxide_bulk',])
        anode_surf = ct.Interface(mech, 'metal_surface', [gas_a])
        oxide_surf_a = ct.Interface(mech, 'oxide_surface', [gas_a, oxide_a])
        tpb_a = ct.Interface(mech, 'tpb', [anode_bulk, anode_surf, oxide_surf_a])

        # Cathode-side phases
        gas_c, cathode_bulk, oxide_c = ct.import_phases(mech,
                                                        ['gas', 'metal', 'oxide_bulk'])
        cathode_surf = ct.Interface(mech, 'metal_surface', [gas_c])
        oxide_surf_c = ct.Interface(mech, 'oxide_surface', [gas_c, oxide_c])
        tpb_c = ct.Interface(mech, 'tpb', [cathode_bulk, cathode_surf,
                                                 oxide_surf_c])

        def anode_curr(E):
            anode_bulk.electric_potential = E
            w = tpb_a.net_production_rates
            return ct.faraday * w[0] * TPB_length_per_area

        def cathode_curr(E):
            cathode_bulk.electric_potential = E + oxide_c.electric_potential
            w = tpb_c.net_production_rates
            return -ct.faraday * w[0] * TPB_length_per_area

        # initialization
        gas_a.TPX = T, P, 'H2:0.97, H2O:0.03'
        gas_a.equilibrate('TP')
        gas_c.TPX = T, P, 'O2:1.0, H2O:0.001'
        gas_c.equilibrate('TP')

        for p in [anode_bulk, anode_surf, oxide_surf_a, oxide_a, cathode_bulk,
                  cathode_surf, oxide_surf_c, oxide_c, tpb_a, tpb_c]:
            p.TP = T, P

        for s in [anode_surf, oxide_surf_a, cathode_surf, oxide_surf_c]:
            s.advance_coverages(50.0)

        # These values are just a regression test with no theoretical basis
        self.assertArrayNear(anode_surf.coverages,
                             [6.18736755e-01, 3.81123779e-01, 8.63037850e-05,
                              2.59274708e-06, 5.05702339e-05])
        self.assertArrayNear(oxide_surf_a.coverages,
                             [4.99435780e-02, 9.48927983e-01, 1.12840577e-03,
                              3.35936530e-08])
        self.assertArrayNear(cathode_surf.coverages,
                             [1.48180380e-07, 7.57234727e-14, 9.99999827e-01,
                              2.49235513e-08, 4.03296469e-13])
        self.assertArrayNear(oxide_surf_c.coverages,
                             [4.99896947e-02, 9.49804199e-01, 2.06104969e-04,
                              1.11970271e-09])

        Ea0 = newton_solve(anode_curr, xstart=-0.51)
        Ec0 = newton_solve(cathode_curr, xstart=0.51)

        data = []

        # vary the anode overpotential, from cathodic to anodic polarization
        for Ea in np.linspace(Ea0 - 0.25, Ea0 + 0.25, 20):
            anode_bulk.electric_potential = Ea
            curr = anode_curr(Ea)
            delta_V = curr * 5.0e-5 / 2.0
            phi_oxide_c = -delta_V
            oxide_c.electric_potential = phi_oxide_c
            oxide_surf_c.electric_potential = phi_oxide_c
            Ec = newton_solve(cathode_curr, xstart=Ec0+0.1, C=curr)
            cathode_bulk.electric_potential = phi_oxide_c + Ec
            data.append([Ea - Ea0, 0.1*curr, Ec - Ec0, delta_V,
                             cathode_bulk.electric_potential -
                             anode_bulk.electric_potential])

        self.compare(data, '../data/sofc-test.csv')
コード例 #8
0
ファイル: diamond_cvd.py プロジェクト: Althenor/Cantera
This example computes the growth rate of a diamond film according to a
simplified version of a particular published growth mechanism (see file
diamond.cti for details). Only the surface coverage equations are solved here;
the gas composition is fixed. (For an example of coupled gas- phase and
surface, see catalytic_combustion.py.)  Atomic hydrogen plays an important
role in diamond CVD, and this example computes the growth rate and surface
coverages as a function of [H] at the surface for fixed temperature and [CH3].
"""

import csv
import cantera as ct

print('\n******  CVD Diamond Example  ******\n')

# import the models for the gas and bulk diamond
g, dbulk = ct.import_phases('diamond.cti', ['gas', 'diamond'])

# import the model for the diamond (100) surface
d = ct.Interface('diamond.cti', 'diamond_100', [g, dbulk])

ns = d.n_species
mw = dbulk.molecular_weights[0]

t = 1200.0
x = g.X
p = 20.0 * ct.one_atm / 760.0  # 20 Torr
g.TP = t, p

ih = g.species_index('H')

xh0 = x[ih]
コード例 #9
0
model that will consider one species in the SEI, one species in the
electrolyte, and track temperature, concentration, and electrical potential of
the species in a discretized grid employing a finite volume method.
"""

# %% Modules imported
import numpy as np
from matplotlib import pyplot as plt
import cantera as ct

from sei_1d_inputs import *
"""----------Geometry calcs----------"""
dx = x / N_x  # USER INPUT length of step in x direction
dy = y / N_y  # USER INPUT length of step in y direction
"""----------Create Cantera objects----------"""
CE, elyte, sei, sei_conductor, WE = ct.import_phases(ctifile, \
    [CE_phase, elyte_phase, sei_phase, sei_conductorphase, WE_phase])
WE_elyte = ct.Interface(ctifile, WE_elyte_surfphase, [WE, elyte, sei])
WE_sei =  ct.Interface(ctifile, WE_sei_surfphase, \
    [WE, sei, sei_conductor])
sei_elyte = ct.Interface(ctifile, sei_elyte_surfphase, \
    [sei, elyte, sei_conductor])
CE_elyte = ct.Interface(ctifile, CE_surfphase, [CE, elyte])

print('\n     Cantera phases created. \n')
"""----------Set phase properties for cantera objects----------"""
TP_o = T_0, P_0
elyte.TP = TP_o
sei.TP = TP_o
WE.TP = TP_o
CE.TP = TP_o
WE_elyte.TP = TP_o
コード例 #10
0
            step = 0.1*step/abs(step)

        x0 += step
        emax = 0.00001  # 0.01 mV tolerance
        if abs(f0) < emax and n > 8:
            return x0
        f0 = f(x0) - C
        n += 1
    raise Exception('no root!')

#####################################################################
# Anode-side phases
#####################################################################

# import the anode-side bulk phases
gas_a, anode_bulk, oxide_a = ct.import_phases('sofc.cti',
                                              ['gas', 'metal', 'oxide_bulk',])

# import the surfaces on the anode side
anode_surf = ct.Interface('sofc.cti', 'metal_surface', [gas_a])
oxide_surf_a = ct.Interface('sofc.cti', 'oxide_surface', [gas_a, oxide_a])

# import the anode-side triple phase boundary
tpb_a = ct.Interface('sofc.cti', 'tpb', [anode_bulk, anode_surf, oxide_surf_a])

anode_surf.name = 'anode surface'
oxide_surf_a.name = 'anode-side oxide surface'


# this function is defined to use with NewtonSolver to invert the current-
# voltage function. NewtonSolver requires a function of one variable, so the
# other objects are accessed through the global namespace.
コード例 #11
0
ファイル: test_convert.py プロジェクト: kyleniemeyer/cantera
    def test_diamond(self):
        gas, solid = ct.import_phases('diamond.cti', ['gas','diamond'])
        face = ct.Interface('diamond.cti', 'diamond_100', [gas, solid])

        self.assertNear(face.site_density, 3e-8)
コード例 #12
0
An equilibrium example with charged species in the gas phase
and multiple condensed phases.

Requires: cantera >= 2.5.0, matplotlib >= 2.0
Keywords: equilibrium, multiphase, plasma, saving output
"""

import cantera as ct
import csv

# create objects representing the gas phase and the condensed phases. The gas
# is a mixture of multiple species, and the condensed phases are all modeled
# as incompressible stoichiometric substances. See file KOH.yaml for more
# information.
phases = ct.import_phases('KOH.yaml', [
    'K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid', 'K2O2_solid',
    'K2O_solid', 'KO2_solid', 'ice', 'liquid_water', 'KOH_plasma'
])

# create the Mixture object from the list of phases
mix = ct.Mixture(phases)
equil_data = []

# loop over temperature
for n in range(100):
    t = 350.0 + 50.0 * n
    print('T = {0}'.format(t))
    mix.T = t
    mix.P = ct.one_atm
    mix.species_moles = "K:1.03, H2:2.12, O2:0.9"

    # set the mixture to a state of chemical equilibrium holding
コード例 #13
0
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from SEI_prelim_functions import df_2spec2var
from SEI_prelim_functions import IC_fun
import cantera as ct
from assimulo.solvers import IDA
from assimulo.problem import Implicit_Problem

cantera_file = 'W_anode_chem.cti'
elyte_name = 'electrolyte'
SEI_name = 'SEI'
anode_name = 'tungsten'
anode_elyte_surf = 'tungsten_electrolyte_surf'

elyte, SEI, anode = ct.import_phases(cantera_file, \
                                     [elyte_name, SEI_name, anode_name])
anode_elyte = ct.Interface(cantera_file, anode_elyte_surf, [anode, elyte, SEI])


# %% Define grid variables

"""----------Define grid dimensions----------"""

# A (2,10) grid will be indexed as shown below with each node having the
# number of tracked variables stored for it. The solution vector will be
# a row vector progressing through each tracked variable for each cell, then
# progressing in increasing column number for increasing row number.
#   
#          |--> electrolyte
#          |
#          |-----------------------------------------------------------|
コード例 #14
0
 def setUpClass(cls):
     cls.phases = ct.import_phases('KOH.xml', [
         'K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid',
         'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water',
         'KOH_plasma'
     ])
コード例 #15
0
    def __init__(self,
                 config_file,
                 prep_capex=0,
                 prep_opex=0,
                 prep_revenue=0,
                 prep_npv=0):
        """Constructor.
        """

        self.confDict = utilities.read_config(config_file)
        solventxHome = self.confDict["solventxHome"]
        reeComps = self.confDict['compositions']
        self.xmlData = self.confDict['xmlData']
        self.modulesData = self.confDict['modules']

        self.xml = os.path.join(
            solventxHome, self.xmlData['xml'], self.xmlData['phase'] + '_' +
            ''.join(self.modulesData["input"]) + '.xml')

        # Set required data

        self.phase_names = self.confDict["phasenames"]  # from xml input file
        self.phase = ct.import_phases(self.xml, self.phase_names)

        # Derived and/or reusable system parameters
        self.column = self.coltypes  # Column name
        self.solv = self.confDict[
            "solvents"]  # solvent list -.i.e., electrolyte, extractant and organic diluent

        # ree by modules
        self.ree = self.modulesData[
            "input"]  #self.REEs[self.moduleID] # (rare earth) metal list

        # Cantera indices
        self.mix = ct.Mixture(self.phase)
        self.aq = self.mix.phase_index(self.phase_names[0])
        self.org = self.mix.phase_index(self.phase_names[1])
        self.ns = self.mix.n_species
        self.naq = self.mix.phase(self.aq).n_species
        self.norg = self.mix.phase(self.org).n_species

        self.HA_Index = self.mix.species_index(
            self.org,
            '(HA)2(org)')  # index of extractant in canera species list
        self.Hp_Index = self.mix.species_index(
            self.aq, 'H+')  # index of H+ in cantera species list
        self.Cl_Index = self.mix.species_index(
            self.aq, 'Cl-')  # index of Cl in cantera species list

        self.canteranames = self.mix.species_names
        self.fixed_species = ['H2O(L)', 'OH-', 'Cl-', 'dodecane']
        self.canteravars = [
            ij for ij in self.canteranames if ij not in self.fixed_species
        ]  # 'Cl-',

        self.nsy = len(self.canteravars)
        self.naqy = len([
            ij for ij in self.mix.species_names[:self.naq]
            if ij not in self.fixed_species
        ])
        self.norgy = len([
            ij for ij in self.mix.species_names[self.naq:]
            if ij not in self.fixed_species
        ])

        self.mwre,\
        self.mwslv          = self.get_mw() # g/mol
        self.rhoslv = [1000, 960, 750]  # [g/L]

        self.upper = [reeComps[i]['upper'] for i in self.ree]
        self.lower = [reeComps[i]['lower'] for i in self.ree]
        ree_mass = [
            np.random.uniform(i, j) for i, j in zip(self.lower, self.upper)
        ]
        self.get_conc(ree_mass)

        self.purity_spec = .99  # not needed?
        self.recov_spec = .99  # not needed?

        self.revenue = [0, 0, 0]
        self.Ns = [0, 0, 0]

        self.nsp = pd.DataFrame()  # feed streams (aq and org) for each column
        self.nsp0 = pd.DataFrame()  # feed streams (aq and org) for each column

        self.y = {}  # all compositions
        self.Ns = {}
コード例 #16
0
 def setUpClass(cls):
     cls.phases = ct.import_phases('KOH.xml',
             ['K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid',
              'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water',
              'KOH_plasma'])
コード例 #17
0
ファイル: test_convert.py プロジェクト: hkmoffat/cantera
    def test_diamond(self):
        gas, solid = ct.import_phases("diamond.cti", ["gas", "diamond"])
        face = ct.Interface("diamond.cti", "diamond_100", [gas, solid])

        self.assertNear(face.site_density, 3e-8)
コード例 #18
0
ファイル: test_kinetics.py プロジェクト: enochd/cantera
    def test_sofc(self):
        mech = 'sofc-test.xml'
        T = 1073.15  # T in K
        P = ct.one_atm
        TPB_length_per_area = 1.0e7  # TPB length per unit area [1/m]

        def newton_solve(f, xstart, C=0.0):
            """ Solve f(x) = C by Newton iteration. """
            x0 = xstart
            dx = 1.0e-6
            while True:
                f0 = f(x0) - C
                x0 -= f0 / (f(x0 + dx) - C - f0) * dx
                if abs(f0) < 0.00001:
                    return x0

        # Anode-side phases
        gas_a, anode_bulk, oxide_a = ct.import_phases(mech, [
            'gas',
            'metal',
            'oxide_bulk',
        ])
        anode_surf = ct.Interface(mech, 'metal_surface', [gas_a])
        oxide_surf_a = ct.Interface(mech, 'oxide_surface', [gas_a, oxide_a])
        tpb_a = ct.Interface(mech, 'tpb',
                             [anode_bulk, anode_surf, oxide_surf_a])

        # Cathode-side phases
        gas_c, cathode_bulk, oxide_c = ct.import_phases(
            mech, ['gas', 'metal', 'oxide_bulk'])
        cathode_surf = ct.Interface(mech, 'metal_surface', [gas_c])
        oxide_surf_c = ct.Interface(mech, 'oxide_surface', [gas_c, oxide_c])
        tpb_c = ct.Interface(mech, 'tpb',
                             [cathode_bulk, cathode_surf, oxide_surf_c])

        def anode_curr(E):
            anode_bulk.electric_potential = E
            w = tpb_a.net_production_rates
            return ct.faraday * w[0] * TPB_length_per_area

        def cathode_curr(E):
            cathode_bulk.electric_potential = E + oxide_c.electric_potential
            w = tpb_c.net_production_rates
            return -ct.faraday * w[0] * TPB_length_per_area

        # initialization
        gas_a.TPX = T, P, 'H2:0.97, H2O:0.03'
        gas_a.equilibrate('TP')
        gas_c.TPX = T, P, 'O2:1.0, H2O:0.001'
        gas_c.equilibrate('TP')

        for p in [
                anode_bulk, anode_surf, oxide_surf_a, oxide_a, cathode_bulk,
                cathode_surf, oxide_surf_c, oxide_c, tpb_a, tpb_c
        ]:
            p.TP = T, P

        for s in [anode_surf, oxide_surf_a, cathode_surf, oxide_surf_c]:
            s.advance_coverages(50.0)

        # These values are just a regression test with no theoretical basis
        self.assertArrayNear(anode_surf.coverages, [
            6.18736755e-01, 3.81123779e-01, 8.63037850e-05, 2.59274708e-06,
            5.05702339e-05
        ])
        self.assertArrayNear(
            oxide_surf_a.coverages,
            [4.99435780e-02, 9.48927983e-01, 1.12840577e-03, 3.35936530e-08])
        self.assertArrayNear(cathode_surf.coverages, [
            1.48180380e-07, 7.57234727e-14, 9.99999827e-01, 2.49235513e-08,
            4.03296469e-13
        ])
        self.assertArrayNear(
            oxide_surf_c.coverages,
            [4.99896947e-02, 9.49804199e-01, 2.06104969e-04, 1.11970271e-09])

        Ea0 = newton_solve(anode_curr, xstart=-0.51)
        Ec0 = newton_solve(cathode_curr, xstart=0.51)

        data = []

        # vary the anode overpotential, from cathodic to anodic polarization
        for Ea in np.linspace(Ea0 - 0.25, Ea0 + 0.25, 20):
            anode_bulk.electric_potential = Ea
            curr = anode_curr(Ea)
            delta_V = curr * 5.0e-5 / 2.0
            phi_oxide_c = -delta_V
            oxide_c.electric_potential = phi_oxide_c
            oxide_surf_c.electric_potential = phi_oxide_c
            Ec = newton_solve(cathode_curr, xstart=Ec0 + 0.1, C=curr)
            cathode_bulk.electric_potential = phi_oxide_c + Ec
            data.append([
                Ea - Ea0, 0.1 * curr, Ec - Ec0, delta_V,
                cathode_bulk.electric_potential - anode_bulk.electric_potential
            ])

        self.compare(data, '../data/sofc-test.csv')
コード例 #19
0
 def setUp(self):
     self.phases = ct.import_phases('KOH.xml',
             ['K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid',
              'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water',
              'KOH_plasma'])
     self.mix = ct.Mixture(self.phases)
コード例 #20
0
ファイル: test_convert.py プロジェクト: minhbau/cantera-1
    def test_diamond(self):
        gas, solid = ct.import_phases('diamond.cti', ['gas', 'diamond'])
        face = ct.Interface('diamond.cti', 'diamond_100', [gas, solid])

        self.assertNear(face.site_density, 3e-8)
コード例 #21
0
"""
An equilibrium example with charged species in the gas phase
and multiple condensed phases.
"""

import cantera as ct
import csv

# create objects representing the gas phase and the condensed phases. The gas
# is a mixture of multiple species, and the condensed phases are all modeled
# as incompressible stoichiometric substances. See file KOH.cti for more
# information.
phases = ct.import_phases('KOH.cti', ['K_solid', 'K_liquid', 'KOH_a', 'KOH_b',
                                      'KOH_liquid', 'K2O2_solid', 'K2O_solid',
                                      'KO2_solid', 'ice', 'liquid_water',
                                      'KOH_plasma'])

# create the Mixture object from the list of phases
mix = ct.Mixture(phases)

csvfile = open('equil_koh.csv', 'w')
writer = csv.writer(csvfile)
writer.writerow(['T'] + mix.species_names)

# loop over temperature
for n in range(100):
    t = 350.0 + 50.0*n
    print('T = {0}'.format(t))
    mix.T = t
    mix.P = ct.one_atm
    mix.species_moles = "K:1.03, H2:2.12, O2:0.9"