本案例演示编程实现一个在计算时进行数据处理的动态库程序。
1 创建文件结构
可以利用工具foamNewFunctionObject
创建一个functionObjects工具。本案例演示创建一个在计算时获取某边界流量信息的functionObject。
采用下面的命令:
run
mkdir demo9 && cd demo9
foamNewFunctionObject pipeCalc
cd 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);
}
}
// 实现函数createFileNames
Foam::wordList Foam::functionObjects::pipeCalc::createFileNames(const dictionary &dict) const
{
DynamicList 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("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(UName_);
// 得到网格面上的速度
surfaceVectorField Uface = fvc::interpolate(U);
scalar flowRate(0.0);
forAll(faces_,faceI)
{
// 得到指定边界面上的流量。流量等于速度向量与面积向量的点积
flowRate += Uface[faces_[faceI]] & mesh_.Sf()[faces_[faceI]];
}
// 进行并行约简
reduce(flowRate, sumOp());
// 将约简后的数据输出
Info << "Total flow rate " << flowRate << " through "
<< returnReduce(faces_.size(), sumOp
通过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版本中存在一些问题,这里懒得调试了。
”
(本文完毕)
清明节放假,休息!
本篇文章来源于微信公众号: CFD之道
评论前必须登录!
注册