大家好,目前我可以输出温度场的三维数据,比如
我想垂直于z轴做100个等间距垂直切面,在每个切面上对温度求积分并取平均值。
\begin{equation}
\int_{A} T dx dy /A
\end{equation}
然后沿着z轴画出一条温度平均值曲线。
谢谢大家!
大家好,目前我可以输出温度场的三维数据,比如
我想垂直于z轴做100个等间距垂直切面,在每个切面上对温度求积分并取平均值。
\begin{equation}
\int_{A} T dx dy /A
\end{equation}
然后沿着z轴画出一条温度平均值曲线。
谢谢大家!
@李东岳 非常感谢李老师,终于搞定,能输出数据了,但还需要进一步验证是否正确。差点放弃想升级新版本of。
volScalarField& summass = const_cast<volScalarField&>(p.mesh().objectRegistry::lookupObject<volScalarField>("summass"));
const label cellIp = p.cell();
scalar& PPC = summass.internalField() [cellIp];
PPC += p.nParticle()*p.mass();
希望对以后需要的朋友有点借鉴作用。特别感谢 @星星星星晴 不厌其烦的解答
@李东岳 李老师,这句命令
volScalarField& summass = p.mesh().objectRegistry::lookupObjectRef<volScalarField>("summass");
又报错了
lnInclude/ParticleCollector.C:745:71: error: ‘class Foam::objectRegistry’ has no member named ‘lookupObjectRef’
volScalarField& summass = p.mesh().objectRegistry::lookupObjectRef<volScalarField>("summass");
@李东岳 李老师,还是不行
const volScalarField& summass = p.mesh().objectRegistry::lookupObject<volScalarField>("summass");
const label cellIp = p.cell();
summass.internalField() [cellIp] += p.nParticle()*p.mass();
编译出错
lnInclude/ParticleCollector.C:749:38: error: assignment of read-only location ‘(&(& summass)->Foam::GeometricField<Type, PatchField, GeoMesh>::internalField<double, Foam::fvPatchField, Foam::volMesh>())->Foam::Field<double>::<anonymous>.Foam::List<double>::<anonymous>.Foam::UList<T>::operator[]<double>(((Foam::label)cellIp))’
summass.internalField() [cellIp] += p.nParticle()*p.mass();
^
lnInclude/ParticleCollector.C: In instantiation of ‘void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&) [with CloudType = Foam::KinematicCloud<Foam::Cloud<Foam::CollidingParcel<Foam::KinematicParcel<Foam::particle> > > >; Foam::ParticleCollector<CloudType>::parcelType = Foam::CollidingParcel<Foam::KinematicParcel<Foam::particle> >; Foam::label = int; Foam::scalar = double; Foam::point = Foam::Vector<double>]’:
parcels/derived/basicKinematicCollidingParcel/makeBasicKinematicCollidingParcelSubmodels.C:53:1: required from here
lnInclude/ParticleCollector.C:749:38: error: assignment of read-only location ‘(&(& summass)->Foam::GeometricField<Type, PatchField, GeoMesh>::internalField<double, Foam::fvPatchField, Foam::volMesh>())->Foam::Field<double>::<anonymous>.Foam::List<double>::<anonymous>.Foam::UList<T>::operator[]<double>(((Foam::label)cellIp))’
summass.internalField() [cellIp] += p.nParticle()*p.mass();
@李东岳 还是不行
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:746:43: error: ‘const InternalField {aka const class Foam::Field<double>}’ has no member named ‘ref’
scalar& PPC = summass.internalField().ref() [cellIp];
^
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:746:43: error: ‘const InternalField {aka const class Foam::Field<double>}’ has no member named ‘ref’
scalar& PPC = summass.internalField().ref() [cellIp];
@tens 应该是这样的,感觉应该带个指针啥的
@李东岳 李老师,按照下列代码
const label cellIp = p.cell();
scalar PPC = summass.internalField() [cellIp];
PPC += p.nParticle()*p.mass();
编译通过了,也能算了,但是好像没有赋值进去,结果是0
FoamFile
{
version 2.0;
format binary;
class volScalarField;
location "0.0002";
object summass;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
walls
{
type calculated;
value uniform 0;
}
}
@李东岳 我把
const volScalarField& summass = p.mesh().objectRegistry::lookupObject<volScalarField>("summass");
挪到程序前面了,还是同样的错误
@李东岳 编译倒是能通过了,但是运行算例log文件显示错误
[12]
[12]
[12] --> FOAM FATAL ERROR:
[12]
request for volScalarField summass from objectRegistry region0 failed
available objects of type volScalarField are
19
(
thermo:mu
thermo:psi
K
h
kappa
air
rho
k
Cp
dpdt
thermo:psi_0
alphat
dQ
p
T
mut
H2O
epsilon
thermo:alpha
)
[12]
[12]
[12] From function objectRegistry::lookupObject<Type>(const word&) const
[12] in file /home/chengan/OpenFOAM/OpenFOAM-2.4.0/src/OpenFOAM/lnInclude/objectRegistryTemplates.C at line 198.
[12]
@李东岳 李老师,又出现了之前的问题:
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:750:31: error: ‘const volScalarField {aka const class Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ has no member named ‘internalFieldRef’
scalar& PPC = summass.internalFieldRef() [cellIp];
^
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:750:31: error: ‘const volScalarField {aka const class Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ has no member named ‘internalFieldRef’
scalar& PPC = summass.internalFieldRef() [cellIp];
我用grep查了一下,有些函数中用的是internalField()而查不到internalFieldRef(),但如果采用
scalar& PPC = summass.internalField() [cellIp]
错误如下
lnInclude/ParticleCollector.C:750:53: error: binding ‘const double’ to reference of type ‘Foam::scalar& {aka double&}’ discards qualifiers
scalar& PPC = summass.internalField()[cellIp];
@李东岳 麻烦李老师了。
const volScalarField& summass = p.mesh().objectRegistry::lookupObject<volScalarField>("summass");
const label cellIp = p.cell();
scalar& PPC = summass.internalField()[cellIp];
PPC += p.nParticle()*p.mass();
还是有错误如下
lnInclude/ParticleCollector.C:750:53: error: binding ‘const double’ to reference of type ‘Foam::scalar& {aka double&}’ discards qualifiers
scalar& PPC = summass.internalField()[cellIp];
@李东岳 在 如何在src文件中创建标量物理filed并且调用 中说:
p.mesh().objectRegistry::lookupObject<volScalarField>("summass")
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:750:31: error: ‘const volScalarField {aka const class Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ has no member named ‘primitiveFieldRef’
scalar& PPC = summass.primitiveFieldRef() [cellIp];
^
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:750:31: error: ‘const volScalarField {aka const class Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ has no member named ‘primitiveFieldRef’
scalar& PPC = summass.primitiveFieldRef() [cellIp];
好像是没有 member named ‘primitiveFieldRef’,我用的是of2.4.0
@李东岳 谢谢李老师帮忙!
我我的是2.4.0版本,这样写的:
const volScalarField& summass = p.mesh().lookupObject<volScalarField>("summass");
const label cellIp = p.cell();
scalar& PPC = summass.primitiveFieldRef() [cellIp];
PPC += p.nParticle()*p.mass();
运行出现如下错误
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:748:77: error: expected primary-expression before ‘>’ token
const volScalarField& summass = p.mesh().lookupObject<volScalarField>("summass");
^
lnInclude/ParticleCollector.C:750:31: error: ‘const volScalarField {aka const class Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ has no member named ‘primitiveFieldRef’
scalar& PPC = summass.primitiveFieldRef() [cellIp];
^
lnInclude/ParticleCollector.C: In member function ‘virtual void Foam::ParticleCollector<CloudType>::postMove(Foam::ParticleCollector<CloudType>::parcelType&, Foam::label, Foam::scalar, const point&, bool&)’:
lnInclude/ParticleCollector.C:748:77: error: expected primary-expression before ‘>’ token
const volScalarField& summass = p.mesh().lookupObject<volScalarField>("summass");
^
lnInclude/ParticleCollector.C:750:31: error: ‘const volScalarField {aka const class Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>}’ has no member named ‘primitiveFieldRef’
scalar& PPC = summass.primitiveFieldRef() [cellIp];
不知道从哪里入手,麻烦李老师了
@李东岳 感谢李老师回复。
我先在求解器中的createFields.H建立过这个field:Euler-Lagrange的一些解析,sprayFoam
之后在ParticleCollector.C文件添加了
cellI = p.cell();
scalar& PPC = summass_->primitiveFieldRef() [cellI];
PPC += p.nParticle()*p.mass();
但我编译时候出现错误,找不到summass
所以我猜应该是把这个field建立到ParticleCollector.H,ParticleCollector.C等文件中吧?!瞎猜的。
李老师能指点一下吗?
大家好,请教一个问题:
我知道如何在求解器中的createFields.H建立field,
volScalarField summass
(
IOobject
(
"summass",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar ("zero", dimMass, 0.0)
);
我想进一步在src文件中创建标量物理filed并且调用,比如ParticleCollector.H,ParticleCollector.C等库文件?
谢谢大家。
@星星星星晴 在 Euler-Lagrange的一些解析,sprayFoam 中说:
- 数据量极大就是这个方法最大的问题,没办法。
- 你的mass3D没有输出,在结束这一步的迭代以后,在下一步迭代会被清空的。
你这一步已经很靠近方法1了,你不要用什么mass3D这个变量,你在solver中建立一个field, 比如叫summass,然后在cloudfunction的postmove 这个function中直接通过,就可以对一下field进行赋值了。cellI = p.cell(); scalar& PPC = summass_->primitiveFieldRef() [cellI]; PPC += p.nParticle()*p.mass();
我的技能也是有限,所以没有办法给你解决所有问题,你可以自己试试,找找资料,如果发现更好的办法,也希望你分享出来。
对于方法2,我个人有个想法,你获得你所要区域的cell number, 然后仅仅对这些cell进行输出也可以的。我自己没做过,大家都是摸着石头过河,可能每个人的解决方法并不通用,很case- sensitive,这也是开源的一个弊端。。
祝你好运~
谢谢。我在createFields.H建立了一个field:
volScalarField summass
(
IOobject
(
"summass",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar ("zero", dimMass, 0.0)
);
我没有理解“在cloudfunction的postmove 这个function中直接通过”是啥意思呢?麻烦了
@星星星星晴 在 Euler-Lagrange的一些解析,sprayFoam 中说:
@chengan-wang 这也简单啊,同理,你不需要判断是否碰到面,而是做一个判断是否在你的区域内即可,比如你需要判断在两个面之间,z-dir
if(p.position(2)<1 & p.position(2)>0) { 输出 }
但是这种方法会出现什么问题,比如一个parcel在这个区域待了3个$\Delta t_L$, 那就输出3次,就是你的输出文件几何倍数的增长。。
您好,我按照您的提示,思路如下:
先是定义了三维空间的范围,以及坐标质量的数组。
scalar xmin = -0.01;
scalar xmax = 0.01;
scalar ymin = 0;
scalar ymax = 0.1;
scalar zmin = -0.01;
scalar zmax = 0.01;
scalar dxyz = 5e-3;
const int nx = floor((xmax - xmin)/dxyz);
const int ny = floor((ymax - ymin)/dxyz);
const int nz = floor((zmax - zmin)/dxyz);
int nxc;
int nyc;
int nzc;
scalar xc[nx];
scalar yc[ny];
scalar zc[nz];
scalar mass3D[nx][ny][nz] = {0};
我只想最后时刻输出结果,所以先用if条件判断是否要输出数据
if ((this->owner().db().time().value()) == 0.02)
{
for (int i=0; i<nx; i++)
{
xc[i] = i*dxyz+xmin;
}
for (int j=0; j<ny; j++)
{
yc[j] = j*dxyz+ymin;
}
for (int k=0; k<nz; k++)
{
zc[k] = k*dxyz+zmin;
}
nxc = floor((p.position().component(0) - xmin)/dxyz);
nyc = floor((p.position().component(1) - ymin)/dxyz);
nzc = floor((p.position().component(2) - zmin)/dxyz);
mass3D[nxc][nyc][nzc] += p.nParticle()*p.mass();
std::ofstream outfile;
outfile.setf(ios_base::fixed, ios_base::floatfield);
outfile.precision(8);
outfile.open("postProcessingWCA/Mass3D.txt", ios_base::app);
for (int i=0; i<nx; i++)
{
for (int j=0; j<ny; j++)
{
for (int k=0; k<nz; k++)
{
outfile << xc[i] << tab << yc[j] << tab << zc[k] << mass3D[i][j][k] << tab << tab << nl;
}
}
}
}
之后我的想法就是根据粒子的位置计算索引位置 nxc nyc nzc,带入到mass3D[nxc][nyc][nzc] 相应的位置。
但是存在两个问题:
想麻烦您帮忙看看,谢谢
@李东岳 我找到如何输出endTime方法了,用this->owner().db().time().endTime().value()就可以。但是放在判断语句中出现如下错误:
note: ‘Foam::word’ is not derived from ‘const std::fpos<_StateT>’
if ((this->owner().db().time().timeName()) == (this->owner().db().time().endTime().value()))
/usr/include/c++/5/bits/stl_iterator.h:349:5: note: candidate: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
operator==(const reverse_iterator<_IteratorL>& __x,
^
/usr/include/c++/5/bits/stl_iterator.h:349:5: note: template argument deduction/substitution failed:
李老师能指点一下么?
@李东岳 谢谢回复。
我要输出一个物理场,网格数量挺大,200x100x100,要是每时每刻都输出的话,数据量很大,所以我需要加一个判断,只输出我感兴趣的时刻就行
大家好,
我在程序中添加了一段代码如下:
/*std::ofstream outfile;
outfile.setf(ios_base::fixed, ios_base::floatfield);
outfile.precision(8);
outfile.open("qq.dat", ios_base::app);
outfile << this->owner().db().time().timeName() << tab
<< "test" << tab
<< nl;*/
这样的话每次程序执行到这段代码时候都会输出到qq.dat文件,如果运行时间很长,文件会非常大,我又不需要输出所有时间点的数据。如果我想输出特定时间点的数据,比如最后一步,用if条件语句判断,条件式子没想好该怎么写,怎么才能方便地提取controlDict中的endTime呢?
startTime 0;
stopAt endTime;
endTime 2e-04;
比如写成if( this->owner().db().time().timeName()==endTime)
大家好、各位大佬好,咨询一个编译函数调用问题
我在别的论坛找到了一个在求解器中定义函数编译调用的例子如下:
//fun.H
#ifndef fun_H
#define fun_H
#include "scalar.H"
#include "vector.H"
namespace Foam
{
vector TestMe(const vector& myvec);
}
#endif
以及
//fun.C
#include "fun.H"
Foam::vector Foam::TestMe(const vector& myvec)
{
Info<< "Hello from TestMe" << endl;
Info<< "vector: " << myvec << endl;
}
然后在主函数里面调用 "fun.H"就行了。
#include "fun.H"
using namespace Foam;
int main(int argc, char *argv[])
{
vector A(1,2,3);
Info<< "Hello from the main()" << endl;
return 0;
}
我的思路就是直接在fun.H中写我想调用的代码。比如在“KinematicCloudI.H”文件中定义的
template<class CloudType>
inline const Foam::tmp<Foam::volVectorField>
Foam::KinematicCloud<CloudType>::UPar() const
{
tmp<volVectorField> tUPar
(
volVectorField::New
(
this->name() + ":UPar",
mesh_,
dimensionedVector(dimVelocity, vector(0,0,0)),
extrapolatedCalculatedFvPatchVectorField::typeName
)
);
volVectorField& UPar = tUPar.ref();
forAllConstIter(typename KinematicCloud<CloudType>, *this, iter)
{
const parcelType& p = iter();
const label celli = p.cell();
UPar[celli] += (p.U())/(p.nParticle());
}
UPar.primitiveFieldRef() /= 1;//mesh_.V();
UPar.correctBoundaryConditions();
return tUPar;
}
我直接移植过来,编译出现了如下错误:
fun.H:16:41: error: no ‘const Foam::tmp<Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh> > Foam::KinematicCloud<CloudType>::UPar() const’ member function declared in class ‘Foam::KinematicCloud<CloudType>’
Foam::KinematicCloud<CloudType>::UPar() const
我尝试把“KinematicCloudI.H”里面的头文件粘上去也通过不了,应该怎么修改以及加一些什么内容呢?
谢谢
@星星星星晴 非常感谢,我再仔细研究一下。我在google以及源代码中没有查到IVT8_StochasticCollisionModel_2022,PPC,它们代表的意思您方便告诉我么?感觉这个PPC应该是粒子的相关信息,又感觉直接用这个名字不对
@星星星星晴 不是要您的code,就是想知道应该改哪个文件而已,您误会了
@星星星星晴 我仔细想了一下,输出文件的方法可能数据量很大,感觉还是转换的方法更合适,
但还是有点没有搞清楚。
您之前告诉我可以放到cloudfunction中,我想知道您具体是放在哪个文件中了,能提供个思路么?我想看看安装包的原始文件,然后再比较一下您的代码,这样可能就清楚该怎么改和调用了。
另外,IVT8_StochasticCollisionModel_2022,PPC这是随便取得名字么?我在使用的时候是不是得改动呢?
@星星星星晴 在 Euler-Lagrange的一些解析,sprayFoam 中说:
@chengan-wang 这也简单啊,同理,你不需要判断是否碰到面,而是做一个判断是否在你的区域内即可,比如你需要判断在两个面之间,z-dir
if(p.position(2)<1 & p.position(2)>0) { 输出 }
但是这种方法会出现什么问题,比如一个parcel在这个区域待了3个$\Delta t_L$, 那就输出3次,就是你的输出文件几何倍数的增长。。
您好,如果加判断条件的话应该是在particleCollector代码中加,然后编译,对吧?这个圆柱面或者矩形面的定义就无所谓了。也就是说单独命名一个输出文件。
还有,我的网格数量挺大,200x100x100,我得定义好多个长方体区域,采用循环的办法,判断粒子与每一个区域的相对位置,如果符合条件就保存数据,跳出循环。但如果我的计算时间很长,每个时间点都保存数据,数据量肯定很大,能否只保存最后一个时间步的数据?也就是说我需要传递controlDict的参数,比如
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 5;
deltaT 0.01;
@星星星星晴 谢谢回复,方法2我倒是能用了,只是我需要输出不仅仅是几个面上的数据,而是统计200x100x100这样的网格节点上的数据,不知道该怎么弄了
@星星星星晴 您好,您推荐的2. 输出文件方法我基本弄明白了,特别适合输出一个平面上不同时刻的统计数据,然后用python数据处理。
我遇到的问题主要是输出三维规则网格空间点上的水滴质量,把这个数据导入到别的程序中。我尝试过用paraview输出粒子所在空间点数据,因为很不规则,所以之后用python三维插值,但是效果很差。
所以我觉得您提出的1. 将拉格朗日场转到EULER场比较适合我的情况。但是关于这个代码使用还想请教您几个问题:
1.
template<class CloudType>
Foam::volScalarField& Foam::IVT8_StochasticCollisionModel_2022<CloudType>::PPC() {
if (!PPCPtr_.valid() ) {
const fvMesh& mesh = this->owner().mesh();
PPCPtr_.reset
(
new volScalarField
(
IOobject
(
this->owner().name() + ":PPC",
mesh.time().timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar ("zero", dimless, 0.0),
zeroGradientFvPatchScalarField::typeName
)
);
}
return PPCPtr_();
}
这段代码应该是定义了一个函数,应该放在求解器的哪个文件中呢?
或者是自己重新定义一个头文件?
这个函数中的PPC应该是一个通用模板吧?比如我想输出 p.mass()质量的数据到EULER场,这个PPC直接用mass替换?
调用的时候您说用下面的代码,我想知道这段代码又是放在对应的哪个文件中呢?
scalar& PPC = PPCPtr_->primitiveFieldRef() [cellI];
PPC += 1.0;
@星星星星晴 感觉nSector不能设为1,最后输出的sum(total mass),sum(average mass flow rate)是nSector>1的4倍左右。
if (nSector_ > 1)
{
refDir = this->coeffDict().lookup("refDir");
refDir -= normal_[0]*(normal_[0] & refDir);
refDir /= mag(refDir);
}
else
{
// set 4 quadrants for single sector cases
nS = 4;
vector tangent = vector::zero;
scalar magTangent = 0.0;
Random rnd(1234);
while (magTangent < SMALL)
{
vector v = rnd.vector01();
tangent = v - (v & normal_[0])*normal_[0];
magTangent = mag(tangent);
}
refDir = tangent/magTangent;
}
可能跟源代码中nS = 4;有关系
@星星星星晴 您好,我有几个参数想请教您,
1.您的算例中radius分别设定1个,36个和9个数据,代表采集不同同心圆的数据?
2.nSector,自带算例设成10, 您设的是1。源代码里面Number of sectors per circle,这个怎么考虑
3.refDir代表啥意思呢?好像跟nSector数量还有关系
打扰了
@星星星星晴 您好,第三个错误我找到了,normal之前设置不对 改成(0 1 0);就可以了。搞不懂为啥坐标都给了,自己还要定义面的法线方向。
通过和您交流和自己实践理解,感觉对这个后处理问题最好还是用“2. 输出文件”方法,“1. 将拉格朗日场转到EULER场”这种方法我没有尝试,但是感觉应该属于空间插值,准确行应该是不如直接统计自己指定特定位置上的数据。
还有两个小疑问,如果我统计某一条线上的数据,实际上粒子很难碰到这条线,所以我应该设置一个很细长的面或者是圆柱吧?
另外就是有什么比较快捷的方式在polygons设置很多个平面吗?比如20个切面,或者50个。我可以提前编辑好,累加粘贴,但是感觉太麻烦了
polygons
(
(
(-0.01 0.06 -0.01)
(-0.01 0.06 0.01)
(0.01 0.06 0.01)
(0.01 0.06 -0.01)
)
);
@星星星星晴 相同的位置统计数据不一样,这个您找到原因了么?有点晕,不知道该怎么统计数据了。还有您的验证validation,sauter mean diameter(D32)VS axial diameter 的图,方便发出来做为一个标准验证么?
@星星星星晴 谢谢哈,麻烦您这么久
@星星星星晴 谢谢
@星星星星晴 您好,谢谢回复
[2] file: /home/chengan/OpenFOAM/chengan-2.4.0/run/sprayFoam/watermist/processor2/0/uniform/lagrangian/sprayCloud/sprayCloudOutputProperties.cloudFunctionObject.particleCollector2.massFlowRate at line 0.
[2]
[2] From function operator>>(Istream&, Scalar&)
[2] in file lnInclude/Scalar.C at line 93.
[2]
FOAM parallel run exiting
[2]
particleCollector output:
--------------------------------------------------------------------------
MPI_ABORT was invoked on rank 2 in communicator MPI_COMM_WORLD
with errorcode 1.
这个问题我大概知道怎么回事了,当resetOnWrite no;如果我采用单核计算,这个错误问题就没有出现;resetOnWrite yes;才能用多核并行,但我不知道有没有啥影响。
第二个问题,我直接在OpenFOAM-2.4.0下面的ParticleCollector.C文件修改,然后在intermediate文件夹下编译,wclean; wmake libso。其它没有动。但是运行结束后在postProcessing文件夹里面没有找到output.txt文件,感觉是没有调用新编译的库文件函数?您的编译方法参考教程能方便发一下么?
第三个问题,我用polygon做了一个切片,
particleCollector2
{
type particleCollector;
mode polygon;
polygons
(
(
(-0.01 0.06 -0.01)
(-0.01 0.06 0.01)
(0.01 0.06 0.01)
(0.01 0.06 -0.01)
)
);
normal (0 0 1);
negateParcelsOppositeNormal no;
removeCollected no;
surfaceFormat vtk;
resetOnWrite yes;
log yes;
}
很明显,粒子已经通过我设计的多边形,但是质量流量等于0,这又是什么原因呢?
@星星星星晴 您好,我这次直接在OpenFOAM-2.4.0下面的ParticleCollector.C文件修改,wclean, wmake libso,编译成功,避免了冲突问题。
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class CloudType>
void Foam::ParticleCollector<CloudType>::postMove
(
parcelType& p,
const label cellI,
const scalar dt,
const point& position0,
bool& keepParticle
)
{
if ((parcelType_ != -1) && (parcelType_ != p.typeId()))
{
return;
}
// slightly extend end position to avoid falling within tracking tolerances
const point position1 = position0 + 1.0001*(p.position() - position0);
hitFaceIDs_.clear();
switch (mode_)
{
case mtPolygon:
{
collectParcelPolygon(position0, position1);
break;
}
case mtConcentricCircle:
{
collectParcelConcentricCircles(position0, position1);
break;
}
default:
{
}
}
forAll(hitFaceIDs_, i)
{
label faceI = hitFaceIDs_[i];
scalar m = p.nParticle()*p.mass();
if (negateParcelsOppositeNormal_)
{
vector Uhat = p.U();
Uhat /= mag(Uhat) + ROOTVSMALL;
if ((Uhat & normal_[faceI]) < 0)
{
m *= -1.0;
}
}
// add mass contribution
mass_[faceI] += m;
if (nSector_ == 1)
{
mass_[faceI + 1] += m;
mass_[faceI + 2] += m;
mass_[faceI + 3] += m;
}
if (removeCollected_)
{
keepParticle = false;
}
}
//******add by myself******
forAll(hitFaceIDs_, i)
{
std::ofstream outfile;
outfile.setf(ios_base::fixed, ios_base::floatfield);
outfile.precision(8);
outfile.open("output.txt", ios_base::app);
outfile << this->owner().db().time().timeName() << tab
<< p.origId() << tab
<< p.typeId() << tab
<< p.age() << tab
<< p.position().component(0) << tab
<< p.position().component(1) << tab
<< p.position().component(2) << tab
<< p.U().component(0) << tab
<< p.U().component(1) << tab
<< p.U().component(2) << tab
<< p.d() << tab
<< p.nParticle() << tab
<< p.mass()*1e18 << tab
<< nl;
}
//******add by myself******
}
之后,我在sprayCloudProperties文件中定义(用的是ParticleCollector.H自带例子)
cloudFunctions
{
particleCollector2
{
type particleCollector;
mode polygon;
polygons
(
(
(-0.01 0.05 -0.01)
(-0.01 0.05 0.01)
(0.01 0.05 0.01)
(0.01 0.05 -0.01)
)
);
normal (0 0 1);
negateParcelsOppositeNormal no;
removeCollected no;
surfaceFormat vtk;
resetOnWrite no;
log yes;
}
}
运行至第一个时间步长就报错了
[2] --> FOAM FATAL IO ERROR: [13]
[13]
[13] --> FOAM FATAL IO ERROR:
[13] wrong token type - expected Scalar, found on line 0 the punctuation token '-'
[13]
[13] file: /home/chengan/OpenFOAM/chengan-2.4.0/run/sprayFoam/watermist/processor13/0/uniform/lagrangian/sprayCloud/sprayCloudOutputProperties.cloudFunctionObject.particleCollector2.massFlowRate at line 0.
[13]
[13] From function operator>>(Istream&, Scalar&)
[13] in file lnInclude/Scalar.C at line 93.
[13]
FOAM parallel run exiting
[13]
[2] wrong token type - expected Scalar, found on line 0 the punctuation token '-'
[2]
[2] file: /home/chengan/OpenFOAM/chengan-2.4.0/run/sprayFoam/watermist/processor2/0/uniform/lagrangian/sprayCloud/sprayCloudOutputProperties.cloudFunctionObject.particleCollector2.massFlowRate at line 0.
[2]
[2] From function operator>>(Istream&, Scalar&)
[2] in file lnInclude/Scalar.C at line 93.
[2]
FOAM parallel run exiting
[2]
particleCollector output:
--------------------------------------------------------------------------
MPI_ABORT was invoked on rank 2 in communicator MPI_COMM_WORLD
with errorcode 1.
NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
You may or may not see output from other processes, depending on
exactly when Open MPI kills them.
--------------------------------------------------------------------------
[chengan-MS-7C80:26316] 1 more process has sent help message help-mpi-api.txt / mpi-abort
[chengan-MS-7C80:26316] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help / error messages
如果不用particleCollector,直接使用cloudFunctions{}算例可以运行。
我没有搞明白到底什么地方出了问题
@星星星星晴 谢谢,我一直用2.4.0,所以用sprayFoam就没有换版本。另外请教您修改cloudfunction之后,采用的是是啥编译方法?能推荐一下么?
@星星星星晴 谢谢指点!
我这两天大概改了一下cloudfunction,似乎能运行了,但是从重新编译的求解器log文件上看,应该有一些问题,我好像重复调用了一些库函数:
Duplicate entry facePostProcessing in runtime selection table CloudFunctionObject
#0 /home/chengan/OpenFOAM/OpenFOAM-2.4.0/platforms/linux64GccDPOpt/lib/libOpenFOAM.so(_ZN4Foam5error14safePrintStackERSo+0x3e) [0x7f28ae2ae0ae]
#1 /home/chengan/OpenFOAM/chengan-2.4.0/platforms/linux64GccDPOpt/lib/libstatisticslagrangianIntermediate.so(_ZN4Foam19CloudFunctionObjectINS_14KinematicCloudINS_5CloudINS_15KinematicParcelINS_8particleEEEEEEEE31adddictionaryConstructorToTableINS_18FacePostProcessingIS7_EEEC1ERKNS_4wordE+0xfb) [0x7f28b4ff288b]
#2 /home/chengan/OpenFOAM/chengan-2.4.0/platforms/linux64GccDPOpt/lib/libstatisticslagrangianIntermediate.so(+0x2410f5) [0x7f28b4fbe0f5]
#3 /lib64/ld-linux-x86-64.so.2(+0x108d3) [0x7f28b55618d3]
#4 /lib64/ld-linux-x86-64.so.2(+0x10ca) [0x7f28b55520ca]
Duplicate entry particleCollector in runtime selection table CloudFunctionObject
#0 /home/chengan/OpenFOAM/OpenFOAM-2.4.0/platforms/linux64GccDPOpt/lib/libOpenFOAM.so(_ZN4Foam5error14safePrintStackERSo+0x3e) [0x7f28ae2ae0ae]
#1 /home/chengan/OpenFOAM/chengan-2.4.0/platforms/linux64GccDPOpt/lib/libstatisticslagrangianIntermediate.so(_ZN4Foam19CloudFunctionObjectINS_14KinematicCloudINS_5CloudINS_15KinematicParcelINS_8particleEEEEEEEE31adddictionaryConstructorToTableINS_17ParticleCollectorIS7_EEEC2ERKNS_4wordE+0xfb) [0x7f28b4ff29cb]
#2 /home/chengan/OpenFOAM/chengan-2.4.0/platforms/linux64GccDPOpt/lib/libstatisticslagrangianIntermediate.so(+0x24115c) [0x7f28b4fbe15c]
#3 /lib64/ld-linux-x86-64.so.2(+0x108d3) [0x7f28b55618d3]
#4 /lib64/ld-linux-x86-64.so.2(+0x10ca) [0x7f28b55520ca]
Duplicate entry particleErosion in runtime selection table CloudFunctionObject
#0 /home/chengan/OpenFOAM/OpenFOAM-2.4.0/platforms/linux64GccDPOpt/lib/libOpenFOAM.so(_ZN4Foam5error14safePrintStackERSo+0x3e) [0x7f28ae2ae0ae]
#1 /home/chengan/OpenFOAM/chengan-2.4.0/platforms/linux64GccDPOpt/lib/libstatisticslagrangianIntermediate.so(_ZN4Foam19CloudFunctionObjectINS_14KinematicCloudINS_5CloudINS_15KinematicParcelINS_8particleEEEEEEEE31adddictionaryConstructorToTableINS_15ParticleErosionIS7_EEEC1ERKNS_4wordE+0xfb) [0x7f28b4ff2b0b]
我又看了一下求解器Make文件夹的options文件:
EXE_INC = \
-Ilagrangian/intermediate/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I${LIB_SRC}/meshTools/lnInclude \
-I${LIB_SRC}/sampling/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/spray/lnInclude \
-I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/liquidProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/liquidMixtureProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/solidProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/solidMixtureProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/thermophysicalFunctions/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/SLGThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/chemistryModel/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude
EXE_LIBS = \
-L$(FOAM_USER_LIBBIN) \
-lstatisticslagrangianIntermediate \
-lfiniteVolume \
-lmeshTools \
-lsampling \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels \
-llagrangian \
-llagrangianTurbulence \
-llagrangianSpray \
-lspecie \
-lfluidThermophysicalModels \
-lliquidProperties \
-lliquidMixtureProperties \
-lsolidProperties \
-lsolidMixtureProperties \
-lthermophysicalFunctions \
-lreactionThermophysicalModels \
-lSLGThermo \
-lchemistryModel \
-lradiationModels \
-lODE \
-lregionModels \
-lsurfaceFilmModels \
-lfvOptions \
-lcombustionModels
没看出来我编译的intermediate文件夹跟哪个冲突。(我在求解器文件夹中建立lagrangian文件夹,然后把原始的intermediate文件夹拷进去,修改particleCollector,然后编译,编译过程中没有报错)。
麻烦您啦!
@星星星星晴 您好,我参考了GOFUN2017_ParticleSimulations_slides.pdf ,建立一个文件夹,并把文件拷过来。
mkdir lagrangian
cp -r $FOAM_SRC/lagrangian/intermediate/ lagrangian/
采用输出文件方法2,修改particleCollector,然后编译也成功了,
但是输出文件中没有看到output.txt文件,
我还需要在算例中设置什么命令才能调用particleCollector?
谢谢
@颗粒传书 或者你只显示lagrangian cloud
@颗粒传书 paraview有设置透明度的功能,你找找
@星星星星晴 非常感谢帮忙,我就是输出水雾就行,不用考虑化学反应,我感觉newFormat没啥用,就注释掉了。目前能生成水雾了,正在琢磨怎么提取质量分布的数据等等。
paraview 处理Lagrangian数据
@星星星星晴 您好,请教您个小问题,coupled是否引⼊1way 还是2way,这个指的是啥意思呢?还有newFormat yes;干啥用的呢?
@李东岳 李老师,那假如我统计垂直于轴线每个平面上的平均直径,然后画出其随轴线的变化规律,这个能实现么?
大家好,请教一个问题,目前我可以用sprayfoam输出水雾,如图所示, ,我想提取沿着轴线上的数据分布比如质量或者直径等等,我直接用plot over line不好使,应该是我的方法出了问题,那该如何做呢?谢谢大家
@星星星星晴 没关系,明白,想尽快弄出来
@李东岳 李老师,我想设置喷雾不随时间变化,
flowRateProfile constant 1e-4;
我试着用这个设置命令,算例也能运行。
如果这个命令没有意义不能用那该怎样设置?必须用下面的命令?把时间设得很长?
flowRateProfile table
(
(0 1e-4)
(100000 1e-4)
);*/
另外,请教关于文件‘sprayCloudProperties’,有些参数没找到资料,比如
solution
{
active true;
coupled true;
transient yes;
cellValueSourceCorrection on;
maxCo 0.3;
sourceTerms
{
schemes
{
rho explicit 1;
}
}
interpolationSchemes
{
rho cell;
U cellPoint;
}
integrationSchemes
{
U Euler;
T analytical;
}
}
以及
constantProperties
{
T0 320; // 这个有意义么?只是初始化用么?
// place holders for rho0 and Cp0
// - reset from liquid properties using T0
rho0 1000;
Cp0 4187;
constantVolume false; //这个是干啥用的呢?
}
最后,我想用paraview看看输出结果的水滴分布情况,这个怎么查看呢?还有水的质量在空间上的分布?
麻烦李老师了,谢谢。
@星星星星晴 您好,您手头有没有自己或别人发表的文献数据可以对比验证?刚接触这水雾,想尽快看看别人都输出了什么物理量。
@星星星星晴 非常感谢,我用的是2.4.0,刚刚使用SprayFoam这个求解器,想做个水喷雾
@星星星星晴 您好,您用sprayfoam做水喷雾成功了么,方便的话,有没有相关的资料可以分享一些?
@星星星星晴 您用的是哪个求解器,算的准么?