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. 计算作用于cellZone上的压力和剪切力

计算作用于cellZone上的压力和剪切力

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

    各位老师和前辈们好,

    我想要通过划定cellZone区域来计算作用于该区域网格上的压力和剪切力,预期功能类似于forces.H中的void Foam::functionObjects::forces::calcForcesMoments()函数,然而,该函数是基于边界patch计算的【代码片段1】,我想要基于cellZone实现。而计算多孔介质部分的力【代码片段2】正是基于cellZone实现的,因此,

    • i) 我想将基于patch的计算边界力的方法移植于多孔介质模块中,这样可行吗?

    • ii) 评论区我放出改写的代码,烦请各位老师指出需要改进的地方

    (如果有老师能够直接给出示例就更好了:140: )

    以下摘取了forces.H中void Foam::functionObjects::forces::calcForcesMoments()部分源码:
    【代码片段1】

        if (directForceDensity_)
        {
            const auto& fD = lookupObject<volVectorField>(fDName_);
    
            const auto& Sfb = mesh_.Sf().boundaryField();
    
            for (const label patchi : patchSet_)
            {
                const vectorField& d = mesh_.C().boundaryField()[patchi];
    
                const vectorField Md(d - origin);
    
                const scalarField sA(mag(Sfb[patchi]));
    
                // Pressure force = surfaceUnitNormal*(surfaceNormal & forceDensity)
                const vectorField fP
                (
                    Sfb[patchi]/sA
                   *(
                        Sfb[patchi] & fD.boundaryField()[patchi]
                    )
                );
    
                // Viscous force (total force minus pressure fP)
                const vectorField fV(sA*fD.boundaryField()[patchi] - fP);
    
                addToPatchFields(patchi, Md, fP, fV);
            }
        }
        else
        {
            const auto& p = lookupObject<volScalarField>(pName_);
    
            const auto& Sfb = mesh_.Sf().boundaryField();
    
            tmp<volSymmTensorField> tdevRhoReff = devRhoReff();
            const auto& devRhoReffb = tdevRhoReff().boundaryField();
    
            // Scale pRef by density for incompressible simulations
            const scalar rhoRef = rho(p);
            const scalar pRef = pRef_/rhoRef;
    
            for (const label patchi : patchSet_)
            {
                const vectorField& d = mesh_.C().boundaryField()[patchi];
    
                const vectorField Md(d - origin);
    
                const vectorField fP
                (
                    rhoRef*Sfb[patchi]*(p.boundaryField()[patchi] - pRef)
                );
    
                const vectorField fV(Sfb[patchi] & devRhoReffb[patchi]);
    
                addToPatchFields(patchi, Md, fP, fV);
            }
        }
    
    

    【代码片段2】

    if (porosity_)
        {
            const auto& U = lookupObject<volVectorField>(UName_);
            const volScalarField rho(this->rho());
            const volScalarField mu(this->mu());
    
            const auto models = obr_.lookupClass<porosityModel>();
    
            if (models.empty())
            {
                WarningInFunction
                    << "Porosity effects requested, "
                    << "but no porosity models found in the database"
                    << endl;
            }
    
            forAllConstIters(models, iter)
            {
                // Non-const access required if mesh is changing
                auto& pm = const_cast<porosityModel&>(*iter());
    
                const vectorField fPTot(pm.force(U, rho, mu));
    
                const labelList& cellZoneIDs = pm.cellZoneIDs();
    
                for (const label zonei : cellZoneIDs)
                {
                    const cellZone& cZone = mesh_.cellZones()[zonei];
    
                    const vectorField d(mesh_.C(), cZone);
                    const vectorField fP(fPTot, cZone);
                    const vectorField Md(d - origin);
    
                    addToInternalField(cZone, Md, fP);
                }
            }
        }
    

    祝好~

    1 条回复 最后回复
  • liujmL 离线
    liujmL 离线
    liujm
    写于 最后由 编辑
    #2

    此处附上改写的代码,烦请各位老师指出错误所在,不胜感激:

        if (porosity_)
        {   
            const volVectorField& U  = lookupObject<volVectorField>(UName_);
            const volScalarField& p  = lookupObject<volScalarField>(pName_);   // Add code.
            const volScalarField rho(this->rho());
            const volScalarField mu(this->mu());
    
            const HashTable<const porosityModel*> models = obr_.lookupClass<porosityModel>();
    
            if (models.empty())
            {
                WarningInFunction
                    << "Porosity effects requested, but no porosity models found "
                    << "in the database"
                    << endl;
            }
    
            forAllConstIters(models, iter)
            {
                  // Non-const access required if mesh is changing
                porosityModel& pm = const_cast<porosityModel&>(*iter());
    
                vectorField fPTot(pm.porousForce(U, rho, mu));  // Modified code.
                
                const labelList& cellZoneIDs = pm.cellZoneIDs();
                
                for (const label zonei : cellZoneIDs)
                {
                    const cellZone& cZone = mesh_.cellZones()[zonei];  // Get cells in zonei.
                    const vectorField d(mesh_.C(), cZone);
                    const vectorField fP(fPTot, cZone);
                    
                    const vectorField Md(d - coordSys_.origin());
                    const labelList& cellsID = cZone;  // Add code: Get cellsID(index) list in zonei.
                    vectorField fN(cZone.size(), Zero);
                    vectorField fT(cZone.size(), Zero);
                    scalar                  pRef                            = pRef_/rho(p);   // Add code: Scale pRef by density for incompressible simulations
                    tmp<volSymmTensorField> tdevRhoReff                     = devRhoReff();
                    const                   volSymmTensorField& devRhoReff1 = tdevRhoReff();
                    
                    Info << "cellZoneIDs zonei = " << zonei << "\n"<< endl;
                    Info << "cells in zonei: cZone.size() = " << cZone.size() << "\n"<< endl;
                    Info << "fN.size() = " << fN.size() << "\n"<< endl;
                    Info << "fT.size() = " << fT.size() << "\n"<< endl;
                    Info << "fP.size() = " << fP.size() << "\n"<< endl;
    
                    forAll (cellsID, celli)
                    {
                        label cellID               = cellsID[celli];
                        const labelList& cellFaces = mesh_.cells()[cellID];
                        forAll (cellFaces, facei)
                        {
                            label faceID = cellFaces[facei];
                              // fN.
                            vector cellFacesFN  = rho(p) * mesh_.Sf()[faceID] * (p[cellID] - pRef);
                            fN    [celli]      += cellFacesFN;
                              // fT.
                            vector cellsFacesfT  = mesh_.Sf()[faceID] & devRhoReff1[faceID];
                            fT    [celli]       += cellFacesFT;
                            
                            Info << "No." << celli << "cell's ID(index) is " << cellID << "\n" << endl;
                            Info << "fN = " << fN[celli] << "\n" << endl;
                            Info << "fT = " << fT[celli] << "\n" << endl;
                            Info << "fP = " << fP[celli] << "\n" << endl;
                        }
                    }                     
                    addToFields(cZone, Md, fN, fT, fP);
    
                    applyBins(Md, fN, fT, fP, d);
                }
            }
        }
    
    1 条回复 最后回复
  • liujmL 离线
    liujmL 离线
    liujm
    写于 最后由 liujm 编辑
    #3

    总体而言,就是要计算cellZone所有网格上的法向力和切向力,而不是仅仅计算作用在固壁边界上的力。
    这里通过图示表达目的:
    33bdd489-1a5e-4b96-ac6f-a108a9ffa9b9-e2bfe6413bc5c6eecfc0b65a00b3268.jpg

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

    你的力定义在面上,如何对你的cellZone里面的所有cells取力?

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

    liujmL 1 条回复 最后回复
  • liujmL 离线
    liujmL 离线
    liujm
    在 中回复了 李东岳 最后由 编辑
    #5

    @李东岳 老师,可以直接对区域内的所有cell压力求积分得出吗?其实这篇帖子是这个帖子的延申:136: 。
    一方面,要保证动网格能够识别到patch名,另一方面也要计算cell上的力,请问李老师有没有更好的实现方法?

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

    一般力都定义在面上,压力、表面张力
    当然存在一些体积力,比如重力,但不会产生剪切
    但是你好像需要一个产生剪切的体积力,这是什么情况?

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

    liujmL 1 条回复 最后回复
  • liujmL 离线
    liujmL 离线
    liujm
    在 中回复了 李东岳 最后由 编辑
    #7

    @李东岳 老师,我想要模拟浮式多孔介质模型在流体中的运动,因此需要获得物体的力(矩),这里的剪切力其实对应一楼【代码片段1】的54行和56行。

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

    33bdd489-1a5e-4b96-ac6f-a108a9ffa9b9-e2bfe6413bc5c6eecfc0b65a00b3268.jpg

    你这个图里面,第一个图是可以理解的,因为force定义在面上,因此可以做面积分。

    第二个myForce,你要对cell做操作,如何做面积分?

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

    liujmL 1 条回复 最后回复
  • liujmL 离线
    liujmL 离线
    liujm
    在 中回复了 李东岳 最后由 liujm 编辑
    #9

    @李东岳 李老师,这也正是我遇到的问题:136: 。

    退一步我做一个简化,在图示的myForces.H的结构最外层cell上套一层patch边界,可不可以仅用patch计算cellZone最外层网格的力和力矩[1],而不阻碍水体穿越被patch包裹的cellZone区域?

    这个想法可行吗,如果可行的话老师方便指点一下,如何实现水体不穿越patch的功能?

    [1] 只计算外层网格表面的受力是因为网衣通常不会太厚,有文献采用2m厚的多孔介质模型,网格尺寸0.5m来模拟。

    在OF2206中,
    对于patch,有addToPatchFields函数:

    void Foam::functionObjects::forces::addToPatchFields
    (
        const label patchi,
        const vectorField& Md,
        const vectorField& fP,
        const vectorField& fV
    )
    {
        sumPatchForcesP_ += sum(fP);
        sumPatchForcesV_ += sum(fV);
        force().boundaryFieldRef()[patchi] += fP + fV;
    
        const vectorField mP(Md^fP);
        const vectorField mV(Md^fV);
    
        sumPatchMomentsP_ += sum(mP);
        sumPatchMomentsV_ += sum(mV);
        moment().boundaryFieldRef()[patchi] += mP + mV;
    }
    

    对于多孔介质的cellZone,有addToInternalField函数:

    void Foam::functionObjects::forces::addToInternalField
    (
        const labelList& cellIDs,
        const vectorField& Md,
        const vectorField& f
    )
    {
        auto& force = this->force();
        auto& moment = this->moment();
    
        forAll(cellIDs, i)
        {
            const label celli = cellIDs[i];
    
            sumInternalForces_ += f[i];
            force[celli] += f[i];
    
            const vector m(Md[i]^f[i]);
            sumInternalMoments_ += m;
            moment[celli] = m;
        }
    }
    
    1 条回复 最后回复
  • liujmL 离线
    liujmL 离线
    liujm
    写于 最后由 编辑
    #10

    已经想到合适的解决方案啦! 封楼

    1 条回复 最后回复

  • 登录

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