本案例演示编程实现一个在计算时进行数据处理的动态库程序。
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版本中存在一些问题,这里懒得调试了。
”(本文完毕)
清明节放假,休息!
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。