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. of中的多相流求解器

of中的多相流求解器

已定时 已固定 已锁定 已移动 OpenFOAM
34 帖子 11 发布者 43.3k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 队长别开枪队 离线
    队长别开枪队 离线
    队长别开枪 超神
    在 中回复了 mohui 最后由 编辑
    #18

    @mohui OpenFOAM的另一个非官方版本(foam-extend)里alpha方程的源代码比官方的看起来简洁一点,比如求解器interFoam,extend版本(4.0)中的alphaEqn.H为

    {
        word alphaScheme("div(phi,alpha)");
        word alpharScheme("div(phirb,alpha)");
    
        surfaceScalarField phic = mag(phi/mesh.magSf());
        phic = min(interface.cAlpha()*phic, max(phic));
        surfaceScalarField phir = phic*interface.nHatf();
    
        for (int aCorr=0; aCorr<nAlphaCorr; aCorr++)
        {
            surfaceScalarField phiAlpha =
                fvc::flux
                (
                    phi,
                    alpha1,
                    alphaScheme
                )
              + fvc::flux
                (
                    -fvc::flux(-phir, scalar(1) - alpha1, alpharScheme),
                    alpha1,
                    alpharScheme
                );
    
            MULES::explicitSolve(alpha1, phi, phiAlpha, 1, 0);
    
            rhoPhi = phiAlpha*(rho1 - rho2) + phi*rho2;
        }
    
        Info<< "Liquid phase volume fraction = "
            << alpha1.weightedAverage(mesh.V()).value()
            << "  Min(alpha1) = " << min(alpha1).value()
            << "  Max(alpha1) = " << max(alpha1).value()
            << endl;
    }
    

    官方版本(4.x)中的为

    {
        word alphaScheme("div(phi,alpha)");
        word alpharScheme("div(phirb,alpha)");
    
        tmp<fv::ddtScheme<scalar>> ddtAlpha
        (
            fv::ddtScheme<scalar>::New
            (
                mesh,
                mesh.ddtScheme("ddt(alpha)")
            )
        );
    
        // Set the off-centering coefficient according to ddt scheme
        scalar ocCoeff = 0;
        if
        (
            isType<fv::EulerDdtScheme<scalar>>(ddtAlpha())
         || isType<fv::localEulerDdtScheme<scalar>>(ddtAlpha())
        )
        {
            ocCoeff = 0;
        }
        else if (isType<fv::CrankNicolsonDdtScheme<scalar>>(ddtAlpha()))
        {
            if (nAlphaSubCycles > 1)
            {
                FatalErrorInFunction
                    << "Sub-cycling is not supported "
                       "with the CrankNicolson ddt scheme"
                    << exit(FatalError);
            }
    
            ocCoeff =
                refCast<const fv::CrankNicolsonDdtScheme<scalar>>(ddtAlpha())
               .ocCoeff();
        }
        else
        {
            FatalErrorInFunction
                << "Only Euler and CrankNicolson ddt schemes are supported"
                << exit(FatalError);
        }
    
        scalar cnCoeff = 1.0/(1.0 + ocCoeff);
    
        // Standard face-flux compression coefficient
        surfaceScalarField phic(mixture.cAlpha()*mag(phi/mesh.magSf()));
    
        // Add the optional isotropic compression contribution
        if (icAlpha > 0)
        {
            phic *= (1.0 - icAlpha);
            phic += (mixture.cAlpha()*icAlpha)*fvc::interpolate(mag(U));
        }
    
        surfaceScalarField::Boundary& phicBf =
            phic.boundaryFieldRef();
    
        // Do not compress interface at non-coupled boundary faces
        // (inlets, outlets etc.)
        forAll(phic.boundaryField(), patchi)
        {
            fvsPatchScalarField& phicp = phicBf[patchi];
    
            if (!phicp.coupled())
            {
                phicp == 0;
            }
        }
    
        tmp<surfaceScalarField> phiCN(phi);
    
        // Calculate the Crank-Nicolson off-centred volumetric flux
        if (ocCoeff > 0)
        {
            phiCN = cnCoeff*phi + (1.0 - cnCoeff)*phi.oldTime();
        }
    
        if (MULESCorr)
        {
            fvScalarMatrix alpha1Eqn
            (
                (
                    LTS
                  ? fv::localEulerDdtScheme<scalar>(mesh).fvmDdt(alpha1)
                  : fv::EulerDdtScheme<scalar>(mesh).fvmDdt(alpha1)
                )
              + fv::gaussConvectionScheme<scalar>
                (
                    mesh,
                    phiCN,
                    upwind<scalar>(mesh, phiCN)
                ).fvmDiv(phiCN, alpha1)
            );
    
            alpha1Eqn.solve();
    
            Info<< "Phase-1 volume fraction = "
                << alpha1.weightedAverage(mesh.Vsc()).value()
                << "  Min(" << alpha1.name() << ") = " << min(alpha1).value()
                << "  Max(" << alpha1.name() << ") = " << max(alpha1).value()
                << endl;
    
            tmp<surfaceScalarField> talphaPhiUD(alpha1Eqn.flux());
            alphaPhi = talphaPhiUD();
    
            if (alphaApplyPrevCorr && talphaPhiCorr0.valid())
            {
                Info<< "Applying the previous iteration compression flux" << endl;
                MULES::correct(alpha1, alphaPhi, talphaPhiCorr0.ref(), 1, 0);
    
                alphaPhi += talphaPhiCorr0();
            }
    
            // Cache the upwind-flux
            talphaPhiCorr0 = talphaPhiUD;
    
            alpha2 = 1.0 - alpha1;
    
            mixture.correct();
        }
    
    
        for (int aCorr=0; aCorr<nAlphaCorr; aCorr++)
        {
            surfaceScalarField phir(phic*mixture.nHatf());
    
            tmp<surfaceScalarField> talphaPhiUn
            (
                fvc::flux
                (
                    phi,
                    alpha1,
                    alphaScheme
                )
              + fvc::flux
                (
                   -fvc::flux(-phir, alpha2, alpharScheme),
                    alpha1,
                    alpharScheme
                )
            );
    
            // Calculate the Crank-Nicolson off-centred alpha flux
            if (ocCoeff > 0)
            {
                talphaPhiUn =
                    cnCoeff*talphaPhiUn + (1.0 - cnCoeff)*alphaPhi.oldTime();
            }
    
            if (MULESCorr)
            {
                tmp<surfaceScalarField> talphaPhiCorr(talphaPhiUn() - alphaPhi);
                volScalarField alpha10("alpha10", alpha1);
    
                MULES::correct(alpha1, talphaPhiUn(), talphaPhiCorr.ref(), 1, 0);
    
                // Under-relax the correction for all but the 1st corrector
                if (aCorr == 0)
                {
                    alphaPhi += talphaPhiCorr();
                }
                else
                {
                    alpha1 = 0.5*alpha1 + 0.5*alpha10;
                    alphaPhi += 0.5*talphaPhiCorr();
                }
            }
            else
            {
                alphaPhi = talphaPhiUn;
    
                MULES::explicitSolve(alpha1, phiCN, alphaPhi, 1, 0);
            }
    
            alpha2 = 1.0 - alpha1;
    
            mixture.correct();
        }
    
        if (alphaApplyPrevCorr && MULESCorr)
        {
            talphaPhiCorr0 = alphaPhi - talphaPhiCorr0;
        }
    
        if
        (
            word(mesh.ddtScheme("ddt(rho,U)"))
         == fv::EulerDdtScheme<vector>::typeName
        )
        {
            rhoPhi = alphaPhi*(rho1 - rho2) + phiCN*rho2;
        }
        else
        {
            if (ocCoeff > 0)
            {
                // Calculate the end-of-time-step alpha flux
                alphaPhi = (alphaPhi - (1.0 - cnCoeff)*alphaPhi.oldTime())/cnCoeff;
            }
    
            // Calculate the end-of-time-step mass flux
            rhoPhi = alphaPhi*(rho1 - rho2) + phi*rho2;
        }
    
        Info<< "Phase-1 volume fraction = "
            << alpha1.weightedAverage(mesh.Vsc()).value()
            << "  Min(" << alpha1.name() << ") = " << min(alpha1).value()
            << "  Max(" << alpha1.name() << ") = " << max(alpha1).value()
            << endl;
    }
    

    具体区别我不大清楚,但看起来还是有区别的。

    M 1 条回复 最后回复
  • 李东岳李 在线
    李东岳李 在线
    李东岳 管理员
    在 中回复了 mohui 最后由 编辑
    #19

    @mohui
    有点迷惑。
    如果你要验证求解一个相方程和两个相方程的区别,你就不需要研究MULES::limiter(),
    如果你要验证MULES的限制器,你可以直接采用求解单alpha方程来仔细研究通量限制器。
    哪个是研究的重点?:confused:

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

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

    @mohui 在 of中的多相流求解器 中说:

    我说的错误是这个,里面是没有alpha1,alpha2的

    是说 compreisblInterFoam解析 中下面这个方程有误?

    \begin{equation}
    \mathrm{dgdt}= \left( \frac{\alpha_2}{\rho_2}\frac{\mathrm{D}\rho_2}{\mathrm{D}t} - \frac{\alpha_1}{\rho_1}\frac{\mathrm{D}\rho_1}{\mathrm{D}t} \right)
    \end{equation}

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

    M 1 条回复 最后回复
  • M 离线
    M 离线
    mohui
    在 中回复了 李东岳 最后由 编辑
    #21

    @李东岳对,这个我推导里面是没有alpha的,源程序里也是没有的。

    李东岳李 1 条回复 最后回复
  • M 离线
    M 离线
    mohui
    在 中回复了 队长别开枪 最后由 编辑
    #22

    @队长别开枪 这两个区别在于后者采用了CrankNicolson格式。现在我最新给的代码是解释多相流求解器如何保证alpha之和有界的,你可以看下

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

    @mohui 非常感谢!原文已更新:cheeky:

    有关MULES的验证(暂时说不上研究,因为基金会已经植入了),我这里分为俩部分验证,第一部分验证已经完毕并且投稿,第二部分验证还在进行中,不过进度很慢毕竟还有别的课题在进行,我只能建议你参考Flux Correct Transport部分数值算法内容,MULES的思想来源于此,只不过基金会将此方法用于多相流

    有关求解一个方程或者两个方程的验证,应该不是很难,并且结果应该一致。在你之前发的相图上,我没有看出太大差别,是否有曲线图。另外,是否对比过1D Riemann问题的解析解?

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

    M M yhdthuY 3 条回复 最后回复
  • M 离线
    M 离线
    mohui
    在 中回复了 李东岳 最后由 编辑
    #24

    @李东岳 东岳老师,你可能还对我提的问题存在误区,我并不是对mules做验证,仅是分析OF中多相流求解器和两相流求解器对与两相流求解的区别。以我目前的测试检验,认为多相流求解器每一相求解并能够同时保证总的alpha之和等于的1的关键在于limitsum这个限制器,关于这个限制器的代码我也上传了,通过代码可以分析的出来,就是在mules求解之前对alphaphi进行了修正,以保证流入流出单元的alphaphi总和为0。其次,就如我前面所言,如果单纯的mules求解每一相是无法保证alpha1+alpha2=1的,虽然我给的图上没有很大区别,但是我输出alpha1+alpha2最大值为2,这是不对的。以上是我这几天的发现。

    1 条回复 最后回复
  • M 离线
    M 离线
    maoyanjun_dut
    在 中回复了 李东岳 最后由 编辑
    #25

    @李东岳

    @李东岳 在 of中的多相流求解器 中说:

    @mohui 非常感谢!原文已更新:cheeky:

    有关MULES的验证(暂时说不上研究,因为基金会已经植入了),我这里分为俩部分验证,第一部分验证已经完毕并且投稿,第二部分验证还在进行中,不过进度很慢毕竟还有别的课题在进行,我只能建议你参考Flux Correct Transport部分数值算法内容,MULES的思想来源于此,只不过基金会将此方法用于多相流

    有关求解一个方程或者两个方程的验证,应该不是很难,并且结果应该一致。在你之前发的相图上,我没有看出太大差别,是否有曲线图。另外,是否对比过1D Riemann问题的解析解?

    岳哥,公式20更新了,公式19却没更新。建议更新一下,否则看着怪怪的。

    Blog:http://maoyanjun.top
    厚德如海,纳川有藏。上善若水,利物不张。大哉斯言,勤勉勿忘。

    赵 1 条回复 最后回复
  • 赵 离线
    赵 离线
    赵一铭
    在 中回复了 maoyanjun_dut 最后由 编辑
    #26

    @maoyanjun_dut

    确实!好眼力。
    @李东岳

    1 条回复 最后回复
  • yhdthuY 离线
    yhdthuY 离线
    yhdthu 大神
    在 中回复了 李东岳 最后由 编辑
    #27

    @李东岳 前辈,compressibleInterFoam解析的(19)式忘记改了,括号内分子没有alpha:laughing:

    长风破浪会有时,直挂云帆济沧海

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

    谢谢,刚改了,interPhaseChangeFoam一直没时间写,估计得10月份开会回来之后能写...
    :big_mouth:

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

    yhdthuY 1 条回复 最后回复
  • yhdthuY 离线
    yhdthuY 离线
    yhdthu 大神
    在 中回复了 李东岳 最后由 编辑
    #29

    @李东岳 好的👌,到时候跟前辈讨论学习一下~

    长风破浪会有时,直挂云帆济沧海

    1 条回复 最后回复
  • J 离线
    J 离线
    Jacobian
    写于 最后由 编辑
    #30

    @mohui 没太看懂limitSum为何能保证体积分数之和为1,可否讲解一下?

    1 条回复 最后回复
  • D 离线
    D 离线
    dzw05 超神
    在 中回复了 mohui 最后由 编辑
    #31

    @mohui 其实也没太懂为什么limitsum可以保证alpha总和有界。limitsum限制的是所谓的修正通量,即“高阶通量”减去“迎风通量”的部分,至于为什么这部分通量总和等于零就可以保证alpha总和有界,这个还是没看懂。

    自主匠心,普惠仿真。

    1 条回复 最后回复
  • 小 离线
    小 离线
    小龙
    写于 最后由 编辑
    #32

    @李东岳 @mohui @赵一铭 我最近再做空化模拟,OF中只有多相流VOF模型,VOF做空化不太适合,想在OF里编译一下mixture模型,前辈们觉得实现的可行性高吗。实现的难度大吗?我初步的想法是基于interPhaseChangeFoam来修改。前辈们有什么建议?

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

    如果单纯的mules求解每一相是无法保证alpha1+alpha2=1的

    现在我就想确定,alpha2通过对应方程推导,用MULES求解不可行的吗?

    MULES的出发点是保证变量的有界。所以如果你用MULES求解alpha1,那么理论上alpha1是有界的。alpha2的求解没有调用MULES,他是通过1-alpha1算出来的,如果alpha1有界,alpha2也有界。

    如果你用算法同时求解alpha1和alpha2,如何处理耦合?这俩个变量是耦合在一起的,就像速度和压力。你不能单独的去分离求解,如果分离求解就就需要迭代。迭代就导致计算速度变慢。因此现存大厂据我所知都是只求解alpha1,然后alpha2=1-alpha1。

    我在去你年底验证了MULES,理论上是可以保证有界,但是真实计算的时候,还是会越界。尤其是物理模型比较复杂的时候。个人觉得这方面内容搞出来,绝对是个好文。

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

    1 条回复 最后回复
  • H 离线
    H 离线
    hehe
    在 中回复了 mohui 最后由 编辑
    #34
    此回复已被删除!
    1 条回复 最后回复

  • 登录

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