メインコンテンツ

分割ソルバーを使用したシミュレーションの高速化

分割ソルバーは、シミュレーションの計算コストを削減することによって特定モデルのパフォーマンスを改善する、Simscape™ の固定ステップ ローカル ソルバーです。計算コストを削減すると、デスクトップ シミュレーションのシミュレーション速度が上がり、展開のタスク実行時間 (TET) が短縮されます。このソルバーは、接続されている Simscape ネットワークの連立方程式全体を、非線形関数によって接続されている線形スイッチド システム方程式の複数の小さいセットに変換します。1 つの大規模な連立方程式の解を計算するよりも、複数のより小さい連立方程式の解を計算するほうが効率的であるため、計算コストは削減されます。

分割ソルバーはモデルを分割するわけではありません。つまり、モデルをマルチコア処理用に個別のサブシステムに分割するわけではありません。Simscape モデルの分割の詳細については、Partition a Model By Using a Network Coupler Blockを参照してください。

分割ソルバーを使用するには、Solver Configuration ブロックの設定を開いて以下を行います。

  1. [ローカル ソルバーを使用] チェック ボックスをオンにします。

  2. [ソルバータイプ] パラメーターを [分割] に設定します。

  3. [定常状態からシミュレーションを開始] チェック ボックスをオフにします。

  4. [方程式の定式化] パラメーターを [時間] に設定します。

リアルタイム シミュレーションの場合は、[固定コストでの実行時整合性の反復を使用] チェック ボックスもオンにします。詳細については、を参照してください。

制限

分割ソルバーを使ってすべてのネットワークのシミュレーションが行えるわけではありません。非線形関数によって接続されている線形スイッチド システム方程式によって Simscape ネットワークを表現できない場合、分割ソルバーを使用するシミュレーションはエラーになります。分割ソルバーを使用するシミュレーションは、以下を含むネットワークでもエラーになります。

  • Simscape 言語の delay 演算子を使用するカスタム コンポーネント。

  • 周期的イベントに離散サンプル時間を使用するブロック。例としては、Simscape/Physical Signals/Sources ライブラリの PS Counter ブロック、PS Random Number ブロック、PS Repeating Sequence ブロック、PS Uniform Random Number ブロックなどが挙げられます。

Solver Configuration ブロックの設定には、分割ソルバーと互換性がないものもあります。次の状態の Solver Configuration ブロックがモデルに含まれている場合、分割ソルバーを使用するシミュレーションはエラーになります。

  • [定常状態からシミュレーションを開始] がオンになっている

  • [方程式の定式化][周波数と時間] に設定されている

オプション

シミュレーションのパフォーマンスをさらに高めるには、[分割ストレージ法] パラメーターを [網羅] に設定し、[分割メモリ割り当て [kB]] パラメーターの値を、統計ビューアーの [合計メモリ推定] データに基づいて指定します。詳細については、Solver Configuration分割ソルバーの統計を参照してください。

分割ソルバーを使用した Simscape モデルのシミュレーション

% This example shows how to compare the speed and the accuracy of a
% simulation that uses the Partitioning solver to baseline results. It
% also shows how to compare the speeds of the Partitioning solver and
% the Backward Euler solver.

永久磁石 DC モーターの例を開いてワークスペース変数として保存するには、以下を入力します。

open_system("PermanentMagnetDCMotor")
model = 'PermanentMagnetDCMotor';

後でシミュレーション時間を比較できるようにすべてのシミュレーション出力を単一の Simulink.SimulationOutput オブジェクト内に返すために、sim コマンドの単出力形式を有効にします。

% Enable single-output format
set_param(model,'ReturnWorkspaceOutputs', 'on')

Simulink&reg データ インスペクターで Simulink® データのログ作成と表示を行うために、[Motor RPM] スコープ ブロックに達する信号を有効にします。

% Define the w sensor subsystem and the path
%    to it as variables
rpmSensor = 'Sensing';
rpmSensorPath = [model,'/',rpmSensor];

% Mark the output signal from the w sensor subsystem
%   for Simulink(R) data logging
phRpmSensor = get_param(rpmSensorPath,'PortHandles');
set_param(phRpmSensor.Outport(1),'DataLogging','on')

ログ バッジによって、モデル内の信号がマークされます。

これらの各ソルバーについて、時間測定付きシミュレーションを実行します。

  • 可変ステップのグローバル ソルバー (モデルの元々のソルバー)

  • 固定ステップのローカル後退オイラー法ソルバー

  • 固定ステップのローカル分割ソルバー

% Define the Solver Configuration block and the path
%    to it as variables
solvConfig = 'Solver Configuration';
solvConfigPath = [model,'/',solvConfig];

% Run a timed simulation using the original solver
out = sim(model);
tBaseline = out.SimulationMetadata.TimingInfo.ExecutionElapsedWallTime;

% Select option Solver Configuration >  Use local solver
set_param(solvConfigPath, 'UseLocalSolver', 'on')

% Set Solver Configuration >  Solver type > Partitioning
set_param(solvConfigPath, 'LocalSolverChoice',...
    'NE_PARTITIONING_ADVANCER')

% Run a timed simulation using the Partitioning solver
out = sim(model);
tPartition = out.SimulationMetadata.TimingInfo.ExecutionElapsedWallTime;

% Set Solver Configuration >  Solver type > Backward Euler
set_param(solvConfigPath, 'UseLocalSolver', 'on',...
    'LocalSolverChoice','NE_BACKWARD_EULER_ADVANCER')

% Run a timed simulation using the Backward Euler solver
out = sim(model);
tBackEuler = out.SimulationMetadata.TimingInfo.ExecutionElapsedWallTime;

% Compute the percent difference for the simulation times
spdPartitionVsBaseline = 100*(tBaseline - tPartition)/tBaseline;
spdBackEulerVsBaseline = 100*(tBaseline - tBackEuler)/tBaseline;
spdPartitionVsBackEuler = 100*(tBackEuler - tPartition)/tBackEuler;

% Reset the solver to the original setting by deselecting Use local solver
set_param(solvConfigPath, 'UseLocalSolver', 'off')
compTimeDiffTable = table({'Baseline';...
    'Partitioning';...
    'Backward Euler'},...
    {tBaseline;tPartition;tBackEuler},...
'VariableNames', {'Solver','Sim_Duration'});

display(compTimeDiffTable);
compTimeDiffTable =

  3×2 table

          Solver          Sim_Duration
    __________________    ____________

    {'Baseline'      }     {[0.0220]} 
    {'Partitioning'  }     {[0.0039]} 
    {'Backward Euler'}     {[0.0039]} 

compPctDiffTable = table({'Partitioning versus Baseline';...
    'Backward Euler versus Baseline';...
    'Partitioning versus Backward Euler'},...
    {spdPartitionVsBaseline;...
    spdBackEulerVsBaseline;...
    spdPartitionVsBackEuler},...
'VariableNames', {'Comparison','Percent_Difference'});

display(compPctDiffTable);
compPctDiffTable =

  3×2 table

                  Comparison                  Percent_Difference
    ______________________________________    __________________

    {'Partitioning versus Baseline'      }       {[82.0555]}    
    {'Backward Euler versus Baseline'    }       {[82.2556]}    
    {'Partitioning versus Backward Euler'}       {[-1.1278]}    

シミュレーション速度はマシンの処理能力と同時実行プロセスの計算コストに応じて異なるため、使用マシンでのシミュレーション時間は違ったものとなる場合があります。

ローカルの固定ステップ分割ソルバーおよび後退オイラー法ソルバーは、可変ステップのベースライン ソルバーより高速です。分割ソルバーは通常、後退オイラー法ソルバーより高速ですが、必ずしもそうであるとは限りません。

結果を比較するために、Simulink&reg データ インスペクターを開きます。

% Get Simulink Data Inspector run IDs for
%    the last three runs
runIDs = Simulink.sdi.getAllRunIDs;
runBaseline = runIDs(end - 2);
runPartition = runIDs(end - 1);
runBackEuler = runIDs(end);

% Open the Simulink Data Inspector
Simulink.sdi.view

compBaselinePartition = Simulink.sdi.compareRuns(runBaseline,...
    runPartition);

比較を確認するには、[比較] をクリックしてから [Sensing 1] をクリックします。

最初のプロットは、ベースラインと分割ソルバーのシミュレーション結果を重ねて示しています。2 番目のプロットは、それらの違いを示しています。既定の許容誤差は 0 です。結果の精度が要件を満たすかどうかを判定するために、相対許容誤差、絶対許容誤差、および時間の許容誤差を調整できます。

参考

トピック