【问题标题】:reproduce Dymola info layer from python script从 python 脚本重现 Dymola 信息层
【发布时间】:2019-10-30 14:13:53
【问题描述】:

我想编写一个 Python 脚本来提取有关 Modelica 函数的输入和输出的相同信息,如 Dymola 信息层所示,例如对于正弦函数:

我想展示一个最小的例子,但我什至不知道从哪里开始。

【问题讨论】:

  • Python 中的某些函数具有用于生成文档的 cmets。 IE。 import mathprint(math.sin.__doc__)help(math.sin)。但是,如果您的函数不是 Python 中的,或者它们没有特殊的 cmets,那么您必须手动编写所有信息。
  • 函数是用Modelica编写的,Dymola是编辑器/IDE。 Dymola 有一个 Python 接口,所以理论上 Dymola GUI 中的所有可能都应该可以从 Python 脚本中实现。
  • 我不知道 Modelica,但在许多程序中,文档是手动创建的(或从源代码生成并手动更正)并保存在 HTML 文件中。后来IDE显示这些HTML文件,当你选择函数时它不会动态生成。所以我宁愿寻找带有文档的文件

标签: python modelica dymola


【解决方案1】:

Dymola 为模型文档动态生成此信息,但我不知道如何检索它。

ModelManagement 库(随 Dymola 提供并包含在标准许可中)允许从加载的类中提取此类信息。 但是,使用起来有点痛苦。问题是这个库中的大多数函数只分析类的确切代码 - 不考虑扩展类。因此,您必须自己循环扩展类。

下面是一个尝试获取类的所有组件定义的示例,包括从扩展类继承的组件定义。对于每个组件,都会返回一个具有多个属性的 dict,它对应于 Dymola 中的记录 ModelManagement.Structure.AST.ComponentAttributes。 它包含组件名称、描述、可变性、前缀 inputoutput 等信息。

因此,对于您的示例类 Modelica.Math.sin,可以使用字典键 isOutputisInput 轻松识别输入和输出。

但请注意,这不适用于像 Modelica.Blocks.Interfaces.RealInput 这样的模块的输入和输出连接器 - 以及像电针这样的非因果连接器。你必须自己实现一些东西来识别它们。

下面的代码只是使用固定的类路径来列出Modelica.Blocks.Continuous.Integrator 的所有输入和输出连接器。此外,它还输出其所有参数。

import pprint
from dymola.dymola_interface import DymolaInterface


def get_extends(dym, c):
    """ return a list with all extended classes (including inherited extends) """

    extends = dym.ExecuteCommand(f'ModelManagement.Structure.AST.ExtendsInClassAttributes("{c}")')

    for e in extends.copy():

        sub_extends = get_extends(dym, e['fullTypeName'])

        # only add sub-extends if they are not already in the list
        for s in sub_extends:
            if not any(s['fullTypeName'] == tmp_e['fullTypeName'] for tmp_e in extends):
                extends.append(s)

    return extends


def get_components(dym, c):
    """ return a list with all components in a class (including inherited ones )"""

    # get components defined in the class itself
    comp = dym.ExecuteCommand(f'ModelManagement.Structure.AST.ComponentsInClassAttributes("{c}")')

    # get components defined in extended classes itself
    for e in get_extends(dym, c):
        comp.extend(dym.ExecuteCommand(
            f'ModelManagement.Structure.AST.ComponentsInClassAttributes("{e["fullTypeName"]}")'))

    return comp


if __name__ == '__main__':

    modelica_class = 'Modelica.Blocks.Continuous.Integrator'

    # get all components in the model
    dymola = DymolaInterface(showwindow=False)
    components = get_components(dymola, modelica_class)
    dymola.close()

    # extract inputs and parameters
    inputs = ['Modelica.Blocks.Interfaces.RealInput', 'Modelica.Blocks.Interfaces.BooleanInput',
              'Modelica.Blocks.Interfaces.BooleanInput']

    inputs = [c for c in components if c['fullTypeName'] in inputs]
    parameters = [c for c in components if c['variability'] == 'parameter']

    print('-------- inputs ------------')
    pprint.pprint(inputs)
    print('\n\n-------- parameters ------------')
    pprint.pprint(parameters)

【讨论】:

  • 感谢您提供如此全面的答案!很有帮助,现在我只关注函数。是否有增强/扩展 ModelManagement 的计划?
  • 我猜不是。根据发行说明,该库的最后一次显着变化发生在 2011 年,使用 Dymola 7.4 FD01。要确定一个类是否是一个函数,您可以使用ModelManagement.Structure.AST.GetClassAttributes 并检查返回的dict 的键restricted
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 2017-03-26
  • 2015-08-18
  • 2017-11-05
相关资源
最近更新 更多