diff --git a/Cantera/matlab/Makefile.in b/Cantera/matlab/Makefile.in index 07afebb94..e60d6ff76 100644 --- a/Cantera/matlab/Makefile.in +++ b/Cantera/matlab/Makefile.in @@ -130,6 +130,9 @@ clean: depends: echo '-' +run-demo: + (cd @ct_dir@; matlab -nojvm -nosplash -r cantera_demos) + # end of file diff --git a/Cantera/matlab/setup_winmatlab.py b/Cantera/matlab/setup_winmatlab.py index 47cb4f659..7f6c14517 100644 --- a/Cantera/matlab/setup_winmatlab.py +++ b/Cantera/matlab/setup_winmatlab.py @@ -1,35 +1,27 @@ import sys -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'] +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' f = open('setup.m','w') -f.write('cd cantera\nbuild_cantera\nexit\n') +f.write('cd cantera\nbuildux\nexit\n') f.close() -fb = open('cantera/build_cantera.m','w') +fb = open('cantera/buildux.m','w') fb.write(""" disp('building Cantera..'); -mex -I"""+incdir+""" private/ctmethods.cpp private/ctfunctions.cpp ... +mex 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/Reactor.py b/Cantera/python/Cantera/Reactor.py index 5bdae4d48..d8125f543 100644 --- a/Cantera/python/Cantera/Reactor.py +++ b/Cantera/python/Cantera/Reactor.py @@ -439,11 +439,12 @@ _mfccount = 0 class MassFlowController(FlowDevice): """Mass flow controllers. A mass flow controller maintains a - constant mass flow rate independent of upstream and downstream - conditions. The equation used to compute the mass flow rate is - \f[ \dot m = \dot m_0, \f] where \f$ \dot m_0 \f$ is a - non-negative value specified when the object is constructed or set - by calling method setMassFlowRate. + specified mass flow rate independent of upstream and downstream + conditions. The equation used to compute the mass flow rate is \f[ + \dot m = \max(\dot m_0, 0.0), \f] where \f$ \dot m_0 \f$ is either + a constant value or a function of time. Note that if \f$\dot m_0 < + 0\f$, the mass flow rate will be set to zero, since reversal of + the flow direction is not allowed. Unlike a real mass flow controller, a MassFlowController object will maintain the flow even if the downstream pressure is greater @@ -460,6 +461,15 @@ class MassFlowController(FlowDevice): are constant across a mass flow controller, and the pressure difference equals the difference in pressure between the upstream and downstream reactors. + + Examples: + + >>> mfc1 = MassFlowController(upstream = res1, downstream = reactr, + ... name = 'fuel_mfc', mdot = 0.1) + >>> air_mdot = Gaussian(A = 0.1, t0 = 2.0, FWHM = 0.1) + >>> mfc2 = MassFlowController(upstream = res2, downstream = reactr, + ... name = 'air_mfc', mdot = air_mdot) + """ def __init__(self, upstream=None, downstream=None, @@ -475,9 +485,10 @@ class MassFlowController(FlowDevice): integer assigned in the order the MassFlowController object was created. - mdot - Mass flow rate [kg/s]. This mass flow rate will be - maintained, independent of unstream and downstream conditions, - unless reset by calling method 'setMassFlowRate'. + mdot - Mass flow rate [kg/s]. This mass flow rate, which may + be a constant of a function of time, will be maintained, + independent of unstream and downstream conditions, unless + reset by calling method 'set'. verbose - if set to a positive integer, additional diagnostic information will be printed. @@ -505,7 +516,9 @@ class MassFlowController(FlowDevice): def set(self, mdot = 0.0): - """Set the mass flow rate [kg/s]. + """Set the mass flow rate [kg/s]. May be called at any time to + change the mass flow rate to a new value, or to a new function + of time. >>> mfc.set(mdot = 0.2) """ @@ -516,12 +529,19 @@ _valvecount = 0 class Valve(FlowDevice): """Valves. In Cantera, a Valve object is a flow devices with mass - flow rate proportional to the pressure drop across it. The equation - used to compute the mass flow rate is + flow rate that is a function of the pressure drop across it. The default behavior + is linear: \f[ \dot m = K_v (P_1 - P_2) \f] if \f$ P_1 > P_2. \f$ Otherwise, - \f$ \dot m = 0 \f$. It is never possible for the flow to reverse + \f$ \dot m = 0 \f$. + However, an arbitrary function \f$ F\f$ can also be specified, such that + \f[ + \dot m = F(P_1 - P_2). + \f] + if \f$ P_1 > P_2, \f$ + or \f$ \dot m = 0 \f$ otherwise. + It is never possible for the flow to reverse and go from the downstream to the upstream reactor/reservoir through a line containing a Valve object. @@ -532,14 +552,6 @@ class Valve(FlowDevice): result in flow between the reactors that counteracts the pressure difference. - Since the mass flow rate is assumed to be linear in \f$ \Delta P \f$, - these objects do not model real, physical valves, in which the flow rate - is proportional to \f$ \sqrt(\Delta P) \f$ for small pressure - differences, and becomes independent of \f$ \Delta P \f$ when - it becomes large (choked flow). Perhaps the name of this class should - be changed to avoid confusion with real valves -- if you have suggestions, - post a comment at the Cantera User's Group site. - A Valve is assumed to be adiabatic, non-reactive, and have negligible internal volume, so that it is internally always in steady-state even if the upstream and downstream reactors are @@ -577,11 +589,10 @@ class Valve(FlowDevice): self.setValveCoeff(Kv, mdot0) - def setValveCoeff(self, Kv = -1.0, mdot0 = 0.0): + def setValveCoeff(self, Kv = -1.0): """Set or reset the valve coefficient \f$ K_v \f$.""" - vv = zeros(2,'d') + vv = zeros(1,'d') vv[0] = Kv - vv[1] = mdot0 if self._verbose: print print self._name+': setting valve coefficient to '+`Kv`+' kg/Pa-s' @@ -595,11 +606,17 @@ class Valve(FlowDevice): else: raise CanteraError("Wrong type for valve characteristic function.") - def set(self, Kv = -1.0, mdot = 0.0, F = None): + def set(self, Kv = -1.0, F = None): + """Set or reset valve properties. All keywords are optional. + + Kv - constant in linear mass flow rate equation. + + F - function of \f$\Delta P\f$. + """ if F: self.setFunction(F) if Kv > 0.0: - self.setValveCoeff(Kv, mdot0 = mdot) + self.setValveCoeff(Kv) @@ -607,6 +624,18 @@ _pccount = 0 class PressureController(FlowDevice): + """ A PressureController is designed to be used in conjunction + with another 'master' flow controller, typically a + MassFlowController. The master flow controller is installed on the + inlet of the reactor, and the corresponding PressureController is + installed on on outlet of the reactor. The PressureController mass + flow rate is equal to the master mass flow rate, plus a + small correction dependent on the pressure difference: + \f[ + \dot m = \dot m_{\rm master} + K_v(P_1 - P_2). + \f] + """ + def __init__(self, upstream=None, downstream=None, name='', master = None, Kv = 0.0, verbose=0): """ @@ -614,10 +643,10 @@ class PressureController(FlowDevice): downstream - downstream reactor or reservoir. - name - name used to identify the valve in output. - If no name is specified, it defaults to 'Valve_n', where n is an - integer assigned in the order the Valve object - was created. + name - name used to identify the pressure controller in + output. If no name is specified, it defaults to + 'PressureController_n', where n is an integer assigned in the + order the PressureController object was created. Kv - the constant in the mass flow rate equation. @@ -646,6 +675,7 @@ class PressureController(FlowDevice): self._setParameters(vv) def setMaster(self, master): + """Set the master flow controller.""" _cantera.flowdev_setMaster(self.flowdev_id(), master.flowdev_id()) diff --git a/Cantera/python/Cantera/importFromFile.py b/Cantera/python/Cantera/importFromFile.py index f51c3efc8..c175731c2 100755 --- a/Cantera/python/Cantera/importFromFile.py +++ b/Cantera/python/Cantera/importFromFile.py @@ -4,16 +4,16 @@ import solution import Interface import XML -def importPhase(file = '', name = ''): +def importPhase(file = '', name = '', loglevel = 0): """Import a phase from a CTI file.""" - return importPhases(file, [name])[0] + return importPhases(file, [name], loglevel)[0] -def importPhases(file = '', names = []): +def importPhases(file = '', names = [], loglevel = 0): """Import multiple phases from one file. The phase names should be entered as a list of strings. """ s = [] for nm in names: - s.append(solution.Solution(src=file,id=nm)) + s.append(solution.Solution(src=file,id=nm,loglevel=loglevel)) return s def importInterface(file = '', name = '', phases = []): diff --git a/Cantera/python/Cantera/solution.py b/Cantera/python/Cantera/solution.py index ec2c566cf..dca438f62 100755 --- a/Cantera/python/Cantera/solution.py +++ b/Cantera/python/Cantera/solution.py @@ -26,7 +26,7 @@ class Solution(ThermoPhase, Kinetics, Transport): """ - def __init__(self, src="", id=""): + def __init__(self, src="", id="", loglevel = 0): self.ckin = 0 self._owner = 0 @@ -52,7 +52,7 @@ class Solution(ThermoPhase, Kinetics, Transport): # initialize the transport model Transport.__init__(self, xml_phase=s, phase=self, - model = '', loglevel=0) + model = '', loglevel=loglevel) def __del__(self): Transport.__del__(self) diff --git a/Cantera/src/transport/TransportFactory.cpp b/Cantera/src/transport/TransportFactory.cpp index 6af124065..8fc746476 100755 --- a/Cantera/src/transport/TransportFactory.cpp +++ b/Cantera/src/transport/TransportFactory.cpp @@ -422,7 +422,7 @@ namespace Cantera { // T* range tr.xml->XML_open(flog, "collision_integrals"); m_integrals = new MMCollisionInt; - m_integrals->init(tr.xml, tstar_min, tstar_max); + m_integrals->init(tr.xml, tstar_min, tstar_max, log_level); fitCollisionIntegrals(flog, tr); tr.xml->XML_close(flog, "collision_integrals"); diff --git a/Makefile.in b/Makefile.in index 20104880f..ce015961c 100755 --- a/Makefile.in +++ b/Makefile.in @@ -213,6 +213,9 @@ test: example_codes datafiles cd test_problems; @MAKE@ all cd test_problems; @MAKE@ test +run-matlab-demo: + cd Cantera/matlab; @MAKE@ run-demo + datafiles: cd data/inputs; @MAKE@ diff --git a/tools/src/finish_install.py.in b/tools/src/finish_install.py.in index 1b696cfc2..04fb30536 100644 --- a/tools/src/finish_install.py.in +++ b/tools/src/finish_install.py.in @@ -80,6 +80,11 @@ fm.write("""path('"""+prefix+"""/matlab/toolbox/cantera/cantera',path)\n""") fm.write("""path('"""+prefix+"""/matlab/toolbox/cantera/cantera/1D',path)\n""") fm.close() +fm = open(ctdir+"/cantera_demos.m","w") +fm.write("""ctpath;\n""") +fm.write("""cd demos/matlab;\n""") +fm.write("""run_examples;\n""") +fm.close() print """ Cantera has been successfully installed.