OpenFOAM代码汇总

下列代码需要在算例0文件夹中的某个场中进行植入

边界条件中定义随位置、时间变化的进口
//随位置变化
inlet
{
    type            codedFixedValue;
    name            dummy;
    value           uniform (0 0 0);
        
    redirectType    inletLaminarSquareProfile;
    code
    #{
         const vectorField& Cf = patch().Cf(); 

         const scalar H	= 0.0052; 
         const scalar Umax = 0.879542893; 

         forAll(Cf, faceI) // loop over all the patch faces
         {
            const scalar y = Cf[faceI].y() - 0.0049; 
            (*this)[faceI] = vector(Umax*(4*y/H-4*sqr(y/H)), 0, 0);
         }
     #};
}
 
//随时间变化
inlet
{
    type            uniformFixedValue;
    uniformValue    coded;

    name            pulse;

    codeInclude
    #{
        #include "mathematicalConstants.H"
    #};

    code
    #{
        return vector
        (
            0,
            0.5*(1 - cos(constant::mathematical::twoPi*x)),
            0
        );
    #};
}
边界条件中调用fvc、mesh、字典文件、时间步长
INLET
{
    type            codedFixedValue;
    value           uniform (10 0 0); 
    name            linearTBC1; 
    codeInclude
    #{
        #include "fvCFD.H"
    #};
    codeOptions
    #{
        -I$(LIB_SRC)/finiteVolume/lnInclude \
        -I$(LIB_SRC)/meshTools/lnInclude
    #};
    codeLibs
    #{
        -lmeshTools \
        -lfiniteVolume
    #};
    code
    #{
        const fvMesh& mesh = this->patch().boundaryMesh().mesh();\\调用mesh
        dictionary C = mesh.lookupObject<dictionary>("physicalProperties");
        scalar test(readScalar(C.lookup("test")));\\调用字典文件
        const fvPatch& inletPatch = this->patch();
        const scalar deltaT = mesh.time().deltaT().value();\\调用时间步长
        const volVectorField& U = mesh.lookupObject<volVectorField>("U");
        volTensorField gradU = fvc::grad(U);\\调用fvc
    #};
}
边界条件中进行计算、更改场的值
INLET
{
    type            codedFixedValue;
    value           uniform (10 0 0); 
    name            linearTBC1; 
    code
    #{
        const fvMesh& mesh = this->patch().boundaryMesh().mesh();
        // 计算inlet的面积
        label patchID = mesh.boundaryMesh().findPatchID("inlet");
        const polyPatch& myPatch = mesh.boundaryMesh()[patchID];
        scalar patchArea = 0.0;
        forAll(myPatch, faceI)
        {
            patchArea += mesh.magSf().boundaryField()[patchID][faceI];
        } 
        
        //更改U的值
        volVectorField& U = mesh.lookupObjectRef<volVectorField>("U");
    #};
}

下列代码需要在程序中植入

网格相关量、常用CFD变量
const scalarField& V = mesh.V();                            // 网格体积
const surfaceVectorField& Sf = mesh.Sf();                   // 网格面矢量
const surfaceScalarField& magSf = mesh.magSf();             // 网格面积的模
const surfaceVectorField& N = Sf/magSf;                     // 网格面法向
const label& nCells = mesh.nCells();                        // 网格单元数量
const label& nInternalFaces = mesh.nInternalFaces();        // 网格内部面数量
const meshCellZones& cellZones = mesh.cellZones();          // 网格cellZone编号
wordList zoneNames = mesh.cellZones().names();              // 网格cellZone的名字
label zoneI =  mesh.cellZones().whichZone(celli);           // 判断celli在哪个cellZone里
label i = cellZones[0][i];                                  // 网格cellZone[0]的真实网格编号
Info<< U[cellZones[0][i]];                                  // 输出cellZone[0]里所有的U的速度

volScalarField S(magSqr(symm(tgradU())));                   // 形变率的双点积
tmp<volTensorField> tgradU = fvc::grad(U);

声明字典文件、tmp体心场面心场、带单位的值、不带边界的体心场、壁面距离、场数组
IOdictionary physicalProperties
(
    IOobject
    (
        "physicalProperties",
        runTime.constant(),
        mesh,
        IOobject::MUST_READ_IF_MODIFIED,
        IOobject::NO_WRITE
    )
);

bool training = readBool(physicalProperties.lookup("training"));

volScalarField T//体心场
(
    IOobject
    (
        "T",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
);

tmp<volScalarField> deltaLambdaT//tmp体心场
(
    volScalarField::New
    (
        "deltaLambdaT",
        mesh,
        dimensionedScalar(dimless, 1.0)
    )   
);

surfaceScalarField phi//面心场
(
    IOobject
    (
        "phi",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar(dimless, 0.0)
);

dimensionedScalar DT//带单位的值
(
    "DT",
    dimensionSet(0,0,0,0,0),
    1.0
);

// 一个scalarField
volScalarField::Internal TInternal("TInternal", T);//不带边界的体心场

#include "wallDist.H"//壁面距离需要包括此头文件
volScalarField y(wallDist::New(mesh).y());

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)                                                   
        )                                                                                            
    );                                                                                               
} 
修改内部场、修改边界值
U.primitiveFieldRef() = ...
U.ref() = ...

U.boundaryFieldRef() = ...
禁用log输出
SolverPerformance<scalar>::debug = 0;
创建2套网格
fvMesh mesh1
(
    IOobject
    (
        "mesh1",
        runTime.timeName(),
        runTime,
        IOobject::MUST_READ
    )
);

fvMesh mesh2
(
    IOobject
    (
        "mesh2",
        runTime.timeName(),
        runTime,
        IOobject::MUST_READ
    )
);
读取scalar的值、读取bool的值、寻找现存的某个场
scalar RR(readScalar(generalProperties.lookup("RR")));

bool RR(readBool(generalProperties.lookup("RR")));

const volScalarField& T(mesh().lookupObject<volScalarField>("T"));
更改变量近壁网格体心值
label patchID = mesh.boundaryMesh().findPatchID("wall");
const scalarField TfaceCell 
  = T.boundaryField()[patchID].patchInternalField();
k.boundaryFieldRef()[patchID] == sqrt(TfaceCell);
判断wall边界、fixedValue边界、processor边界
#include "wallFvPatch.H"

forAll(mesh.boundary(), patchi)
{
    if (isA<wallFvPatch>(mesh.boundary()[patchi]))
    {

    }
    
    if
    (
        isA<fixedValueFvPatchScalarField>
        (
            T.boundaryField()[patchi]
        ) 
    )
    {

    }
    
    if
    (
        isA<processorPolyPatch>
        (
            mesh.boundaryMesn()[patchi]
        ) 
    )
    {

    }
}
把A的边界条件类型赋给B、强制边界条件类型
volScalarField B
(
    IOobject
    (
        "B",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar(dimless, 0.0),
    A.boundaryField().types()
);

volScalarField B
(
    IOobject
    (
        "B",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar(dimless, 0.0),
    zeroGradientFvPatchScalarField::typeName
);
强制修改const变量
volScalarField& alphat =
    const_cast<volScalarField&>(mesh().lookupObject<volScalarField>("alphat"));  
声明一个动态调整的数组
List<label> markedCell;

for (int i = 0; i < 10; i++)
{
    markedCell.append(i);
}
矩阵操作
scalarSquareMatrix squareMatrix(3, Zero);
squareMatrix(0, 0) = 4;
squareMatrix(0, 1) = 12;
squareMatrix(0, 2) = -16;
squareMatrix(1, 0) = 12;
squareMatrix(1, 1) = 37;
squareMatrix(1, 2) = -43;
squareMatrix(2, 0) = -16;
squareMatrix(2, 1) = -43;
squareMatrix(2, 2) = 98;
const scalarField S(3, 1);

LUscalarMatrix L(squareMatrix);

scalarSquareMatrix inv(3); //矩阵求逆
L.inv(inv);

scalarField x(3, Zero);
scalarField Mx = squareMatrix*x; //矩阵乘以向量

scalarField x(L.solve(S)); //计算L \cdot x = S
监控代码计算时间
#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
IOField<scalar> utau
(
    IOobject
    (
        "utau",
         runTime.constant(),
        "../postProcessing",//输出到postProcessing文件夹中
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE 
    ),
    scalarField(totalFSize,0.0)
);
对某个变量做界限
bound(S, dimensionedScalar(S.dimensions(), 0));
显性、隐性离散
fvm::ddt(T)            \\隐性时间项离散
fvm::laplacian(T)      \\隐性拉普拉斯项离散
fvm::div(phi, T)       \\隐性对流项离散
fvm::Sp(coeff, T)      \\隐性源项离散
fvm::SuSp(coeff, T)    \\依据coeff的符号进行隐性或显性源项离散
fvc::ddt(T)            \\显性时间项离散
fvc::laplacian(T)      \\显性拉普拉斯项离散
fvc::div(phi, T)       \\显性对流项离散
fvc::grad(T)           \\显性梯度项离散

下面的代码需要放到算例文件的controlDict中执行:

输出时间平均、雷诺应力、空气龄、舒适度、缓存场、热通量、多相界面、界面高度
cacheTemporaryObjects//输出缓存场需要用
(
    kEpsilon:G
);

libs//输出多相界面、界面高度需要用
(
    "libwaves.so"
);

functions
{
    #includeFunc fieldAverage(U, p, prime2Mean = yes)\\场的时间平均
    
    #includeFunc mag(UPrime2Mean)
    #includeFunc multiply(half, mag(UPrime2Mean), result = k)
    
    age
    {
        libs            ("libfieldFunctionObjects.so");
        type            age;

        diffusion       on;

        writeControl    writeTime;
        executeControl  writeTime;
    }
    
    comfort
    {
        libs            ("libfieldFunctionObjects.so");
        type            comfort;

        clothing        0.5;
        metabolicRate   1.2;
        extWork         0;
        relHumidity     60;

        writeControl    writeTime;
        executeControl  writeTime;
    }
    

    #includeFunc writeObjects(kEpsilon:G)
    
    wallHeatFlux1
    {
        type        wallHeatFlux;
        libs        ("libfieldFunctionObjects.so");
        region      fluid;
        patches     (".*Wall");
    }
    
    #includeFunc isoSurface(isoField=alpha.water, isoValue=0.5, fields=())
    
    interfaceHeight1
    {
        type            interfaceHeight;
        libs            ("libfieldFunctionObjects.so");
        locations       ((300 0 0) (450 0 0) (600 0 0));
        alpha           alpha.water;
    }
}
输出速度分量、自定义变量、自定义时间步长、马赫数、yPlus、涡量、示踪颗粒
functions
{
    #includeFunc components(U)
    
    setDeltaT
    {
        type coded;
        libs            ("libutilityFunctionObjects.so");
        writeControl    writeTime;
        executeControl  writeTime;

        code
        #{
        #};

        codeExecute
        #{
            const volVectorField& U
            (
                mesh().lookupObject<volVectorField>("U")
            ); 
            volScalarField strainRate(sqrt(2.0)*mag(symm(fvc::grad(U))));
            strainRate.write();
        #};
    }
    
    setDeltaT
    {
        type coded;
        libs            ("libutilityFunctionObjects.so");
        codeExecute
        #{
            const Time& runTime = mesh().time();
            if (runTime.userTimeValue() >= -15.0)
            {
                const_cast<Time&>(runTime).setDeltaT
                (
                    runTime.userTimeToTime(0.025)
                );
            }
        #};
    }
    
    #includeFunc MachNo
    
    #includeFunc yPlus
    
    #includeFunc Q
    
    #includeFunc vorticity
    
    #includeFunc Lambda2
    
    particles
    {
        libs        ("liblagrangianFunctionObjects.so");
        type        particles;
    }
}
}
输出重组速度场、传输的标量、某个场的最大值、阻力系数、流线图、残差、监控流率
functions
{
    #includeFunc reconstruct(phi)\\重组速度场
     
    #includeFunc scalarTransport(s)
     
    minMaxp
    {
        type        fieldMinMax;
        functionObjectLibs ("libfieldFunctionObjects.so");
        fields
        (
             U
        );
        location        no;
        writeControl    timeStep;
        writeInterval   1;
    }
    
    forces
    {
        type            forceCoeffs;
        libs            ("libforces.so");
        writeControl    timeStep;
        writeInterval   1;
    
        patches         ("motorBike.*");
        rho             rhoInf;      // Indicates incompressible
        log             true;
        rhoInf          1;           // Redundant for incompressible
        liftDir         (0 0 1);
        dragDir         (1 0 0);
        CofR            (0.72 0 0);  // Axle midpoint on ground
        pitchAxis       (0 1 0);
        magUInf         20;
        lRef            1.42;        // Wheelbase length
        Aref            0.75;        // Estimated
    }
    
    streamlines1
    {
        type            streamlines;
    
        libs            ("libfieldFunctionObjects.so");
    
        // Output every
        writeControl    writeTime;
    
        // Write format
        setFormat       vtk;
    
        // Track forward (+U) or backward (-U) or both
        direction       forward;
    
        // Names of fields to sample. Should contain above velocity field!
        fields (p U);
    
        // Steps particles can travel before being removed
        lifeTime        10000;
    
        // Number of steps per cell (estimate). Set to 1 to disable subcycling.
        nSubCycle 5;
    
        // Cloud name to use
        cloudName       particleTracks;
    
        // Seeding method.
        seedSampleSet
        {
            type        lineUniform;
            start       (-1.001 1e-7 0.0011);
            end         (-1.001 1e-7 1.0011);
            nPoints     20;
        }
    }
    
    #includeFunc streamlinesLine(funcName=streamlines, start=(0 0.5 0), end=(9 0.5 0), nPoints=24, U)
    
    #includeFunc residuals
    
    #includeFunc patchFlowRate(patch=outlet1)
    #includeFunc faceZoneFlowRate(name=fz1)
    #includeFunc patchFlowRate(patch=outlet2)
    #includeFunc faceZoneFlowRate(name=fz2)
}
输出边界积分值、场的体积分、场的平均值、转换坐标系、屏蔽迭代求解器输出
functions
{
    #includeFunc patchAverage(patch=outlet, fields=(p U))
    #includeFunc patchAverage(patch=inlet, fields=(p U)) 
    
    volFieldValue1
    {
        type            volFieldValue;
        libs            ("libfieldFunctionObjects.so");
        writeControl    writeTime;
        log             yes;
        writeFields     no;
        regionType      all;
        name            outlet;
        operation       volIntegrate;//min, max, etc.
        //weightField     phi;
        fields
        (
            alpha
        );
    }
    
    volFieldValue1
    {
        type            volFieldValue;
        libs            ("libfieldFunctionObjects.so");
        writeControl    writeTime;
        log             yes;
        writeFields     no;
        regionType      all;
        name            outlet;
        operation       volAverage;//min, max, etc.
        fields
        (
            T
        );
    }
    
    cartesianToCylindrical
    {
        type        cylindrical;
        libs        ("libfieldFunctionObjects.so");

        origin      (0 0 0);
        axis        (1 0 0);

        field       U;

        writeControl    outputTime;
        writeInterval   1;
    }
}
屏蔽迭代求解器输出
DebugSwitches
{
    SolverPerformance   0;
}
fvModels自定义源项
//fvModels如下指定
USource
{
    type            coded;
    selectionMode   all;
    field           U;

    codeAddSup
    #{
        const volVectorField& U = eqn.psi();
        vectorField& USource = eqn.source();

        const fvMesh& mesh = U.mesh();
        const DimensionedField<scalar, volMesh>& V = mesh.V();
        const volVectorField& C = mesh.C();
        scalar A = 0.919;
        scalar Cd = 0.15;

        forAll(U, i)
        {
            vector position = C[i];
            scalar pz = position.z();
            if (pz < 10.0)
            {
                USource[i] -= -Cd*A*mag(U[i])*U[i]*V[i];
            }
        }
    #};
}