KEpsilon.C中k定义时使用的autoCreateK("k", mesh_)函数含义?



  • 最近在看湍流模型代码,发现一个小问题:比如在kEpsilon.C文件关于湍动能k的的定义:
    OpenFOAM的版本中(3.0以上)

    k_
        (
            IOobject
            (
                IOobject::groupName("k", U.group()),
                this->runTime_.timeName(),
                this->mesh_,
                IOobject::MUST_READ,
                IOobject::AUTO_WRITE
            ),
            this->mesh_
        ),
    

    foam-extend版本中(4.1)

    k_
        (
            IOobject
            (
                "k",
                runTime_.timeName(),
                U_.db(),
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            autoCreateK("k", mesh_)
        ),
    

    可以发现,OpenFOAM中k为MUST_READ,而foam-extend中k为NO_READ,但存在一个autoCreateK("k", mesh_)函数,其定义在backwardsCompatibilityWallFunctions.C中,代码如下:

    tmp<volScalarField> autoCreateK
    (
        const word& fieldName,
        const fvMesh& mesh
    )
    {
        return
            autoCreateWallFunctionField
            <
                scalar,
                RASModels::kqRWallFunctionFvPatchField<scalar>
            >
            (
                fieldName,
                mesh,
                mesh
            );
    }
    

    backwardsCompatibilityWallFunctionsTemplates.C中有autoCreateWallFunctionField的定义:

    template<class Type, class PatchType>
    tmp<GeometricField<Type, fvPatchField, volMesh> >
    autoCreateWallFunctionField
    (
        const word& fieldName,
        const fvMesh& mesh,
        const objectRegistry& obj
    )
    {
        IOobject mutHeader
        (
            "mut",
            mesh.time().timeName(),
            obj,
            IOobject::MUST_READ
        );
    
        typedef GeometricField<Type, fvPatchField, volMesh> fieldType;//起了一个别名: fieldType
    
        if (mutHeader.headerOk())//如果找到了文件路径,并读取了文件头,则为true
        {
            return tmp<fieldType>
            (
                new fieldType
                (
                    IOobject
                    (
                        fieldName,
                        mesh.time().timeName(),
                        obj,
                        IOobject::MUST_READ,
                        IOobject::NO_WRITE,
                        false
                    ),
                    mesh
                )
            );
        }
        else //如果没有找到文件路径,或无法读取文件头,返回一个新的场
        {
            Info<< "--> Upgrading " << fieldName
                << " to employ run-time selectable wall functions" << endl;
    
            // Read existing field
            IOobject ioObj
            (
                fieldName,
                mesh.time().timeName(),
                obj,
                IOobject::MUST_READ,
                IOobject::NO_WRITE,
                false
            );
    
            tmp<fieldType> fieldOrig
            (
                new fieldType
                (
                    ioObj,
                    mesh
                )
            );
    
            // rename file
            Info<< "    Backup original " << fieldName << " to "
                << fieldName << ".old" << endl;
            mvBak(ioObj.objectPath(), "old");
    
    
            PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size());
    
            forAll(newPatchFields, patchI)
            {
                if (mesh.boundary()[patchI].isWall())
                {
                    newPatchFields.set
                    (
                        patchI,
                        new PatchType
                        (
                            mesh.boundary()[patchI],
                            fieldOrig().dimensionedInternalField()
                        )
                    );
                    newPatchFields[patchI] == fieldOrig().boundaryField()[patchI];
                }
                else
                {
                    newPatchFields.set
                    (
                        patchI,
                        fieldOrig().boundaryField()[patchI].clone()
                    );
                }
            }
    
            tmp<fieldType> fieldNew
            (
                new fieldType
                (
                    IOobject
                    (
                        fieldName,
                        mesh.time().timeName(),
                        obj,
                        IOobject::NO_READ,
                        IOobject::NO_WRITE,
                        false
                    ),
                    mesh,
                    fieldOrig().dimensions(),
                    fieldOrig().internalField(),
                    newPatchFields
                )
            );
    
            Info<< "    Writing updated " << fieldName << endl;
            fieldNew().write();
    
            return fieldNew;
        }
    }
    

    问题:对于autoCreatek函数具体实现的功能还是不太明了,另外,函数

    autoCreateWallFunctionField
    <scalar, RASModels::kqRWallFunctionFvPatchField<scalar> > 
    (fieldName, mesh, mesh);
    

    是什么形式,<>内代表什么意思?
    特向各位同行请教:xinxin:


  • 管理员

    这是模板的使用

    autoCreateWallFunctionField
    <scalar, RASModels::kqRWallFunctionFvPatchField<scalar> > 
    (fieldName, mesh, mesh);
    

    template<class Type, class PatchType>
    tmp<GeometricField<Type, fvPatchField, volMesh> >
    

    是对应的,第一个scalar对应Type,第二个RASModels::kqRWallFunctionFvPatchField<scalar>对应PatchType

    所以你这么写应该也是可以的:

    autoCreateWallFunctionField
    <一个类型, 一个类型> 
    (fieldName, mesh, mesh);
    


  • @李东岳 谢谢李老师!这是调用函数模板的一种形式吧。此问题已解决!但关于autoCreatek函数的实现功能还是不太明白:mihu:


Log in to reply
 


CFD中文网 | 东岳流体学术 | 东岳流体商业 | 吉ICP备20003622号-1