我目前正在做一个研究混合气体性质的项目。通过不同的输入测试我的代码,我遇到了一个bug(?)我无法解释。基本上,它是关于for循环中的numpy数组的计算。当它计算for-循环时,它会产生不同的(错误的)结果,而不是手动构造结果,使用与for-循环相同的代码片段,但是手动索引。我不知道为什么会发生这种事,也不知道是我自己的错误,还是我自己的错误。
非常奇怪的是,所需输入对象的某些实例在整个for循环中运行而没有任何问题,而其他实例则完全运行到某个索引,而其他实例甚至无法计算第一个循环。
例如,一个输入总是在索引16处停止,抛出一个:
ValueError: could not broadcast input array from shape (25,) into shape (32,)经过进一步的研究,我可以证实,前15个循环抛出了正确的结果,指数16的循环中的结果是错误的,甚至没有正确的大小。当通过控制台手动运行循环16时,没有发生错误.
下面的数组在循环中运行时显示索引16的结果。 这是在控制台的for循环中手动运行代码时索引16的结果。这些都是人们所期望得到的。
代码的重要部分实际上只是for循环中的np.multiply() --我将其馀部分放在上下文中,但我确信它不应该干扰我的意图。
def thermic_dissociation(input_gas, pressure):
# Copy of the input_gas object, which may not be altered out of scope
gas = copy.copy(input_gas)
# Temperature range
T = np.logspace(2.473, 4.4, 1000)
# Matrix containing the data over the whole range of interest
moles = np.zeros((gas.gas_cantera.n_species, len(T)))
# Array containing other property of interest
sum_particles = np.zeros(len(T))
# The troublesome for-loop:
for index in range(len(T)):
print(str(index) + ' start')
# Set temperature and pressure of the gas
gas.gas_cantera.TP = T[index], pressure
# Set gas mixture to a state of chemical equilibrium
gas.gas_cantera.equilibrate('TP')
# Sum of particles = Molar Density * Avogadro constant for every temperature
sum_particles[index] = gas.gas_cantera.density_mole * ct.avogadro
#This multiplication is doing the weird stuff, printed it to see what's computed before it puts it into the result matrix and throwing the error
print(np.multiply(list(gas.gas_cantera.mole_fraction_dict().values()), sum_particles[index]))
# This is where the error is thrown, as the resulting array is of smaller size, than it should be and thus resulting in the error
moles[:, index] = np.multiply(list(gas.gas_cantera.mole_fraction_dict().values()), sum_particles[index])
print(str(index) + ' end')
# An array helping to handle the results
molecule_order = list(gas.gas_cantera.mole_fraction_dict().keys())
return [moles, sum_particles, T, molecule_order]我们将非常感谢您的帮助!
发布于 2022-04-21 10:27:42
这个特别的问题与numpy无关。对mole_fraction_dict的调用返回一个标准的python字典。字典中的元素数取决于可选的threshold参数,该参数的默认值为0.0。
可以检查Cantera的源代码,看看到底发生了什么。
换句话说,如果是x > threshold,一个值将在字典中结束。如果在这里使用>=而不是>,也许会更有意义。也许这会阻止你的意外结果。
正如注释中所确认的那样,您可以使用mole_fraction_dict(threshold=-np.inf)在字典中获取所有想要的值。也可以使用-float('inf')。
在您的代码中,您将继续调用字典中的.values(),但是如果不能保证值的顺序,这将是一个问题。我不确定是不是这样。最好是通过使用dict键从dict中检索值,从而使顺序显式化。
发布于 2022-04-21 14:25:49
如果需要所有物种摩尔分数的数组,则应使用cantera.Solution对象的cantera.Solution属性,该属性始终直接返回该完整数组。您可以看到该方法的文档:cantera.Solution.X`。
mole_fraction_dict方法专门用于您希望按名称引用物种的情况,而不是它们在Solution对象中的顺序,例如在关联定义不同物种集的两个不同的Solution对象时。
https://stackoverflow.com/questions/71945082
复制相似问题