哈哈哈,没事,谢谢东岳老师!
悬铃神木
帖子
-
-
差不多,
U[cellID].x(), U[cellID].y(),
之类 -
是这样的,我想在求解过程中使用python做一些处理,要把流场数据传到python,处理后在传回,关于在of求解过程中调用python,我找到了一篇帖子:OpenFOAM 与 python 代码之间的通信
但是volScalarField这样一个类,python肯定不能识别,请问我如何能单独把流场的值作为double数组提取出来?
如果不能把整个流场值变成一个double数组,能每个cell挨个提取出来也是极好的。
我尝试去代码里找volScalarField的结构,但模板套模板实在没读明白,希望各位老师大牛们能不吝赐教。 -
@wwzhao 嗯嗯,明白了,非常感谢您的解答!
-
哦哦,感谢
如果是吸收到压力梯度项里去了,那需要对压力梯度项或压力方程做修正吗? -
在构建湍流模型时,雷诺应力根据Boussinesq假设可写为
S-A模型中,建立了涡粘系数nut的输运方程,可由此得到nut,那么上式中的k是怎么处理的?
看的几个资料中都没有提及这个部分,请各位老师解个惑 -
是我应该感谢cfd中文网的各位老师,对我的帮助很大.
另外,我测试的这个构造函数和析构函数只承担了new和delete一个double[]的任务,如果是功能更复杂的构造函数,就不好说了。 -
是的,调用1000000次构造函数和1次,带来的差别不大
-
@Zephyr 嗯嗯,感谢,我去尝试一些库
-
谢谢您的回答!我试了下不使用动态分配而用固定大小的数组p[10000]来代替,确实提高了一些效率,从10S+变成了7S+。
但我这里确实需要动态分配,因为我希望做成一个有一定通用性的矩阵类来储存各种流场信息,我无法在编程时就知道需要多大内存,也许这次计算只要几千网格,也许下次就需要几千万网格。 -
谢谢您的回答!试了一下确实是编译器优化带来的问题,我在linux系统下使用g++编译这串代码,以下分别是优化等级-O0(无优化)、-O1、-O2、-O3时得到的运行速度:
-O0 Time1 = 47.759S Time2 = 29.2934S -O1 Time1 = 16.7366S Time2 = 4.35349S -O2 Time1 = 11.9593S Time2 = 1e-06S -O3: Time1 = 12.2002S Time2 = 0S
可见无优化时虽然我这种使用类的写法也要慢一些,但两者在一个数量级上,优化等级越高,直接使用数组的方法优势就越大了……
编译器的优化好神奇哦!
看来以后还是尽量去用别人写的成熟的函数库吧…… -
7.415S,确实快了一些。但是这样写相当于改变了两个被乘数组之一,这样限制了它的使用方式,像C=A+A*B这样的或者更复杂的表达式就很难写了。我试了一下,确实如楼下所言是优化的问题,零优化情况下就和直接用数组的方式没有这么大的差距。
-
希望像matlab那样可以直接在矩阵层面操作,这样写出程序来简洁一些,我不知道有哪种自带的类可以满足,我只试过vector,但是并不比我自己写的类快。
-
谢谢东岳老师,测试了一下确实是这样,构造和return这个类耗费时间很多……
但是没想到好方法……要实现相关功能+-*/必须返回一个相同的类……
不知道成熟的代码是怎么解决这个问题的 -
这个循环嵌套直接用double数组速度很快啊,用了0.492S
上面那个用了我写的类的地方:for (int t = 0; t < 1000000; t++)C = A * B;
这个地方很慢,做相同的事情用了 10.4S
-
我在写一个CFD程序的时候碰到的问题,我想使用c++的特性把double数组封装成一个新的类,这样就可以重载运算符,像使用matlab那样直接进行矩阵层次的操作。
比如,在c++里要分别对元素操作:for(int i=0;i<10000;i++)C[i]=A[i]+B[i]
用matlab就可以直接写:
C=A+B;
但我写成一个类后,运算效率却比直接这样运行慢太多,甚至比matlab慢很多(C++应该比matlab快才对吧?)
比如如下代码:#include "pch.h" #include <iostream> #include <time.h> class Array { public: Array(int S):Size(S) //构造函数 { p = new double[Size]; } Array(int S, double n):Size(S) //构造函数 { p = new double[Size]; for (int i = 0; i < Size; i++)p[i] = n; } ~Array() //析构函数 { delete[] p; } Array & operator=(const Array & A) //重载= { if (this == &A) return *this; delete[] p; Size = A.Size; p = new double[Size]; memcpy(p, A.p, Size * sizeof(double)); return *this; } Array operator*(const Array & A) //对应元素* { Array result(Size); for (int i = 0; i < Size; i++)result.p[i] = p[i] * A.p[i]; return result; } private: int Size; double *p; }; int main() { clock_t time1, time2; Array A(10000, 1.0); Array B(10000, 1.0); Array C(10000, 1.0); time1 = clock(); for (int t = 0; t < 1000000; t++)C = A * B; time2 = clock(); std::cout<< "Time1 = " << (double)(time2 - time1) / CLOCKS_PER_SEC << "S" << std::endl; //测试直接使用double数组的速度 double a[10000]; double b[10000]; double c[10000]; for (int i = 0; i < 10000; i++)a[i] = 1, b[i] = 1; time1 = clock(); for (int t = 0; t < 1000000; t++) for (int i = 0; i < 10000; i++)c[i]=a[i] * b[i]; time2 = clock(); std::cout << "Time2 = " << (double)(time2 - time1) / CLOCKS_PER_SEC << "S" << std::endl; system("pause"); return 0; }
输出:
Time1 = 10.4S
Time2 = 0.492S
使用对象的时候慢了20多倍用matlab做相同工作的时候:
A=ones(10000,1); B=zeros(10000,1); t1=clock; for i=1:1000000 C=A.*B; end t2=clock; T=etime(t2,t1)
输出:
T =4.8610
我这样写是否犯了什么错误? 这种情况下应该如何提升c++的效率呢? -
@我是河滩 MPI是OpenFoam官方使用的并行方法,现在来看应该是只能用这个。我没有研究过并行的代码,复不复杂应该取决于你对openFoam求解器改动程度的大小,小改动一般不用重写并行的代码。
-
@FluidGao 嗯嗯,感谢。
-
@FluidGao 谢谢您的解答,dugks和LBM都基于BGK对玻尔兹曼方程进行离散,但是数值方法上是不是有很大差别?因为我最近试用了dugksFoam这个求解器
:dugksfoam-求解离散速度boltzmann模型方程的求解器
里面有个简单的cavity算例,但是感觉计算速度较慢,无法与LBM的计算效率相比。 -
@东岳 嗯嗯,十分感谢,我再去多读点文章,兴许就懂了
-
@rogerchan 十分感谢,我回头看看这篇文章。
@东岳 这两种都不属于格子玻尔兹曼(LBM)方法吗? -
@东岳 东岳老师,请问LBM(Lattice-Boltzmann-Method)和openFOAM里的dsmcFOAM的关系是什么,还有@lhzhu老师开发的dugksFOAM求解器,都是针对稀薄求解玻尔兹曼方程的方法?是两个不同的体系吗?主要区别在哪里?
-
@东岳 哦哦,对对对,能通过边界条件来实现的话就方便多了!
-
@东岳 是的,求解本身没有用到平均速度 ,也没有规定平均速度,给它一个压力梯度(实际相当于增加了一个体积力),让摩擦力自己跟压力梯度平衡去,平均速度会在某个值附近上下波动。
-
@东岳 破案了……
出现错误的原因在于离散格式,当时我看到dnsFoam的那个算例里使用了div(phi,U) Gauss cubic;
这个离散格式,一查还是个高阶格式,就直接拿来在我的算例里用了。现在改回Gauss linear格式,算得很好:
基本到达了文献中的效果
我翻了一下中文版指南,发现这个cubic格式被描述为dnsFoam专用的
里面的详细原理还不太清楚,我现在对离散格式的选用还理解不深,感觉还是玄学般的东西,哈哈ORZ -
@东岳 嗯嗯,我都会尝试一下
-
@东岳 谢谢东岳老师
这个meanVelocityForce的源项我用过,但是和我想要的不太一样,meanVelocityForce也是通过添加一个压力梯度来控制平均速度的,但它给添加的压力梯度项是随时间步不断计算调整的,我想添加一个简单的常数的压力梯度。不过我确实可以通过修改meanVelocityForce来达到这个目的,今后我会试一下这个。
另外,我那个平均速度的代码就是从meanVelocityForce中copy过来的,稍微改了一下下让他能在求解器中运行,现在来看运行的还可以。而且这个平均速度只是为了在log中输出一个当前流场的平均速度,方便我检测求解状况,不会影响迭代求解的,所以还是不太清楚结果中的问题出在了哪里。ORZ -
我想用q-DNS模拟一个Re_tau=180的槽道湍流,网格与这篇链接文本文献中基本相同。
我更改了一下icoFoam的计算公式,代码包:0_1546247060398_pGradIcoFoam.zip
具体改法如下:
- createFields.H中,添加一个pGrad场,量纲与压力梯度相同,大小直接给出:
volVectorField pGrad ( IOobject ( "pGrad", runTime.timeName(), mesh, IOobject::NO_READ, //MUST_READ, IOobject::AUTO_WRITE ), mesh, dimensionedVector("pGrad",dimensionSet(0, 1, -2, 0, 0),vector(-1,0,0)) );
- 动量预测方程中把pGrad项加入到方程右边,与压力梯度项并列
{ solve(UEqn == -fvc::grad(p)-pGrad); }
-
压力泊松方程中也加入pGrad项带来的影响
fvScalarMatrix pEqn ( fvm::laplacian(rAU, p) + fvc::div(rAU\*pGrad) == fvc::div(phiHbyA) );
-
还有最后一步的速度修正:
U = HbyA - rAU\*fvc::grad(p)- rAU\*pGrad;
- 另外,还有按照苏老师博客里的方法,把icoFoam改为可以变时间步长的求解器
- 加入计算并输出平均速度的代码:
scalar magUbarAve = 0.0; scalar V = 0.0; const scalarField& cv = mesh.V(); vector flowDir_ = vector(1,0,0); for(label celli=0; celli < mesh.C().size() ; celli++) { scalar volCell = cv[celli]; V += volCell; magUbarAve += (flowDir_ & U[celli])*volCell; } reduce(magUbarAve, sumOp<scalar>()); reduce(V, sumOp<scalar>()); magUbarAve /= V; Info << "Ubar = " << magUbarAve << endl;
计算算例:
0_1546249122420_channel180.zip
计算初始场用perturbU工具进行打乱,然后计算一些时间步获得完全发展的湍流场
我现在遇到的问题是,计算一段时间后,发现靠近边界层的速度算得还比较准,但是槽道中部远离边界层的地方出现奇怪的脉动
放大可看到这个脉动大概以三个cells为一个周期。
最奇怪的是平均速度型竟然上下不对称已做时间足够长的平均
我的改动中应该没有会引起这种不对称的地方?
壁面律图像和雷诺应力图像也同样,壁面处算得还好,中间算不好
似乎可能是中间网格不够密的原因?但是我使用的网格应该和那篇参考文献中相同啊,他也用的是openFoam做的q-DNS,但他得到的结果就很好,所以我现在不知道错在什么地方。
我修改后的求解器、算例的基本设定都已上传,希望各位老师能帮忙指点一下,不胜感激! -
@东岳 是官方的求解器,不过有一个自已的边界条件。而且只出现过一次,后来再用就没问题了。
-
说起MPI我也遇到过奇怪的问题,我用虚拟机进行的计算,就只用两个核并行跑程序,算了一个晚上,第二天早上起来发现产生了几十个G的内存,直接把我放虚拟机的那个硬盘撑满了,导致虚拟机直接崩溃。我后来直接删了那个虚拟机文件重新安装的。
我没有让他保存太多的时间步啊,不知道哪里产生的这么大内存。因为硬盘撑满了虚拟机打不开我也没有再查看到底怎么了,这就变成悬案了QAQ
不过幸好后来没有再遇到过一样的问题,我再次安装的时候也更新了MPI版本,不知道是不是这个原因……
有人遇到过类似问题吗? -
@东岳 李老师,一般说xx计算对y+的要求,是指的y+的最大值,最小值,还是平均值呢?
-
感谢@东岳 老师的详细解答!
-
1.dnsFoam.C中描述这个求解器用来模拟box中的各向同性湍流,也就是说这个求解器不适合模拟壁湍流是吗?
2.据说icoFoam在网格足够密的情况下相对于dns计算,那么pisoFoam在网格足够密且laminar模式下是否也相对于dns?这样与ico的计算有区别吗?
3.很多人把openfoam里的dns称为quasi-dns。这个怎么理解?它与标准dns的区别在哪里?
感谢大神解惑(。・ω・。)ノ♡
如何把volScalarField中的数据转化为double数组?
如何把volScalarField中的数据转化为double数组?
如何把volScalarField中的数据转化为double数组?
S-A模型是如何处理湍动能k的?
S-A模型是如何处理湍动能k的?
S-A模型是如何处理湍动能k的?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
可以讨论一个编程问题吗?这样写C++代码效率为何这么低?
一个奇怪的问题,OpenFOAM在断网的时候终止计算
求关于LBM方法的算例或者教程
求关于LBM方法的算例或者教程
求关于LBM方法的算例或者教程
求关于LBM方法的算例或者教程
求关于LBM方法的算例或者教程
Cyclic周期性边界条件
q-DNS计算槽道流遇到了一些问题,求大神们指点
q-DNS计算槽道流遇到了一些问题,求大神们指点
q-DNS计算槽道流遇到了一些问题,求大神们指点
q-DNS计算槽道流遇到了一些问题,求大神们指点
q-DNS计算槽道流遇到了一些问题,求大神们指点
一个奇怪的问题,OpenFOAM在断网的时候终止计算
一个奇怪的问题,OpenFOAM在断网的时候终止计算
OpenFOAM中kOmegaSST和yPlusRAS
关于dns的几个小问题
关于dns的几个小问题