Exemple #1
0
	def removeSpeciesFromEdge(self, spec):
		"""
		Remove species `spec` from the reaction model edge.
		"""
		# remove the species
		self.edge.species.remove(spec)
		# identify any reactions it's involved in
		rxnList = []
		for rxn in self.edge.reactions:
			if spec in rxn.reactants or spec in rxn.products:
				rxnList.append(rxn)
		# remove those reactions
		for rxn in rxnList:
			self.edge.reactions.remove(rxn)

		# Remove the species from any unirxn networks it is in
		if settings.unimolecularReactionNetworks:
			networksToDelete = []
			for network in self.unirxnNetworks:
				if spec in network.getSpeciesList():
					# Delete all path reactions involving the species
					rxnList = []
					for rxn in network.pathReactions:
						if spec in rxn.reactants or spec in rxn.products:
							rxnList.append(rxn)
					for rxn in rxnList:
						network.pathReactions.remove(rxn)
					# Delete all net reactions involving the species
					rxnList = []
					for rxn in network.netReactions:
						if spec in rxn.reactants or spec in rxn.products:
							rxnList.append(rxn)
					for rxn in rxnList:
						network.netReactions.remove(rxn)
					# Delete all isomers involving the species
					isomerList = []
					for isomer in network.isomers:
						if spec in isomer.species:
							isomerList.append(isomer)
					for isomer in isomerList:
						network.isomers.remove(isomer)
					# If no remaining reactions, delete the network (actually
					# add to list of networks to be deleted in a subsequent
					# step)
					if len(network.pathReactions) == 0 and len(network.netReactions) == 0:
						networksToDelete.append(network)

			# Complete deletion of empty networks
			for network in networksToDelete:
				logging.debug('Deleting empty unirxn network %s' % network.id)
				self.unirxnNetworks.remove(network)



		# remove from the global list of species, to free memory
		species.speciesList.remove(spec)
Exemple #2
0
	def updateUnimolecularReactionNetworks(self):
		"""
		Iterate through all of the currently-existing unimolecular reaction
		networks, updating those that have been marked as invalid. In each update,
		the phenomonological rate coefficients :math:`k(T,P)` are computed for
		each net reaction in the network, and the resulting reactions added or
		updated.
		"""

		from unirxn.network import Isomer, UnirxnNetworkException
		from reaction import PDepReaction
		from kinetics import ChebyshevKinetics, PDepArrheniusKinetics

		count = sum([1 for network in self.unirxnNetworks if not network.valid])
		logging.info('Updating %i modified unimolecular reaction networks...' % count)

		for network in self.unirxnNetworks:
			if not network.valid:

				logging.verbose('Updating unimolecular reaction network %s' % network.id)

				# Other inputs
				method, Tlist, Plist, grainSize, numGrains, model = settings.unimolecularReactionNetworks

				network.bathGas = [spec for spec in self.core.species if not spec.reactive][0]
				network.bathGas.expDownParam = 4.86 * 4184

				# Generate isomers
				for reaction in network.pathReactions:

					# Create isomer for the reactant
					isomer = None
					for isom in network.isomers:
						if all([spec in isom.species for spec in reaction.reactants]):
							isomer = isom
					if isomer is None:
						isomer = Isomer(reaction.reactants)
						network.isomers.append(isomer)
					reaction.reactant = isomer

					# Create isomer for the product
					isomer = None
					for isom in network.isomers:
						if all([spec in isom.species for spec in reaction.products]):
							isomer = isom
					if isomer is None:
						isomer = Isomer(reaction.products)
						network.isomers.append(isomer)
					reaction.product = isomer

				# Update list of explored isomers to include all species in core
				for isom in network.isomers:
					if isom.isUnimolecular():
						spec = isom.species[0]
						if spec not in network.explored:
							if spec in self.core.species:
								network.explored.append(spec)

				# Remove any isomers that aren't found in any path reactions
				# Ideally this block of code wouldn't be needed, but it's here
				# just in case
				isomerList = []
				for isomer in network.isomers:
					found = False
					for reaction in network.pathReactions:
						if reaction.reactant is isomer or reaction.product is isomer:
							found = True
							break
					if not found:
						isomerList.append(isomer)
				if len(isomerList) > 0:
					logging.debug('Removed %i isomer(s) from network %i.' % (len(isomerList), network.id))
					for isomer in isomerList: network.isomers.remove(isomer)

				# Sort isomers so that all unimolecular isomers come first
				isomers = [isom for isom in network.isomers if isom.isUnimolecular()]
				isomers.extend([isom for isom in network.isomers if isom.isMultimolecular()])
				network.isomers = isomers

				# Get list of species in network
				speciesList = network.getSpeciesList()

				# Calculate ground-state energy of all species in network
				# For now we assume that this is equal to the enthalpy of formation
				# of the species
				for spec in speciesList:
					spec.E0 = spec.getEnthalpy(T=298)

				# Determine isomer ground-state energies
				for isomer in network.isomers:
					isomer.E0 = sum([spec.E0 for spec in isomer.species])
				# Determine transition state ground-state energies of the reactions
				for reaction in network.pathReactions:
					E0 = sum([spec.E0 for spec in reaction.reactants])
					reaction.E0 = E0 + reaction.kinetics[0].getActivationEnergy(reaction.getEnthalpyOfReaction(T=298))

				# Shift network such that lowest-energy isomer has a ground state of 0.0
				network.shiftToZeroEnergy()

				# Determine energy grains
				Elist = network.determineEnergyGrains(grainSize, numGrains, max(Tlist))

				# Calculate density of states for all isomers in network
				network.calculateDensitiesOfStates(Elist)

				# Determine phenomenological rate coefficients
				K = network.calculateRateCoefficients(Tlist, Plist, Elist, method)

				# Generate PDepReaction objects
				for i, product in enumerate(network.isomers):
					for j, reactant in enumerate(network.isomers[0:i]):
						if numpy.any(K[:,:,i,j]):
							if not numpy.all(K[:,:,i,j]):
								raise UnirxnNetworkException('Zero rate coefficient encountered while updating network %s.' % network)
							# Find the path reaction
							netReaction = None
							for r in network.netReactions:
								if r.hasTemplate(reactant.species, product.species):
									netReaction = r
							# If path reaction does not already exist, make a new one
							if netReaction is None:
								netReaction = PDepReaction(reactant.species, product.species, network, None)
								network.netReactions.append(netReaction)
								self.addReactionToEdge(netReaction)
							# Set its kinetics using interpolation model
							if model[0].lower() == 'chebyshev':
								modelType, degreeT, degreeP = model
								chebyshev = ChebyshevKinetics()
								chebyshev.fitToData(Tlist, Plist, K[:,:,i,j], degreeT, degreeP)
								netReaction.kinetics = chebyshev
							elif model.lower() == 'pdeparrhenius':
								pDepArrhenius = PDepArrheniusKinetics()
								pDepArrhenius.fitToData(Tlist, Plist, K[:,:,i,j])
								netReaction.kinetics = pDepArrhenius
							else:
								pass

							# Update cantera if this is a core reaction
							if netReaction in self.core.reactions:
								netReaction.toCantera()

				for spec in speciesList:
					del spec.E0
				for reaction in network.pathReactions:
					del reaction.reactant
					del reaction.product
					del reaction.E0

				network.valid = True