You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在C#控制台独立应用中调用Ocean Petrel API运行模拟工况?

解决独立应用调用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.dllSchlumberger.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.PrimaryProjectSimulationRoot。但注意:这种方式可能会因为缺少配置文件、许可证验证失败或依赖缺失而报错,而且不同Petrel版本的初始化逻辑可能有差异。

额外提醒

  • 许可证:不管用哪种方式,都需要有效的Petrel许可证,自动化模式需要Petrel处于运行状态,Standalone模式需要许可证能正常激活。
  • 版本匹配:你的应用使用的Petrel API版本必须和安装的Petrel版本完全一致,否则会出现各种兼容性问题。
  • 错误处理:记得在代码中添加null检查(比如先判断PetrelProject.PrimaryProject是否为null),避免空引用异常。

内容的提问来源于stack exchange,提问作者Vivek Acharya

火山引擎 最新活动