openFOAM的源碼文件夾src
中的內容如下:
dyfluid@dyfluid:~/OpenFOAM/OpenFOAM-7/src$ ls
Allwmake genericPatchFields rigidBodyDynamics
atmosphericModels lagrangian rigidBodyMeshMotion
combustionModels mesh rigidBodyState
conversion meshTools sampling
dummyThirdParty ODE semiPermeableBaffle
dynamicFvMesh OpenFOAM sixDoFRigidBodyMotion
dynamicMesh OSspecific sixDoFRigidBodyState
engine parallel surfMesh
fileFormats Pstream thermophysicalModels
finiteVolume radiationModels topoChangerFvMesh
functionObjects randomProcesses transportModels
fvAgglomerationMethods regionCoupled triSurface
fvMotionSolver regionModels TurbulenceModels
fvOptions renumber waves
我們實際上比較關注的是其中的combustion
相關的文件夾,但是爲了讀懂那個文件夾之前,我們需要先了解openFOAM的底層實現,即文件夾OpenFOAM
。進入這個文件夾後,可以得到如下內容:
dyfluid@dyfluid:~/OpenFOAM/OpenFOAM-7/src/OpenFOAM$ ls
algorithms dimensionedTypes global interpolations matrices primitives
containers dimensionSet graph lnInclude memory
db fields include Make meshes
這其中的primitives
爲多個文件夾最終引用的文件所在位置,那麼我們從這裏開始,內容如下:
dyfluid@dyfluid:~/OpenFOAM/OpenFOAM-7/src/OpenFOAM/primitives$ ls
Barycentric hashes Random SymmTensor
Barycentric2D ints ranges SymmTensor2D
bools MatrixSpace RowVector Tensor
chars nil Scalar Tensor2D
complex nullObject septernion transform
contiguous one spatialVectorAlgebra triad
demandDrivenEntry ops SphericalTensor Tuple2
DiagTensor Pair SphericalTensor2D Vector
direction polynomialEqns strings Vector2D
functions pTraits subModelBase VectorSpace
globalIndexAndTransform quaternion Swap zero
本次閱讀的是其中的chars/char
文件夾,其中包含兩個文件:
char.H charIO.C
其中char.H
的內容如下:
namespace Foam
{
class Istream;
class Ostream; //並非iostream中的流函數,而是在Foam這個名字空間的輸出
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
char readChar(Istream&);
Istream& operator>>(Istream&, char&);
Ostream& operator<<(Ostream&, const char);
Ostream& operator<<(Ostream&, const char*);
inline bool isspace(char c)
{
return
(
c == ' '
|| c == '\n'
|| c == '\r'
|| c == '\t'
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
}
首先是名字空間的定義,這裏使用了一個新的名字空間Foam
。這裏首先定義了兩個新的類Istream
和Ostream
,並給出了四個函數聲明,以及一個inline
函數,inline
函數的作用是判斷一個char
類型是否是空格space
。
我們再來看這幾個函數的具體實現,他們在當前文件夾的charIO.C
中,主要內容如下:
#include "char.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
char Foam::readChar(Istream& is)
{
char c;
is.read(c);
return c;
}
Foam::Istream& Foam::operator>>(Istream& is, char& c)
{
is.read(c);
is.check("Istream& operator>>(Istream&, char&)");
return is;
}
Foam::Ostream& Foam::operator<<(Ostream& os, const char c)
{
os.write(c);
os.check("Ostream& operator<<(Ostream&, const char)");
return os;
}
Foam::Ostream& Foam::operator<<(Ostream& os, const char* s)
{
os.write(s);
os.check("Ostream& operator<<(Ostream&, const char*)");
return os;
}
其中使用了一個我們這裏沒有的頭文件IOstreams.H
,它位於文件夾src/OpenFOAM/db/IOstreams
,這裏我們先不管它的具體內容,直接閱讀。
第一個函數readChar
的作用是讀取文件流中的一個char
,然後check
是否合法(具體是怎麼check以後去那個文件夾看),然後將讀取的結果作爲函數的返回值返回。
第二個函數,其實是一個運算符>>
的重定義,比如如下:
Foam::Istream Is;
char a;
...
Is>>a>>b;
就代表讀取文件流中的一個char
,然後將它賦值給a
,同時return
,可以再繼續將文件流中的下一個char
再賦值給b
。return
的技巧可以讓我們的重定義運算可以連續使用,《Essential C++》提到了這一技巧,筆者以前的博客中有提到。
第三第四個函數其實是同一個運算符<<
的重定義,只不過根據輸入的是char
本身還是&char
進行了多態,對如下用法:
Os<<a<<b;
相當於現將a
輸入文件流,再將b
輸入文件流。