0

我正在使用 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)

结果是一个以 ids 为键、模型为值的字典:{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',)'

但我无法想象没有办法并行初始化模型。也欢迎使用除线程/多处理之外的其他框架/库。

我看到了这个答案,但似乎它侧重于初始化后的模拟。

4

1 回答 1

1

您所指的答案下方的答案似乎可以解释多处理和 FMU 实例化的问题。

我尝试了这个答案中建议的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 模型中,并围绕它们构建一个ifcase子句(伪代码):

if (id_building == 1) {
    [model the building one]
elseif (if_building == 2) {
    [model the building two]
[...]

将“天气”或您需要的任何内容定义为 FMU 的输入变量,并将id_building也定义为参数。将总热通量定义为输出变量。

这将允许您在开始模拟之前选择建筑物。

两个要求是:

  1. EnergyPlus 语法允许ifcase结构。
  2. 您的所有模型都使用相同的界面(在我们的示例中,我们将天气作为输入变量,将通量作为输出变量)

第二个要求有一个肮脏的解决方法:只需定义所有模型所需的所有变量,并仅在相应的 if 块中使用您需要的变量。

于 2020-02-03T14:52:29.983 回答