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. 如何获得cell里的parcel数量,得到总的体积?

如何获得cell里的parcel数量,得到总的体积?

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

    @zhe 更新一下,我发现在KinematicCloudI.H中可以直接得到每个cell里的总质量,也可以直接得到总体积theta。但是,我也有了新的的问题,我不知道怎么调取theta。错误提示是:error: ‘theta’ was not declared in this scope
    我刚开始在头文件中加了#include "KinematicCloudI.H",但是提示重复命名里面所有的项。如果去掉,就显示error: ‘theta’ was not declared in this scope了。希望哪位知道的,能帮忙给个提示。谢谢啦!

    1 条回复 最后回复
  • 小 离线
    小 离线
    小考拉
    写于 最后由 编辑
    #3

    你好,我目前也在研究lagrangian库中的代码,我主要参考瑞典查尔姆斯理工OpenFOAM课程的PPT,网址链接:http://www.tfd.chalmers.se/~hani/kurser/OS_CFD/ 希望对你有所帮助

    另外,可以和您邮件或者其他方式交流一下 有关lagrangian库的 问题吗?我现在主要在做 欧拉-拉格朗日的耦合,针对的是气液两相空化流动,有一些心得和问题,可以交流一下吗?

    zheZ 1 条回复 最后回复
  • zheZ 离线
    zheZ 离线
    zhe
    在 中回复了 小考拉 最后由 编辑
    #4

    @小考拉 你好,谢谢你的回复。我的邮件是zhecao1990@gmail.com。你可以发邮件咱们互相交流一下。

    1 条回复 最后回复
  • 闻 离线
    闻 离线
    闻久STU
    写于 最后由 编辑
    #5

    mark,在将来的一段时间,我应该也会关注到这个问题

    1 条回复 最后回复
  • 白 离线
    白 离线
    白礼耕
    写于 最后由 编辑
    #6

    parcels.theta()().write();
    后处理通过theta场和网格体积求parcel的体积。
    总质量不就是书橱文件中的mass introduced么

    李 1 条回复 最后回复
  • 李 离线
    李 离线
    李梦瑶
    在 中回复了 白礼耕 最后由 编辑
    #7

    @白礼耕 前辈您好,我想请教一下,您是否知道如何在后处理中显示theta

    白 1 条回复 最后回复
  • 马乔马 离线
    马乔马 离线
    马乔 大神
    写于 最后由 编辑
    #8

    其实这个问题可以很直接的得到结果,完全不必这么绕的,让我们直接开始吧。
    我们注意到,其实平均体积这个量在计算过程中是被计算了的,就在这里:
    MPPICParcel<ParcelType>::TrackingData<CloudType>类的构造中,

    volumeAverage_
        (
            AveragingMethod<scalar>::New
            (
                IOobject
                (
                    cloud.name() + ":volumeAverage",
                    cloud.db().time().timeName(),
                    cloud.mesh()
                ),
                cloud.solution().dict(),
                cloud.mesh()
            )
        ),
    

    但是IO行为被控制了,所以我们接下来要做的是写个类控制它的IO,从头开始朔源,
    MPPICCloud<CloudType>::evolve()--->this->solve(*this, td);这个solve是KinematicCloud的

    {
            cloud.preEvolve();
    
            evolveCloud(cloud, td);
    
            if (solution_.coupled())
            {
                cloud.scaleSources();
            }
        }
    
        cloud.info();
    
        cloud.postEvolve();
    

    可以看到,这个流程里调用两个重要函数preEvolve和postEvolve,
    其中这两个函数都调用了functions_.preEvolve();和functions_.postEvolve();来看看functions_的定义
    typedef CloudFunctionObjectList<KinematicCloud<CloudType>>
    functionType;
    以及构造

    functions_
        (
            *this,
            particleProperties_.subOrEmptyDict("cloudFunctions"),
            solution_.active()
        ),
    

    是个可以通过字典控制的对象List,好,进入正题,我们建个类

    template<class CloudType>
    class cloudAverageField
    :
        public CloudFunctionObject<CloudType>
    {
    

    并定义我们需要的数据

    autoPtr<volScalarField> rhoAvgPtr_;
            
    autoPtr<volVectorField> velAvgPtr_;
            
     autoPtr<volScalarField> volAvgPtr_;
    

    以及接口preEvolve和postEvolve
    preEvolve做的工作是检查和初始化

    void Foam::cloudAverageField<CloudType>::preEvolve()
    {
    
        const fvMesh& mesh = this->owner().mesh();
        
        if (!rhoAvgPtr_.valid())
        {
            
            rhoAvgPtr_.reset
            (
                new volScalarField
                (
                    IOobject
                    (
                        this->owner().name() + "RhoAvg",
                        mesh.time().timeName(),
                        mesh,
                        IOobject::NO_READ,
                        IOobject::NO_WRITE
                    ),
                    mesh,
                    dimensionedScalar("zero", dimDensity, 0.0)
                )
            );
        }
        ...
    

    postEvolve则把数据保存下来

    Field<scalar> pRhoField(mesh.lookupObject<AveragingMethod<scalar> >(this->owner().name() + ":rhoAverage")[0]);
        Field<vector> pVelField(mesh.lookupObject<AveragingMethod<vector> >(this->owner().name() + ":uAverage")[0]);
        Field<scalar> pVolField(mesh.lookupObject<AveragingMethod<scalar> >(this->owner().name() + ":volumeAverage")[0]);
    

    最后在用个write函数在需要的时候把数据写出来

    template<class CloudType>
    void Foam::cloudAverageField<CloudType>::write()
    {
        if (rhoAvgPtr_.valid())
        {
            rhoAvgPtr_->write();
            velAvgPtr_->write();
            volAvgPtr_->write();
        }
        else
        {
            FatalErrorIn("void Foam::cloudAverageField<CloudType>::write()")
                << "thetaPtr not valid" << abort(FatalError);
        }
    }
    

    最最后,把函数注册下

    namespace Foam
    {
        makeCloudFunctionObjectType(cloudAverageField, basicKinematicMPPICCloud);
    }
    

    这样就可以通过字典在运行时选择了。
    回到主题,我们看这个怎么被触发
    在前面的evolveCloud(cloud, td);函数会调用cloud.motion(cloud, td);这次回到MPPICCloud<CloudType>::motion
    里面会调用td.updateAverages(td.cloud());它的主要工作是

    // averaging sums
        forAllConstIter(typename CloudType, cloud, iter)
        {
            const typename CloudType::parcelType& p = iter();
            const tetIndices tetIs(p.cell(), p.tetFace(), p.tetPt(), cloud.mesh());
    
            const scalar m = p.nParticle()*p.mass();
    
            volumeAverage_->add(p.position(), tetIs, p.nParticle()*p.volume());
            rhoAverage_->add(p.position(), tetIs, m*p.rho());
            uAverage_->add(p.position(), tetIs, m*p.U());
            massAverage_->add(p.position(), tetIs, m);
        }
        volumeAverage_->average();
        massAverage_->average();
        rhoAverage_->average(massAverage_);
        uAverage_->average(massAverage_);
    

    就是更新计算每个cell的粒子平均信息。
    嗯,大概是这样。至于信息的输出控制则具体由CloudFunctionObjectList和字典信息控制,当然这些行为你还可以自己定制。

    装逼没输过,吵架没赢过!

    1 条回复 最后回复
  • 马乔马 离线
    马乔马 离线
    马乔 大神
    写于 最后由 编辑
    #9

    最后再加一句这个write的动作其实是这样被触发的

    template<class CloudType>
    void Foam::CloudFunctionObject<CloudType>::postEvolve()
    {
        if (this->owner().time().writeTime())
        {
            this->write();
        }
    }
    

    所以记得子类中记得调用

    CloudFunctionObject<CloudType>::postEvolve();
    

    这样整个调用闭环,脉络清晰:146:

    装逼没输过,吵架没赢过!

    1 条回复 最后回复
  • 白 离线
    白 离线
    白礼耕
    在 中回复了 李梦瑶 最后由 编辑
    #10

    @李梦瑶 最简单的办法就是在计算过程中输出,写出的theta可以直接用paraView读。后处理的话,@浪迹天大 有套流程。https://github.com/ZhangYanTJU/functionObjects

    李 1 条回复 最后回复
  • 李 离线
    李 离线
    李梦瑶
    在 中回复了 白礼耕 最后由 编辑
    #11

    @白礼耕 好的,谢谢您

    1 条回复 最后回复

  • 登录

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