0

私は現在Petrel、(「For ループ」を介して) シミュレーション ケースを実行する必要があるプラグインに取り組んでいます。ケース ランナーを作成し、エクスポートして実行します...しかし、シミュレーションを終了して閉じた後コンソール、CaseRunner.IsRunningプロパティを確認すると、表示されますtrue! これにより、結果が petrel システムにロードされていません。

Runケースを終了した後 (コードでバッチ ファイルを使用し、またバッチ ファイルを使用して) 結果を手動でロードしようとしcaserunnerましたが、プログラミング環境で結果が表示されません。

この状況の解決策はありますか?
これは私のコードの関連部分です:

Case theCase = arguments.TheCase;                    
Case Test2 = simroots.CreateCase(theCase, "FinalCase");
CaseRunner cRunners = SimulationSystem.GetCaseRunner(Test2);
cRunners.Export();
cRunners.Run();
bool b = cRunners.IsRunning;

実際、プロセスがいつ終了するかを確認しました。「cRunners.Run」の後、コードは次を使用してプロセスの終了を待ちます。

  System.Diagnostics.Process[] parray = System.Diagnostics.Process.GetProcesses();
  foreach (System.Diagnostics.Process pr in parray)
  {

      if (pr.ProcessName == "cmd")
      {
            pr.WaitForExit();//just wait

      }
  }

コンソールが閉じたら、cRunners.IsRunning 用語をチェックしました。しかし、私はそれほど専門家ではありません... CaseRunnerMonitor の使用例を示してもらえますか? 派生クラスの定義とその実装の両方。

  • 必要なのは、for ループを介してシミュレーション ケースを n 回実行し、各実行後に、提供された要約結果にアクセスすることだけです。

希望する結果を得るために、いくつかの異なるシナリオを試しました。ここにその一部を示します。まず、CaseRunnerMonitor クラスを作成します。

     public class MyMonitor : CaseRunnerMonitor
     {
        //…
        public override void RunCompleted()
        {
        // define arguments
        foreach (Slb.Ocean.Petrel.DomainObject.Simulation.SummaryResult sr in simroot.SummaryResults)
                {
                    IEnumerable ….
                    List ….
                    // some codes to change the input arguments according to the current step simulation summary results


                }

            PetrelLogger.InfoOutputWindow("MyMonitor is completed!");
        }
        //…

    }

そしてそれを使用します:

        private void button1_Click(object sender, EventArgs e)
        {
            // Some codes that define some arguments…

            for (int j = 0; j < 8; j++)
            {
                // some changes in the arguments
                Case MyTest;
                MyMonitor monit4 = new MyMonitor();
                SimulationRoot simroot = SimulationRoot.Get(PetrelProject.PrimaryProject);

                using (ITransaction trans = DataManager.NewTransaction())
                {
                    trans.Lock(simroot);
                    MyTest = simroot.CreateCase(OriginalCase, MycaseNameFunc());

                    trans.Commit();
                }
                CaseRunner cRun = SimulationSystem.GetCaseRunner(MyTest);
                cRun.Export();
                cRun.Run(monit4);

                //Wait();   //waits for current process to close

            }
        }

しかし問題は、実行が完了した後、MyTest ケースの結果の部分が空になることです。この場合、8 回目 (最後) のシミュレーションが完了すると、すべての結果がペトレルにロードされます。Wait() 関数を有効にしないと、8 回の実行すべてがほぼ同時に呼び出されます…</p>

シナリオを変更し、各実行後のコールバックでシミュレーション結果を読み取り、何かを変更して次の実行を呼び出すので、CaseRunnerMonitor クラスを作成します。

    public class MyMonitor2 : CaseRunnerMonitor
    {
        //…
        public override void RunCompleted()
        {   

        // define arguments
                    index++;
                if (index <=8)
        {
                    foreach (Slb.Ocean.Petrel.DomainObject.Simulation.SummaryResult sr in simroot.SummaryResults)
                {
                    IEnumerable ….
                    List ….
                    // some codes to change the input arguments according to the current step simulation summary results


                }
                Case MyTest;
                MyMonitor monit4 = new MyMonitor();
                SimulationRoot simroot = SimulationRoot.Get(PetrelProject.PrimaryProject);

                using (ITransaction trans = DataManager.NewTransaction())
                {
                    trans.Lock(simroot);
                    MyTest = simroot.CreateCase(OriginalCase, MycaseNameFunc());

                    trans.Commit();
                }
                CaseRunner cRun = SimulationSystem.GetCaseRunner(MyTest);
                cRun.Export();
                cRun.Run(monit4);
    }

            PetrelLogger.InfoOutputWindow("MyMonitor2 is completed!");
        }
        //…

    }

そしてそれを使用します:

        private void button1_Click(object sender, EventArgs e)
        {   
                Index=0;
                // Some codes that define some arguments…
                // some changes in the arguments
                Case MyTest;
                MyMonitor monit5 = new MyMonitor();
                SimulationRoot simroot = SimulationRoot.Get(PetrelProject.PrimaryProject);

                using (ITransaction trans = DataManager.NewTransaction())
                {
                    trans.Lock(simroot);
                    MyTest = simroot.CreateCase(OriginalCase, MycaseNameFunc());

                    trans.Commit();
                }
                CaseRunner cRun = SimulationSystem.GetCaseRunner(MyTest);
                cRun.Export();
                cRun.Run(monit5);
        }

この状況では、wait() 関数は必要ありません。しかし問題は、現在の実行が完了する前に、MyTest ケースの結果に 1 つのレベルでアクセスすることです。つまり、実行が完了したにもかかわらず、ステップ 6 の結果が空である間に実行 6 が完了したときに、MyTest.Results を介してステップ 5 の結果を表示できます。

4

2 に答える 2

0

CaseRunner.IsRunningプロパティを確認すると、表示されますtrue

これは、 Caserunner.Run() がノンブロッキングであるためです。つまり、別のスレッドを開始して実行を開始します。cRunners.IsRunning制御フローは、シミュレーションが進行中であるため、true であるチェックにすぐに渡されます。

cRunners.Run(); //non-blocking
bool b = cRunners.IsRunning;

CaseRunnerMonitorシミュレーションが完了したときにコールバックが必要かどうかを確認する必要があります。

編集:

CaseRunnerMonitor の使用例を見せてもらえますか? 派生クラスの定義とその実装の両方。

モニター クラスを作成します。

public class CustomCaseRunnerMonitor : CaseRunnerMonitor
{
    //...
    public override void RunCompleted()
    {
        //This is probably the callback you want
    }
}

これを使って:

Case myCase = WellKnownSimulators.ECLIPSE100.CreateSimulationCase(...);
CaseRunner runner = SimulationSystem.GetCaseRunner(myCase);

var myMonitor = new CustomCaseRunnerMonitor(...);
runner.Run(myMonitor);
//Your callbacks defined in your CustomCaseRunnerMonitor will now be called

SimulationSystem API ドキュメントの「シミュレーションの実行と監視」も参照してください。

于 2014-05-19T08:16:05.180 に答える
0

ああ、わかりました。CaseMonitor で結果を読み込もうとしていたことに気がつきませんでした。

残念ながら、短い答えは「いいえ、Petrel がいつ結果をロードしたかを知ることはできません」です。

長い答えは、Case 引数でオプションが設定されている場合、Petrel は自動的に結果をロードするということです。(シミュレーション ケースの定義 -> アドバンス -> 結果の自動ロード)。

API では:

EclipseFormatSimulator.Arguments args = EclipseFormatSimulator.GetEclipseFormatSimulatorArguments(myCase);
EclipseFormatSimulator.Arguments.RuntimeArguments runtimeArgs = args.Runtime;
runtimeArgs.AutoLoadResults = true;
runtimeArgs.AutoLoadResultsInterval = 120; //How frequently in seconds Petrel polls sim dir. 

ケースが終了したら、SimulationRoot.SummaryResults を (既に使用しているのと同じ API を使用して) ポーリングする必要があります。System.Diagnostics.Process[] parray = System.Diagnostics.Process.GetProcesses();これをいつ開始するかを判断するには、現在持っているコードではなく、ここで説明した CaseRunnerMonitor を使用する必要があります。

于 2014-05-27T10:14:26.040 に答える