本文是OpenFOAM编程基础系列文章的第2篇,也是自己学习的笔记,将随着学习的深入逐渐更新。本文的内容是在开源项目Basic OpenFOAM Programming Tutorials的基础上改写而来。由于原项目只有源代码和英文注释,本系列文章计划将代码进行分解、添加更加详细的注释,即是分享,也是自己学习。
从现在起,在运行案例前请检查案例的路径不包含空格!!否则会报错。
本文食用方法:
- 你可以按顺序阅读,理解代码之后再下载案例代码自己运行;或者
- 先跳到最后,下载案例代码,一遍读一边测试运行代码。
开始正文吧:
一个求解器的主程序(.c 为后缀的文件)都会包含以下代码:
#include "fvCFD.H"
int main(int argc, char *argv[])
{
// Initialise OF case
#include "setRootCase.H"
// These two create the time system (instance called runTime) and fvMesh (instance called mesh).
#include "createTime.H"
#include "createMesh.H"
// more code lines
Info<< "End\n" << endl;
return 0;
}
在编写新的求解器时,我们需要做的是根据需求在第12行的位置添加更多功能性代码。注意,程序的第9行需要检查./system/controlDict 文件是否存在,并读取其中的设置参数,若不存在则会报错,求解器无法运行:
-->FOAM FATAL ERROR:
cannot find file "/mnt/BasicOpenFOAMProgrammingTutorials-master/helloWorld/system/controlDict"
同样,第10行代码则检查./constant 文件下的网格文件是否存在, 若不存在同样会报错并退出运行:
--> FOAM FATAL ERROR:
Cannot find file "points" in directory "polyMesh" in times "0" down to constant
From function virtual Foam::IOobject Foam::fileOperation::findInstance(const Foam::IOobject&, Foam::scalar, const Foam::word&) const
in file global/fileOperations/fileOperation/fileOperation.C at line 871.
FOAM exiting
下面,将根据输入输出的数据类型分别讲解相应的代码。
1. OpenFOAM格式的字典文件
本案例以读取一个名为customProperties 的字典为例。字典的内容如下:
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
someWord myWord;
someScalar 0.01;
someBool on;
someList
(
0
1
2
);
someHashTable
(
key0 (0 0 0)
key1 (1 0 0)
);
首先,现创建一个字典类型,指定文件名称、文件路径和读取要求:
// Get access to a custom dictionary
dictionary customDict;
const word dictName("customProperties");
// Create and input-output object - this holds the path to the dict and its name
IOobject dictIO
(
dictName, // name of the file
mesh.time().constant(), // path to where the file is: ./constant
mesh, // reference to the mesh needed by the constructor
IOobject::MUST_READ // indicate that reading this dictionary is compulsory
);
可以采用以下代码检查输入的字典文件是否符合OpenFOAM的格式要求,检查通过后则将字典初始化:
// Check the if the dictionary is present and follows the OF format
if (!dictIO.typeHeaderOk<dictionary>(true))
FatalErrorIn(args.executable()) << "Cannot open specified refinement dictionary "
<< dictName << exit(FatalError);
// Initialise the dictionary object
customDict = IOdictionary(dictIO);
下面,就可以从字典中读取信息了。这里我们使用.lookup 函数实现。使用该函数不需要指定变量类型。
// Lookup which does not need to be told what type of variable we're looking for and
// uses the standard C++ stringstream syntax
word someWord;
customDict.lookup("someWord") >> someWord;
如果需要检查读取数据的类型,并且在读取的内容不存在时赋一个默认值,则可以使用以下代码:
// This template method needs to know the type of the variable and can provide
// a default value if the entry is not found in the dictionary
scalar someScalar( customDict.lookupOrDefault<scalar>("someScalar", 1.0) );
也可以从字典中读取Bool类型的数据:
// A switch is a neat feature allowing boolean values to be read from a dict,
// it supports the OpenFOAM yes/on/true/1 and no/off/false/0 values automatically.
bool someBool ( customDict.lookupOrDefault<Switch>("someBool",true) );
读取列表数据(List)和哈希表(HashTable)数据:
// Lists of values may also be read in the same way
List<scalar> someList ( customDict.lookup("someList") );
// This type of container is particularly interesting - it associates entries with
// given key values (here of word type but can be anything); useful when
// associating things by indices in a list is less handy
HashTable<vector,word> someHashTable ( customDict.lookup("someHashTable") );
最后,我们将所有读取到的数据输出到终端:
// Summarise what's been read and print in the console
Info << nl << "Read the following:" << nl << nl
<< "someWord " << someWord << nl << nl
<< "someScalar " << someScalar << nl << nl
<< "someList " << someList << nl << nl
<< "someHashTable " << someHashTable << nl << nl
<< "someBool " << someBool << nl << nl
<< endl;
2. 创建一个目录并写入一个输出文件
首先,在案例的根目录下创建一个名为postProcessing 的文件夹,然后打开新创建的文件:
// Create the output path directory; "Case/postProcessing"
fileName outputDir = mesh.time().path()/"postProcessing";
// Creathe the directory
mkDir(outputDir);
// File pointer to direct the output to
autoPtr<OFstream> outputFilePtr;
// Open the file in the newly created directory
outputFilePtr.reset(new OFstream(outputDir/"customOutputFile.dat"));
向文件中写数据可以使用以下语句实现:
// Write stuff
outputFilePtr() << "# This is a header" << endl;
outputFilePtr() << "0 1 2 3 4 5" << endl;
// Append to the imported hash table and wirte it too
someHashTable.insert("newKey", vector(1., 0., 0.));
outputFilePtr() << someHashTable << endl;
3 案例文件下载
点击下载 提取码:cjkn
|