_images/ddles.JPG

ML: 代码实例-数据驱动LES

数据驱动CFD相对于经典CFD是一个非常新的研究方向。做科研有了核心代码之后,做一些修修补补的工作,一个博士就可以毕业。在2024年12月,本代码是国际上首次详细介绍基于OpenFOAM/libtorch的数据驱动LES开源代码。本文的工作,也会在LCO算法编程课上详细讲解。

本文代码进行小改,就可以修修补补做一些工作,或许有机会刊发在流体力学顶刊JFM(因为JFM在2023年2024年发表过完全一样的工作)。本文将JFM的工作进行了复现。

在阅读本文之前,要详细阅读本网站的其他资料,否则一定会看不懂。相应的代码如下。由于代码量过大,不对其进行介绍。建议系统学习OpenFOAM以及libtorch后再来理解。

步骤1,首先准备好一个瞬态求解器,按照OpenFOAM libtorch tutorial step by step设置好基本的求解器框架并进行改名,改名后编译。随后我们要替换掉其中的湍流模型;

步骤2,下面的代码用来创建神经网络:

struct NN
:
    torch::nn::Module 
{
    torch::nn::Sequential net_;

    int cel = 300;
    NN()
    {
        net_ = register_module
        (
            "net", 
            torch::nn::Sequential
            (
                torch::nn::Linear(9,cel),
                torch::nn::Tanh(),
                torch::nn::Linear(cel,cel),
                torch::nn::Tanh(),
                torch::nn::Linear(cel,cel),
                torch::nn::Tanh(),
                torch::nn::Linear(cel,cel),
                torch::nn::Tanh(),
                torch::nn::Linear(cel,1)
            )
        );
    }

    auto forward(torch::Tensor x)
    {
        return net_->forward(x);
    }
};

步骤3,将神经网络在求解器中进行包含,实现OpenFOAM与libtorch混编,典型的设置如下:

#include <torch/torch.h>
#include "fvCFD.H"
#include "viscosityModel.H"
#include "incompressibleMomentumTransportModels.H"
#include "pisoControl.H"
#include "pressureReference.H"
#include "fvModels.H"
#include "fvConstraints.H"
#include "NN.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
//...
}

步骤4,在主程序中加载训练好的神经网络。在这里下载net.pth文件。

torch::load(net, "net.pth");

步骤5,调用神经网络,对有效粘度nuML进行推理:

while (runTime.loop())
{
    Info<< "Time = " << runTime.userTimeName() << nl << endl;

    #include "CourantNo.H"
    net->eval();

    volTensorField gradU("", fvc::grad(U));

    auto inBatch = torch::full({nuML.size(), 9}, 0.0);

    forAll(nuML, celli)
    {
        inBatch[celli][0] = gradU[celli].component(tensor::XX);
        inBatch[celli][1] = gradU[celli].component(tensor::XY);
        inBatch[celli][2] = gradU[celli].component(tensor::XZ);
        inBatch[celli][3] = gradU[celli].component(tensor::YX);
        inBatch[celli][4] = gradU[celli].component(tensor::YY);
        inBatch[celli][5] = gradU[celli].component(tensor::YZ);
        inBatch[celli][6] = gradU[celli].component(tensor::ZX);
        inBatch[celli][7] = gradU[celli].component(tensor::ZY);
        inBatch[celli][8] = gradU[celli].component(tensor::ZZ);
    }

    auto yPred = net->forward(inBatch);

    forAll(nuML, celli)
    {
        nuML[celli] = yPred[celli].item<float>()/1e5 + 2e-5;;    
    }
}

步骤6,步骤5中的nuML就是神经网络预测的有效粘度,将nuML当做湍流模型预测的有效粘度即可随后进行PISO循环的计算。这个流程与经典CFD无差别。

至此,在OpenFOAM调用数据驱动LES的工作介绍完毕。相应的求解器用来进行了一个经典管道流动的LES计算。数据驱动LES模拟的结果,与经典CFD预测的结果,结果高度吻合。云图见本文顶部第一张图,线图结果如下:

_images/data_driven_LES.svg