[OpenFOAM] 编程基础 02 Input and output

发布于 2023-05-04  346 次阅读


Please refresh the page if equations are not rendered correctly.
---------------------------------------------------------------

Input and output

从现在起,在运行案例前请检查案例的路径不包含空格!!否则会报错。

一个求解器的主程序(.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(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("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("someBool",true) );

读取列表数据(List)和哈希表(HashTable)数据:

    // Lists of values may also be read in the same way
    List 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 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 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 案例文件下载

[点击下载](https://pan.baidu.com/s/1YWoPQsCVLkb4cPQcHt00Qw?pwd=cjkn
提取码:cjkn)

Everything not saved will be lost.
最后更新于 2023-05-04