克山县利北食用油有限公司!

2))/(p_r*p_r))

克山县利北食用油有限公司

栏目分类
2))/(p_r*p_r))
发布日期:2024-07-06 13:26    点击次数:147

2))/(p_r*p_r))

OpenFOAM中诚然提供了好多不同类型的界限条件,但有些极度的界限类型可能依然无法斥逐(如指定某界限上随时空散播的物理量)。好在OpenFOAM允许用户自界说界限条件,因此表面上不错指定任性神志的界限条件。要斥逐我方的界限条件,不错禁受三种方式:codeStream、高层编程(High level programing)、外部形态库(如swak4foam)。

codeStream是斥逐自界说界限条件的最浅薄方法,大巨额情况下用户王人不错使用其对界限条件进行编码。若是一些界限条件无法使用codeStream斥逐,此时不错使用高层编程(即编程配置一个新的界限条件类型),天然这需要对C++和OpenFOAM API有更潜入的了解。

关于诈欺swak4foam,有兴趣的说念友不错自行查阅干系贵府,我对其了解未几。

1 诈欺codeStream斥逐界限条件

OpenFOAM大要在运行时编译、加载并实行C++代码。诈欺提醒#codeStream不错斥逐此此功能。

该提醒可在职何输入文献顶用于运行时编译此伪提醒读取要求code(必选),codeInclude(可选),codeOptions(可选)和codeLibs(可选),并使用它们生成动态代码源代码在运行时自动编译,自动生成源代码和二进制文献,而况复制到现时算例目次dynamicCode中关于浅薄的界限条件,使用codeStream是幸免对界限条件进行高等编程或使用外部库的一种很好的遴荐codeStream不错在职何字典文献中使用

注:codeStream有点雷同Fluent UDF中的DEFINE_PROFILE宏,在不惊动求解器内核的前提下使用编程的方式斥逐界限条件上物理场散播的自界说。

底下是一个codeStream应用代码片断:

// 界限称呼patch-name{    // 数值界限类型为fixedValue    type            fixedValue;    // 指定界限值禁受codeStream进行指定    value           #codeStream    {        // 底下插入编译所需的头文献        // 巨额情况下需要包含fvCFD.H        codeInclude        #{             #include "fvCFD.H"        #};         // 这里插入编译选项        // 巨额情况下如下所示保捏不变        codeOptions        #{            -I$(LIB_SRC)/finiteVolume/lnInclude \            -I$(LIB_SRC)/meshTools/lnInclude        #};        // 这里插入编译所需的库        // 巨额情况下如下所示        codeLibs        #{            -lmeshTools \            -lfiniteVolume        #};         // 这里插入源代码        code        #{         #};    };}

大巨额情况下只需要按上头的框架,填充code底下的内容即可。

2 codeStream例子

底下用几个浅薄的例子来姿色这一历程。

2.1 二维空间散播

如下需要不才图所示的计较模子中指定进口界限velocity-inlet-5的速率沿Y标的成抛物线散播。

图片

该界限的坐标界限为:x[0,0],y[0,16],z[-0.938,0.938],速率沿Y轴的散播函数为:

这里,因此速率抒发式为:

在编写速率抒发式之前,需要最初通过形态找到界限位置并大要打听界限变量。这不错通过底下的代码来斥逐:

code#{    // 这里插足到case旅途下    const IOdictionary& d = static_cast<const IOdictionary&>    (        dict.parent().parent()    );    // 打听网格数据    const fvMesh& mesh = refCast<const fvMesh>(d.db());    // 在网格数据中找到界限velocity-inlet-5的id    const label id = mesh.boundary().findPatchID("velocity-inlet-5");    // 诈欺界限id打听界限网格信息    const fvPatch& patch = mesh.boundary()[id];    // 启动化向量场,这个向量场用于为界限赋值    vectorField U(patch.size(), vector(0,上海一众乙新网络科技有限公司 0,
宁波划一马达有限公司 0));    ...    ...    ...#};

这里的代码除了界限称呼外,其他的基本不必修改。信息准备罢了后即可诈欺形态代码斥逐界限散播。

如本算例,不错禁受底下的代码:

code#{    // 这里界说公式中需要的常量    const scalar pi = constant::mathematical::pi;    const scalar U_0   = 2.;    const scalar p_ctr = 8.;    const scalar p_r   = 8.;    // 轮回打听界限上的总共网格面    // 这里等效于for (int i=0;i<patch.size();i++)    forAll(U, i)    {        // 赢得网格的y坐标        const scalar y = patch.Cf()[i][1];        // 给每一个网格指定其速率向量        U[i] = vector(U_0*(1-(pow(y - p_ctr,2))/(p_r*p_r)), 0., 0.);    }    // 将U值写入到字典中    writeEntry(os, "", U);#};

计较恶果罢了后的速率散播如下图所示。

图片

界限velocity-inlet-5上速率散播如下图所示。速率在空间上成抛物线散播,与前边预设的保捏一致。

图片

2.2 三维空间散播

如底下的三维模子。

图片

要指定进口界限auto3的速率散播为:

这个其实和前边二维模子不错相通贬责。code中形态代码如下所示:

code#{    ...    ...    ...    vectorField U(patch.size(), vector(0,美容健身 0, 0) );    const scalar s  = 0.5;     forAll(U, i)    {        // 先得到x、y、z的坐标值,然后将函数规定写入字典        const scalar x = patch.Cf()[i][0];        const scalar y = patch.Cf()[i][1];        const scalar z = patch.Cf()[i][2];        U[i] = vector((pow(z/s, 2) + pow((y-s)/s,2) - 1.0), 0, 0);    }     writeEntry(os, "", U);#};
3 codedFixedValue界限

OpenFOAM中还不错使用界限条件codeFixedValue,该界限条件由codeStream派生而来,不错采选与codeStream雷同的方式职责。codedFixedValue界限使用起来更友好,且允许打听仿真数据库的更多信息(如不错打听时候信息)。这些界限条件还不错从可运行时修改的外部字典(system/codeDict)中读取代码。

另一种界限条件codedMixed与codedFixedValue职责方式雷同,此界限条件不错打听固定值(Dirichlet BC)和梯度值(Neumann BC)。

底下使用codedFixedValue斥逐抛物线速率散播。

// 界限称呼patch-name{    // 指定类型为codeFixedValue    type            codedFixedValue;    // 指定界限启动值    value           uniform (0 0 0);    // 指定的称呼标志符    name              name_of_BC;     // 编译时所需的信息,按本体需求给    codeOptions    #{        -I$(LIB_SRC)/finiteVolume/lnInclude \        -I$(LIB_SRC)/meshTools/lnInclude    #};     codeInclude    #{        #include "fvCFD.H"        #include <cmath>        #include <iostream>    #};     code    #{        // 底下三行为步履写法,一般不必修改        const fvPatch& boundaryPatch = patch();        const vectorField& Cf = boundaryPatch.Cf();        vectorField& field = *this;         scalar U_0 = 2, p_ctr = 8, p_r = 8;         forAll(Cf, faceI)        {            field[faceI] = vector(U_0*(1-(pow(Cf[faceI].y()-p_ctr,2))/(p_r*p_r)),0,0);        }    #};}

不错看到,codeFixedValue的写法要比codeStream浮松得多。在本体应用历程中不错将其动作模板,只需要字据本体界限条件修改代码部分。字据所编写的形态代码,可能需要添加新的头文献和编译选项。需要提防,若是现时使用向量,则需要使用向量场。而若是使用标量,则需要使用标量场。使用这些界限条件的一个污点是无法查抄零时期的物理场散播,需要至少仿真迭代一次。这些界限条件最大的克己是不错从仿真数据库中仿真时候。不错通过添加以下语句打听时候:

this -> db().time.value()

如底下构造一个与时候干系的界限条件:

不错禁受底下的形态代码:

code#{    const fvPatch& boundaryPatch = patch();    const vectorField& Cf = boundaryPatch.Cf();    vectorField& field = *this;     scalar U_0 = 2, p_ctr = 8, p_r = 8;    // 得到时候    scalar t = this->db().time().value();     forAll(Cf, faceI)    {        field[faceI] = vector(sin(t)*U_0*(1-(pow(Cf[faceI].y()-p_ctr,2))/(p_r*p_r))),0,0);    }#};
4 codedFixedValue例子

这里举一个使用codedFixedValue同期贬责标量场与矢量场的例子。

如底下的计较模子,需要为图中深色位置指定速率场(矢量)与体积分数(标量)。浅薄起见,这里只展示代码部分。

图片

在0/U文献中指定速率场:

加西亚电子电器股份有限公司
leftWall{    type            codedFixedValue;    value           uniform (0 0 0);    name            inletProfile1;     code    #{        const fvPatch& boundaryPatch = patch();        const vectorField& Cf = boundaryPatch.Cf();        vectorField& field = *this;         scalar minz = 0.4;        scalar maxz = 0.6;        scalar miny = 0.5;        scalar maxy = 0.7;         scalar t = this->db().time().value();         forAll(Cf, faceI)          {             if ((Cf[faceI].z() > minz) &&                (Cf[faceI].z() < maxz) &&                (Cf[faceI].y() > miny) &&                (Cf[faceI].y() < maxy))            {                if ( t < 1.)                {                    field[faceI] = vector(1,0,0);                }                else                {                    field[faceI] = vector(0,0,0);                }            }        }    #};}

在alpha.water文献中指定界限上水相的体积分数:

leftWall{    type codedFixedValue;    value uniform 0;    Name inletProfile2;     code    #{        const fvPatch &boundaryPatch = patch();        const vectorField &Cf = boundaryPatch.Cf();        scalarField &field = *this;         field = patchInternalField();         scalar minz = 0.4;        scalar maxz = 0.6;        scalar miny = 0.5;        scalar maxy = 0.7;         scalar t = this->db().time().value();        forAll(Cf, faceI)        {            if (                (Cf[faceI].z() > minz) &&                (Cf[faceI].z() < maxz) &&                (Cf[faceI].y() > miny) &&                (Cf[faceI].y() < maxy))            {                if (t < 1.)                {                    field[faceI] = 1.;                }                else                {                    field[faceI] = 0.;                }            }        }   #};}

具体就不精通解说了美容健身,其实很容易读懂。

本站仅提供存储功绩,总共内容均由用户发布,如发现存害或侵权内容,请点击举报。