如何在C#控制台独立应用中调用Ocean Petrel API运行模拟工况?
首先得把问题根源说清楚:你写的代码是Petrel插件环境下的写法,但独立应用根本没有启动Petrel的完整运行时环境,所以PetrelProject.PrimaryProject会返回null,进而导致SimulationRoot.Get()抛出空引用。
Petrel的.NET API设计初衷是为插件服务的——插件运行在Petrel主程序内部,此时Petrel已经初始化了所有核心对象(比如项目、模拟根节点等)。但独立应用是在Petrel外部运行,这些对象默认都不会被实例化。
下面给你两种可行的解决方案,优先推荐第一种:
方案1:使用Petrel Automation Server(官方推荐的外部调用方式)
Petrel提供了COM自动化接口,允许外部应用通过自动化服务器来控制Petrel,这是最稳定的外部调用方式。
步骤1:启用Petrel Automation Server
打开Petrel,依次点击Tools > Options > Automation,勾选Enable Automation Server,然后重启Petrel生效。
步骤2:在项目中引用Petrel自动化COM库
在Visual Studio里,右键你的项目 → 添加引用 → COM标签页,找到Schlumberger Petrel Automation(注意版本要和你的Petrel安装版本一致),添加引用。
步骤3:改写代码使用自动化接口
下面是适配后的示例代码,你可以根据自己的需求调整:
using System; using Schlumberger.Petrel.Automation; class Program { static void Main(string[] args) { try { // 连接到运行中的Petrel自动化服务器 var petrelApp = new Application(); petrelApp.Visible = true; // 可选:显示Petrel窗口,方便调试 // 加载目标Petrel项目(替换成你自己的项目路径) var petrelProject = petrelApp.OpenProject(@"C:\Your\Project\Path\YourProject.pet"); // 获取模拟根节点 var simulationRoot = petrelProject.SimulationRoot; if (simulationRoot == null) { Console.WriteLine("当前项目中没有找到模拟根节点"); return; } // 获取第一个模拟Case(注意Petrel自动化接口的索引从1开始) var targetCase = simulationRoot.Cases[1]; if (targetCase == null) { Console.WriteLine("项目中没有找到可用的模拟Case"); return; } // 初始化Case运行器并执行模拟 var caseRunner = targetCase.GetRunner(); caseRunner.Run(); // 导出模拟结果(替换成你的导出路径) caseRunner.ExportResults(@"C:\Your\Export\Path"); Console.WriteLine("模拟运行完成!"); } catch (Exception ex) { Console.WriteLine($"出错了:{ex.Message}\n{ex.StackTrace}"); } finally { Console.ReadKey(); } } }
方案2:初始化Petrel Standalone运行时(不推荐,复杂且受限)
如果你一定要直接调用Petrel的.NET API而不通过COM自动化,可以尝试初始化Petrel的独立运行时,但这个过程坑比较多,官方支持也有限:
步骤1:引用所有必要的Petrel程序集
从Petrel安装目录(默认C:\Program Files\Schlumberger\Petrel <你的版本号>)中,添加所有Schlumberger.*开头的核心程序集引用,比如Schlumberger.Petrel.Core.dll、Schlumberger.Petrel.Simulation.dll等。
步骤2:初始化Petrel独立运行时
在代码最开头添加初始化逻辑:
using Schlumberger.Petrel.Core; using Schlumberger.Petrel.Project; // 初始化Petrel独立运行时环境 RuntimeEnvironment.Initialize(RuntimeMode.Standalone); // 加载指定的Petrel项目 PetrelProject.InitializeStandaloneProject(@"C:\Your\Project\Path\YourProject.pet");
之后你原来的代码才能正常获取PetrelProject.PrimaryProject和SimulationRoot。但注意:这种方式可能会因为缺少配置文件、许可证验证失败或依赖缺失而报错,而且不同Petrel版本的初始化逻辑可能有差异。
额外提醒
- 许可证:不管用哪种方式,都需要有效的Petrel许可证,自动化模式需要Petrel处于运行状态,Standalone模式需要许可证能正常激活。
- 版本匹配:你的应用使用的Petrel API版本必须和安装的Petrel版本完全一致,否则会出现各种兼容性问题。
- 错误处理:记得在代码中添加null检查(比如先判断
PetrelProject.PrimaryProject是否为null),避免空引用异常。
内容的提问来源于stack exchange,提问作者Vivek Acharya




