OpenFOAM小代码-常用函数

如得到owner和neighbour网格中心的距离?

mesh.surfaceInterpolation::deltaCoeffs() 返回的体心距离的倒数

某个patch的第一个face在boundary中的所有face中的索引

label bFacei = bm[patchi].patch().start() - mesh.nInternalFaces();

 

 

//-------------------来自CFD中文网,持续更新中..........---------------------------------

by @李东岳

计算Patch的面积

    // 计算某个patch的面积 http://www.cfd-china.com/topic/3498
    {
        label patchID = mesh.boundaryMesh().findPatchID("inlet");

        // Create a polyPatch for looping
        const polyPatch& myPatch = mesh.boundaryMesh()[patchID];
        
        // Initialize patchArea
        scalar patchArea = 0.0;
        
        // Loop trhough all faces on the polyPatch, adding their magnitude surface
        // area vectors
        forAll(myPatch, faceI)
        {
            patchArea += mesh.magSf().boundaryField()[patchID][faceI];
        } 
    }

更改壁面一层网格值

        label patchID = mesh.boundaryMesh().findPatchID("wall");
        const scalarField& TfaceCell = 
            T.boundaryField()[patchID].patchInternalField();

        k.boundaryFieldRef()[patchID] = sqrt(TfaceCell);

给定patch调用网格

如果p是一个fvPatch

const fvMesh& mesh = p.boundaryMesh().mesh();

类内调用时间步长

假定mesh_是类内可以调用的成员变量。

const scalar deltaT = mesh_.time().deltaT().value();

如果mesh_不可获取,U_可获取:

const scalar deltaT = U_.mesh().time().deltaT().value();

声明一个tmp变量

tmp<volScalarField> deltaLambdaT   
(
    volScalarField::New
    (
        "deltaLambdaT",
        mesh_,
        dimensionedScalar(dimless, 1.0)
    )   
);   

简写边界场

volScalarField::Boundary& meanUb = meanU_.boundaryFieldRef();

forAll(meanUb, patchi)
{
    fvPatchScalarField test = meanUb[patchi];
}

判断是否是固定值边界、processor边界

    forAll(mesh_.boundary(), P)                                              
    {                                                                        
        if
        (
            isA<fixedValueFvPatchScalarField>
            (
                T.boundaryField()[P]
            ) 
         ||
            isA<processorPolyPatch>(mesh_.boundaryMesh()[P])
        )
        {
        }
    }

codedFixedValue

wall
    {
        type            codedFixedValue;
        value           uniform 300; //default value
        redirectType    linearTBC; //name of new BC type
        code
        #{
        const vectorField& Cf = patch().Cf(); // get face center coordinate;
        //assume the wall is a vertical wall       
        scalar ymax = max(Cf&vector(0,1,0)); // `&` is dot product
        scalar ymin = min(Cf&vector(0,1,0));
        // Info<<"ymax="<<ymax<<",ymin="<<ymin<<nl;
        
        vectorField& vf = *this; // get the boundary field (List of vectors defined at face centers) to fill.
        //temporal coordinate, type: scalar
        scalar t =this->db().time().value(); // get time
        // temporal term
        // scalar tt = 1+0.1*sin(5*t);
        scalar tt = 1.0;
        forAll(Cf,faceI)
        {
        	//spatial coordinates, type: scalar
        	//scalar x = Cf[faceI].x();
        	scalar y = Cf[faceI].y(); 
        	//scalar z = Cf[faceI].z();
        
        	vf[faceI] = ((y-ymin)/(ymax-ymin)*500+300)*tt; 
        }
        #};
        
        //I do not know why I need to add those things
        //codeInclude
        //#{
        //    #include "fvCFD.H"
        //#};
        
        //codeOptions
        //#{
        //    -I$(LIB_SRC)/finiteVolume/lnInclude
        //#};
    }

努塞尔数

下列代码可以添加到controlDict中执行


functions
{
    coded
    {
        functionObjectLibs ( "libutilityFunctionObjects.so" );
        enabled         true;
        type            coded;
        redirectType    printMinU;
        writeControl   timeStep;
        writeInterval  1;

        codeOptions
        #{
            -I$(LIB_SRC)/meshTools/lnInclude
        #};

        codeExecute
        #{
            const volScalarField& T
            (
                mesh().lookupObject<volScalarField>("T")
            );

            const fvPatchList& patches = mesh().boundary();

            forAll(patches, patchi)
            {
                const fvPatch& currPatch = patches[patchi];

                if (mesh().time().value() == 30001)
                {
                    if (currPatch.name() == "downwall")
                    {
                        fvPatchScalarField nus = T.boundaryField()[patchi];

                        scalar L = 0.014231;
                        scalar Tref = 309.1;
                        scalar Timp = 347.6;
                        
                        nus = T.boundaryField()[patchi].snGrad()*L/(Timp - Tref);

                        forAll(T.boundaryField()[patchi], facei)
                        {
                            Pout << mesh().C().boundaryField()[patchi][facei].x()/0.014231
                                 << " " << nus[facei] << nl;
                        }
                    }
                }
            } 
       #};
    }
}

获取某个函数的计算时间

#include <chrono>
auto start = std::chrono::steady_clock::now();                                                   
// Functions here
auto end = std::chrono::steady_clock::now();                                                     
auto diff = end - start;
Info<< "Calculate nodes and weights, using " 
    << std::chrono::duration <double, std::milli> (diff).count()                                 
    << " ms" << endl;

在某个文件夹下输出scalarField

by @Samuel-Tu

    IOField<scalar> utau
    (
        IOobject
        (
            "utau",
             runTime.constant(),
            "../postProcessing",
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE 
        ),
        scalarField(totalFSize,0.0)
    );

BlockMesh-simpleGrading

处理非均一网格

blocks
(
    hex (0 1 2 3 4 5 6 7) (100 300 100)
    simpleGrading
    (
        1                  // x-direction expansion ratio
        (
            (0.2 0.3 4)    // 20% y-dir, 30% cells, expansion = 4
            (0.6 0.4 1)    // 60% y-dir, 40% cells, expansion = 1
            (0.2 0.3 0.25) // 20% y-dir, 30% cells, expansion = 0.25 (1/4)
        )
        3                  // z-direction expansion ratio
    )
);

输出yplus

functions
{
       yplus
      {
         type                   yPlus;	 
         functionObjectLibs      ("libutilityFunctionObjects.so");
         outputControl           outputTime;
         enabled                 true;
       }
}

by @Sloan

在流场中添加颗粒失踪

controlDict添加下述内容,同时需要在constant文件夹添加kinematicProperties字典文件

functions
{
    tracks
    {
        libs        ("liblagrangianFunctionObjects.so");
        type        icoUncoupledKinematicCloud;
        U           U.water;//速度场名字
    }
}

在流场中添加欧拉标量传输

controlDict添加下述内容,同时需要在0文件夹下添加s标量场,以及fvScheme、fvSolution都要做适配

functions
{
    s
    {
        type            scalarTransport;
        libs            ("libsolverFunctionObjects.so");
        resetOnStartUp  no;
        field           s;
        phi             phi.water;
    }
}

输出场的最大值最小值

    minMax
    {
        type            fieldMinMax;
        functionObjectLibs ("libfieldFunctionObjects.so");
        enabled         true;
        log             true;
        write           true;
        location        false;
        fields
        (
           m00
           U.water
        );
    }

对网格进行赋值

forAll(T, C)//遍历网格,T为场
{
    T[C] = min(nu[C], 100);//对T的第C个网格,赋值第C个网格的nu与100的最小值
}

声明多个场PtrList

PtrList<surfaceScalarField> abPosCoeff(4);                                                           
                                                                                                     
forAll(abPosCoeff, i)
{                                                                                                    
    abPosCoeff.set
    (                                                                                                
        i,                                                                                           
        new surfaceScalarField                                                                       
        (                                                                                            
            IOobject                                                                                 
            (                                                                                        
                "abPosCoeff" + name(i),                                                              
                mesh.time().timeName(),                                                              
                mesh,                                                                                
                IOobject::NO_READ,                                                                   
                IOobject::NO_WRITE                                                                   
            ),                                                                                       
            mesh,                                                                                    
            dimensionedScalar(inv(dimLength), 0.0)                                                   
        )                                                                                            
    );                                                                                               
} 

补充一个CodeStream实现充分发展的湍流入口,请东岳老师不要建议


dw为到壁面的最短距离

OpenFoam 7:

gasinlet
{
    type            fixedValue;
    value           #codeStream
    {
        codeInclude
        #{
            #include "fvCFD.H"
            #include "DynamicList.H"
        #};

        codeOptions
        #{
            -I
(LIB_SRC)/meshTools/lnInclude
        #};

	    //libs needed to visualize BC in paraview
	    codeLibs
	    #{
    	    -lmeshTools \
    	    -lfiniteVolume
	    #};

        code
        #{
            const IOdictionary& d = static_cast<const IOdictionary&>
			(
                dict.parent().parent()
            );
            const fvMesh& mesh = refCast<const fvMesh>(d.db());
            const label id = mesh.boundary().findPatchID("gasinlet");
            const fvPatch& patch = mesh.boundary()[id];

            vectorField U(patch.size(), vector(0, 0, 0));

            const scalar U_inf=93.5;
            const scalar LT=0.2;
            const scalar visco=2.3183558929634845e-06;
            const scalar deltaT=0.37*pow(visco/U_inf,0.2)*pow(LT,0.8);
            scalar dw=0.0;
            forAll(U, i)
            {
                const scalar x = patch.Cf()[i][0];
                const scalar y = patch.Cf()[i][1];
                const scalar z = patch.Cf()[i][2];
                DynamicList<scalar>  distance(4);
                distance.append(mag(y));
                distance.append(mag(y-30e-6));
                distance.append(mag(z-23e-6));
                distance.append(mag(z+23e-6));
                dw=min(distance);
                distance.clearStorage();
                scalar Ux=0.0;
                if(deltaT>dw)
                {
                    Ux=U_inf*pow(dw/deltaT,1.0/7.0);
                }
                else
                {
                    Ux=U_inf;
                }
	            U[i] = vector(Ux, 0, 0);
            }

            writeEntry(os, "", U);
        #};
    };
}


@马乔
wordHashSet unMatchedkeys(dict.toc());
forAll(names, nameI)
{
    const word& name = names[nameI];
    const entry* ePtr = dict.findEntry(name, keyType::REGEX);
    if(ePtr)
       unMatchedKeys.erase(ePtr->keyWord());
}

class derived
:public base
{
public:
    derived() {}
    void printInfo()
    {
	Info << "derived class" << endl;
    }
};

int main(int argc, char *argv[])
{
...
    derived d;
    base::store(&d);
...
}




@veen

 

fvOption小工具

根据GitHub上一个python脚本改写了一个生成fvOption的小工具 https://github.com/Veenxz/fvSchemes
用Foam没有多久,各位大佬可以多提提意见。

# version 2.0
# Based on https://github.com/Carlopasquinucci/fvSchemes
# Generation by Veenxz
# relaesed under license GPL GNU 3.0

steady = True
pseudo_transient = False
precision = 2    # First order 1 or Second order 2
unbounded = False
LUST = False
secondorder = True

maxOrtho = 80
maxSkew = 20

# Header and Footer
h = [
    "/*--------------------------------*- C++ -*----------------------------------*|",
    "| =========                 |                                                 |",
    "| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |",
    "|  \\    /   O peration     | Website:  https://openfoam.org                  |",
    "|   \\  /    A nd           | Version:  7                                     |",
    "|    \\/     M anipulation  |                                                 |",
    "\*---------------------------------------------------------------------------*/",
    "FoamFile", "{", "    version     2.0;", "    format      ascii;",
    "    class       dictionary;", '    location    "system";', "    object      fvSchemes;",
    "}",
    "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //",
    ""
]
footer = '\n// ************************************************************************* //'

nonOrthogonalCorrectors = 1
if (maxOrtho) > 80:
    print(
        'Warning: mesh is not so nice. Use 3 nonOrthogonalCorrectors in fvSolution file'
    )
    nonOrthogonalCorrectors = 3
if (maxSkew) > 8:
    print('Warning: mesh is not so nice')

if (maxOrtho) > 80:

    gradSchemes = (
        '{\n    default          cellLimited Gauss linear 0.5;\n'
           '    grad(U)          faceLimited Gauss linear 1.0;\n}'
    )
    divSchemes = (
        '{\n    div(phi,U)       Gauss linearUpwind grad(U);\n'
           '    div(phi,omega)   Gauss upwind;\n'
           '    div(phi,k)       Gauss upwind;\n'
           '    div(phi,e)       Gauss upwind;\n'
           '    div((nuEff*dev(T(grad(U))))) Gauss linear;\n}'
    )
    laplacianSchemes = (
        '{\n    default          Gauss linear limited 0.333;\n}'
    )
    snGradSchemes = (
        '{\n    default          Gauss linear limited 0.333;\n}'
    )

    blending = 0.2
    nonOrthogonalCorrectors = 3

if (maxOrtho) > 70:

    gradSchemes = (
        '{\n    default          cellLimited Gauss linear 0.5;\n'
           '    grad(U)          cellLimited Gauss linear 1.0;\n}'
    )
    divSchemes = (
        '{\n    div(phi,U)       Gauss linearUpwind grad(U);\n'
           '    div(phi,omega)   Gauss linearUpwind grad(omega);\n'
           '    div(phi,k)       Gauss linearUpwind grad(k);\n'
           '    div(phi,e)       Gauss linearUpwind grad(e);\n'
           '    div((nuEff*dev(T(grad(U))))) Gauss linear;\n}'
    )
    laplacianSchemes = (
        '{\n    default          Gauss linear limited 0.5;\n}'
    )
    snGradSchemes = (
        '{\n    default          Gauss linear limited 0.5;\n}'
    )

    blending = 0.5
    nonOrthogonalCorrectors = 3

if (maxOrtho) > 60:

    gradSchemes = (
        '{\n    default          cellMDLimited Gauss linear 0.5;\n'
           '    grad(U)          cellMDLimited Gauss linear 0.5;\n}'
    )
    divSchemes = (
        '{\n    div(phi,U)       Gauss linearUpwind grad(U);\n'
           '    div(phi,omega)   Gauss linearUpwind grad(omega);\n'
           '    div(phi,k)       Gauss linearUpwind grad(k);\n'
           '    div(phi,e)       Gauss linearUpwind grad(e);\n'
           '    div((nuEff*dev(T(grad(U))))) Gauss linear;\n}'
    )
    laplacianSchemes = (
        '{\n    default          Gauss linear limited 0.777;\n} '
    )
    snGradSchemes = (
        '{\n    default          Gauss linear limited 0.777;\n} '
    )

    blending = 0.7
    nonOrthogonalCorrectors = 2

if (maxOrtho) > 0:

    gradSchemes = (
        '{\n    default          cellMDLimited Gauss linear 0;\n'
           '    grad(U)          cellMDLimited Gauss linear 0.333;\n}'
    )
    divSchemes = (
        '{\n    div(phi,U)       Gauss linearUpwind grad(U);\n'
           '    div(phi,omega)   Gauss linearUpwind grad(omega);\n'
           '    div(phi,k)       Gauss linearUpwind grad(k);\n'
           '    div(phi,e)       Gauss linearUpwind grad(e);\n'
           '    div((nuEff*dev(T(grad(U))))) Gauss linear;\n}'
    )
    laplacianSchemes = (
        '{\n    default          Gauss linear limited 0.95;\n}'
    )
    snGradSchemes = (
        '{\n    default          Gauss linear limited 0.95;\n}'
    )

    blending = 0.8
    nonOrthogonalCorrectors = 1

if (LUST):
    gradSchemes = (
        '{\n    default          Gauss linear;\n'
           '    grad(U)          cellMDLimited leastSquares 1;\n}'
    )
    divSchemes = (
        '{\n    div(phi,U)       Gauss LUST grad(U);\n'
           '    div(phi,omega)   Gauss LUST grad(omega);\n'
           '    div(phi,k)       Gauss LUST grad(k);\n'
           '    div(phi,e)       Gauss LUST grad(e);\n'
           '    div((nuEff*dev(T(grad(U))))) Gauss linear;\n}'
    )
    laplacianSchemes = (
        '{\n    default          Gauss linear corrected;\n}'
    )
    snGradSchemes = (
        '{\n    default          Gauss linear corrected;\n}'
    )
    
    blending = 0.9
    nonOrthogonalCorrectors = 1

if (steady):
    ddtSchemes = (
        '{\n    default          steadyState;\n}'
    )
    if (pseudo_transient):
                ddtSchemes = (
                    '{\n    default          localEuler;\n}'
                )
else:
    ddtSchemes = (
        '{\n    default           CrankNicolson ' + str(blending) + ' ;\n}'
    )
    if precision == 1:
        ddtSchemes = (
            '{\n    default           Euler;\n}'
        )
    if (unbounded):
        ddtSchemes = (
            '{\n    default           backward;\n}'
        )


wallDist = (
    "{\n    method           meshWave;\n}"
)

#open fvSchemes and write inside

f = open("fvSchemes", "w")

for i in h:
	f.write(i + "\n")

f.write("ddtSchemes" + "\n")
f.write(ddtSchemes + "\n")
f.write("\n")
f.write("gradSchemes" + "\n")
f.write(gradSchemes + "\n")
f.write("\n")
f.write("divSchemes" + "\n")
f.write(divSchemes + "\n")
f.write("\n")
f.write("laplacianSchemes" + "\n")
f.write(laplacianSchemes + "\n")
f.write("\n")
f.write("snGradSchemes" + "\n")
f.write(snGradSchemes + "\n")
f.write("\n")
f.write("wallDist" + "\n")
f.write(wallDist + "\n")
f.write(footer)

f.close()

print('File fvSchemes created')

 


 



 

posted @ 2020-12-26 21:57  Lagomgom  阅读(3697)  评论(0)    收藏  举报