Skip to content
  • 最新
  • 版块
  • 东岳流体
  • 随机看[请狂点我]
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
CFD中文网

CFD中文网

  1. CFD中文网
  2. OpenFOAM
  3. 重新看icoFoam

重新看icoFoam

已定时 已固定 已锁定 已移动 OpenFOAM
7 帖子 4 发布者 5.9k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 史 离线
    史 离线
    史浩 神
    写于 最后由 编辑
    #1

    今天重新看OpenFOAM中的icoFoam求解器,有个疑问:在压力修正过程中,感觉每次求解的压力方程中的系数都没有变化。压力修正过程代码如下,压力方程中的rAU和HbyA都是从动量预测方程(UEqn)求出的,UEqn并没有随着U变化而变化,所以压力方程按理并没有发生变化,但是PISO算法中,压力方程中的系数是要随着速度的更新而更新的。那修改压力方程中系数的部分在什么地方?

             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();
             }
    

    让我们随波逐流

    队长别开枪队 1 条回复 最后回复
  • 队长别开枪队 离线
    队长别开枪队 离线
    队长别开枪 超神
    在 中回复了 史浩 最后由 编辑
    #2

    @史浩 UEqn.H()是关于U的一个函数,因此每次迭代更新U以后也会更新phiHbyA。

    1 条回复 最后回复
  • 李东岳李 离线
    李东岳李 离线
    李东岳 管理员
    写于 最后由 李东岳 编辑
    #3

    没有修正压力系数。这是可以理解的因为库郎数的作用瞬态计算时间布长内的变化并没有稳态计算那么大。可以这样想:

    1. 如果修正压力系数
    2. 如果每次求解一次压力、更新一次速度

    你就变成了SIMPLE

    http://dyfluid.com/index.html
    需要帮助debug算例的看这个 https://cfd-china.com/topic/8018

    1 条回复 最后回复
  • winsway_zeroW 离线
    winsway_zeroW 离线
    winsway_zero
    写于 最后由 编辑
    #4
    volScalarField rAU(1.0/UEqn.A());
    

    按照道理说这个应该是矢量场才对,因为三个方向volVectorField。

    李东岳李 1 条回复 最后回复
  • 李东岳李 离线
    李东岳李 离线
    李东岳 管理员
    在 中回复了 winsway_zero 最后由 编辑
    #5

    @winsway_zero 是三个方向,但是他们的对角线元素是一样的,

    http://dyfluid.com/index.html
    需要帮助debug算例的看这个 https://cfd-china.com/topic/8018

    winsway_zeroW 1 条回复 最后回复
  • winsway_zeroW 离线
    winsway_zeroW 离线
    winsway_zero
    在 中回复了 李东岳 最后由 编辑
    #6

    @李东岳 如果只是离散内部面是相同的,但是将边界的影响引入到了对角线上的Ap系数后,对角线系数就不一样了。比如Wall边界条件,里面涉及到了应力的分解:
    3e470f68-dd83-4126-9382-a0a66d4ac225-image.png

    1 条回复 最后回复
  • winsway_zeroW 离线
    winsway_zeroW 离线
    winsway_zero
    写于 最后由 winsway_zero 编辑
    #7

    @李东岳 我下面仔细推导了一下:
    首先 rAU(1.0/UEqn.A());,这个公式的计算得到的结果是:

    对角系数

    这是A()函数:

     template<class Type>
     Foam::tmp<Foam::volScalarField> Foam::fvMatrix<Type>::A() const
     {
         tmp<volScalarField> tAphi
         (
             volScalarField::New
             (
                 "A("+psi_.name()+')',
                 psi_.mesh(),
                 dimensions_/psi_.dimensions()/dimVol,
                 extrapolatedCalculatedFvPatchScalarField::typeName
             )
         );
     
         tAphi.ref().primitiveFieldRef() = D()/psi_.mesh().V();
         tAphi.ref().correctBoundaryConditions();
     
         return tAphi;
     }
     
    

    这是D()对角系数的平均化处理

     template<class Type>
     Foam::tmp<Foam::scalarField> Foam::fvMatrix<Type>::D() const
     {
         tmp<scalarField> tdiag(new scalarField(diag()));
         addCmptAvBoundaryDiag(tdiag.ref());
         return tdiag;
     }
    

    边界对对角系数的影响:

     template<class Type>
     void Foam::fvMatrix<Type>::addCmptAvBoundaryDiag(scalarField& diag) const
     {
         forAll(internalCoeffs_, patchi)
         {
             addToInternalField
             (
                 lduAddr().patchAddr(patchi),
                 cmptAv(internalCoeffs_[patchi]),
                 diag
             );
         }
     }
    

    从上面的代码可以得到:
    $$
    A_p=\frac{\bar{D}}{\Delta V}
    $$
    其中:
    $$
    \bar{D}=average(a_p')+diag
    $$
    式子中average(Ap')表示的是边界对主对角线系数的影响的平均;diag表示的是内部面离散的主对角线系数。

    周围系数作为源项:

    H()

     template<class Type>
     Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
     Foam::fvMatrix<Type>::H() const
     {
         tmp<GeometricField<Type, fvPatchField, volMesh>> tHphi
         (
             GeometricField<Type, fvPatchField, volMesh>::New
             (
                 "H("+psi_.name()+')',
                 psi_.mesh(),
                 dimensions_/dimVol,
                 extrapolatedCalculatedFvPatchScalarField::typeName
             )
         );
         GeometricField<Type, fvPatchField, volMesh>& Hphi = tHphi.ref();
     
         // Loop over field components
         for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
         {
             scalarField psiCmpt(psi_.primitiveField().component(cmpt));
     
             scalarField boundaryDiagCmpt(psi_.size(), 0.0);
             addBoundaryDiag(boundaryDiagCmpt, cmpt);
             boundaryDiagCmpt.negate();
             addCmptAvBoundaryDiag(boundaryDiagCmpt);
     
             Hphi.primitiveFieldRef().replace(cmpt, boundaryDiagCmpt*psiCmpt);
         }
     
         Hphi.primitiveFieldRef() += lduMatrix::H(psi_.primitiveField()) + source_;
         addBoundarySource(Hphi.primitiveFieldRef());
     
         Hphi.primitiveFieldRef() /= psi_.mesh().V();
         Hphi.correctBoundaryConditions();
     
         typename Type::labelType validComponents
         (
             psi_.mesh().template validComponents<Type>()
         );
     
         for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
         {
             if (validComponents[cmpt] == -1)
             {
                 Hphi.replace
                 (
                     cmpt,
                     dimensionedScalar(Hphi.dimensions(), 0)
                 );
             }
         }
     
         return tHphi;
     }
    
     template<class Type>
     void Foam::fvMatrix<Type>::addBoundaryDiag
     (
         scalarField& diag,
         const direction solveCmpt
     ) const
     {
         forAll(internalCoeffs_, patchi)
         {
             addToInternalField
             (
                 lduAddr().patchAddr(patchi),
                 internalCoeffs_[patchi].component(solveCmpt),
                 diag
             );
         }
     }
    

    这里面的求解过程包含了:
    $$
    H=\frac{\left [-\sum a_{\mathbf{N}}\mathbf{U_N} + (\mathbf{b}+\mathbf{b'})+(average(a_p')-a_p')\mathbf{U_C}\right]}{\Delta V}
    $$

    最后:

    $$
    HbyA= \frac{H}{A}=\frac{\Delta V}{average(a_p')+diag}\frac{\left [-\sum a_{\mathbf{N}}\mathbf{U_N} + (\mathbf{b}+\mathbf{b'})+(average(a_p')-a_p')\mathbf{U_C}\right]}{\Delta V}
    $$
    $$
    HbyA= \frac{H}{A}=\frac{\left [-\sum a_{\mathbf{N}}\mathbf{U_N} + (\mathbf{b}+\mathbf{b'})+(average(a_p')-a_p')\mathbf{U_C}\right]}{average(a_p')+diag}
    $$

    1 条回复 最后回复

  • 登录

  • 登录或注册以进行搜索。
  • 第一个帖子
    最后一个帖子
0
  • 最新
  • 版块
  • 东岳流体
  • 随机看[请狂点我]