首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Modelica:如何使用可替换的组件?

Modelica:如何使用可替换的组件?
EN

Stack Overflow用户
提问于 2019-01-21 22:33:11
回答 1查看 832关注 0票数 1

我正在试图建立一个模型,可以在同一范围内使用两个不同的组件(取自现有的库):特别是一个带有换热器的系统;这种换热器可以基于不同的技术,例如管道或板。

然后,我想定义一个带有默认可替换交换机的模型,并说明可以使用哪些其他技术。

这是我尝试过的一个简单的例子:

代码语言:javascript
运行
复制
package Test

  // Component 1 original definition in the library
  model COMP1
    parameter Real p1=1 "";
    Real v "";
  equation 
    v=p1*time;
  end COMP1;

  // Component 2 original definition in the library
  model COMP2
    parameter Real p2=1 "";
    Real v "";
  equation 
    v=p2*time;
  end COMP2;

  // Main module (system)
  model MAIN
    parameter Real pm=100 "";
    Real vm "";

    // Redefinition of the component modifing the default values
    model call1 = COMP1(p1=10);
    model call2 = COMP2(p2=20);

    replaceable call1 OBJ
    annotation(choices(
            choice(redeclare call1 OBJ "Default"),
            choice(redeclare call2 OBJ "Variant")));

  equation 
    vm = OBJ.v+pm;
  end MAIN;

  // Application model, using the main model
  model APP
    MAIN mAIN;
  end APP;

end Test;

模型应用程序成功运行。但是,如果打开APP.mAIN的参数并更改OBJ (选择“默认”或“变体”),将导致修改APP模型如下:

代码语言:javascript
运行
复制
  model APP
    MAIN mAIN(redeclare call1 OBJ "Default");
  end APP;

我得到以下错误:

代码语言:javascript
运行
复制
Component type specifier call1 not found

我不明白我做错了什么,请帮帮忙。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-22 08:29:00

出现与错误相关的问题,因为您没有在选项注释中使用正确的类路径。

如果在APP中选择“默认”,将得到以下代码:

代码语言:javascript
运行
复制
model APP
  MAIN mAIN(redeclare call1 OBJ "Default");
end APP;

这里我们看到类路径call1是无效的。APP只能通过使用相对类路径MAIN.call1或绝对类路径Test.MAIN.call1来访问Test.MAIN.call1。因此,您可以使用以下注释解决此问题:

代码语言:javascript
运行
复制
  replaceable call1 OBJ
  annotation(choices(
          choice(redeclare MAIN.call1 OBJ "Default"),
          choice(redeclare MAIN.call2 OBJ "Variant")));

但是,在Dymola中,由于MAIN中的局部类定义,在修改默认值的组件的重新定义下,模型仍然不检查。在这里,您创建了新的类call1call2。这可能是一个Dymola错误,因为它在OpenModelica中工作-但新的类是不必要的。相反,您可以使用原始类并在redeclare语句中使用修饰符方程设置参数,如下所示:

代码语言:javascript
运行
复制
model MAIN
  parameter Real pm=100 "";
  Real vm "";

  replaceable COMP1 OBJ
  annotation(choices(
          choice(redeclare Test.COMP1 OBJ(p1=10) "Default"),
          choice(redeclare Test.COMP2 OBJ(p2=10) "Variant")));
equation 
  vm = OBJ.v+pm;
end MAIN;

现在,该模型不适用于任何选择和“默认”,但当选择“variables”时,Dymola抱怨重新声明的类不包含与原始类相同的变量。这是使用可替换类时的限制之一(同样,OpenModelica对它没有问题,但Dymola警告您,这不符合Modelica语言规范)

替代方法:带有接口的MSL样式

我建议像Modelica库通常所做的那样创建一个接口模型(例如使用Modelica.Electrical.Analog.Interfaces.OnePort):

  • 您可以创建一个partial基模型,它包含所有变体所共有的所有内容,称为接口
  • 变体扩展了现有库的接口和模型之一。
  • 使用变体的类实例化其中一个变体并使用约束将重声明约束到接口。
  • 现在,您可以使用注释choicesAllMatching自动创建它,而不是手动创建选择注释。

这就是你的例子的样子。第三方组件COMP1COMP2被移动到包ReadOnlyLibrary中。

代码语言:javascript
运行
复制
package Test
  // Original definition of Component 1 and 2 in the external library
  package ReadOnlyLibrary
    model COMP1
      parameter Real p1=1 "";
      Real v "";
    equation 
      v=p1*time;
    end COMP1;

    model COMP2
      parameter Real p2=1 "";
      Real v "";
    equation 
      v=p2*time;
    end COMP2;
  end ReadOnlyLibrary;

  // Interface and variants with modified default values
  partial model Call_Interface
    Real v "";
  end Call_Interface;

  model Call1 "Default"
    extends Call_Interface;
    extends ReadOnlyLibrary.COMP1(p1=10);
  end Call1;

  model Call2 "Variant"
    extends Call_Interface;
    extends ReadOnlyLibrary.COMP2(p2=20);
  end Call2;

  // Main module (system)
  model Main
    parameter Real pm=100 "";
    Real vm "";

    replaceable Test.Call1 OBJ constrainedby Test.Call_Interface annotation (choicesAllMatching);

  equation 
    vm = OBJ.v+pm;
  end Main;

  // Application model, using the main model
  model App
    Main main annotation (Placement(transformation(extent={{-12,10},{8,30}})));
  end App;
end Test;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54298679

复制
相关文章

相似问题

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