def default(self, obj): quantities.set_default_units(time='s', current='A') if isinstance(obj, quantities.quantity.Quantity): return float(obj.simplified.magnitude) elif isinstance(obj, numbers.Number): # Noticed Sciunit does not use always quantities, # this will avoid the entire UI to explode return float(obj) else: db_logger.exception(f"I do not know this unit: {obj}")
def scaling_factor_du(Q_rescale, defaultUnits): """Computes the scaling factor to multiply a quantity with, if it is to be expressed in the default units provided. INPUT: Q_rescale: The quantity instance or unit-string that is to be rescaled. defaultUnits: The default units as dictionary, e.g.: {'length': 'm', 'mass': 'kg', 'time': 's'} OUTPUT: Factor by which Q_rescale is to be multiplied with, if expressed in the default units. """ pq.set_default_units(**defaultUnits) if not isinstance(Q_rescale, pq.Quantity): Q_rescale = pq.Quantity(1.0, Q_rescale) return Q_rescale.simplified.magnitude.tolist()
def scaling_factor_du(Q_rescale, defaultUnits): """Computes the scaling factor to multiply a quantity with, if it is to be expressed in the default units provided. INPUT: Q_rescale: The quantity instance or unit-string that is to be rescaled. defaultUnits: The default units as dictionary, e.g.: {'length': 'm', 'mass': 'kg', 'time': 's'} OUTPUT: Factor by which Q_rescale is to be multiplied with, if expressed in the default units. """ pq.set_default_units(**defaultUnits) if not isinstance(Q_rescale, pq.Quantity): Q_rescale = pq.Quantity(1.0, Q_rescale) return Q_rescale.simplified.magnitude.tolist()
# The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # ################################################################################ import logging import quantities quantities.set_default_units('si') quantities.UnitQuantity('kilocalorie', 1000.0*quantities.cal, symbol='kcal') from chempy.species import Species, TransitionState from chempy.reaction import Reaction from chempy.species import LennardJones as LennardJonesModel from chempy.states import * from chempy.kinetics import ArrheniusModel from network import Network from collision import SingleExponentialDownModel ################################################################################ # The current network network = None
""" import logging import cython import numpy as np import quantities as pq import rmgpy.constants as constants from rmgpy.exceptions import QuantityError from rmgpy.rmgobject import RMGObject, expand_to_dict ################################################################################ # Explicitly set the default units to SI pq.set_default_units('si') # These units are not defined by the quantities package, but occur frequently # in data handled by RMG, so we define them manually pq.UnitQuantity('kilocalories', pq.cal * 1e3, symbol='kcal') pq.UnitQuantity('kilojoules', pq.J * 1e3, symbol='kJ') pq.UnitQuantity('kilomoles', pq.mol * 1e3, symbol='kmol') pq.UnitQuantity('molecule', pq.mol / 6.02214179e23, symbol='molecule') pq.UnitQuantity('molecules', pq.mol / 6.02214179e23, symbol='molecules') pq.UnitQuantity('debye', 1.0 / (constants.c * 1e21) * pq.C * pq.m, symbol='De') ################################################################################ # Units that should not be used in RMG-Py: NOT_IMPLEMENTED_UNITS = ['degC', 'C', 'degF', 'F', 'degR', 'R']
sys.exit(0) # User adjustable parameters if args.nwalkers == -1: nwalkers = 64 else: nwalkers = args.nwalkers if args.nsteps == -1: nsteps = 1000 else: nsteps = args.nsteps nburn = nsteps/2 t0 = 1.e5 # Constants and units pq.set_default_units('cgs') G = pq.constants.G.simplified.magnitude pc = pq.pc.simplified.magnitude au = pq.au.simplified.magnitude yr = pq.year.simplified.magnitude kpc = 1.e3*pc mpc = 1.e-3*pc impc = 1./mpc km = 1.e5 ikm = 1./km msun = 1.9891e33 asec = 2.*3600.*180./np.pi iasec = 1./asec masec = 1.e3*asec imasec = 1./masec
################################################################################ """ This module contains classes and methods for working with physical quantities, particularly the :class:`Quantity` class for representing physical quantities. """ import numpy import quantities as pq import rmgpy.constants as constants ################################################################################ # Explicitly set the default units to SI pq.set_default_units('si') # These units are not defined by the quantities package, but occur frequently # in data handled by RMG, so we define them manually pq.UnitQuantity('kilocalories', pq.cal*1e3, symbol='kcal') pq.UnitQuantity('kilojoules', pq.J*1e3, symbol='kJ') pq.UnitQuantity('kilomoles', pq.mol*1e3, symbol='kmol') pq.UnitQuantity('molecule', pq.mol/6.02214179e23, symbol='molecule') pq.UnitQuantity('molecules', pq.mol/6.02214179e23, symbol='molecules') pq.UnitQuantity('debye', 1.0/(constants.c*1e21)*pq.C*pq.m, symbol='De') ################################################################################ # Units that should not be used in RMG-Py: NOT_IMPLEMENTED_UNITS = [ 'degC',
def readInputFile(fstr): """ Parse an RMG input file at the location `fstr`. If successful, this function returns a :class:`rmg.model.CoreEdgeReactionModel` object and a list of one or more :class:`rmg.model.ReactionSystem` objects. """ try: # Parse the RMG input XML file into a DOM tree xml0 = XML(path=fstr) # Make sure root element is a <rmginput> element rootElement = xml0.getRootElement() if rootElement.tagName != 'rmginput': raise InvalidInputFileException('Incorrect root element; should be <rmginput>.') # Process option list optionList = xml0.getChildElement(rootElement, 'optionList') # Process units option units = xml0.getChildElementText(optionList, 'units', required=False, default='si') pq.set_default_units(units) # Read draw molecules option drawMolecules = xml0.getChildElement(optionList, 'drawMolecules', required=False) settings.drawMolecules = (drawMolecules is not None) # Read generate plots option generatePlots = xml0.getChildElement(optionList, 'generatePlots', required=False) settings.generatePlots = (generatePlots is not None) # Read spectral data estimation option spectralDataEstimation = xml0.getChildElement(optionList, 'spectralDataEstimation', required=False) settings.spectralDataEstimation = (spectralDataEstimation is not None) # Read unimolecular reaction network option unirxnNetworks = xml0.getChildElement(optionList, 'unimolecularReactionNetworks', required=False) if unirxnNetworks is not None: # Read method method = str(xml0.getChildElementText(unirxnNetworks, 'method', required=True)) allowed = ['modifiedstrongcollision', 'reservoirstate'] if method.lower() not in allowed: raise InvalidInputFileException('Invalid unimolecular reaction networks method "%s"; allowed values are %s.' % (method, allowed)) # Read temperatures temperatures = xml0.getChildQuantity(unirxnNetworks, 'temperatures', required=False, default=pq.Quantity([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0], 'K')) temperatures = [float(T.simplified) for T in temperatures] # Read pressures pressures = xml0.getChildQuantity(unirxnNetworks, 'pressures', required=False, default=pq.Quantity([1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7], 'Pa')) pressures = [float(P.simplified) for P in pressures] # Read grain size grainSize = xml0.getChildQuantity(unirxnNetworks, 'grainSize', required=False, default=pq.Quantity(0.0, 'J/mol')) grainSize = float(grainSize.simplified) # Read number of grains numberOfGrains = int(xml0.getChildElementText(unirxnNetworks, 'numberOfGrains', required=False, default=0)) if grainSize == 0.0 and numberOfGrains == 0: raise InvalidInputFileException('Must specify a grain size or number of grains for unimolecular reaction networks calculations.') # Read interpolation model interpolationModel = xml0.getChildElement(unirxnNetworks, 'interpolationModel', required=True) modelType = str(xml0.getAttribute(interpolationModel, 'type', required=True)) allowed = ['none', 'chebyshev', 'pdeparrhenius'] if modelType.lower() not in allowed: raise InvalidInputFileException('Invalid unimolecular reaction networks interpolation model "%s"; allowed values are %s.' % (method, allowed)) if modelType.lower() == 'chebyshev': numTPolys = int(xml0.getChildElementText(interpolationModel, 'numberOfTemperaturePolynomials', required=False, default='4')) numPPolys = int(xml0.getChildElementText(interpolationModel, 'numberOfPressurePolynomials', required=False, default='4')) interpolationModel = (modelType, numTPolys, numPPolys) else: interpolationModel = (modelType) settings.unimolecularReactionNetworks = (method, temperatures, pressures, grainSize, numberOfGrains, interpolationModel) else: settings.unimolecularReactionNetworks = None # Create an empty reaction model reactionModel = model.CoreEdgeReactionModel() # Load databases databases = readDatabaseList(xml0, rootElement) for database in databases: if database[1] == 'general': logging.verbose('General database: ' + database[2]) # Load all databases loadThermoDatabase(database[2] + os.sep) loadKineticsDatabase(database[2] + os.sep) loadFrequencyDatabase(database[2]) elif database[1] == 'seedmechanism': logging.verbose('Seed mechanism: ' + database[2]) reactionModel.loadSeedMechanism(database[2]) logging.verbose('') # Process species coreSpecies = []; speciesDict = {} speciesList = xml0.getChildElement(rootElement, 'speciesList') speciesElements = xml0.getChildElements(speciesList, 'species') logging.info('Found ' + str(len(speciesElements)) + ' species') for element in speciesElements: # Load species ID sid = str(xml0.getAttribute(element, 'id', required=True)) # Load the species data from the file spec = species.Species() spec.fromXML(xml0, element) # Check that the species isn't already in the core (e.g. from a seed mechanism) existingSpecies = None for s in reactionModel.core.species: if s.isIsomorphic(spec): existingSpecies = s break if existingSpecies is not None: # Point to existing species rather than newly created species # This means that any information about the species in the # input file will be discarded in favor of the existing species # data spec = existingSpecies else: # Handle other aspects of RMG species creation logging.verbose('Creating new species %s' % str(spec)) species.processNewSpecies(spec) # All species in RMG input file are immediately added to the core coreSpecies.append(spec) # Add to local species dictionary (for matching with other parts of file) speciesDict[sid] = spec logging.verbose('') # Read model flux tolerance fluxTolerance = xml0.getChildElement(rootElement, 'fluxTolerance') reactionModel.fluxToleranceKeepInEdge = float(xml0.getChildElementText(fluxTolerance, 'keepInEdge')) reactionModel.fluxToleranceMoveToCore = float(xml0.getChildElementText(fluxTolerance, 'moveToCore')) reactionModel.fluxToleranceInterrupt = float(xml0.getChildElementText(fluxTolerance, 'interruptSimulation')) logging.debug('Model flux tolerances set to:') logging.debug('\tKeep in edge: %s' % (reactionModel.fluxToleranceKeepInEdge) ) logging.debug('\tMove to core: %s' % (reactionModel.fluxToleranceMoveToCore) ) logging.debug('\tInterrupt simulation: %s' % (reactionModel.fluxToleranceInterrupt) ) logging.debug('') # Read maximum model size maxModelSize = xml0.getChildElement(rootElement, 'maximumModelSize') if maxModelSize is None: logging.debug('Maximum model size is not set') else: reactionModel.maximumEdgeSpecies = int(xml0.getChildElementText(maxModelSize, 'edgeSpecies')) logging.debug('Maximum model size set to:') logging.debug('\tEdge species: %s' % (reactionModel.maximumEdgeSpecies) ) logging.debug('') # Read dynamic simulator element = xml0.getChildElement(rootElement, 'simulator') reactionModel.absoluteTolerance = float(xml0.getAttribute(element, 'atol')) reactionModel.relativeTolerance = float(xml0.getAttribute(element, 'rtol')) logging.info('Read dynamic simulator') logging.debug('Simulator:') logging.debug('\tAbsolute tolerance set to %s' % (reactionModel.absoluteTolerance)) logging.debug('\tRelative tolerance set to %s' % (reactionModel.relativeTolerance)) logging.debug('') # Read termination targets termination = xml0.getChildElement(rootElement, 'termination') targetElements = xml0.getChildElements(termination, 'target') for element in targetElements: targetType = xml0.getAttribute(element, 'type') if targetType == 'conversion': sid = xml0.getAttribute(element, 'speciesID') spec = speciesDict[sid] conv = float(xml0.getElementText(element)) if conv < 0.0 or conv > 1.0: raise InvalidInputFileException('Invalid value for termination fractional conversion.') reactionModel.termination.append(model.TerminationConversion(spec, conv)) elif targetType == 'time': units = str(xml0.getAttribute(element, 'units')) time = float(xml0.getElementText(element)) time = pq.Quantity(time, units); time = float(time.simplified) if time < 0.0: raise InvalidInputFileException('Invalid value for termination time.') reactionModel.termination.append(model.TerminationTime(time)) else: raise InvalidInputFileException('Invalid termination target type "'+targetType+'".') if len(reactionModel.termination) == 0: raise InvalidInputFileException('No termination targets specified.') # Output info about termination targets if len(reactionModel.termination) == 1: logging.info('Found ' + str(len(reactionModel.termination)) + ' termination target') else: logging.info('Found ' + str(len(reactionModel.termination)) + ' termination targets') for index, target in enumerate(reactionModel.termination): string = '\tTermination target #' + str(index+1) + ': ' if target.__class__ == model.TerminationConversion: string += 'conversion ' + str(target.species) + ' ' + str(target.conversion) elif target.__class__ == model.TerminationTime: string += 'time ' + str(target.time) logging.debug(string) logging.debug('') # Get list of available reaction systems import system as systemModule availableSystems = systemModule.getAvailableReactionSystems() # Process reaction systems reactionSystems = [] reactionSystemList = xml0.getChildElement(rootElement, 'reactionSystemList') systemElements = xml0.getChildElements(reactionSystemList, 'reactionSystem') for systemElement in systemElements: # Determine the class of reaction system rsClass = xml0.getAttribute(systemElement, 'class') if rsClass not in availableSystems: raise InvalidInputFileException('Reaction system class "%s" not available.' % (rsClass)) # Declare the reaction system and populate it with info reactionSystem = availableSystems[rsClass]() reactionSystem.fromXML(xml0, systemElement, speciesDict) reactionSystem.initializeCantera() # Append to the list of reaction systems reactionSystems.append(reactionSystem) # Output info about reaction system if len(reactionSystems) == 1: logging.info('Found ' + str(len(reactionSystems)) + ' reaction system') else: logging.info('Found ' + str(len(reactionSystems)) + ' reaction systems') for index, reactionSystem in enumerate(reactionSystems): logging.debug('Reaction system #%i: %s' % (index+1, reactionSystem)) logging.debug('') # Cleanup the DOM tree when finished xml0.cleanup() except InvalidInputFileException, e: logging.exception(str(e)) raise e
################################################################################ """ This module contains classes and methods for working with physical quantities, particularly the :class:`Quantity` class for representing physical quantities. """ import numpy import quantities as pq import rmgpy.constants as constants ################################################################################ # Explicitly set the default units to SI pq.set_default_units("si") # These units are not defined by the quantities package, but occur frequently # in data handled by RMG, so we define them manually pq.UnitQuantity("kilocalories", pq.cal * 1e3, symbol="kcal") pq.UnitQuantity("kilojoules", pq.J * 1e3, symbol="kJ") pq.UnitQuantity("kilomoles", pq.mol * 1e3, symbol="kmol") pq.UnitQuantity("molecule", pq.mol / 6.02214179e23, symbol="molecule") pq.UnitQuantity("molecules", pq.mol / 6.02214179e23, symbol="molecules") pq.UnitQuantity("debye", 1.0 / (constants.c * 1e21) * pq.C * pq.m, symbol="De") ################################################################################ class QuantityError(Exception): """
def readInputFile(fstr): """ Parse an RMG input file at the location `fstr`. If successful, this function returns a :class:`rmg.model.CoreEdgeReactionModel` object and a list of one or more :class:`rmg.model.ReactionSystem` objects. """ try: # Parse the RMG input XML file into a DOM tree xml0 = XML(path=fstr) # Make sure root element is a <rmginput> element rootElement = xml0.getRootElement() if rootElement.tagName != 'rmginput': raise InvalidInputFileException('Incorrect root element; should be <rmginput>.') # Process units units = xml0.getChildElementText(rootElement, 'units', required=False, default='si') pq.set_default_units(units) # Read draw molecules option drawMolecules = xml0.getChildElementText(rootElement, 'drawMolecules', required=False, default='off') drawMolecules = drawMolecules.lower() settings.drawMolecules = (drawMolecules == 'on' or drawMolecules == 'true' or drawMolecules == 'yes') # Read generate plots option generatePlots = xml0.getChildElementText(rootElement, 'generatePlots', required=False, default='off') generatePlots = generatePlots.lower() settings.generatePlots = (generatePlots == 'on' or generatePlots == 'true' or generatePlots == 'yes') # Process databases databases = [] databaseElements = xml0.getChildElements(rootElement, 'database') for element in databaseElements: # Get database type databaseType = xml0.getAttribute(element, 'type', required=True) databaseType = databaseType.lower() if databaseType != 'general': raise InvalidInputFileException('Invalid database type "' + databaseType + '"; valid types are "general".') # Get database name and form path databaseName = xml0.getElementText(element) databasePath = os.path.dirname(__file__) databasePath = os.path.join(databasePath, '..') databasePath = os.path.join(databasePath, '..') databasePath = os.path.join(databasePath, 'data') databasePath = os.path.join(databasePath, databaseName) if not os.path.exists(databasePath): raise InvalidInputFileException('Database "%s" not found.' % databaseName) databases.append([databaseName, databaseType, databasePath]) # Output info about databases logging.info('Found %s database%s' % (len(databases), 's' if len(databases) > 1 else '')) # Check that exactly one general database was specified generalDatabaseCount = sum([1 for database in databases if database[1] == 'general']) if generalDatabaseCount == 0: raise InvalidInputFileException('No general database specified; one must be present.') elif generalDatabaseCount > 1: raise InvalidInputFileException('Multiple general databases specified; only one is allowed.') # Load databases for database in databases: if database[1] == 'general': logging.debug('General database: ' + database[2]) # Load thermo databases species.thermoDatabase = species.ThermoDatabaseSet() species.thermoDatabase.load(database[2] + os.sep) # Load forbidden structures thermo.forbiddenStructures = data.Dictionary() thermo.forbiddenStructures.load(database[2] + os.sep + 'forbiddenStructure.txt') thermo.forbiddenStructures.toStructure() # Load kinetic databases (reaction families) reaction.kineticsDatabase = reaction.ReactionFamilySet() reaction.kineticsDatabase.load(database[2] + os.sep) logging.debug('') # Process species coreSpecies = []; speciesDict = {} speciesElements = xml0.getChildElements(rootElement, 'species') logging.info('Found ' + str(len(speciesElements)) + ' species') for element in speciesElements: # Attributes of the species element sid = xml0.getAttribute(element, 'id') label = xml0.getAttribute(element, 'label') reactive = xml0.getAttribute(element, 'reactive', required=False, default='yes') reactive = reactive.lower() reactive = not (reactive == 'no' or reactive == 'false' or reactive == 'n') # Load structure struct = structure.Structure() cml = xml0.getChildElement(element, 'cml', required=False) inchi = xml0.getChildElement(element, 'inchi', required=False) smiles = xml0.getChildElement(element, 'smiles', required=False) if cml is not None: cmlstr = str(xml0.getChildElement(cml, 'molecule', required=True).toxml()) struct.fromCML(cmlstr) elif inchi is not None: inchistr = str(xml0.getElementText(inchi)) struct.fromInChI(inchistr) elif smiles is not None: smilesstr = str(xml0.getElementText(smiles)) struct.fromSMILES(smilesstr) else: raise InvalidInputFileException('Species "%s" missing structure information.' % label) # Create a new species and append the species to the core spec = species.makeNewSpecies(struct, label, reactive) coreSpecies.append(spec) # Add to local species dictionary (for matching with other parts of file) speciesDict[sid] = spec logging.debug('') # Create an empty reaction model reactionModel = model.CoreEdgeReactionModel() # Read model flux tolerance fluxTolerance = xml0.getChildElement(rootElement, 'fluxTolerance') reactionModel.fluxToleranceKeepInEdge = float(xml0.getChildElementText(fluxTolerance, 'keepInEdge')) reactionModel.fluxToleranceMoveToCore = float(xml0.getChildElementText(fluxTolerance, 'moveToCore')) reactionModel.fluxToleranceInterrupt = float(xml0.getChildElementText(fluxTolerance, 'interruptSimulation')) logging.debug('Model flux tolerances set to:') logging.debug('\tKeep in edge: %s' % (reactionModel.fluxToleranceKeepInEdge) ) logging.debug('\tMove to core: %s' % (reactionModel.fluxToleranceMoveToCore) ) logging.debug('\tInterrupt simulation: %s' % (reactionModel.fluxToleranceInterrupt) ) logging.debug('') # Read maximum model size maxModelSize = xml0.getChildElement(rootElement, 'maximumModelSize') if maxModelSize is None: logging.debug('Maximum model size is not set') else: reactionModel.maximumEdgeSpecies = int(xml0.getChildElementText(maxModelSize, 'edgeSpecies')) logging.debug('Maximum model size set to:') logging.debug('\tEdge species: %s' % (reactionModel.maximumEdgeSpecies) ) logging.debug('') # Read dynamic simulator element = xml0.getChildElement(rootElement, 'simulator') reactionModel.absoluteTolerance = float(xml0.getAttribute(element, 'atol')) reactionModel.relativeTolerance = float(xml0.getAttribute(element, 'rtol')) logging.info('Read dynamic simulator') logging.debug('Simulator:') logging.debug('\tAbsolute tolerance set to %s' % (reactionModel.absoluteTolerance)) logging.debug('\tRelative tolerance set to %s' % (reactionModel.relativeTolerance)) logging.debug('') # Read termination targets termination = xml0.getChildElement(rootElement, 'termination') targetElements = xml0.getChildElements(termination, 'target') for element in targetElements: targetType = xml0.getAttribute(element, 'type') if targetType == 'conversion': sid = xml0.getAttribute(element, 'speciesID') spec = speciesDict[sid] conv = float(xml0.getElementText(element)) if conv < 0.0 or conv > 1.0: raise InvalidInputFileException('Invalid value for termination fractional conversion.') reactionModel.termination.append(model.TerminationConversion(spec, conv)) elif targetType == 'time': units = str(xml0.getAttribute(element, 'units')) time = float(xml0.getElementText(element)) time = pq.Quantity(time, units); time = float(time.simplified) if time < 0.0: raise InvalidInputFileException('Invalid value for termination time.') reactionModel.termination.append(model.TerminationTime(time)) else: raise InvalidInputFileException('Invalid termination target type "'+targetType+'".') if len(reactionModel.termination) == 0: raise InvalidInputFileException('No termination targets specified.') # Output info about termination targets if len(reactionModel.termination) == 1: logging.info('Found ' + str(len(reactionModel.termination)) + ' termination target') else: logging.info('Found ' + str(len(reactionModel.termination)) + ' termination targets') for index, target in enumerate(reactionModel.termination): string = '\tTermination target #' + str(index+1) + ': ' if target.__class__ == model.TerminationConversion: string += 'conversion ' + str(target.species) + ' ' + str(target.conversion) elif target.__class__ == model.TerminationTime: string += 'time ' + str(target.time) logging.debug(string) logging.debug('') # Process reaction systems reactionSystems = [] systemElements = xml0.getChildElements(rootElement, 'reactionSystem') for element in systemElements: # Create a new reaction system rsType = xml0.getAttribute(element, 'type') if rsType == 'batch': reactionSystem = model.BatchReactor() else: raise InvalidInputFileException('Invalid reaction system type "' + rsType + '".') # Temperature model temperatureModel = xml0.getChildElement(element, 'temperatureModel') tempModelType = xml0.getAttribute(temperatureModel, 'type') if tempModelType == 'isothermal': # Read the (constant) temperature from the file temperature = xml0.getChildElement(temperatureModel, 'temperature') value = float(xml0.getElementText(temperature)) units = str(xml0.getAttribute(temperature, 'units')) T = pq.Quantity(value, units); T = float(T.simplified) # Set the reaction system's temperature model to isothermal reactionSystem.temperatureModel = model.TemperatureModel() reactionSystem.temperatureModel.setIsothermal(T) else: raise InvalidInputFileException('Invalid temperature model type "' + tempModelType + '".') # Pressure model pressureModel = xml0.getChildElement(element, 'pressureModel') pressModelType = xml0.getAttribute(pressureModel, 'type') if pressModelType == 'isobaric': # Read the (constant) pressure from the file pressure = xml0.getChildElement(pressureModel, 'pressure') value = float(xml0.getElementText(pressure)) units = str(xml0.getAttribute(pressure, 'units')) P = pq.Quantity(value, units); P = float(P.simplified) # Set the reaction system's pressure model to isobaric reactionSystem.pressureModel = model.PressureModel() reactionSystem.pressureModel.setIsobaric(P) else: raise InvalidInputFileException('Invalid pressure model type "' + pressModelType + '".') # Physical property model propModel = xml0.getChildElement(element, 'physicalPropertyModel') propModelType = xml0.getAttribute(propModel, 'type') if propModelType.lower() == 'idealgas': # Set the reaction system's pressure model to isobaric reactionSystem.equationOfState = model.IdealGas() elif propModelType.lower() == 'incompressibleliquid': molarVolume = xml0.getFirstChildElement(element, 'molarVolume') value = float(xml0.getElementText(molarVolume)) units = str(xml0.getAttribute(molarVolume, 'units')) Vmol = float(pq.Quantity(value, units).simplified); reactionSystem.equationOfState = model.IncompressibleLiquid( P = reactionSystem.pressureModel.getPressure(), T = reactionSystem.temperatureModel.getTemperature(), Vmol = Vmol ) else: raise InvalidInputFileException('Invalid physical property model type "' + propModelType + '".') # Get total concentration T = reactionSystem.temperatureModel.getTemperature(0) P = reactionSystem.pressureModel.getPressure(0) totalConc = 1.0 / reactionSystem.equationOfState.getVolume(T, P, [1.0]) # Initialize all initial concentrations to zero for spec in coreSpecies: reactionSystem.initialConcentration[spec] = 0.0 # List of initial concentrations moleFractions = xml0.getChildElements(element, 'moleFraction') for moleFraction in moleFractions: # Read the concentration from the file value = float(xml0.getElementText(moleFraction)) sid = xml0.getAttribute(moleFraction, 'speciesID') reactionSystem.initialConcentration[speciesDict[sid]] = value * totalConc # Append to list of reaction systems reactionSystems.append(reactionSystem) # Output info about reaction system if len(reactionSystems) == 1: logging.info('Found ' + str(len(reactionSystems)) + ' reaction system') else: logging.info('Found ' + str(len(reactionSystems)) + ' reaction systems') for index, reactionSystem in enumerate(reactionSystems): logging.debug('Reaction system #' + str(index+1) + ':') logging.debug('\t' + str(reactionSystem.temperatureModel)) logging.debug('\t' + str(reactionSystem.pressureModel)) for spec, conc in reactionSystem.initialConcentration.iteritems(): if spec.reactive: logging.debug('\tInitial concentration of ' + str(spec) + ': ' + str(conc)) else: logging.debug('\tConstant concentration of ' + str(spec) + ': ' + str(conc)) logging.debug('') # Cleanup the DOM tree when finished xml0.cleanup() except InvalidInputFileException, e: logging.exception(str(e)) raise e