速率在空间上成抛物线漫衍

发布日期:2024-06-21 16:57    点击次数:52

速率在空间上成抛物线漫衍

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.;                }            }        }   #};}

具体就概略备说明了环保,其实很容易读懂。

本站仅提供存储处事,整个内容均由用户发布,如发现存害或侵权内容,请点击举报。

下一篇:没有了