并行计算更新边界的问题?



  • 在网上找到一段讲解并行计算的代码

     while (runTime.loop())
    {
        Info<< "Time = " << runTime.timeName() << nl << endl;
    
        // assign values to the field;
        // sin function expects a dimensionless argument, hence need to convert
        // current time using .value().
        // r has dimensions of length, hence the small value being added to it
        // needs to match that.
        // Finally, the result has to match dimensions of pressure, which are
        // m^2 / s^-2/
        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.);
    
      // NOTE: this is needed to update the values on the processor boundaries.
      // If this is not done, the gradient operator will get confused around the
      // processor patches.
       p.correctBoundaryConditions();
    
           // calculate velocity from gradient of pressure
    	U = fvc::grad(p)*dimensionedScalar("tmp", dimTime, 1.);
    	runTime.write();
    }
    

    疑惑的是在p.correctBoundaryConditions();上一行有NOTE提醒需要执行p.correctBoundaryConditions();,否则计算p的梯度时会有问题。但是我在icoFoam中没有找到
    p.correctBoundaryConditions();,只有U.correctBoundaryConditions();,而实际上在预测步里有用到fvc::grad(p).这是什么原因呢??

    int main(int argc, char *argv[])
    {
        #include "addCheckCaseOptions.H"
        #include "setRootCase.H"
        #include "createTime.H"
        #include "createMesh.H"
    
        pisoControl piso(mesh);
    
        #include "createFields.H"
        #include "initContinuityErrs.H"
    
        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
        Info<< "\nStarting time loop\n" << endl;
    
        while (runTime.loop())
        {
            Info<< "Time = " << runTime.timeName() << nl << endl;
    
            #include "CourantNo.H"
    
            // Momentum predictor
    
            fvVectorMatrix UEqn
            (
                fvm::ddt(U)
              + fvm::div(phi, U)
              - fvm::laplacian(nu, U)
            );
    
            if (piso.momentumPredictor())
            {
                solve(UEqn == -fvc::grad(p));
            }
    
            // --- PISO loop
            while (piso.correct())
            {
                volScalarField rAU(1.0/UEqn.A());
                volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p));
                surfaceScalarField phiHbyA
                (
                    "phiHbyA",
                    fvc::flux(HbyA)
                  + fvc::interpolate(rAU)*fvc::ddtCorr(U, phi)
                );
    
                adjustPhi(phiHbyA, U, p);
    
                // Update the pressure BCs to ensure flux consistency
                constrainPressure(p, U, phiHbyA, rAU);
    
                // Non-orthogonal pressure corrector loop
                while (piso.correctNonOrthogonal())
                {
                    // Pressure corrector
    
                    fvScalarMatrix pEqn
                    (
                        fvm::laplacian(rAU, p) == fvc::div(phiHbyA)
                    );
    
                    pEqn.setReference(pRefCell, pRefValue);
    
                    pEqn.solve(mesh.solver(p.select(piso.finalInnerIter())));
    
                    if (piso.finalNonOrthogonalIter())
                    {
                        phi = phiHbyA - pEqn.flux();
                    }
                }
    
                #include "continuityErrs.H"
    
                U = HbyA - rAU*fvc::grad(p);
                U.correctBoundaryConditions();
            }
    
            runTime.write();
    
            runTime.printExecutionTime(Info);
        }
    
        Info<< "End\n" << endl;
    
        return 0;
    }
    


  • =等号类似的操作都需要correctBoundaryConditions()solve()出来的都不需要



  • @东岳 谢谢:baobao:



  • @东岳 东岳老师,现在我有点拿不准,我先建立了一个体积力f的体心场,然后利用速度U计算出体积力f,最后需要用体积力f插值成面心场phiF

    f=U*系数;
    surfaceScalarField phiF
    (
        "pihF",
        fvc::flux(rAU*f)
    );
    

    计算f=U*系数后,是否还需要更新f的边界呢



  • 如果f就是f=U*系数,就不需要。
    如果f是你需要更新边界的场,就需要,否则U*系数会抹掉你的边界信息



  • @东岳 谢谢老师,我想了下应该要更新边界。因为计算surfaceScalarField的时候,并行计算切割区域的边界面上的surfaceScalarField计算需要f的边界场,不像内部面可以通过fvc::interpolate把体心场插值成面心场


Log in to reply
 

CFD中文网 2016 - 2020 | 京ICP备15017992号-2