0

我目前正在开发一个Petrel插件,我需要在其中运行一个模拟案例(通过“For Loop”),我创建了我的案例运行器,导出它并运行它......但是在完成模拟并关闭之后控制台,我检查了CaseRunner.IsRunning属性,它显示了true!这导致结果尚未加载到海燕系统。

我尝试在完成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 案例结果的一个级别。即,当运行 6 完成时,我可以通过 MyTest.Results 查看第 5 步结果,而第 6 步结果为空,尽管运行完成。

4

2 回答 2

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)。您应该使用我们讨论过的 CaseRunnerMonitor 来确定何时开始执行此操作,而不是System.Diagnostics.Process[] parray = System.Diagnostics.Process.GetProcesses();您当前拥有的代码。

于 2014-05-27T10:14:26.040 回答
0

我检查了CaseRunner.IsRunning财产,它显示true

这是因为 Caserunner.Run() 是非阻塞的;也就是说,它启动另一个线程来启动运行。然后控制流立即传递给您的cRunners.IsRunning检查,因为模拟正在进行中,这是正确的。

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 回答