OpenFAOM | 子模型StochasticCollision in sprayFoam的接口 && RTS

写下本文主要为了增进对OF的理解,消化http://xiaopingqiu.github.io/2016/03/12/RTS1/https://openfoam.top/simpleRTS/#%E5%9F%BA%E7%B1%BB%E6%A8%A1%E5%9E%8B%E7%B1%BB%E5%88%ABreactionrateflamearea的内容。

 

OpenFOAM 中大部分求解器都包含多个模型,比如一个sprayFoam既要包括连续相的燃烧模型,又要包括粒子的蒸发模型,喷雾模型,这些模型可能又会细分。从 C++ 的角度来看,其实这些模型都是以类来表示的。一般来说,基类用作接口,hashTable就是在基类定义的,派生类则可能是一个具体的模型。

接下来,本文以OpenFOAM-7为基础,以sprayFoam中的lagrangian子模型stochasticCollisionModel的接口为例,说明sprayFoam里lagrangian库的子模型的接口。

子模型StochasticCollision in sprayFoam的接口

首先,sprayFoam里的关于粒子的运动都是用parcels这个对象来表述的,比如在主程序里可以找到parcels.evolve()等语句,而parcels是basicSprayCloud类的,basicSprayCloud的声明如下

namespace Foam  {   typedef SprayCloud   <   ReactingCloud   <   ThermoCloud   <   KinematicCloud   <   Cloud   <   basicSprayParcel   >   >   >       >   > basicSprayCloud;   }

说明parcels具有SprayCloud, ReactingCloud, ThermoCloud, KinematicCloud等Cloud的属性,而stochasticCollisionModel则是属于KinematicCloud的一个子模型。具体的过程如下所示:

KinematicCloud.H里定义了stochasticCollisionModel_,代码如下:

//- Stochastic collision model
autoPtr<StochasticCollisionModel<KinematicCloud<CloudType>>>    stochasticCollisionModel_;

而在KinematicCloud的构造函数里,则调用了setModels()函数,setModels()则选择了KinematicCloud的各个子模型,比如:

template<class CloudType>
void Foam::KinematicCloud<CloudType>::setModels()
{
    ...
    stochasticCollisionModel_.reset
    (
        StochasticCollisionModel<KinematicCloud<CloudType>>::New
        (
            subModelProperties_,
            *this
        ).ptr()                 // Bu 2022/1/5 : New() returns a temporary object, which is converted by .ptr() to a pointer as an argument to function reset()
    );
    ...
}

reset()的定义在src\OpenFOAM\memory\autoPtr\autoPtrI.H里,根据下面代码,可知reset()即把指针p赋给ptr_,即把上面StochasticCollisionModel<KinematicCloud<CloudType>>::New( , ).ptr()返回的指针赋给了stochasticCollisionModel_。故关键在于弄懂StochasticCollisionModel<KinematicCloud<CloudType>>::New。

//- If object pointer already set, delete object and set to given  pointer             
inline void reset(T* = nullptr);

template<class T>inline void Foam::autoPtr<T>::reset(T* p) {     if (ptr_)     {         delete ptr_;     }     ptr_ = p; }

//defination of ptr_
template<class T>class autoPtr 
{    
    //- Pointer to object         
        mutable T* ptr_;
}

提起New函数,就不得不介绍一下OpenFOAM里的RTS机制(RunTimeSelection)!RTS机制是OpenFOAM根据用户指定的关键字来选择对应的模型,通过selector即New函数来进行模型选择,通过"虚构造函数"的方式来实现通过基类类型的指针调用派生类的功能。可见,这里有可能是接口所在。(参考http://xiaopingqiu.github.io/2016/06/25/thermophysics1/的思路)。

这里,附上一张自己总结的思维导图,记录了RTS涉及到的函数的位置以及作用,可与下文对比着看。​

 RTS思维导图

RTS在本例中,Base基类指的是StochasticCollisionModel,Derived派生类指的是ORourkeCollision或者TrajectoryCollision,其中TrajectoryCollision还是ORourkeCollision的派生类,本例派生类仅取TrajectoryCollision进行说明。

根据http://xiaopingqiu.github.io/2016/03/12/RTS1/博客中记录的,RTS 机制的实现跟几个函数的调用有关:declareRunTimeSelectionTable,defineRunTimeSelectionTable,defineTypeNameAndDebug,addToRunTimeSelectionTable。规律可以总结如下:

基类类体里调用TypeName和declareRunTimeSelectionTable两个函数,类体外面调用defineTypeNameAndDebug,defineRunTimeSelectionTable和addToRunTimeSelectionTable三个函数;基类中需要一个静态New函数作为 selector。

派生类类体中需要调用TypeName函数,类体外调用defineRunTimeSelectionTable和addToRunTimeSelectionTable两个宏函数。

但其实并不一定每个模型的调用都是用的这些函数,比如本例中用到的就用defineTemplateRunTimeSelectionTable来代替defineRunTimeSelectionTable的作用。理解RTS的核心问题在于哪个函数实现了什么样的作用。下面通过代码理解每个函数的作用。

对基类BaseClass:

首先,基类头文件(src\lagrangian\intermediate\submodels\Kinematic\StochasticCollision\StochasticCollisionModel\StochasticCollisionModel.H)中部分代码如下所示:

public:
    //- Runtime type information
    TypeName("collisionModel");

    //- Declare runtime constructor selection table
    declareRunTimeSelectionTable
    (
        autoPtr,
        StochasticCollisionModel,
        dictionary,
        (
            const dictionary& dict,
            CloudType& owner
        ),
        (dict, owner)
    );

也就是说,在基类头文件里调用了两个宏函数 TypeName 和 declareRunTimeSelectionTable。

1.宏函数TypeName()的定义在src/OpenFOAM/db/typeInfo/typeInfo.H和className.H里,代码如下:

//- Declare a ClassName() with extra virtual type info
#define TypeName(TypeNameString) \
    ClassName(TypeNameString); \
    virtual const word& type() const { return typeName; }

//- Add typeName information from argument \a TypeNameString to a class.
//  Also declares debug information.
#define ClassName(TypeNameString)                                              \
    ClassNameNoDebug(TypeNameString);                                          \
    static int debug

//- Add typeName information from argument \a TypeNameString to a class.
//  Without debug information
#define ClassNameNoDebug(TypeNameString)                                       \
    static const char* typeName_() { return TypeNameString; }                  \
    static const ::Foam::word typeName

由此可知,TypeName()的作用即令typeName_()返回TypeNameString的值。

2.宏函数declareRunTimeSelectionTable的定义在src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H中,declareRunTimeSelectionTable的形参对应基类头文件的参数可知,autoPtr=autoPtr, baseType=StochasticCollisionModel, argNames=dictionary, argList=( const dictionary& dict, CloudType& owner), parList=(dict, owner),代码如下:

//- Declare a run-time selection
#define declareRunTimeSelectionTable(autoPtr,baseType,argNames,argList,parList)\
                                                                               \
    /* Construct from argList function pointer type */                         \
    typedef autoPtr<baseType> (*argNames##ConstructorPtr)argList;              \   //Bu 2022/1/2 : create a function pointer
                                                                               \
    /* Construct from argList function table type */                           \
    typedef HashTable<argNames##ConstructorPtr, word, string::hash>            \   //Bu 2022/1/2 : the value of HashTable is argNames##ConstructorPtr, the key of HashTable is word
        argNames##ConstructorTable;                                            \
                                                                               \
    /* Construct from argList function pointer table pointer */                \
    static argNames##ConstructorTable* argNames##ConstructorTablePtr_;         \
                                                                               \
    /* Table constructor called from the table add function */                 \
    static void construct##argNames##ConstructorTables();                      \   //Bu 2022/1/2 : create hash table
                                                                               \
    /* Table destructor called from the table add function destructor */       \
    static void destroy##argNames##ConstructorTables();                        \   //Bu 2022/1/2 : delete hash table
                                                                               \
    /* Class to add constructor from argList to table */                       \
    template<class baseType##Type>                                             \
    class add##argNames##ConstructorToTable                                    \
    {                             
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值