如何使用CaseRunner函数运行模拟案例?

时间:2014-05-14 11:15:51

标签: ocean petrel

我目前正在开发一个Petrel插件,我需要运行一个模拟案例(通过“For循环”),我创建我的案例运行器,导出它并运行它.. 。)在完成模拟并关闭控制台后,我检查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次运行几乎都是同时调用...

我改变了我的场景,每次运行后我的回调都是读取模拟结果,改变一些东西并调用下一次运行 我创建了我的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步结果是空的,尽管运行完成。

2 个答案:

答案 0 :(得分: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

另见&#34;运行和监控模拟&#34;在SimulationSystem API文档中。

答案 1 :(得分:0)

啊,好的。我没有意识到你正试图用CaseMonitor加载结果。

我担心简短的回答是&#34;不,你不能知道Petrel加载结果的时间&#34;。

如果在Case参数中设置了选项,那么Petrel会自动加载结果。 (定义模拟案例 - &gt;前进 - &gt;自动加载结果)。

在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();代码。