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.3k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • L 离线
    L 离线
    liujm
    写于2025年3月24日 14:18 最后由 编辑
    #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 条回复 最后回复
  • L 离线
    L 离线
    liujm
    写于2025年3月24日 14:22 最后由 编辑
    #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 条回复 最后回复
  • L 离线
    L 离线
    liujm
    写于2025年3月24日 14:30 最后由 liujm 编辑 2025年3月24日 22:35
    #3

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

    李 1 条回复 最后回复 2025年3月24日 15:26
  • 李 在线
    李 在线
    李东岳 管理员
    写于2025年3月24日 14:51 最后由 编辑
    #4

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

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

    L 1 条回复 最后回复 2025年3月24日 14:58
  • L 离线
    L 离线
    liujm
    在 2025年3月24日 14:58 中回复了 李东岳 最后由 编辑
    #5

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

    1 条回复 最后回复
  • 李 在线
    李 在线
    李东岳 管理员
    写于2025年3月24日 15:02 最后由 编辑
    #6

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

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

    L 1 条回复 最后回复 2025年3月24日 15:06
  • L 离线
    L 离线
    liujm
    在 2025年3月24日 15:06 中回复了 李东岳 最后由 编辑
    #7

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

    1 条回复 最后回复
  • 李 在线
    李 在线
    李东岳 管理员
    在 2025年3月24日 15:26 中回复了 liujm 最后由 编辑
    #8

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

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

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

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

    L 1 条回复 最后回复 2025年3月25日 03:26
  • L 离线
    L 离线
    liujm
    在 2025年3月25日 03:26 中回复了 李东岳 最后由 liujm 编辑 2025年3月25日 11:28
    #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 条回复 最后回复
  • L 离线
    L 离线
    liujm
    写于2025年3月26日 07:26 最后由 编辑
    #10

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

    1 条回复 最后回复
2025年3月24日 14:18

8/10

2025年3月24日 15:26

未读 2
2025年3月26日 07:26
  • 登录

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