openFOAM中的Scalar

位于路径src/OpenFOAM/primitives/Scalar

标量,其实就是浮点数。但是浮点数具有不同的精度,最终文件将根据宏的设置决定程序使用哪种精度

文件依赖关系如下:
在这里插入图片描述

注意这里大小写的scalar是两个文件,大写的Scalar是各个精度的浮点数的依赖文件,而这些具体的精度的实现又是小写的scalar的实现

floatScalar

这里给出其中一个文件的具体实现方式,其余的类似
头文件内容如下:

typedef float floatScalar;

定义最大最小的浮点数
floatScalarVGreat  floatScalarVSmall
floatScalarSmall   floatScalarGreat
floatScalarRootVGreat  floatScalarRootVSmall 
floatScalarRootGreat  floatScalarRootSmall

给定函数readScalar(const char* buf, floatScalar& s)
{
    char* endPtr;
    s = strtof(buf, &endPtr);

    return (*endPtr == '\\0');
}

//注意这里很重要
#define Scalar floatScalar
#define ScalarVGreat floatScalarVGreat
#define ScalarVSmall floatScalarVSmall
#define ScalarRootVGreat floatScalarRootVGreat
#define ScalarRootVSmall floatScalarRootVSmall
#define readScalar readFloatScalar

其他若干基础函数

.C文件的内容如下

#define Scalar floatScalar
#define ScalarVGreat floatScalarVGreat
#define ScalarVSmall floatScalarVSmall
#define ScalarRootVGreat floatScalarRootVGreat
#define ScalarRootVSmall floatScalarRootVSmall
#define readScalar readFloatScalar
#include "Scalar.C"   //这里添加了大写的Scalar.C
#undef Scalar
#undef ScalarVSmall
#undef ScalarVSmall
#undef ScalarRootVGreat
#undef ScalarRootVSmall
#undef readScalar

实际上这些宏定义在Scalar.C中被使用,因为不同的浮点精度要实现相同的功能,所以通过将类名称统一成Scalar,就可以给出统一的代码。比如说,如果是doubleScalar,那么.C文件中的内容为:

#define Scalar doubleScalar
#define ScalarVGreat doubleScalarVGreat
#define ScalarVSmall doubleScalarVSmall
#define ScalarRootVGreat doubleScalarRootVGreat
#define ScalarRootVSmall doubleScalarRootVSmall
#define readScalar readDoubleScalar
#include "Scalar.C"
#undef Scalar
#undef ScalarVGreat
#undef ScalarVSmall
#undef ScalarRootVGreat
#undef ScalarRootVSmall
#undef readScalar

Scalar

头文件内容如下:

class pTraits<Scalar>  //pTraits是用来帮基础类实现构造函数和文件流函数的模板
{
    Scalar p_;  //Scalar在前面已经宏定义为对应的类型
public:
    typedef Scalar cmptType;
    typedef label labelType;

    static const direction dim = 3;   //- Dimensionality of space
    static const direction rank = 0;  //- Rank of Scalar is 0
    static const direction nComponents = 1; //- Number of components in Scalar is 1

    若干支持性的成员变量
    构造函数和析构函数
};
sign minMod pow dot等等功能性函数
readScalar  >>  <<等文件流操作    

.C文件中只给出了对应的函数的实现以及成员变量的初始化

const char* const pTraits<Scalar>::typeName = "scalar";
const Scalar pTraits<Scalar>::zero = 0.0;
const Scalar pTraits<Scalar>::one = 1.0;
const Scalar pTraits<Scalar>::min = -ScalarVGreat;
const Scalar pTraits<Scalar>::max = ScalarVGreat;
const Scalar pTraits<Scalar>::rootMin = -ScalarRootVGreat;
const Scalar pTraits<Scalar>::rootMax = ScalarRootVGreat;

其他非inline函数的实现

相当于所有的浮点精度有相同的功能,这些功能通过将类型统一定义为Scalar然后统一实现

这里有一个我不太明白的点,这里的标量在openFOAM是指单个的数据,所以
static const direction nComponents = 1; //- Number of components in Scalar is 1
但是这里还给出了维度,这个代表三维空间吗?等后续理解了再来修改
static const direction dim = 3; //- Dimensionality of space

scalar

其实这个文件是我们平时在其他程序中添加的头文件,头文件内容如下:

#if defined(WM_SP)
// Define scalar as a float
namespace Foam
{
    typedef floatScalar scalar;

    static const scalar great = floatScalarGreat;
    static const scalar rootGreat = floatScalarRootGreat;
    static const scalar vGreat = floatScalarVGreat;
    static const scalar rootVGreat = floatScalarRootVGreat;
    static const scalar small = floatScalarSmall;
    static const scalar rootSmall = floatScalarRootSmall;
    static const scalar vSmall = floatScalarVSmall;
    static const scalar rootVSmall = floatScalarRootVSmall;
}
#elif defined(WM_DP)
// Define scalar as a double
namespace Foam
{
    typedef doubleScalar scalar;
    ....
}
#elif defined(WM_LP)
// Define scalar as a long double
namespace Foam
{
    typedef longDoubleScalar scalar;
    ...
}
#else
    #error "Precision not set, please set either WM_SP, WM_DP or WM_LP"
#endif

//- Deprecated limit constant for backward-compatibility
namespace Foam
{
    static const scalar GREAT = great;
    static const scalar ROOTGREAT = rootGreat;
    static const scalar VGREAT = vGreat;
    static const scalar ROOTVGREAT = rootVGreat;
    static const scalar SMALL = small;
    static const scalar ROOTSMALL = rootSmall;
    static const scalar VSMALL = vSmall;
    static const scalar ROOTVSMALL = rootVSmall;
}

若干Gamma函数相关的函数

.C文件则是其中非inline函数的实现。

就是说根据我们定义的宏为WM_SP还是WM_DP还是WM_LP,决定我们最终使用哪个精度作为scalar的最终精度。文件只不过另外添加了一些函数

文件流的操作

最后讲讲scalar.H中的一个文件流操作,这个非常常用,所以单独拿出来说:

scalar readScalar(Istream& is)
{
    scalar rs;
    is >> rs;

    return rs;
}

我们提供一个文件流,这里创建了一个标量rs,然后将文件流>>rs,注意这里的>>进行了操作符重定义。然后将得到的标量rs返回。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片