我正在使用pyfmi与EnergyPlus进行模拟。我认识到初始化单个EnergyPlus模型需要相当长的时间。因此,我希望找到一种并行初始化模型的方法。我尝试了python库的多进程,但没有成功。如果重要的话,我在Ubuntu 16.10上使用Python 3.6。以下是我想要在序列中完成的工作:
fmus = {}
for id in id_list:
chdir(fmu_path+str(id))
fmus[id] = load_fmu('f_' + str(id)+'.fmu',fmu_path+str(id))
fmus[id].initialize(start_time,final_time)结果是一个以is为键、以模型为值的字典:{id1:FMUModelCS1,id2:FMUModelCS1}
其目的是稍后根据模型的键调用模型并进行模拟。
下面是我对多进程的尝试:
def ep_intialization(id,start_time,final_time):
chdir(fmu_path+str(id))
model = load_fmu('f_' + str(id)+'.fmu',fmu_path+str(id))
model.initialize(start_time,final_time)
return {id:model}
data = ((id,start_time,final_time) for id in id_list)
if __name__ == '__main__':
pool = Pool(processes=cpus)
pool.starmap(ep_intialization, data)
pool.close()
pool.join() 我可以在我的系统监视器中看到模型的进程,但是脚本引发了一个错误,因为模型是不可拾取的:
MaybeEncodingError: Error sending result: '[{id2: <pyfmi.fmi.FMUModelCS1 object at 0x561eaf851188>}]'. Reason: 'TypeError('self._fmu,self.callBackFunctions,self.callbacks,self.context,self.variable_list cannot be converted to a Python object for pickling',)'但我无法想象没有办法并行初始化这些模型。除了线程/多处理之外的其他框架/库也是受欢迎的。
我看过这个answer,但它似乎侧重于初始化后的模拟。
发布于 2020-02-03 22:52:30
answer below the one you refer to似乎解释了多处理和FMU实例化的问题所在。
我尝试了this answer中建议的pathos,但遇到了同样的问题:
from pyfmi import load_fmu
from multiprocessing import Pool
from os import chdir
from pathos.multiprocessing import Pool
def ep_intialization(id):
chdir('folder' + str(id))
model = load_fmu('BouncingBall.fmu')
model.initialize(0,10)
return {id:model}
id_list = [1,2]
cpus = 2
data = ((id) for id in id_list)
pool = Pool(cpus)
out = pool.map(ep_intialization, data)这提供了:
MaybeEncodingError: Error sending result: '[{1: <pyfmi.fmi.FMUModelME2 object at 0x564e0c529290>}]'. Reason: 'TypeError('self._context,self._fmu,self.callBackFunctions,self.callbacks cannot be converted to a Python object for pickling',)'这是另一个想法:
我认为实例化很慢,因为EnergyPlus将大量的库链接到FMU中。如果您正在建模的所有组件都具有相同的接口(输入、输出、参数),则您可能可以使用带有在模型之间切换的附加参数的单个FMU。
这样效率会高得多:您只需实例化一个FMU,并且可以使用不同的参数和输入并行调用它。
示例:
我从未使用过EnergyPlus,但也许下面的示例可以说明这种方法:
你有三种不同的建筑物,你只对建筑物整个表面积上的总热流感兴趣,因为它是“天气”的函数(无论这是什么意思-可能有很多变量)。
将所有三个建筑放入单个EnergyPlus模型中,并围绕它们构建一个if或case子句(伪代码):
if (id_building == 1) {
[model the building one]
elseif (if_building == 2) {
[model the building two]
[...]将“天气”或您需要的任何东西定义为FMU 的输入变量,并将 id_building 也定义为参数。将总热流定义为输出变量。
这将允许您在开始模拟之前选择建筑物。
这两个要求是:
第二个需求有一个肮脏的变通方法:只需定义所有模型所需的所有变量,并仅在相应的if块中使用所需的变量。
https://stackoverflow.com/questions/60035287
复制相似问题