如何获得cell里的parcel数量,得到总的体积?
-
@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了。希望哪位知道的,能帮忙给个提示。谢谢啦! -
你好,我目前也在研究lagrangian库中的代码,我主要参考瑞典查尔姆斯理工OpenFOAM课程的PPT,网址链接:http://www.tfd.chalmers.se/~hani/kurser/OS_CFD/ 希望对你有所帮助
另外,可以和您邮件或者其他方式交流一下 有关lagrangian库的 问题吗?我现在主要在做 欧拉-拉格朗日的耦合,针对的是气液两相空化流动,有一些心得和问题,可以交流一下吗?
-
其实这个问题可以很直接的得到结果,完全不必这么绕的,让我们直接开始吧。
我们注意到,其实平均体积这个量在计算过程中是被计算了的,就在这里:
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和字典信息控制,当然这些行为你还可以自己定制。