Dsl (Digital Simulation Library) for .Net
先頭へ
単純な液面レベル系の例
イメージ |
説明 |
||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
コードをコピー | |
---|---|
// // 単純な液面レベル系の例. // using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using Dsl; // Dsl.Dll を参照. using DslDialog; using DslSerializer; namespace Test { class Program { // // [STAThread] を指定しないと DslDialogBox 中の DataGridView から Clipboard にアクセスできない. // [STAThread] static void Main(string[] args) { SimpleTankModel(); } /// <summary> /// [単純なタンクモデル] /// 底面積 S のタンクに液面高 H で液が入っており, /// これに流入流量 Q で液が流入し、タンク底からバルブを通して流出している. /// タンク底からの流出流量は液面高 H とバルブの抵抗 R に依存し,(流出流量) = Sqrt(H)/R とする. /// 底面積 ... S /// 流入流量 ... Qin /// 流出流量 ... Qout ( =Sqrt(H)/R ) /// 液面高 ... H /// /// Qout = Sqrt(H)/R /// dH/dt = (Qin - Qout)/S /// R = 1 /// Qin = 20 /// </summary> static void SimpleTankModel() { // Processor の作成. Dsl.Processor gr = new Processor(); // DslDialogBox() の作成. DslDialogBox dlg = new DslDialogBox(); dlg.VariableFilter = delegate(Processor proc, Variable v) { if (!v.IsAlive()) return null; // 計算から無視された変数は一覧から除外する. if (v.IsConstant()) return ""; // 時間に依存しない変数は折れ線グラフ出力はしない. return "各変数値の時間変化"; // 時間に依存する変数を一つの紙面に折れ線グラフ出力する. }; // 各変数の作成(と同時にProcessorへの登録)と設定. Variable Qout = new Variable(gr, "Qout", USERFLAG.REQUIRED, 0.0); // 流出流量. Variable Qin = new Variable(gr, "Qin" , USERFLAG.SET,20.0); // 流入流量. Variable S = new Variable(gr, "S" , USERFLAG.SET, 5.0); // タンク底面積. Variable R = new Variable(gr, "R" , USERFLAG.SET, 0.1); // バルブ抵抗. Variable dHdt = new Variable(gr,"dHdt" , USERFLAG.VOLATILE, 0.0, Qin, Qout, S); // 液面変化率(微係数). Variable H = new Variable(gr, "H" , USERFLAG.INTEGRATED | USERFLAG.REQUIRED, 0.0, dHdt); // 液面高(積分変数: H = Integral(dH/dt)). Qout.SetRightSideVariables(H, R); // Qout = f(H,R) の因果(関数)関係の定義. // 計算式の定義 dH/dt = (Qin - Qout)/S dHdt.ComputeValueAt = delegate(Processor pr, Variable self, double time, double step) { double qin = self.RightSideVariables[0].Value; // Qin double qout = self.RightSideVariables[1].Value; // Qout double s = self.RightSideVariables[2].Value; // S return (qin - qout) / s; // dH/dt = (Qin - Qout)/S }; Qout.ComputeValueAt = delegate(Processor pr, Variable self, double time, double step) { double h = self.RightSideVariables[0].Value; // H double r = self.RightSideVariables[1].Value; // R if (h <= 0.0) return 0.0; return Math.Sqrt(h) / r; // Qout = Sqrt(H)/R }; // 結果の出力 StreamWriter df = new StreamWriter(Application.ExecutablePath + ".Log"); // Processor が出力するログファイル gr.LogFile = df; if (gr.DeterminateOrder() == RESULT.OK) { // 時間 0 ~ 10 まで刻み 0.1 で実行. dlg.Run(gr,0.0, 10.0, 0.1); // ここで定常状態を計算する. if (gr.DeterminateOrder(true) == RESULT.OK) { // 時刻 10.0 の時の定常状態を計算する. // 一度計算すればいいので終了時刻=開始時刻とする. dlg.Show(null,gr,10.0, 10.0, 0.0); } } df.Close(); } } } |
計算結果: