Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@UedaShigenori

Modelicaチートシート

自分がよく使用するものを重点的にメモとして記述します。
クラス、インスタンスや非因果とは何かなどの説明は文章が長くなるため記述していません。
それらの意味が分かっている人があんちょこ的に使用することを想定しています。

クラス

クラス 内容 メモ
class 一番汎用的になんにでもなるクラス 使用したことはないしチュートリアルでしか見かけたことも無い
model 非因果モデルとして使用。方程式はequationセクションに記述 一番よく使用する
connector modelやblock間で接続する変数を定義 ツールによってはflow変数とAcross変数がセットで揃っていないとワーニングが出る
block 因果モデルとして使用。方程式はalgorithmセクションに記述 よく使用する
record 変数を纏めて格納。方程式は記述できない 材料物性(一定値)を格納する場合などに使用する。これとinner, outerを用いれば材料物性の差し替えが簡単。いわゆるC言語の構造体
type 変数の型、配列などを定義 単位などを変数に付与するときに使用する。
function 複数入力、複数出力の関数。内部はalgorithmセクションで記述。 数式はalgorithmで記述されている.実はalgorithmセクションを非因果にしたいときに役に立つ。Function内ではいくつかのオペレータ(der, pre etc.)は使用出来ない。
package 複数のクラスを一つのライブラリとして読み込めるようにする パッケージファイルは一つのmoファイルでもいいし、複数のmoファイルに分けることも出来る。複数のmoファイルに分けると一つの巨大なファイルとならないですむが、OpenModelicaでは全てのコードが消えて復元不可能となる現象が頻発したのでトラウマがある
expandable connector modelやblock間で接続する変数をexpandable connector内で宣言された変数の中から選択出来る。 使ったことは無いが自由に接続出来る変数を選択出来るので便利だと思う。コントローラモデルは多くの変数を受け渡すので役立つのでは。
operator オペレータを多重定義する "+"や"-"等の記号に独自の定義を持たせることが出来る。
例. 複素数の計算など
operator record オペレータの定義(調査中)
operator function オペレータの定義(調査中)
ExternalObject ExternalObjectクラスを継承して使用する特殊なクラス。外部の言語で書かれたモデルを呼び出すときコンストラクタとデコンストラクタを定義できる。 https://mbe.modelica.university/behavior/functions/interpolation/

クラス宣言時につける接頭辞

宣言 内容 メモ
partial 継承されることが前提となるクラスに用いられる。このクラス内では方程式数と変数の数が一致しなくてもよい。このクラスを継承した先で方程式数と変数の数が一致すればよい。partialクラスはインスタンス化できない 親クラスであることを明示するときによく使用する
encapsulated いわゆるカプセル化。外部のパッケージを明示しない限り使えない。importなどで明示的に宣言すれば使える あまり使用しない
State (調査中)

演算子

演算子 説明 メモ
+, -, *, / 和、差、積、除算
^ べき乗
== 等しい
<> 等しくない
< 未満
<= 以下
> 超える
>= 以上
and かつ a and b
not ではない not b
or または a or b

セクション

クラスの中は以下の4つのセクションに分けて考えると良いかもしれない

セクションのイメージ : 長いので折り畳んでいます

class hogehoge

/********************************************************
declarationセクション 変数やインスタンスを宣言
/*******************************************************/
  parameter Real hoge1;
  parameter Real hoge2;
  Real hoge3;
  Real hoge4;

/********************************************************
equationセクション 非因果系の方程式
/*******************************************************/
equation
  hoge2=hoge1;

/********************************************************
algorithmセクション 因果系の計算式
/*******************************************************/
algorithm
  hoge2:=hoge4;

/********************************************************
annotationセクション 様々な設定
/*******************************************************/
annotation(
    Icon(graphics = {Rectangle(origin = {0, 0}, extent = {{-100, 100}, {100, -100}}), Text(origin = {0, 23}, extent = {{-66, 41}, {66, -41}}, textString = "ホゲホゲクラスです")}));

end hogehoge;

declarationセクション

変数やインスタンスを宣言するセクション
(公式にこの呼び名がある訳ではない。便宜的に名付けている個人的な呼び名)

Real F;
parameter Real m=1;
parameter Real a=10;

public&protectedサブセクション

publicとprotectedはdeclarationセクション内で宣言されるサブセクション。(個人的な呼び名)
publicは外部から参照できる変数を宣言するサブセクション。何も宣言しないとpublicとなる。
public内で宣言されたパラメータ変数はインスタンス化にした際に変更できる。パラメータでは無い変数はインスタンス化した際に参照できる。
protectedは内部変数を宣言するサブセクション。protected内で宣言された変数は変更、参照できない。

public
  parametere Real a=2;
protected
  parameter Integer n=1;

equationセクション

非因果な方程式を記述するセクション

equation
  F=m*a;
  m=1;
  F=10;

initial equationセクション

非因果な方程式で初期値を計算するセクション

model FirstOrderSteady
  "First order equation with steady state initial condition"
  Real x "State variable";
initial equation
  der(x) = 0 "Initialize the system in steady state";
equation
  der(x) = 1-x "Drives value of x toward 1.0";
end FirstOrderSteady;

algorithmセクション

因果な計算式を記述するセクション

algorithm
  m:=1;
  a:=10;
  F:=m*a;

initial algorithmセクション

因果な計算式を記述するセクション

model FirstOrderSteady
  "First order equation with steady state initial condition"
  Real x "State variable";
initial algorithm
  der(x) := 0 "Initialize the system in steady state";
equation
  der(x) = 1-x "Drives value of x toward 1.0";
end FirstOrderSteady;

annotationセクション

グラフィカルな情報、シミュレーションの条件や使用するライブラリなどの様々な情報を記述するセクション(個人的な呼び名)

書きかけ

宣言 内容                                     コード
dateModified 以下のフォーマットでpackageクラスが変更された日付と時刻を表示する。
YYYY-MM-DD hh: mm:ssZ
defaultComponentName インスタンス生成時のデフォルト名 annotation(defaultComponentName = "name")
defaultComponentPrefixes インスタンス生成時のprefixを定義
使用できるprefix
inner, outer, replaceable, constant, parameter, discrete
annotation(defaultComponentPrefixes = "prefixes")
defaultConnectionStructurallyInconsistent annotation(defaultConnectionStructurallyInconsistent=tru
derivative functionクラスの導関数を別のfunctionクラスに定義する function foo0 annotation(derivative=foo1); end foo0;
function foo1 annotation(derivative(order=2)=foo2); end foo1;
function foo2 end foo2;
Documentation コンポーネントのドキュメント設定
下記で説明
DocumentationClass UsersGuideなどの文書のみのクラスとして宣言する package UsersGuide "User's Guide"
annotation (DocumentationClass=true,
Documentation(info="
hogehoge
"));
end UsersGuide;
DynamicSelect アイコンの表示などをパラメータや条件に応じて変更する タンクのアイコンを水位に応じて変更するアイコン
annotation(
Icon(graphics={Rectangle(
extent=DynamicSelect({{0,0},{20,20}},{{0,0},{20,level}}),
fillColor=DynamicSelect({0,0,255},
if overflow then {255,0,0} else {0,0,255}))}
);
Evaluate
experiment 以下の計算設定をモデルの中に定義する
StartTime
StopTime
Interval
Tolerance
annotation(experiment(StartTime=0, StopTime=5, Tolerance=1e-6))
HideResult コンポーネントの結果を出力しない
Inline (調査中:解説文の「If "Inline = true", the model developer proposes to inline the function.」のinline the functionの意味が分からない)
InlineAfterIndexReduction (調査中)
inverse functionクラスのインプットとアウトプットを入れ替えたときの出力を定義する function h_pTX
input Real p "pressure";
input Real T "temperature";
input Real X[:] "mass fractions";
output Real h "specific enthalpy";
annotation(inverse(T = T_phX(p,h,X)));
algorithm
...
end h_pTX;
LateInline (調査中)
missingInnerMessage innerモデルに対応するouterモデルがない時に、メッセージを出力する annotation(missingInnerMessage = "message")
obsolete このクラスを使用することを全く持って推奨できないときに使う。 annotation(obsolete = "message");
preferredView クラスを開いたときに表示させるビューを定義 annotation"(" preferredView "=" ("info" "diagram" "text") ")"
revisionId バージョン管理のためのID 下記「packageクラスのバージョン情報」参照
smoothOrder 微分可能な回数を定義
functionクラスの中でのみ使用可能
一階微分まで可能
function SpecialPolynomial
input Real u;
output Real y;
algorithm
y = if u > 0 then u^2 else 0;
annotation(smoothOrder = 1);
end SpecialPolynomial;
unassignedMessage 方程式の構造から計算式が解けない場合に表示させるエラーメッセージを定義 下記「packageクラスのバージョン情報」参照
uses 使用するpackageクラスのバージョンを指定する model B
annotation(uses(Modelica(version="2.1 Beta 1")));
...
end B;
version packageクラスのバージョンを定義する 下記「packageクラスのバージョン情報」参照
versionBuild packageクラスのビルドバージョンを定義する 下記「packageクラスのバージョン情報」参照

packageクラスのバージョン情報

annotationセクション内にpackageクラスのバージョン情報を定義する。

長いので折り畳んでいます
package Modelica
  annotation(version      = "3.0.1",
             versionDate  = "2008-04-10",
             versionBuild = 4,
             dateModified = "2009-02-15 16:33:14Z",
             revisionId   = "c04e23a0d 2018-08-01 12:00:00 +0200");
  ...
  end Modelica;

version annotationの例

Main release versions:
""" UNSIGNED_INTEGER { "." UNSIGNED_INTEGER } """
Example: "2.1"

Pre-release versions:
""" UNSIGNED_INTEGER { "." UNSIGNED_INTEGER } " " {S-CHAR} """
Example: "2.1 Beta 1"

Un-ordered versions:
 """ NON-DIGIT {S-CHAR} """ 
Example: "Test 1"

unassignedMessageの例

connector Frame "Frame of a mechanical system"
    ...
  flow Modelica.SIunits.Force f[3] annotation(unassignedMessage =
"All Forces cannot be uniquely calculated. The reason could be that the
mechanism contains a planar loop or that joints constrain the same motion.
For planar loops, use in one revolute joint per loop the option
PlanarCutJoint=true in the Advanced menu.
");
end Frame;

変数

変数の型(Type)

型宣言 内容
Real 実数型
Integer 整数型
Boolean ブーリアン型
String 文字型
enumeration 列挙型
Clock クロック型(Modelica Specification 3.3(2014年)から導入)

変数の接頭辞

接頭辞 内容
parameter インスタンス時に入力できる定数値
constant 計算中変化することのない一定値
input 引数の宣言
output 戻り値の宣言
flow 接続されたポート間の総和がゼロとなる物理量
stream flow変数によって輸送される物理量
replaceable 交換可能なインスタンスや変数であることを示す
redeclareとセットで使用する
discrete

変数の属性(Attributes)

属性 内容
max 最高値。この値を超えるとワーニングが出る
min 最低値。この値を下回るとワーニングが出る
start 初期値
fixed 初期値を固定するかどうか。fixed=trueにしてinitial equationにも初期値を入れるとエラーとなる。
nominal 数値計算上の丸め誤差を回避するために用いられる値
unit 方程式の中で使用される単位
displayUnit 表示する単位
StateSelect Real変数を独立変数(微分項の分子となる変数)として使用するかどうかの選択。
以下から選択する。
never(使用しない)
avoid(できるだけ使用しない)
default(適切なら使用する)
prefer(できるだけ使用する)
always(使用する)
  //絶対温度の下限を-273.15℃に設定する場合
  Real Temperature (min = -273.1) ;

変数のAnnotation

declarationセクション内で変数やインスタンスを宣言した際に使用するannotationの文法

宣言 内容 コード
absoluteValue 特定のtypeクラスの単位換算を行うためのアノテーション。trueにすると絶対値を、falseにすると相対値を表示する。温度をK, ℃のどちらかで表示する際に使用される。 type ThermodynamicTemperature = Real ( hogehoge )" annotation(absoluteValue=true);
choices 選択できる値やクラスなどの候補を定義する。 type KindOfController=Integer(min=1,max=3)
annotation(choices(
choice=1 "P",
coice=2 "PI",
choice=3 "PID"));
model A
KindOfController x;
end A;

A a(x=3 "PID");
choicesAllMatching 選択できるすべてのクラスをパラメータメニューに表示する。 replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater constrainedby Modelica.Media.Interfaces.PartialMedium annotation (choicesAllMatching=true);
defaultComponentName インスタンス生成時のデフォルト名 annotation(defaultComponentName = "name")
defaultComponentPrefixes インスタンス生成時のprefixを定義
使用できるprefix
inner, outer, replaceable, constant, parameter, discrete
annotation(defaultComponentPrefixes = "prefixes")
missingInnerMessage innerモデルに対応するouterモデルがない時に、メッセージを出力する annotation(missingInnerMessage = "message")
absoluteValue annotation(absoluteValue=false);
defaultConnectionStructurallyInconsistent annotation(defaultConnectionStructurallyInconsistent=tru
obsolete annotation(obsolete = "message");
unassignedMessage connector Frame "Frame of a mechanical system" ... flow Modelica.SIunits.Force f[3] annotation(unassignedMessage = "All Forces cannot be uniquely calculated. The reason could be that the mechanism contains a planar loop or that joints constrain the same motion. For planar loops, use in one revolute joint per loop the option PlanarCutJoint=true in the Advanced menu. "); end Frame; annotation(unassignedMessage = "message");
Dialog パラメータウィンドウの表示設定
下記で説明
HideResult trueなら結果を出力しない
Placement ダイアグラムビューなどのコンポーネントの表示設定
下記で説明

Dialogアノテーション

パラメータウィンドウの表示設定の定義。パラメータ変数のグループやタブの設定を定義する。

宣言 内容
tab パラメータウィンドウ内でパラメータ変数をタブ毎に分ける
group パラメータウィンドウ内でパラメータ変数をグループ毎に分ける。
enable パラメータウィンドウ内にパラメータ変数の表示させるかどうかを定義
falseなら非表示
showStartAttribute
colorSelector
loadSelector
saveSelector
groupImage パラメータグループに表示させるイメージファイルのURL。各グループに一つだけイメージファイルを設定できる。
connectorSizing
DialogのExample
annotation(Dialog(
    enable = true, 
    tab = "General", 
    group = "Parameters", 
    showStartAttribute = false, 
    colorSelector = false, 
    groupImage="modelica://MyPackage/Resources/Images/switch.png", 
    connectorSizing = false));

Placementアノテーション

ダイアグラムビューなどのコンポーネントの表示設定。アイコンやコンポーネントのGUIの設定を定義する。

宣言 内容
Icon
Diagram

インスタンス

インスタンスの宣言

test.mo
//クラス インスタンス名;
Test test1;

modification

インスタンスのパラメータ変数に値を与える

//クラス インスタンス名(変数=入力値);  以下の例ではtest1インスタンスのaに1を代入している
Test test1(a=1);

インスタンスのannotation

インスタンスのグラフィック情報を定義する

  Test test1 annotation(
    Placement(visible = true, transformation(origin = {100, -6}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, -6}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));

インスタンスの接頭辞

名前 内容 メモ
outer connectorで接続しなくても外部インスタンスの変数を参照できるようにする。外部インスタンスはinnerで宣言される必要がある。innerとセットで使用する。
inner outerで宣言されたインスタンスがinnerで宣言された外部インスタンスを参照できるようにする
宣言されているインスタンス名は固定しないといけない。
inner側のannotation内に annotation (defaultComponentName="world", defaultComponentPrefixes="inner")を書くと良い

replaceable&redeclare

replaceableで宣言されたクラスをredeclareによって入れ替える

model FixedBoundary
  ~
  replaceable package Medium =
      Modelica.Media.Interfaces.PartialMedium;
model main
  package Medium = Modelica.Media.Water.StandardWaterOnePhase
    constrainedby Modelica.Media.Interfaces.PartialMedium;
  Modelica.Fluid.Sources.FixedBoundary source(
    redeclare package Medium = Medium);
   ~

配列

変数にもインスタンスにも配列は使用出来る。

配列の宣言

//以下はどちらも同じ結果を返す

// ベクトル 
Real[5] a;
Real a[5];

//3×3配列
Real[3,3] b;
Real b[3,3];

//declarationセクションで値をセットする場合
parameter Real c[3,3]={{1,2,3},{4,5,6},{7,8,9}};

//インスタンスも配列に出来る
Modelica.Blocks.Sources.Constant const[3];

//各インスタンスのパラメータに値を入れる
Modelica.Blocks.Sources.Constant const[3](k={2,3,4});

//「each」を使用すると各インスタンスに同じ値を入れる
Modelica.Blocks.Sources.Constant const[3](each k=1);

配列のサイズをパラメータとして入力する場合

parameter Integer arraySize=5;
Real[arraySize] a={1,2,3,4,5};

動的配列

Real[:] a;

配列の計算

  parameter Real[3] a={1,2,3};
  parameter Real b=2;
  Real[3] y;
equation
  y = b * a;  //=y={2,4,6}

その他の文法

キーワード 説明 メモ
extends クラスの継承
import クラスの参照先のパスを省略したり他の変数で置き換える

import

クラスの参照先のパスを省略したり他の変数で置き換えるために使用する。

詳しい使い方
  • 参照先を他の変数で置き換える
class Lookup
  import SI = Modelica.SIunits; // #
  SI.Torque torque; // due to # (Modelica.SIunits.Torque)
end Lookup;
  • パスを省略する①
  import Modelica.Math.*; // # (Try to avoid wildcard imports,
                          //     consider using #1 or #3  instead!)
equation
  torque = sin(time); // due to # (Modelica.Math.sin)
  • パスを省略する②
  import Modelica.Mechanics.Rotational; // #
  Rotational.Components.Inertia inertia; // due to # (Modelica.Mechanics.Rotational.Components.Inertia)

オペレータ

()内はすべて引数。

数値計算オペレータと変換オペレータ

イベントを生成しないオペレータ

オペレータ 説明 メモ
abs(変数x) 絶対値を返す
sign(変数or整数x) 引数xが0以上なら1、0以下なら-1を返す 読み方はサインだが、sinと紛らわしいので大体シグナムとかシグンと呼ばれている。
sqrt(変数x) 平方根を返す
Integer(enum型) 引数となるenum型の変数の順番を返す。 type Size = enumeration(small, medium, large, xlarge);//4個のenumeration型の変数
Size tshirt = Size.large;//三番目のlargeを代入
Integer tshirtValue = Integer(tshirt); // = 3
EnumTypeName(整数i) enum型の名前に整数iを入力すると、i番目のenum型の変数を返す OpenModelica1.14ではエラーとなった

type Colors = enumeration ( RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW );
c = Colors(3); //c = Colors.BLUE
String(String以外の型) String型にする

イベントを生成するオペレータ

イベントを生成するので、うまく使いこなせば精度よく計算するのに使えるかも。

オペレータ 説明 メモ
div(変数x,変数y) x÷yの整数部だけを返す
mod(変数x,変数y) x÷yの剰余だけを返す
rem(変数x,変数y) x÷yの剰余の小数部だけを返す
ceil(変数x) xより大きな整数の最小値を返す ceil(3.14) = 4
integer(変数) 引数の変数を超えない最大の整数を返す 大文字Integer(変数)とは異なる
floor(変数x) 変数x以下の整数となるようにReal型を返す floor({-3.14, 3.14})
= {-4.0, 3.0}

数学的なオペレータ

オペレータ 説明 メモ
sin(変数) サイン
cos(変数) コサイン
tan(変数) タンジェント
asin(変数) アークサイン
acos(変数) アークコサイン
atan(変数) アークタンジェント
atan2(変数y, 変数x) tan(y/x)のアークタンジェント
sinh(変数) ハイパボリックサイン
cosh(変数) ハイパボリックコサイン
tanh(変数) ハイパボリックタンジェント
exp(変数) ネイピア数
log(変数x) 自然対数
log10(変数x) 常用対数

微分や特別な目的のためのオペレータ

オペレータ 説明 メモ
der(変数x) 変数xの導関数 Functionクラスの中では使えない
delay(変数, 時間) 指定した時間分だけ遡った値を返す preの実数型版
cardinality(コネクターのインスタンス) [このオペレータは廃止されました]
ポートに接続されたコネクターの数を返す。
何も接続されていないときにとりあえず断熱にしたり壁面境界条件にするのに役立つと思われる。あと、何もコネクタに接続されていないとエラーを出したりするのに重宝する。FixedTranslationモデルに使用されている。
homotopy(実際の計算式X1, 初期値推定のための計算式X2) ホモトピー法によって計算式X1から計算式X2を徐々に計算する まだ使用したことはないがMSL.Fluidには頻出する。計算の安定性が向上する。
semiLinear(x, positiveSlope, negativeSlope) 定義は以下
if x >= 0 then
positiveSlope * x
else
negativeSlope * x
エンタルピーなどの輸送量の計算に用いられる。逆流が発生した時にゼロ点付近の計算を処理をして解いてくれる。
H_flow = semiLinear(m_flow, port.h, h);
inStream(stream変数) flow変数に依存する輸送量の計算に使用する。 以下の「inStreamとactualStream」参照
actualStream(stream変数) flow変数に依存する輸送量の計算に使用する。 以下の「inStreamとactualStream」参照
spatialDistribution(in0, in1, x, positiveVelocity
initialPoints = {0.0, 1.0},
initialValues = {0.0, 0.0});
以下の偏微分方程式を解くためのオペレータ
image.png
Buildings.Fluid.FixedResistances.BaseClasses.PlugFlowの比エンタルピー、substancesなどの計算に使用されている
getInstanceName() 計算したモデルやブロックの名前を返す

inStreamとactualStream

inStream、actualStreamはflow変数で輸送される物理量(比エンタルピー、質量分率 etc.)を計算するためにstream変数を引数として用いられる。

詳細内容(長いので折り畳んでいます)

(注意 あまり分かりやすい説明に出来なかったため改めて別資料として解説を書きたい)
例えば、ある系に流入出する比エンタルピーは質量流量に応じて計算されるため比エンタルピーをstream変数で定義しておけばinStream, actualStreamで簡便に計算できる。
これらのオペレータは計算したいポートのstream変数を引数とする。
しかし、ポートのstream変数自体に値を定義するわけではないところが少しややこしい。
また二つポートがある場合、工夫しないと片方のポートのstream変数の値は不自然な結果となる。不自然な結果となった方のポートの結果値はユーザーが見ないようにすれば良いだけだが知らないで使用すると変な結果が入っていてちょっと驚く。

inStreamオペレータ

定義式

inStream(h_i)=\frac{\sum_{j}^{}max(-mflow_j,\epsilon)h_j}{\sum_{j}^{}max(-mflow_j,\epsilon)}
  • mflowはflow変数   質量流量を想定

  • hはstream変数    比エンタルピーを想定

  • iはstream変数の値を計算したいポートの番号

  • jはiポートに接続したポートの番号

  • εはゼロ割を防ぐための微小値

ポートiのstream変数を引数として、ポートiに接続されたその他のポートj(=1,2...)から流入するstream変数の値を計算する。

inStreamオペレータの例 2ポートの場合

やりたい計算に合わせて色々な実装方法がある。

ここでは以下のように2つポートがあり中心部から熱量Q_flowが流入する場合を例に挙げ、各ポートの比エンタルピー(h)をinStreamを使用して計算する。

コネクターport_a, port_bは以下のように定義したとする。

  Real p "圧力";
  flow Real mflow "質量流量";
  stream Real h "比エンタルピー";

計算式を見やすくするために記号は以下のように定義する。

  • mflow_a, mflow_b ポートa,bの質量流量
  • h_a, h_b ポートa,bの比エンタルピー

二つのポートを持つパイプの比エンタルピーの計算式は以下となる。(圧縮性は考慮しない)

  mflow_a + mflow_b = 0;
  h_b = inStream(h_a) + Q_flow/mflow_a;
  h_a = inStream(h_b) + Q_flow/mflow_b;

mflow_a > 0 のとき、h_bは自然な結果が返ってくるがh_aには不自然な結果が返ってくる。
逆向きの流れも同様に流出する側の結果は自然な結果となり、流入する側は不自然な結果となる。
流入側のポートの計算結果は見ないようにすれば問題無い。

actualStreamオペレータ

定義式

actualStream(h_a) = 
    if mflow_a > 0 then 
        inStream(h_a) else 
        h_a;
    end if;

port_aから流入する場合(mflow_a > 0 )、inStream(h_a)の値が返される。
port_aから流出する場合、h_aが返される。
h_aの値は別途計算する。

actualStreamオペレータの例 2ポートの場合

  • 典型的な使用方法1 保存則の式に使用

「inStreamオペレータの例 2ポートの場合」で示した2ポートの場合と同様の計算をactualStreamを使用して実装する。

  //エネルギー保存式
  0 = mflow_a*actualStream(h_a) + mflow_b*actualStream(h_b) + Q_flow;
  //上記のままだとport_aかh_bのhが未定のため以下でダミー値を入力する
  h_a = h_b;

mflow_a > 0 のとき、エネルギー保存式からh_bの値が計算される。

h_aの値は計算されないためダミー値としてh_bの値を入れる。もちろんh_aには不自然な結果が入っているので無視する。

  • 典型的な使用方法2 ポートの値のモニタリング

これまでの使用方法では上流のポートの比エンタルピーには不自然な結果が返ってきてしまうため、ポートの比エンタルピーは別途定義した変数に代入することにする。

  //エネルギー保存式
  0 = mflow_a*actualStream(h_a) + mflow_b*actualStream(h_b) + Q_flow;
  //上記のままだとport_aかh_bのhが未定のため以下でダミー値を入力する
  h_a = h_b;
  //ポートa,bのhをモニタする変数 ha_monitor,hb_monitor,
  ha_monitor = actualStream(h_a);
  hb_monitor = actualStream(h_b);

上流側に不自然な結果が入らないようにする 2ポートの場合

上記の実装例だと必ず流入側のポートに不自然な結果が返され不便である。

可読性は下がるが以下のようにすることで各ポートに自然なstream変数の値が返される。

  mflow_b + mflow_a = 0;
  h_a = semiLinear(sign(mflow_a), inStream(h_a), h_mid);
  h_b = semiLinear(sign(mflow_b), inStream(h_b), -h_mid);
  //パイプの中央部分の比エンタルピー h_mid
  h_mid = semiLinear(sign(mflow_a), inStream(h_a), -inStream(h_b))+heatPort.Q_flow/abs(mflow_a);

イベントに関係するオペレータ

オペレータ 説明 メモ
initial() Initialization中(初期値の計算中)ならtrueを返す Initialization中かどうかを判断したいときに使用するようだが見かけたことがない
terminal() 計算が正常に終了したらtrueを返す 沢山の計算をスクリプトで流して正常に終了したかどうかをterminalで判断するのに使用するのかもしれない
noEvent(計算式F) 式Fの計算時にイベントを発生させないようにする
smooth(p、計算式F) 式Fがp回まで滑らかに時間微分可能であることをコンパイラに明示する 恐らく計算の安定化、効率化のため使用。noEventよりsmoothを使用すべきとのこと。
sample(start, interval) タイムイベントのトリガー when sample(1, 0.1) then
i = pre(i) + 1;
end when;
pre(y) 一つ前のイベント時の値を返す
離散化変数のみに使用可能
一部のツールでは実数型にも使用可能。その場合は前ステップの値を取得するものが多い気がする
edge(Boolean) 引数となるBooleanがfalseからtrueに切り替わった瞬間だけtrueを返す
change(Boolean) 引数となるBooleanがfalseからtrueもしくはtrueからfalseに切り替わった瞬間だけtrueを返す。
reinit 値を定義しなおす

配列関係のオペレータ

配列に関する用語の定義

用語 記号 説明 メモ
Vector ベクトル V 1次元の配列
Matrix マトリックス M 2次元の配列
Array アレイ A n次元の配列

以降の表はまだ上記の表に従って整理されていない個所がある

オペレータ 説明 メモ
promote [Modelica言語には実装されていないオペレータだが他のオペレータの挙動の説明に使用される]
ndims(ベクトルv) ベクトルvの次元を返す サンプル
Real A[8,4,5];
Integer n = ndims(A); // = 3
size(配列A) Aの配列のサイズを返す Real A[8,4,5];
Integer n3 = size(A,3); // = 5
Integer n[:] = size(A); // = {8, 4, 5}
scalar(マトリックスA) 配列の値を変数として返す。配列のサイズが1となる場合のみ有効。 scalarをつけなくても値は取得できるが以下がサンプル。
parameter Real A[3]={77,88,99};
parameter Real a2=scalar(A[2]); //a2=88
vector(配列A) 配列Aをベクトルに変換する Real A[1,2,1] = {{{3},{4}}};
Real v[2] = vector(A); // = {3,4}
matrix(ベクトルV or 変数R) 引数を配列に変換する parameter Real A=22;
Real B[1,1];
equation
B=matrix(A);
identity(整数A) A×Aのidentity matrix(単位行列)を返す Multibodyパッケージ内のPointMass(球)の回転行列の生成に用いられていた。つまり無回転。
diagonal(ベクトルv) ベクトルvが対角に入る行列を返す。対角以外の値はゼロ。 サンプル
parameter Real v[2]={2,4};
Real w[2,2]=diagonal(v); //{{2,0}.{0,4}}
zeros(整数A,整数B, ...) 値が全て0のA×B×...行列を返す
ones(整数A,整数B, ...) 値が全て1のA×B×...行列を返す
fill(変数X、整数A、整数B, ・・・) すべての要素に変数Xが代入された配列A×B×・・・を返す
linspace(変数x1,変数x2,整数n) x1とx2をn分割した数列を返す 1から7を4分割した数列
Real v[:] = linspace(1,7,4); // = {1, 3, 5, 7}
min(マトリックスA)
min(変数x,変数y)
最小値
max(マトリックスA)
max(変数x,変数y)
最大値
sum() 合計値
product(配列A) 配列Aのスカラー積
transpose(配列A) 配列Aの転置行列を返す
outerProduct(ベクトルv1、ベクトルv2) ベクトルv1,v2の直積(テンソル積)
symmetric(A) 対称行列
cross(ベクトルx、ベクトルy) ベクトルx, yのベクトル積(クロス積) cross(x,y) = vector( [ x[2]*y[3]-x[3]*y[2];
x[3]*y[1]-x[1]*y[3];
x[1]*y[2]-x[2]*y[1] ] );
skew(ベクトルV) ベクトルVを成分とするskew-symmetric matrix(交代行列、歪対称行列) skew(x) = [ 0 , -x[3], x[2];
x[3], 0 , -x[1];
-x[2], x[1], 0 ];
array(変数X、変数Y) 配列{X,Y}を返す 以下は同じ結果となる
Real[3] v = array(1, 2, 3)
Real[3] v = {1, 2, 3}
cat(k, 配列A、配列B、・・・) 配列をk次の次元になるように結合 1次元の配列になるように結合
cat(1, {1,2}, {10,12,13} ) // Result: {1,2,10,12,13}
2次元の配列になるように結合
cat(2, {{1,2},{3,4}}, {{10},(11}} ) // Result: {{1,2,10},{3,4,11}}

Virtual connection graphに関するオペレータ

ここでの記号は以下
  A connectorクラス
  R recordまたはtypeクラス

オペレータ 説明 メモ
Connections.branch(A.R,B.R) virtual connection graphにおいて、A.RとB.Rは結合が解かれないことを表す FixedTranslationモデル内で剛体移動を表すために使用
Connections.root(A.R) virtual connection graphにおいて、A.Rをルートノードとして定義する MultibodyのFixedモデル内で固定されていることを表すために使用。またMultibodyのBodyモデル内で使用
Connections.potentialRoot(A.R)
Connections.potentialRoot(A.R, priority = p)
virtual connection graphにおいて、A.Rをポテンシャルルートノードとして定義する MultibodyのBodyモデル内で使用
Connections.isRoot(A.R) virtual connection graphにおいて、A.Rがルートとなっているかどうかを返す MultibodyのBodyモデル内で使用
Connections.rooted(A.R) Connections.branch(A.R, B.R)の第一引数として定義されたノードA.RがB.Rよりルートに近い場合はtrueを返す FixedRotation内でルートに近い方からRを計算するために使用
rooted Connections.rootedと同じ。ただ非推奨のため使わない方が良い。

Clock型に関するオペレータ

調査中

オペレータ 説明 メモ
previous
sample
hold
subSample
superSample
shiftSample
backSample
noClock
firstTick
interval

状態遷移図に関するオペレータ

調査中

オペレータ 説明 メモ
transition
initialState
activeState
ticksInState
timeInState

その他のオペレータ

オペレータ 説明 メモ
assert(条件式, メッセージ, アサートのレベル) 条件式を満たさない場合にメッセージを表示する。
アサートのレベルはワーニングかエラー(計算中断) 表記は assert(condition, message, level = AssertionLevel.error)
connect(コネクター1、コネクター2) コネクター1、コネクター2を接続する。 アクロス(ポテンシャル)変数、フロー(スルー)変数、ストリーム変数に応じて接続時の方程式は異なる

条件判定、繰り返し

if

典型例

if linear then
  y = x + 1;
elseif quadratic then
  y = x^2 + x + 1;
else
  y = Modelica.Math.sin(x) + 1;
end if;

内包表記

sign_of_i=if i<0 then -1 else if i==0 then 0 else 1;

for

sample

    parameter Integer np=10;
    Real p[np], x, y;
  algorithm
     y := p[1];
     for i in 2:np loop   // i shall not be declared
        y := y*x + p[i];
     end for;

内包表記

  Real a[3];
equation
  a = {i^2 for i in 1:3};  //a=1,4,6

when

sample

 equation
   when x > 2 then
     y3 = 2*x +y1+y2; // Order of y1 and y3 equations does not matter
     y1 = sin(x);
   end when;
   y2 = sin(y1);

while

sample

    Integer i;
algorithm
    i := 1;
    while i < 10 loop
      i := i + 1;
      ...
    end while;

コメント

コメントはC言語と同様

オペレータ 文法
インラインコメント // コメント
ブロックコメント /*
コメント
*/

外部プログラミング言語の関数とのインターフェース

Modelica言語からC言語と FORTRAN77で書かれた関数を実行させその結果を返すことが出来る。

詳細内容(長いので折り畳んでいます)

以下はModelicaモデルからC言語で書かれたExternalFunc2ファンクションを実行するサンプルコード。

//Modelicaモデル ExternalLibraries.mo
model ExternalLibraries

  function ExternalFunc2
    input Real x;
    output Real y;
  external "C" annotation(Library="ExternalFunc2", LibraryDirectory="modelica://ExternalLibraries");
  end ExternalFunc2;

  Real x(start=1.0, fixed=true), y(start=2.0, fixed=true);
equation
  der(y)=-ExternalFunc2(y);
end ExternalLibraries;
//Cコード ExternalFunc2.c
double ExternalFunc2(double x)
{
  double res;
  res = (x-1.0)*(x+2.0);
  return res;
}

Modelica Standard Library内の便利クラス

Mathライブラリ

Vector

Function 説明 メモ
toString(ベクトル) ベクトルを文字列にして返す
length(ベクトル) ベクトルの長さを返す
normalize(ベクトル、ゼロ割回避の微小値(任意)) ベクトルの単位ベクトルを返す。
normalizeWithAssert(ベクトル) ベクトルの単位ベクトルを返す。
ベクトルの大きさが0なら警告を出力する

BooleanVector

Matrix

Nonlinear

Random

FastFourierTransform

Fluidライブラリ

Fluidライブラリの中には方程式を補間したりゼロ割を避けるための便利なファンクションが沢山あり流体以外にも使える。

Utility

Function 内容 メモ
regRoot
regRoot_der
regSquare
regPow
regRoot2
regSquare2
regStep
regFun3

参考資料

4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
UedaShigenori
CAEの普及と活用に興味があります。 プロフィールは以下から https://connpass.com/user/uedashige/

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?