栏目分类
热点资讯
你的位置:软件软件开发要多少钱 > 软件定制开发 > 软件开发公司 OpenFOAM编程案例|05 并行编程

软件定制开发

软件开发公司 OpenFOAM编程案例|05 并行编程

发布日期:2024-08-09 03:32    点击次数:145

本案例演示诈欺OpenFOAM进行并行料想的基础循序。

CFD料想当然离不开并行料想,在对大界限问题进行料想时,OpenFOAM也不错使用并行模式。然则诈欺并行模式进行料想时,可能需要修改一些循序代码,尤其是在需要赢得全场信息时。本文以一个浅近的案例演示并行循序编写时需要防护的一些问题。

1 文献准备

诈欺底下的号召准备文献:

runfoamNewApp demo5cd demo5 && touch createFields.H

如下图所示。

图片

在历史同期号码中,组选0-9号码出现次数为:7出现3次,号码0、6出现4次,号码2、5出现6次,号码1出现7次,号码3、9出现8次,号码4、8出现10次,本期看好两码3、9出现。

2 循序代船埠文献createFields.H
// 界说一些物理量 Info << "读取transportProperties文献" << endl;IOdictionary transportProperties(    IOobject    (        "transportProperties", //文献名        runTime.constant(),     //文献旅途        mesh,        IOobject::MUST_READ_IF_MODIFIED,        IOobject::NO_WRITE    ));// 读取物理属性nudimensionedScalar nu(    "nu",    dimViscosity,    transportProperties);  Info << "读取速率U" << endl;volVectorField U(    IOobject    (        "U",        runTime.timeName(),        mesh,        IOobject::MUST_READ,        IOobject::AUTO_WRITE    ),    mesh); Info << "读取压力场p" << endl;volScalarField p(    IOobject    (        "p",        runTime.timeName(),        mesh,        IOobject::MUST_READ,        IOobject::AUTO_WRITE    ),    mesh); 
源文献demo5.C
#include "fvCFD.H"// * * * * * * * * * * * * * * * * * * * * //int main(int argc, char *argv[]){    // 查验案例文献组织结构    #include "setRootCase.H"    // 创建runTime对象    #include "createTime.H"    // 创建fvMesh对象    #include "createMesh.H"     /*    关于并交运行的案例,料想域被判辨成几许个processor网格。    每个子域齐在单独的经管器中运行,并保存网格、U或p等对象的实例,就像串行料想相似。    Pout是每个经管器齐不错写入的流,而Info只可由head进度(Processor0)使用。    在并行料想时,若思要输出料想节点的信息,需要使用Pout流    */    Pout << "这是经管器No:" << Pstream::myProcNo() << ",网格数目:" << mesh.C().size() << endl;     // 在经管器之间交换信息,需要调用迥殊的OpenMPI进度    // 料想子域的体积    scalar meshVolume;    forAll(mesh.V(), cellI)    {        meshVolume += mesh.V()[cellI];    }    Pout << "本经管器上的网格体积:" << meshVolume << endl;     // 料想整个的子域的网格体积,使用全局约简函数reduce    reduce(meshVolume, sumOp<scalar>());    // 诈欺Info在head节点上输出信息    Info << "整个经管器上的总网格数目:" << returnReduce(mesh.C().size(), sumOp<label>()) << endl         << "网格总体积:" << meshVolume << endl;     /*    在并行约简时不错践诺多样操作,如前边使用的sumOp模板所刻画的乞降是其中之一。    其他越过有效的操作还有minOp和maxOp,远离用于索取最小值与最大值。    防护必须添加变量类型才气创建模板实例,这里是通过在尖括号中指定变量类型来完好意思的。    自界说约简操作很容易完好意思,但是需要熟悉地使用OpenFOAM中的面向对象编程,软件开发公司是以当今先跳过这一步。    */    // 在整个经管器发送一个值不错通过scatter函数来完好意思    Pstream ::scatter(meshVolume);    Pout << "当今本经管器上的网格体积为:" << meshVolume << endl;     /*    查验某些实验在整个经管器上的散播时时很有效。    不错使用List来完成,列表中的每个元素只由一个经管器写入。    */    List<label> nInternalFaces(Pstream::nProcs());    List<label> nBoundaries(Pstream::nProcs());    nInternalFaces[Pstream::myProcNo()] = mesh.Cf().size();    nBoundaries[Pstream::myProcNo()] = mesh.boundary().size();     // 在head节点汇注信息    Pstream::gatherList(nInternalFaces);    Pstream::gatherList(nBoundaries);    // 也不错散布数据    Pstream::scatterList(nInternalFaces);    Pstream::scatterList(nBoundaries);     /*    巧合代仅在头节点上践诺操作也很有效    */    if (Pstream::master())    {        forAll(nInternalFaces, i)        {            // 这里其实不错胜利使用Info,不需要进行master判断            Pout << "经管器[" << i << "]领有 " << nInternalFaces[i]                << " 个里面面,以及 " << nBoundaries[i] << " 个界限面" << endl;        }    }     /*    由于区域判辨,导致经管器之间的接壤面变为了patch,意味着每个子域齐将processor界限视为界限    */    forAll(mesh.boundary(), patchI)    {        Pout << "Patch " << patchI << " 的称号为 " << mesh.boundary()[patchI].name() << endl;    }     /*    在搜索processor界限时,不错先判断其类型    */    forAll(mesh.boundary(), patchI)    {        const polyPatch &pp = mesh.boundaryMesh()[patchI];        if (isA<processorPolyPatch>(pp))        {            Pout << "Patch " << patchI << " 的称号为:" << mesh.boundary()[patchI].name()                << " ,其界说在processor界限上." << endl;        }    }     /*    这是Tutorial 2中的代码的一个示例,该代码已调遣为并交运行。    在OpenFOAM中,时时会将大部分声明代码放到单独的.h文献中,以使求解器自己的代码更具可读性。    除了setRootCase、createTime和createMesh(它们是通用的)除外,    一个非往往见的头文献是createFields,其关于每个求解器时时是唯独的。    这里还是将经管建立物理场和输运常量的整个代码放到了这个头文献中。    */    #include "createFields.H"    const dimensionedVector originVector("x0", dimLength, vector(0.05, 0.05, 0.005));    volScalarField r(mag(mesh.C() - originVector));     // 料想网格中心到指定点的最大距离,全局参数需要改酿成并行代码    const scalar rFarCell = returnReduce(max(r).value(), maxOp<scalar>());     scalar f(1.0);    Info << "\n运转时辰迭代" << endl;     while (runTime.loop())    {        // 料想压力,确保量纲一致        p = Foam::sin(2. * constant::mathematical::pi * f *                      runTime.time().value()) / (r / rFarCell + dimensionedScalar("small", dimLength, 1e-12)) *            dimensionedScalar("tmp", dimensionSet(0, 3, -2, 0, 0), 1.);         // 并行料想必须修正界限        p.correctBoundaryConditions();         U = fvc::grad(p) * dimensionedScalar("tmp", dimTime, 1.0);        runTime.write();    }    // * * * * * * * * * *  * * * * * * * * * * //    Foam::Info << nl;    runTime.printExecutionTime(Info);    Info << "End\n" << endl;    return 0;}

诈欺号召wmake编译循序,确保莫得失实或教学信息,如下图所示。

图片

3 测试循序

这里使用cavity的案例,并行料想需要添加decomposeParDict字典。插足案例根旅途,运行底下的号召添加字典文献:

foamGetDict decomposeParDict

诈欺decomposeParDict字典文献指定并行分区样式。这里使用的字典文献如下:

FoamFile{    version     2.0;    format      ascii;    class       dictionary;    location    "system";    object      decomposeParDict;}// * * * * * * * * * * * * * * * * * // numberOfSubdomains 4;method hierarchical;hierarchicalCoeffs{    n               (4 1 1);    delta 0.0001;    order           xyz;}

插足案例根旅途,运行底下的号召运行案例:

blockMeshdecomposeParmpirun -np 4 demo5 -parallel

运行成果如下图所示,不错看到并行模式赢得了正确的信息。

图片

软件开发

(罢了)

本站仅提供存储行状,整个实验均由用户发布,如发现存害或侵权实验,请点击举报。