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预测的结果,结果高度吻合。云图见本文顶部第一张图,线图结果如下: