如何在其他函数内调用中函数?

时间:2018-07-09 13:55:32

标签: function modelica

请考虑以下MWE,其中模型具有可调节的功能,可以从许多选项中选择如何计算中等比热容,有些则使用中等模型中的函数,有些则没有。因此,使用包装来收集所有特定的热容量功能。

package Library
      model Model
        replaceable package Medium =
            Modelica.Media.Interfaces.PartialSimpleIdealGasMedium annotation(choicesAllMatching=true);
        replaceable function cp = FunctionPackage.baseCp annotation(choicesAllMatching=true);
        parameter Real M;
        parameter Real V;
        parameter Real Qflow;
        Real T;
        Real p;
      equation 
        M*cp(p,T)*der(T) = Qflow;
        p*V = M*Medium.R_gas*T;
      end Model;

    package FunctionPackage
        partial function baseCp
            input Real p;
            input Real T;
            output Real cp;
        end baseCp;

        function realCp
            extends baseCp;
        algorithm 
            cp := Medium.specificHeatCapacity(p, T);
        end realCp;

        function linearCp
            extends baseCp;
        algorithm 
            cp :=0.1*T + 1000;
        end linearCp;
    end FunctionPackage;
end Library;

如果要在另一个模型中模拟Model,则必须选择要计算cp的函数:

model Simulation
  Library.Model Model(
    redeclare package Medium = Modelica.Media.Air.SimpleAir,
    M=1,
    Qflow=1,
    V=0.1,
    redeclare function cp = Library.FunctionPackage.linearCp);
end Simulation;

模拟效果很好,但是,如果我选择realCp函数,则错误会上升:

Function Medium.specificHeatCapacity is not known in (function Library.FunctionPackage.realCp)

这对我来说真的不足为奇,我知道FunctionPackage中声明的函数“不知道” Model模型中声明的Medium包。因此,我的问题是:如何使他们知道?是否可以将Medium作为输入传递给函数?

我知道在FunctionPackage内从Model声明函数将把它们放在与Medium相同的范围内,使我能够在函数内调用它而没有任何问题。尽管这样做会使我失去replaceable function的下拉功能,但我确实需要在这里具有这些功能,因此丢失它不是一种选择。

顺便说一句,不知道这对这个问题有什么用,但是我在Windows 10 64位下使用Dymola 2017(32位)。

2 个答案:

答案 0 :(得分:2)

您不能直接将Medium-package作为常规函数输入传递。

一种解决方案如下:

将Medium添加为可替换的LibraryFunction程序包

package FunctionPackage
  replaceable package Medium =
      Modelica.Media.Interfaces.PartialSimpleIdealGasMedium annotation (
      choicesAllMatching=true);
  ...

并在需要的地方创建一个新的FunctionPackage:

model Model
  replaceable package Medium =
      Modelica.Media.Interfaces.PartialSimpleIdealGasMedium annotation (
      choicesAllMatching=true);
  replaceable function cp = MyFunctionPackage.baseCp annotation (
      choicesAllMatching=true);
  package MyFunctionPackage = FunctionPackage (redeclare package Medium =
          Medium);
  ...

model Simulation
  package MyFunctionPackage = Library.FunctionPackage(redeclare package Medium=
          Modelica.Media.Air.SimpleAir);
Library.Model Model(
  redeclare package Medium = Modelica.Media.Air.SimpleAir,
  ...
  redeclare function cp = MyFunctionPackage.linearCp);
end Simulation;

另一个变体是将其作为可替换的程序包包含在函数中,如下所示(较短,但我发现它更令人困惑):

  function realCp
    extends baseCp;
    replaceable package Medium =
      Modelica.Media.Interfaces.PartialSimpleIdealGasMedium annotation (
      choicesAllMatching=true);
  algorithm 
    cp := Medium.specificHeatCapacityCp(p, T);
  end realCp;

并用作:

function cp = FunctionPackage.realCp(redeclare package Medium=Medium);

答案 1 :(得分:1)

不是一个完整的答案,但这是一个基于原始问题和汉斯的答案(使用变体2)的可模拟模型(在Dymola 2019中进行了测试):

package Library
  model Model
    replaceable package myMedium = Modelica.Media.Air.SimpleAir constrainedby 
      Modelica.Media.Interfaces.PartialSimpleIdealGasMedium annotation (
      choicesAllMatching=true);

    function funMach = FunctionPackage.Mach(redeclare package funMedium=myMedium);

    Real Mach;
    parameter Modelica.SIunits.Temperature T=293.15;
    parameter Modelica.SIunits.Pressure p=101325;
  protected 
    Real TempTime = T + time;
  equation 
    Mach = funMach(state=myMedium.setState_pT(p,TempTime), velo=300);
  end Model;

  package FunctionPackage
    function Mach
      replaceable package funMedium = Modelica.Media.Interfaces.PartialSimpleIdealGasMedium annotation (
      choicesAllMatching=true);
      input funMedium.ThermodynamicState state;
      input Modelica.SIunits.Velocity velo;
      output Real Mach;
    protected 
      Modelica.SIunits.Velocity souvel;
    algorithm 
      souvel := funMedium.velocityOfSound(state);
      Mach := velo/souvel;
    end Mach;
  end FunctionPackage;
end Library;