吾生有涯 学海无涯
析模有界 知识无界

OpenFOAM编程案例|07 自定义库

本文演示在OpenFOAM中自定义库的基本过程。

有时候为了数据封装的需要,可以将特殊的代码先编译成库,然后在其他的代码中对库加以调用。本案例演示此过程。

1 文件准备

这里将库文件、功能文件以及测试文件分开。所有的文件都放置在run文件夹下。

使用下面的命令创建文件结构。

run
mkdir demo7 && cd demo7
mkdir customLibrary && cd customLibrary
mkdir Make
touch customLibrary.H customLibrary.C
touch Make/files Make/options
cd ..
foamNewApp demo7

创建完毕后的文件结构如下所示。

2 库的定义与编译

  • 修改customLibrary/Make/files文件
customLibrary.C
LIB = $(FOAM_USER_LIBBIN)/libcustomLibrary

注意这里不再是之前案例的EXE了,而是换成了LIB

  • 修改customLibrary/Make/options文件
EXE_INC = 
    -I$(LIB_SRC)/finiteVolume/lnInclude 
    -I$(LIB_SRC)/meshTools/lnInclude
 
EXE_LIBS = 
    -lfiniteVolume
    -lmeshTools
  • 修改头文件customLibrary/customLibrary.H
#include "fvCFD.H"
// 在头文件中声明函数
scalar computeR(const fvMesh &mesh,volScalarField & r, dimensionedVector x0);
void computeU(const fvMesh & mesh, volVectorField &U, word pname="p");

头文件中只是声明了两个函数。

  • 修改源文件customLibrary/customLibrary.C
#include "customLibrary.H"

// 这两个函数之前的案例中使用过,就不重复介绍了
scalar computeR(const fvMesh &mesh,volScalarField &r, dimensionedVector x0)
{
    r = mag(mesh.C()-x0);
    return returnReduce(max(r).value(),maxOp());
}
 
void computeU(const fvMesh &mesh, volVectorField &U,word pName)
{
    const volScalarField &pField = mesh.lookupObject(pName);
    U = fvc::grad(pField)*dimensionedScalar("tmp",dimTime,1.0);
}
 

所有文件修改完毕后,进入customLibrary路径下,执行命令wmake进行编译。

可以看到在$FOAM_USER_LIBBIN路径下生成了一个名为libcustomLibrary.so的动态库文件。

3 功能程序定义

进入demo7目录下。利用命令touch createFields.H创建文件,此时demo7文件夹中的文件结构如下:

  • 修改files文件
demo7.C
EXE = demo7
  • 修改options文件,注意编译为库的话指定的是EXE_LIBS,还要注意包含头文件
EXE_INC = 
    -I$(LIB_SRC)/finiteVolume/lnInclude 
    -I$(LIB_SRC)/meshTools/lnInclude
    -I../customLibrary
 
EXE_LIBS = 
    -lfiniteVolume 
    -lmeshTools 
    -L$(FOAM_USER_LIBBIN) -lcustomLibrary

注意库文件的加载,先加载路径后加载库名称,把库名称前面的lib去掉。

  • 编写createFields.H头文件
// createFields.H中包含了各种参数及物理场的读入
Info << "读取tranportProperties文件n" << endl;
 
IOdictionary transportProperties
(
    IOobject
    (
        "transportProperties",
        runTime.constant(),
        mesh,
        IOobject::MUST_READ_IF_MODIFIED,
        IOobject::NO_WRITE
    )
)
;
 
dimensionedScalar nu
(
    "nu",
    dimViscosity,
    transportProperties
)
;
 
Info << "读取p文件"<< endl;
volScalarField p
(
    IOobject
    (
        "p",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
)
;
 
Info << "读取U文件" << endl;
volVectorField U
(
    IOobject
    (
        "U",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
)
;
  • 编写源代码demo7.C
 
#include "fvCFD.H"
// 注意文件路径
#include "../customLibrary/customLibrary.H"
 
// * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
 
// 添加两个头文件,一个创建fvMesh对象,另一个读取数据
#include "createMesh.H"
#include "createFields.H"
 
    // 定义一个向量x0,其量纲为dimLength
    const dimensionedVector originVector("x0", dimLength, vector(0.050.050.005));
    scalar f(1.0);
 
    // 定义一个标量场r,给了一个初始值r0
    volScalarField r(
        IOobject(
            "r",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE),
        mesh,
        dimensionedScalar("r0", dimLength, 0.0))
;
 
    // 利用自定义库中的computeR函数
    const scalar rFaceCell = computeR(mesh, r, originVector);
 
    Info << "Starting time loopn" << endl;
    while (runTime.loop())
    {
        Info << "Time = " << runTime.timeName() << nl << endl;
        // 利用网格距离进行压力计算,没什么特别的意义,只是随便计算
        // 场变量计算的时候需要注意量纲
        p = Foam::sin(2. * constant::mathematical::pi * f * runTime.time().value()) /
            (r / rFaceCell + dimensionedScalar("small", dimLength, 1e-12)) *
            dimensionedScalar("tmp", dimensionSet(03-200), 1.0);
        p.correctBoundaryConditions();
 
        // 利用自定义库中的computeU函数计算速度
        computeU(mesh, U);
        runTime.write();
    }
    // * * * * * * * * * * * * * * * * * * * //
    Info << nl;
    runTime.printExecutionTime(Info);
    Info << "Endn" << endl;
    return 0;
}

代码编写完毕后,可以使用wmake进行编译。

4 测试案例

利用cavity案例作为测试案例。将cavity案例拷贝到run/demo7文件夹下。

cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity .

注意demo7文件夹下的子文件夹组织形式,如下图所示。

当前目录为run/demo7,利用下面的命令进入cavity目录,生成网格并调用上面编译成功的程序。

cd cavity
blockMesh
../demo7/demo7

修改system/controlDict文件中endTime关键字的值为2,设置deltaT0.1

执行结果如下图所示。

压力场如下图所示。


(本文结束)

本篇文章来源于微信公众号: CFD之道

赞(0) 打赏
版权声明:未经允许,请勿随意用于商业用途。
文章名称:《OpenFOAM编程案例|07 自定义库》
文章链接:https://www.topcfd.cn/18646/
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到

说两句 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者吧

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册