首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何并行初始化PYFMI模型?

如何并行初始化PYFMI模型?
EN

Stack Overflow用户
提问于 2020-02-03 16:08:02
回答 1查看 227关注 0票数 0

我正在使用pyfmi与EnergyPlus进行模拟。我认识到初始化单个EnergyPlus模型需要相当长的时间。因此,我希望找到一种并行初始化模型的方法。我尝试了python库的多进程,但没有成功。如果重要的话,我在Ubuntu 16.10上使用Python 3.6。以下是我想要在序列中完成的工作:

代码语言:javascript
复制
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}

其目的是稍后根据模型的键调用模型并进行模拟。

下面是我对多进程的尝试:

代码语言:javascript
复制
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() 

我可以在我的系统监视器中看到模型的进程,但是脚本引发了一个错误,因为模型是不可拾取的:

代码语言:javascript
复制
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,但它似乎侧重于初始化后的模拟。

EN

回答 1

Stack Overflow用户

发布于 2020-02-03 22:52:30

answer below the one you refer to似乎解释了多处理和FMU实例化的问题所在。

我尝试了this answer中建议的pathos,但遇到了同样的问题:

代码语言:javascript
复制
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)

这提供了:

代码语言:javascript
复制
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子句(伪代码):

代码语言:javascript
复制
if (id_building == 1) {
    [model the building one]
elseif (if_building == 2) {
    [model the building two]
[...]

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

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

这两个要求是:

  1. EnergyPlus语法允许if或case structures.
  2. All您的模型使用相同的接口(在我们的示例中,天气作为输入变量,通量作为输出变量)

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60035287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档