2014-05-14 1 views
0

Je travaille actuellement sur un plug-in Petrel dans lequel je dois faire un cas de simulation (via un "For Loop"), je crée mon coureur de cas, je l'exporte et je l'exécute ... mais après avoir terminé le simulation et la fermeture de la console, je vérifie la propriété CaseRunner.IsRunning et il montre true! Cela cause que les résultats n'ont pas été chargés dans le système Petrel.Comment exécuter un cas de simulation à l'aide de la fonction CaseRunner?

J'ai essayé de charger les résultats manuellement après avoir terminé le Run de mon cas (en utilisant caserunner et en utilisant également un fichier séquentiel dans mon code) et je ne peux voir aucun résultat dans l'environnement de programmation.

Est-ce que quelqu'un a une solution pour cette situation?
Ceci est la partie connexe de mon code:

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

en fait je vérifié lorsque la fin du processus; après « cRunners.Run » le code attend la sortie du processus en utilisant:

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

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

     } 
    } 

et lorsque la console se ferme, i vérifié l'expression de cRunners.IsRunning. Cependant, je ne suis pas si expert ... pouvez-vous me montrer un exemple d'utilisation de CaseRunnerMonitor? à la fois la définition de la classe dérivée et sa mise en œuvre.

  • Tout ce que je besoin est en cours d'exécution d'un cas de simulation n fois par une boucle et après chaque accès Exécuter à ses résultats sommaires fournis.

J'ai essayé quelques scénarios différents pour obtenir mes résultats souhaités, je mets ici quelques-uns d'entre eux D'abord, je crée ma classe 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!"); 
     } 
     //… 

    } 

Et puis utilisez:

 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 

      } 
     } 

Mais la chose est que la partie des résultats de cas MyTest sont vides après que mon exécution est terminée. dans ce cas, tous les résultats sont chargés sur le pétrel lorsque la 8ème (dernière) simulation est terminée. Si je n'active pas la fonction Wait(), les 8 appels sont presque tous appelés simultanément ...

J'ai modifié mon scénario, mon rappel après chaque exécution est lu les résultats de la simulation, change quelque chose et appelle la prochaine exécution donc Je crée ma classe 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!"); 
     } 
     //… 

    } 

Et puis l'utiliser:

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

dans cette situation sans fonction besoin d'attendre() est nécessaire. Mais le problème est que j'accède aux résultats de cas MyTest dans un niveau avant la fin de l'exécution en cours. Par exemple, je peux voir les résultats de l'étape 5 via MyTest.Results lorsque l'exécution 6 est terminée alors que les résultats de l'étape 6 sont vides malgré l'achèvement de son exécution.

+0

S'il vous plaît montrez comment vous essayez de charger les résultats. – RJFalconer

+0

J'ai utilisé un code comme celui-ci après l'exécution: Slb.Ocean.Petrel.Simulation.Results.SummaryResultsProvider resultss = Slb.Ocean.Petrel.Simulation.Results.SummaryResultsProvider.CreateEclipseResultsProvider (MyTestCase); Mais rien n'était arrivé! – user3636337

+0

Les réponses ci-dessous ont-elles permis de résoudre votre problème? – RJFalconer

Répondre

0

Je vérifie la propriété CaseRunner.IsRunning et il montre true

En effet, Caserunner.Run() est non-bloquant; c'est-à-dire, il commence un autre thread pour lancer la course. Le flux de contrôle passe alors immédiatement à votre contrôle cRunners.IsRunning, ce qui est vrai lorsque la simulation est en cours.

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

Vous devriez regarder CaseRunnerMonitor si vous voulez un rappel lorsque la simulation est terminée.

Edit:

pouvez-vous me montrer un exemple d'utilisation CaseRunnerMonitor? à la fois la définition de la classe dérivée et sa mise en œuvre.

Créer votre classe moniteur:

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

utiliser:

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 

Voir aussi "La course et le suivi d'une simulation" dans la documentation API SimulationSystem.

+0

Merci beaucoup, vraiment vos explications étaient plus applicables que celles de la documentation sur l'océan. cela ne fonctionne que pour une boucle. Quand j'utilise la classe dérivée via une boucle for, le code veut exécuter tous les CaseRunners, puis va à la partie runner.RunCompleted() de la définition; – user3636337

+0

S'il vous plaît modifier votre question pour montrer le code actuel que vous avez qui se traduit par la situation que vous décrivez. (Et supprimer tout code plus pertinent de la question). Il est assez difficile de suivre où vous êtes en ce moment. – RJFalconer

+0

Je modifie la question, y at-il une idée ...?! – user3636337

0

Ah, OK. Je n'avais pas réalisé que vous essayiez de charger les résultats avec CaseMonitor. Je crains que la réponse courte soit "Non, vous ne pouvez pas savoir quand Petrel a chargé des résultats". La réponse longue est que Petrel chargera automatiquement les résultats si l'option est définie dans les arguments Case. (Définir cas de simulation -> Avancer -> Charger automatiquement les résultats).

Dans l'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. 

Vous devrez interroger SimulationRoot.SummaryResults (en utilisant la même API que vous utilisez déjà) après le cas est terminé. Vous devriez utiliser le CaseRunnerMonitor dont nous avons discuté pour déterminer quand commencer à le faire, plutôt que le code System.Diagnostics.Process[] parray = System.Diagnostics.Process.GetProcesses(); que vous avez actuellement.

Questions connexes