How to run a simulation case using CaseRunner function?

好久不见. 提交于 2019-12-25 18:13:34

问题


I'm currently working on a Petrel plug-in in which I need to run a simulation case (through a "For Loop"), I create my case runner, export it and the run it...but after finishing the simulation and closing the console, I check the CaseRunner.IsRunning property and it shows true! This cause that the results have not been loaded to the petrel system.

I tried to load the results manually after finishing the Run of my case (using caserunner and also using a batch file in my code) and I can't see any results in the programming environment.

Does anybody have a solution for this situation?
This is the related part of my code:

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

actually I checked when the process finishes; after "cRunners.Run" the code waits for exit the process using:

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

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

      }
  }

and when the console closes itself, i checked the cRunners.IsRunning term. However, I'm not so expert... can you show me an example of using CaseRunnerMonitor? both definition of the derived class and its implementation.

  • All I need is running a simulation case n times via a for loop and after each Run access to its provided summary results.

I tried some different scenarios to get my desired results, I put here some of them First I create my CaseRunnerMonitor class:

     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!");
        }
        //…

    }

And then use it:

        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

            }
        }

But the thing is that MyTest case results part are empty after my run is completed. in this case all the results loaded to the petrel when the 8th (last) simulation completes. If I don’t activate the Wait() function, all 8 runs are almost calling simultaneously…

I changed my scenario, my callback after each run is read the simulation results, change something and call next run so I create my CaseRunnerMonitor class:

    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!");
        }
        //…

    }

And then use it:

        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);
        }

in this situation no need to wait() function is required. But the problem is that I access to MyTest case results in one level before the current run completes. i.e, I can view the step 5 results via MyTest.Results when the run 6 is completed while step 6 results are empty despite of completion of its run.


回答1:


I check the CaseRunner.IsRunning property and it shows true

This is because Caserunner.Run() is non-blocking; that is, it starts another thread to launch the run. Control flow then passes immediately to your cRunners.IsRunning check which is true as simulation is in progress.

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

You should look at CaseRunnerMonitor if you want a call-back when the simulation is complete.

Edit:

can you show me an example of using CaseRunnerMonitor? both definition of the derived class and its implementation.

Create your monitor class:

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

Use it:

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

See also "Running and monitoring a Simulation" in SimulationSystem API documentation.




回答2:


Ah, OK. I didn't realise you were trying to load results with the CaseMonitor.

I'm afraid the short answer is "No, you can't know when Petrel has loaded results".

The long answer is Petrel will automatically load results if the option is set in the Case arguments. (Define Simulation Case -> Advance -> Automatically load results).

In 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. 

You will have to poll SimulationRoot.SummaryResults (using the same API you are already using) after case has finished. You should use the CaseRunnerMonitor we discussed to determine when to start doing this, rather than the System.Diagnostics.Process[] parray = System.Diagnostics.Process.GetProcesses(); code you currently have.



来源:https://stackoverflow.com/questions/23653102/how-to-run-a-simulation-case-using-caserunner-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!