From adf3649ecd263db1fa71e8e89d790223ebabff35 Mon Sep 17 00:00:00 2001 From: Dave Goodwin Date: Sat, 24 Apr 2004 15:44:57 +0000 Subject: [PATCH] updated examples --- Cantera/matlab/setup_winmatlab.py | 26 ++++++---- Cantera/python/Cantera/Func.py | 8 ++-- Cantera/python/Cantera/Reactor.py | 2 +- Cantera/python/examples/catcomb.py | 3 +- Cantera/python/examples/diamond.py | 16 +++---- Cantera/python/examples/dustygas.py | 2 +- Cantera/python/examples/flame1.py | 2 +- Cantera/python/examples/isentropic.py | 4 +- Cantera/python/examples/mix1.py | 24 +++++----- Cantera/python/examples/mix2.py | 68 +++++++++++++++------------ Cantera/python/examples/reactor1.py | 41 ++++++++++++++-- Cantera/python/examples/reactor2.py | 11 +++-- configure | 19 ++------ data/inputs/diamond.cti | 2 +- 14 files changed, 132 insertions(+), 96 deletions(-) diff --git a/Cantera/matlab/setup_winmatlab.py b/Cantera/matlab/setup_winmatlab.py index 7f6c14517..47cb4f659 100644 --- a/Cantera/matlab/setup_winmatlab.py +++ b/Cantera/matlab/setup_winmatlab.py @@ -1,27 +1,35 @@ import sys -bindir = '/usr/local/bin' -libdir = '/Users/dgg/dv/sf/cantera/build/lib/powerpc-apple-darwin7.3.0' -incdir = '/Users/dgg/dv/sf/cantera/build/include' -libs = '-lclib -loneD -lzeroD -ltransport -lcantera -lrecipes -lcvode -lctlapack -lctmath -lctblas -ltpx -lg2c -lgcc' +bindir = '/home/goodwin/ct154/bin' +libdir = '/home/goodwin/dv/sf/cantera/build/lib/i686-pc-linux-gnu' +incdir = '/home/goodwin/dv/sf/cantera/build/include' +dflibdir = '' + +libs = ['clib', 'oneD', 'zeroD', 'transport', 'cantera', 'recipes', + 'cvode', 'ctlapack', 'ctmath', 'ctblas', 'tpx'] f = open('setup.m','w') -f.write('cd cantera\nbuildux\nexit\n') +f.write('cd cantera\nbuild_cantera\nexit\n') f.close() -fb = open('cantera/buildux.m','w') +fb = open('cantera/build_cantera.m','w') fb.write(""" disp('building Cantera..'); -mex private/ctmethods.cpp private/ctfunctions.cpp ... +mex -I"""+incdir+""" private/ctmethods.cpp private/ctfunctions.cpp ... private/xmlmethods.cpp private/phasemethods.cpp ... private/thermomethods.cpp private/kineticsmethods.cpp ... private/transportmethods.cpp private/reactormethods.cpp ... private/wallmethods.cpp private/flowdevicemethods.cpp ... - private/funcmethods.cpp ... private/onedimmethods.cpp private/surfmethods.cpp private/write.cpp ... -"""+'-I'+incdir+' -L'+libdir+' '+libs+'\n'+"""disp('done.'); """) +s = '' +for lib in libs: + s += ' '+libdir+'/'+lib+'.lib ...\n' +fb.write(s) +fb.write(' "'+dflibdir+'/dformd.lib" ...\n') +fb.write(' "'+dflibdir+'/dfconsol.lib" ...\n') +fb.write(' "'+dflibdir+'/dfport.lib" \n') fb.close() fp = open('cantera/ctbin.m','w') diff --git a/Cantera/python/Cantera/Func.py b/Cantera/python/Cantera/Func.py index 07e8ba657..227afac16 100644 --- a/Cantera/python/Cantera/Func.py +++ b/Cantera/python/Cantera/Func.py @@ -182,7 +182,7 @@ def Const(value): class PeriodicFunction(Func1): def __init__(self, func, T): - Func1.__init__(self, 50, func._func_id(), array([T],'d')) + Func1.__init__(self, 50, func.func_id(), array([T],'d')) # functions that combine two functions @@ -209,7 +209,7 @@ class SumFunction(Func1): self.f1 = f1 self.f2 = f2 self.n = -1 - self._func_id = _cantera.func_newcombo(20, f1._func_id(), f2._func_id()) + self._func_id = _cantera.func_newcombo(20, f1.func_id(), f2.func_id()) class ProdFunction(Func1): """Product of two functions. @@ -232,7 +232,7 @@ class ProdFunction(Func1): self.f1 = f1 self.f2 = f2 self.n = -1 - self._func_id = _cantera.func_newcombo(30, f1._func_id(), f2._func_id()) + self._func_id = _cantera.func_newcombo(30, f1.func_id(), f2.func_id()) class RatioFunction(Func1): """Ratio of two functions. @@ -255,6 +255,6 @@ class RatioFunction(Func1): self.f1 = f1 self.f2 = f2 self.n = -1 - self._func_id = _cantera.func_newcombo(40, f1._func_id(), f2._func_id()) + self._func_id = _cantera.func_newcombo(40, f1.func_id(), f2.func_id()) diff --git a/Cantera/python/Cantera/Reactor.py b/Cantera/python/Cantera/Reactor.py index 38a9a8589..61def5b3b 100644 --- a/Cantera/python/Cantera/Reactor.py +++ b/Cantera/python/Cantera/Reactor.py @@ -271,7 +271,7 @@ class ReactorBase: It is also allowed to write >>> gas = r.contents() """ - syncContents() + self.syncContents() return self._contents diff --git a/Cantera/python/examples/catcomb.py b/Cantera/python/examples/catcomb.py index e4ccd2663..3b5d8d243 100644 --- a/Cantera/python/examples/catcomb.py +++ b/Cantera/python/examples/catcomb.py @@ -10,7 +10,6 @@ # The catalytic combustion mechanism is from Deutschman et al., 26th # Symp. (Intl.) on Combustion,1996 pp. 1747-1754 # -# On a Mac G4, this example takes about 20 sec. # from Cantera import * @@ -62,7 +61,7 @@ refine_grid = 1 # 1 to enable refinement, 0 to # input file 'ptcombust.cti,' which is a stripped-down version of # GRI-Mech 3.0. gas = importPhase('ptcombust.cti','gas') -gas.setState_TPX(tinlet, p, comp1) +gas.set(T = tinlet, P = p, X = comp1) ################ create the interface object ################## diff --git a/Cantera/python/examples/diamond.py b/Cantera/python/examples/diamond.py index ee6057cbb..c8c9f8a86 100644 --- a/Cantera/python/examples/diamond.py +++ b/Cantera/python/examples/diamond.py @@ -1,11 +1,11 @@ # A CVD example. 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 -#catcomb.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]. +# 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 +# catcomb.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]. from Cantera import * import math @@ -24,7 +24,7 @@ mw = dbulk.molarMasses()[0] t = 1200.0 x = g.moleFractions() p = 20.0*OneAtm/760.0 # 20 Torr -g.setState_TPX(t, p, x) +g.set(T = t, P = p, X = x) ih = g.speciesIndex('H') diff --git a/Cantera/python/examples/dustygas.py b/Cantera/python/examples/dustygas.py index 70949a840..6a11cbf82 100644 --- a/Cantera/python/examples/dustygas.py +++ b/Cantera/python/examples/dustygas.py @@ -16,7 +16,7 @@ from Cantera.DustyGasTransport import * g = importPhase('h2o2.cti') # set the gas state -g.setState_TPX(500.0, OneAtm, "OH:1, H:2, O2:3") +g.set(T = 500.0, P = OneAtm, X = "OH:1, H:2, O2:3") # create a Dusty Gas transport manager for this phase d = DustyGasTransport(g) diff --git a/Cantera/python/examples/flame1.py b/Cantera/python/examples/flame1.py index 5af347037..3ae594150 100755 --- a/Cantera/python/examples/flame1.py +++ b/Cantera/python/examples/flame1.py @@ -44,7 +44,7 @@ refine_grid = 1 # 1 to enable refinement, 0 to gas = IdealGasMix(rxnmech, mix) # set its state to that of the unburned gas at the burner -gas.setState_TPX(tburner, p, comp) +gas.set(T = tburner, P = p, X = comp) f = BurnerFlame(gas = gas, grid = initial_grid) diff --git a/Cantera/python/examples/isentropic.py b/Cantera/python/examples/isentropic.py index c353ca481..70f222fe4 100755 --- a/Cantera/python/examples/isentropic.py +++ b/Cantera/python/examples/isentropic.py @@ -30,7 +30,7 @@ def isentropic(g = None): if g == None: gas = GRI30() - gas.setState_TPX(1200.0,10.0*OneAtm,'H2:1,N2:0.1') + gas.set(T = 1200.0,P = 10.0*OneAtm,X = 'H2:1,N2:0.1') else: gas = g @@ -50,7 +50,7 @@ def isentropic(g = None): p = p0*(r+1)/201.0 # set the state using (p,s0) - gas.setState_SP(s0,p) + gas.set(S = s0, P = p) h = gas.enthalpy_mass() rho = gas.density() diff --git a/Cantera/python/examples/mix1.py b/Cantera/python/examples/mix1.py index 495019a53..f43d2df34 100644 --- a/Cantera/python/examples/mix1.py +++ b/Cantera/python/examples/mix1.py @@ -16,14 +16,14 @@ #----------------------------------------------------------------------- from Cantera import * -from Cantera.Reactor import Reactor, Reservoir, MassFlowController, Valve +from Cantera.Reactor import * # Use air for stream a. Note that the Air() function does not set the # composition correctly; thus, we need to explicitly set the # composition to that of air. gas_a = Air() -gas_a.setState_TPX(300.0, OneAtm, 'O2:0.21, N2:0.78, AR:0.01') +gas_a.set(T = 300.0, P = OneAtm, X = 'O2:0.21, N2:0.78, AR:0.01') rho_a = gas_a.density() @@ -31,7 +31,7 @@ rho_a = gas_a.density() # desired to have a pure mixer, with no chemistry, use instead a # reaction mechanism for gas_b that has no reactions. gas_b = GRI30() -gas_b.setState_TPX(300.0, OneAtm, 'CH4:1') +gas_b.set(T = 300.0, P = OneAtm, X = 'CH4:1') rho_b = gas_b.density() @@ -55,17 +55,17 @@ mixer = Reactor(gas_b) # create two mass flow controllers connecting the upstream reservoirs # to the mixer, and set their mass flow rates to values corresponding # to stoichiometric combustion. -mfc1 = MassFlowController(res_a, mixer) -mfc1.setMassFlowRate(rho_a*2.5/0.21) +mfc1 = MassFlowController(upstream = res_a, downstream = mixer, + mdot = rho_a*2.5/0.21) -mfc2 = MassFlowController(res_b, mixer) -mfc2.setMassFlowRate(rho_b*1.0) +mfc2 = MassFlowController(upstream = res_b, downstream = mixer, + mdot = rho_b*1.0) # connect the mixer to the downstream reservoir with a valve. -outlet = Valve(mixer, downstream) -outlet.setValveCoeff(1.0) +outlet = Valve(upstream = mixer, downstream = downstream, Kv = 1.0) +sim = ReactorNet([mixer]) # Since the mixer is a reactor, we need to integrate in time to reach # steady state. A few residence times should be enough. @@ -73,14 +73,12 @@ t = 0.0 for n in range(30): tres = mixer.mass()/(mfc1.massFlowRate() + mfc2.massFlowRate()) t += 0.5*tres - mixer.advance(t) + sim.advance(t) print '%14.5g %14.5g %14.5g %14.5g %14.5g' % (t, mixer.temperature(), mixer.enthalpy_mass(), mixer.pressure(), mixer.massFraction('CH4')) # view the state of the gas in the mixer -gas_b.setState_TPY(mixer.temperature(), mixer.pressure(), - mixer.massFractions()) -print gas_b +print mixer.contents() diff --git a/Cantera/python/examples/mix2.py b/Cantera/python/examples/mix2.py index 7e98dd39d..653e731b6 100644 --- a/Cantera/python/examples/mix2.py +++ b/Cantera/python/examples/mix2.py @@ -1,17 +1,29 @@ -# Mixing two streams with reaction. This is the same as mix1.py, -# except that a source of H atoms is added to ignite the fuel/air -# mixture. Once ignited, the flow of H atoms is stopped. +# Mixing two streams. + +# Since reactors can have multiple inlets and outlets, they can be +# used to implement mixers, splitters, etc. In this example, air and +# methane are mixed in stoichiometric proportions. Due to the low +# temperature, no reactions occur. Note that the air stream and the +# methane stream use *different* reaction mechanisms, with different +# numbers of species and reactions. When gas flows from one reactor or +# reservoir to another one with a different reaction mechanism, +# species are matched by name. If the upstream reactor contains a +# species that is not present in the downstream reaction mechanism, it +# will be ignored. In general, reaction mechanisms for downstream +# reactors should contain all species that might be present in any +# upstream reactor. +# +#----------------------------------------------------------------------- -import math from Cantera import * -from Cantera.Reactor import Reactor, Reservoir, MassFlowController, Valve +from Cantera.Reactor import * # Use air for stream a. Note that the Air() function does not set the # composition correctly; thus, we need to explicitly set the # composition to that of air. gas_a = Air() -gas_a.setState_TPX(300.0, OneAtm, 'O2:0.21, N2:0.78, AR:0.01') +gas_a.set(T = 300.0, P = OneAtm, X = 'O2:0.21, N2:0.78, AR:0.01') rho_a = gas_a.density() @@ -19,7 +31,7 @@ rho_a = gas_a.density() # desired to have a pure mixer, with no chemistry, use instead a # reaction mechanism for gas_b that has no reactions. gas_b = GRI30() -gas_b.setState_TPX(300.0, OneAtm, 'CH4:1') +gas_b.set(T = 300.0, P = OneAtm, X = 'CH4:1') rho_b = gas_b.density() @@ -43,51 +55,49 @@ mixer = Reactor(gas_b) # create two mass flow controllers connecting the upstream reservoirs # to the mixer, and set their mass flow rates to values corresponding # to stoichiometric combustion. -mfc1 = MassFlowController(res_a, mixer) -mfc1.setMassFlowRate(rho_a*2.5/0.21) +mfc1 = MassFlowController(upstream = res_a, + downstream = mixer, + mdot = rho_a*2.5/0.21) -mfc2 = MassFlowController(res_b, mixer) -mfc2.setMassFlowRate(rho_b*1.0) - - -# connect the mixer to the downstream reservoir with a valve. -outlet = Valve(mixer, downstream) -outlet.setValveCoeff(1.0) +mfc2 = MassFlowController(upstream = res_b, + downstream = mixer, + mdot = rho_b*1.0) # add an igniter to ignite the mixture. The 'igniter' consists of a # stream of pure H. -gas_c = IdealGasMix('h2o2.xml') -gas_c.setState_TPX(300.0, OneAtm, 'H:1') +gas_c = IdealGasMix('h2o2.cti') +gas_c.set(T = 300.0, P = OneAtm, X = 'H:1') igniter = Reactor(gas_c) -mfc3 = MassFlowController(igniter, mixer) -mfc3.setMassFlowRate(0.05) +mfc3 = MassFlowController(upstream = igniter, downstream = mixer, + mdot = 0.05) +# connect the mixer to the downstream reservoir with a valve. +outlet = Valve(upstream = mixer, downstream = downstream, Kv = 1.0) + +sim = ReactorNet([mixer]) # Since the mixer is a reactor, we need to integrate in time to reach # steady state. A few residence times should be enough. t = 0.0 for n in range(30): tres = mixer.mass()/(mfc1.massFlowRate() + mfc2.massFlowRate()) - tnow = t t += 0.5*tres - mixer.advance(t) - + sim.advance(t) + # if ignited, turn the igniter off. # We also need to restart the integration in this case. if mixer.temperature() > 1200.0: - mfc3.setMassFlowRate(0.0) - mixer.setInitialTime(t) + mfc3.set(mdot = 0.0) + sim.setInitialTime(t) print '%14.5g %14.5g %14.5g %14.5g %14.5g' % (t, mixer.temperature(), mixer.enthalpy_mass(), mixer.pressure(), mixer.massFraction('CH4')) -gas_b.setState_TPY(mixer.temperature(), mixer.pressure(), mixer.massFractions()) # view the state of the gas in the mixer -gas_b.setState_TPY(mixer.temperature(), mixer.pressure(), - mixer.massFractions()) -print gas_b +print mixer.contents() + diff --git a/Cantera/python/examples/reactor1.py b/Cantera/python/examples/reactor1.py index e8610bd19..99672be6b 100644 --- a/Cantera/python/examples/reactor1.py +++ b/Cantera/python/examples/reactor1.py @@ -10,7 +10,7 @@ from Cantera import rxnpath gri3 = GRI30() -gri3.setState_TPX(1001.0, OneAtm, 'H2:2,O2:1,N2:4') +gri3.set(T = 1001.0, P = OneAtm, X = 'H2:2,O2:1,N2:4') r = Reactor(gri3) env = Reservoir(Air()) @@ -19,16 +19,47 @@ env = Reservoir(Air()) # make it flexible, so that the pressure in the reactor is held # at the environment pressure. w = Wall(r,env) -w.set(K = 1.0e6) # set expansion parameter. dV/dt = K(P_1 - P_2) +w.set(K = 1.0e6) # set expansion parameter. dV/dt = KA(P_1 - P_2) w.set(A = 1.0) +sim = ReactorNet([r]) time = 0.0 +tim = zeros(100,'d') +data = zeros([100,5],'d') + for n in range(100): time += 1.e-5 - r.advance(time) - env.advance(time) + sim.advance(time) + tim[n] = time + data[n,0] = r.temperature() + data[n,1] = r.moleFraction('OH') + data[n,2] = r.moleFraction('H') + data[n,3] = r.moleFraction('H2') print '%10.3e %10.3f %10.3f %14.6e' % (r.time(), r.temperature(), r.pressure(), r.intEnergy_mass()) - print env.pressure() +# plot the results if matplotlib is installed. +# see http://matplotlib.sourceforge.net to get it +try: + from matplotlib.matlab import * + clf + subplot(2,2,1) + plot(tim,data[:,0]) + xlabel('Time (s)'); + ylabel('Temperature (K)'); + subplot(2,2,2) + plot(tim,data[:,1]) + xlabel('Time (s)'); + ylabel('OH Mole Fraction'); + subplot(2,2,3) + plot(tim,data[:,2]); + xlabel('Time (s)'); + ylabel('H Mole Fraction'); + subplot(2,2,4) + plot(tim,data[:,3]); + xlabel('Time (s)'); + ylabel('H2 Mole Fraction'); + show() +except: + pass diff --git a/Cantera/python/examples/reactor2.py b/Cantera/python/examples/reactor2.py index 8e856f5b6..7584e584c 100644 --- a/Cantera/python/examples/reactor2.py +++ b/Cantera/python/examples/reactor2.py @@ -32,7 +32,7 @@ from Cantera.Func import * # 'GRI30()' ar = Argon() -ar.setState_TPX(1000.0, 20.0*OneAtm, 'AR:1') +ar.set(T = 1000.0, P = 20.0*OneAtm, X = 'AR:1') # create a reactor to represent the side of the cylinder filled with argon r1 = Reactor(ar) @@ -45,7 +45,7 @@ env = Reservoir(Air()) # use GRI-Mech 3.0 for the methane/air mixture, and set its initial state gri3 = GRI30() -gri3.setState_TPX(500.0, 0.1*OneAtm, 'CH4:1.1, O2:2, N2:7.52') +gri3.set(T = 500.0, P = 0.1*OneAtm, X = 'CH4:1.1, O2:2, N2:7.52') # create a reactor for the methane/air side r2 = Reactor(gri3) @@ -58,7 +58,7 @@ r2 = Reactor(gri3) # add a flexible wall (a piston) between r2 and r1 w = Wall(r2, r1) -w.set(area = 2.0, K=1.1e-4) +w.set(area = 2.0, K=0.55e-4) # heat loss to the environment. Heat loss always occur through walls, @@ -68,6 +68,8 @@ w.set(area = 2.0, K=1.1e-4) w2 = Wall(r1, env) w2.set(area = 0.5, U=100.0) +sim = ReactorNet([r1, r2]) + # Now the problem is set up, and we're ready to solve it. print 'finished setup, begin solution...' @@ -78,8 +80,7 @@ writeCSV(f,['time (s)','T2 (K)','P2 (Pa)','V2 (m3)', for n in range(300): time += 4.e-5 print time, r2.temperature(),n - r1.advance(time) - r2.advance(time) + sim.advance(time) writeCSV(f, [r2.time(), r2.temperature(), r2.pressure(), r2.volume(), r1.temperature(), r1.pressure(), r1.volume()]) f.close() diff --git a/configure b/configure index cee6d0cbb..c7b0d02fa 100755 --- a/configure +++ b/configure @@ -21,7 +21,7 @@ ####################################################################### -CANTERA_VERSION=${CANTERA_VERSION:="1.5.3"} +CANTERA_VERSION=${CANTERA_VERSION:="1.5.4"} CANTERA_CONFIG_PREFIX=${CANTERA_CONFIG_PREFIX:=""} @@ -82,17 +82,6 @@ SET_PYTHON_SITE_PACKAGE_TOPDIR=${SET_PYTHON_SITE_PACKAGE_TOPDIR:="n"} PYTHON_SITE_PACKAGE_TOPDIR=${PYTHON_SITE_PACKAGE_TOPDIR:="/usr/local"} -# -# Proposed extension: -# Use when site packages must be put in system directories -# but Cantera tutorials must be put in user space. -# (this is pretty much the norm on many multiuser unix systems) -# -SET_PYTHON_SITE_PACKAGE_TOPDIR=${SET_PYTHON_SITE_PACKAGE_TOPDIR:="n"} - -PYTHON_SITE_PACKAGE_TOPDIR=${PYTHON_SITE_PACKAGE_TOPDIR:="/usr/local"} - - #----------- Matlab -------------------------------------------------- @@ -101,7 +90,7 @@ PYTHON_SITE_PACKAGE_TOPDIR=${PYTHON_SITE_PACKAGE_TOPDIR:="/usr/local"} # Matlab script. If this is set to "y" but Matlab is not found, the # Matlab toolbox will not be built. -BUILD_MATLAB_TOOLBOX=${BUILD_MATLAB_TOOLBOX:="y"} +BUILD_MATLAB_TOOLBOX=${BUILD_MATLAB_TOOLBOX:="n"} #---------------------------------------------------------------------- @@ -202,7 +191,7 @@ LAPACK_FTN_STRING_LEN_AT_END='y' CXX=${CXX:=g++} # C++ compiler flags -CXXFLAGS=${CXXFLAGS:="-O0 -Wall"} +CXXFLAGS=${CXXFLAGS:="-O2 -Wall"} # the C++ flags required for linking #LCXX_FLAGS= @@ -234,7 +223,7 @@ F77=${F77:=g77} F90=${F90:=f90} # Fortran compiler flags -FFLAGS=${FFLAGS:='-O2 -g'} +FFLAGS=${FFLAGS:='-O2'} # the additional Fortran flags required for linking, if any #LFORT_FLAGS="-lF77 -lFI77" diff --git a/data/inputs/diamond.cti b/data/inputs/diamond.cti index ab06fbf58..88a41c7d8 100644 --- a/data/inputs/diamond.cti +++ b/data/inputs/diamond.cti @@ -11,7 +11,7 @@ ideal_gas(name = 'gas', pressure = 1.0e3, mole_fractions = 'H:0.002, H2:1, CH4:0.01, CH3:0.0002')) -pure_solid(name = 'diamond', +stoichiometric_solid(name = 'diamond', elements = 'C', density = (3.52, 'g/cm3'), species = 'C(d)')