你的位置:先锋娱乐 > 最新动态 > OpenFOAM编程案例|09 创建functionObject

OpenFOAM编程案例|09 创建functionObject

发布日期:2024-07-22 06:51    点击次数:51

本案例演示编程实现一个在计算时进行数据处理的动态库程序。

1 创建文件结构

可以利用工具foamNewFunctionObject创建一个functionObjects工具。本案例演示创建一个在计算时获取某边界流量信息的functionObject。

采用下面的命令:

runmkdir demo9 && cd demo9foamNewFunctionObject pipeCalccd pipeCalc

程序自动创建一个pipeCalc的文件夹,其内结构如下所示。

图片

2 编写代码

这里Make文件夹中的内容保持默认即可,程序已经帮我们准备好了。只需要编写头文件与源文件即可。

编写头文件pipeCalc.H
#ifndef pipeCalc_H#define pipeCalc_H #include "fvMeshFunctionObject.H"#include "Switch.H"#include "fvc.H"#include "volFieldsFwd.H"#include "logFiles.H"#include "addToMemberFunctionSelectionTable.H"// * * * * * * * * * * * * * * * * * * * * * * * //namespace Foam{    namespace functionObjects    {     // 继承自fvMeshFunctionObject与logFiles类        // 加基类logFiles不是必须的        class pipeCalc            : public fvMeshFunctionObject,              public logFiles         {        private:            word name_;            bool active_;            word UName_;            word faceZoneName_;            label faceZoneLabel_;            const labelList &faces_;             pipeCalc(const pipeCalc &);            void operator=(const pipeCalc &);         protected :            enum fileID            {                MAIN_FILE = 0            };             wordList createFileNames(const dictionary &dict) const;            virtual void writeFileHeader();         public:            //- 运行时类型,在案例的字典文件中必须与之对应            TypeName("pipeCalc");             //- 从Time及dictionary对象进行构造            pipeCalc(const word &name,const Time &runTime,const dictionary &dict);            //- 析构函数            virtual ~pipeCalc();                              virtual const word& name() const {return name_;}             //- 读取数据            virtual bool read(const dictionary &dict);             //- 迭代时执行一些操作,本案例不需要            virtual bool execute();             //- 在时间迭代完毕后执行一些操作,本案例不需要            virtual bool end();             //- 写入数据            virtual bool write();             virtual void timeSet();             virtual void updateMesh(const mapPolyMesh &){}            virtual void movePoints(const polyMesh&) {}        };    } }  // * * * * * * * * * * * * * * * * * * * // #endif
编辑源文件pipeCalc.C
#include "pipeCalc.H"#include "Time.H"#include "fvMesh.H"#include "addToRunTimeSelectionTable.H" namespace Foam{    namespace functionObjects    {        defineTypeNameAndDebug(pipeCalc, 0);        addToRunTimeSelectionTable(functionObject, pipeCalc, dictionary);    }}// 实现函数createFileNamesFoam::wordList Foam::functionObjects::pipeCalc::createFileNames(const dictionary &dict) const{    DynamicList<word> names(1);    const word objectType(dict.lookup("type"));    names.append(objectType);    return names;}// 利用函数writeFileHeader写入文件头信息void Foam::functionObjects::pipeCalc::writeFileHeader(){    writeHeader(file(), "Flow rate through face zone");    writeHeaderValue(file(), "Face Zone name", faceZoneName_);    writeCommented(file(), "Time[s] | Flow rate [m3s-1]");    file() << endl;}// 构造函数进行成员变量初始化Foam::functionObjects::pipeCalc::pipeCalc(    const word &name,    const Time &runTime,    const dictionary &dict)    : fvMeshFunctionObject(name, runTime, dict),      logFiles(obr_, name),      name_(name),      active_(true),      UName_("U"),       faceZoneName_(dict.lookup("faceZoneName")),      faceZoneLabel_(mesh_.faceZones().findZoneID(faceZoneName_)),      faces_(mesh_.faceZones()[faceZoneLabel_]){    read(dict);     resetNames(createFileNames(dict));    if (active_)    {        Info << "完成初始化" << type() << ": " << name_ << nl << endl;    }} Foam::functionObjects::pipeCalc::~pipeCalc(){}// 读取字典文件信息bool Foam::functionObjects::pipeCalc::read(const dictionary &dict){    if (active_)    {        UName_ = dict.lookupOrDefault<word>("UName", "U");    }     return true;} bool Foam::functionObjects::pipeCalc::execute(){    if (active_)    {    }    return true;} bool Foam::functionObjects::pipeCalc::end(){    if (active_)    {        execute();    }    return true;} void Foam::functionObjects::pipeCalc::timeSet(){}// 获取信息并写入到文件bool Foam::functionObjects::pipeCalc::write(){    if (active_)    {        // 得到速度向量        const volVectorField &U = obr_.lookupObject<volVectorField>(UName_);        // 得到网格面上的速度        surfaceVectorField Uface = fvc::interpolate(U);         scalar flowRate(0.0);        forAll(faces_,faceI)        {            // 得到指定边界面上的流量。流量等于速度向量与面积向量的点积            flowRate += Uface[faces_[faceI]] & mesh_.Sf()[faces_[faceI]];             }     // 进行并行约简       reduce(flowRate, sumOp<scalar>());    // 将约简后的数据输出       Info << "Total flow rate " << flowRate << " through "            << returnReduce(faces_.size(), sumOp<label>()) << " faces" << nl << endl;         if (Pstream::master())        {            logFiles::write();            file() << obr_.time().value() << tab << flowRate << endl;        }    }     return true;}

通过wmake编译后如下图所示。

图片

编译生成的动态库被放置在$FOAM_USER_LIBBIN文件夹中。

3 测试

修改案例的system/constrolDict文件

FoamFile{    version     2.0;    format      ascii;    class       dictionary;    location    "system";    object      controlDict;}// * * * * * * * * * * * * * * * * * * * * //application     simpleFoam;startFrom       latestTime;startTime       0;stopAt          endTime;endTime         10;deltaT          1;writeControl    runTime;writeInterval   50;purgeWrite      1;writeFormat     binary;writePrecision  6;writeCompression off;timeFormat      general;timePrecision   6;runTimeModifiable true; // 添加下面的语句functions{    pipeCalculator    {        //加载库        libs ("libpipeCalcFunctionObject.so");        //指定对象类型,需要与程序中所定义的TypeName保持一致        type pipeCalc;        //程序需要读取关键字faceZoneName与UName           faceZoneName planeFaceZone;        UName U;        // 指定数据输出方式与写出间隔        writeInterval timeStep;        writeInterval 1;    }} 

测试文件夹中执行命令./Allrun运行案例。

图片

此时在案例目录下生成文件postProcessing/pipeCalculator/0/pipeCalc.dat,打开该文件,其内容如下所示。

图片

文件中包含两列内容,分别为时间与流量。

注:下面的例子在v9版本下通过。在com版本中存在一些问题,这里懒得调试了。

(本文完毕)

清明节放假,休息!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。

Powered by 先锋娱乐 @2013-2022 RSS地图 HTML地图