openFOAM学习笔记(五)——chemFoam的运行过程
在前面的帖子中已经大概给出了chemFoam主程序的结构,这里给出一个比较全面的总结
首先程序结构如下:
添加头文件//*****************************//
int main(int argc, char *argv[])
{ 初始化 while(runTime.run()){ 计算化学反应输出中间结果}return 0;
}
我们接下来介绍各个部分的具体内容
while循环中的燃烧计算
其源码如下:
while (runTime.run()){//控制时间步长#include "readControls.H" #include "setDeltaT.H" runTime++;Info<< "Time = " << runTime.timeName() << nl << endl;//燃烧的求解#include "solveChemistry.H" #include "YEqn.H" #include "hEqn.H" #include "pEqn.H" //输出中间过程#include "output.H" Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"<< " ClockTime = " << runTime.elapsedClockTime() << " s"<< nl << endl;}
其中燃烧的过程的头文件源码内容如下:
//#include "solveChemistry.H"
dtChem = chemistry.solve(runTime.deltaT().value()); //求解之后的反应速率存在类中
scalar Qdot = chemistry.Qdot()()[0]/rho[0]; //反应放热速度?直接从类中提取
integratedHeat += Qdot*runTime.deltaT().value(); //反应放热
//#include "YEqn.H" 更新组分
{forAll(Y, specieI){volScalarField& Yi = Y[specieI];solve(fvm::ddt(rho, Yi) - chemistry.RR(specieI), "Yi"); //代表 d(rho*Yi)/dt - 速率=0这个ode方程}
}
//#include "hEqn.H" 更新焓,同时更新温度
if (constProp != "temperature") //非定温的情况下
{volScalarField& h = thermo.he(); //可以计算焓if (constProp == "volume") //定容和定压两种{h[0] = u0 + p[0]/rho[0] + integratedHeat;}else{h[0] = h0 + integratedHeat;}thermo.correct();
}
//#include "pEqn.H" 更新压力,密度本来就不变
{rho = thermo.rho();if (constProp == "volume"){scalar invW = 0.0;forAll(Y, i){invW += Y[i][0]/W[i];}Rspecific[0] = 1000.0*constant::physicoChemical::R.value()*invW;p[0] = rho0*Rspecific[0]*thermo.T()[0]; //p = rho R Trho[0] = rho0;}
}
计算过程为,先计算反应速率,然后用反应速率计算组分,然后更新焓和温度,最后更新压力。其中组分和各个热学量的计算不难理解,而反应速率的计算调用了另外一个函数solve。该函数来自类StandardChemistryModel
,内容如下:
template<class ReactionThermo, class ThermoType>
template<class DeltaTType>
Foam::scalar Foam::StandardChemistryModel<ReactionThermo, ThermoType>::solve
(const DeltaTType& deltaT
)
{BasicChemistryModel<ReactionThermo>::correct();scalar deltaTMin = great;if (!this->chemistry_){return deltaTMin;}tmp<volScalarField> trho(this->thermo().rho());const scalarField& rho = trho();const scalarField& T = this->thermo().T();const scalarField& p = this->thermo().p();scalarField c0(nSpecie_);forAll(rho, celli) //对所有的cell遍历{scalar Ti = T[celli];if (Ti > Treact_) //超过燃点才会燃烧{const scalar rhoi = rho[celli];scalar pi = p[celli];for (label i=0; i<nSpecie_; i++) //通过密度和质量分数计算摩尔浓度{c_[i] = rhoi*Y_[i][celli]/specieThermo_[i].W();c0[i] = c_[i];}// Initialise time progressscalar timeLeft = deltaT[celli];// Calculate the chemical source termswhile (timeLeft > small){scalar dt = timeLeft;this->solve(c_, Ti, pi, dt, this->deltaTChem_[celli]); //这里调用的是basicChemistryModel中纯虚函数的一个实现,更新了c_timeLeft -= dt;}deltaTMin = min(this->deltaTChem_[celli], deltaTMin);this->deltaTChem_[celli] =min(this->deltaTChem_[celli], this->deltaTChemMax_);for (label i=0; i<nSpecie_; i++){RR_[i][celli] =(c_[i] - c0[i])*specieThermo_[i].W()/deltaT[celli];} //先计算出更新的摩尔浓度,再除以时间得到反映速率?}else{for (label i=0; i<nSpecie_; i++){RR_[i][celli] = 0;}}}return deltaTMin;
}
其中RR_
即为计算所得的反应速率。
所以chemFoam计算燃烧的过程如下:
while
{ 更新当前反应速率利用反应速率计算反应热更新组分更新焓和温度更新压力
}
头文件部分
首先给出一共添加了哪些头文件:
#include "fvCFD.H"
#include "rhoReactionThermo.H"
#include "BasicChemistryModel.H"
#include "reactingMixture.H"
#include "chemistrySolver.H"
#include "OFstream.H"
#include "thermoPhysicsTypes.H"
#include "basicSpecieMixture.H"
#include "cellModeller.H"
#include "thermoTypeFunctions.H"
其中fvCFD.H
为有限体积法求解过程中需要使用的代码,它添加了大量的头文件。设计时间相关的类,优先体积法离散格式相关的类,以及单位制转换相关的类。求解过程中的solve(fvm::ddt(rho, Yi) - chemistry.RR(specieI), "Yi");
依赖这部分代码。
rhoReactionThermo.H
和reactingMixture.H
以及baicSpecieMixture.H
为多组分和热学相关的类,前面求解过程中焓温度以及压力的更新,依赖这些类中的函数。
BasicChemistryModel.H
和chemistrySolver.H
为燃烧求解过程使用的类,前面求解过程中的chemistry.solve()
依赖这部分含糊,
OFstream.H
为文件流和文件操作需要使用的头文件
thermoPhysicsTypes.H
和thermoTypeFunctions.H
进行了部分类型定义和函数定义,方便后面使用。
初始化部分
源码如下:
argList::noParallel(); //并行操作#define CREATE_MESH createSingleCellMesh.H
#define NO_CONTROL
#include "postProcess.H" //续算时有用
#include "setRootCaseLists.H" //对终端输入args进行处理
#include "createTime.H" //初始化时间类runTime,同时从控制文件读取控制参数以进行初始化
#include "createSingleCellMesh.H" //创建一个只有一个cell的网格,正常的算例中此处为读取给定的网格
#include "createFields.H" //读取initialConditions,读取基础的热学信息,创建pChemistry
#include "createFieldRefs.H" //利用pChemistry创建chemistry
#include "readInitialConditions.H" //继续读取initialCondtions中信息,constantProperty以及各个组分初始浓度
#include "createControls.H" //继续读取controlDict中的信息,主要为时间步长的控制
主要创建的类为:
Foam::Time runTime
fvMesh mesh
autoPtr<rhoReactionThermo> pThermo(rhoReactionThermo::New(mesh))
rhoReactionThermo& thermo = pThermo()
autoPtr<BasicChemistryModel<rhoReactionThermo>> pChemistry(BasicChemistryModel<rhoReactionThermo>::New(thermo))
OFstream post(args.path()/"chemFoam.out")
BasicChemistryModel<rhoReactionThermo>& chemistry = pChemistry()
分别时间,网格控制,以及热学和化学反应的控制。类对象在创建过程中就通过构造函数读取了控制文件进行了初始化。
执行方法
首先chemFoam是编译好的文件,我们只需要调用即可,将我们希望计算的控制文件配置好。例如我们希望计算氢气燃烧,就将配置好的文件夹添加到路径~.OpenFOAM/dyfluid-7/run/h2
中:
键入chemFoam > chemFoam.out
把结果保存起来方便后续和CHEMKIN的结果做对比:
之后将计算结果chemFoam.out
复制到validation
文件夹中,调用预先写好的createGraph
脚本作图
脚本内容其实是gnuplot
作图的代码
#!/bin/shif ! which gnuplot > /dev/null 2>&1
thenecho "gnuplot not found - skipping graph creation" >&2exit 1
fignuplot<<EOFset terminal postscript eps color enhanced "Helvetica,20"set output "OF_vs_CHEMKINII.eps"set xlabel "Time / [s]" font "Helvetica,24"set ylabel "Temperature / [K]" font "Helvetica,24"set gridset key left topset xrange [0:0.001]set yrange [750:2750]set ytic 250plot \"../chemFoam.out" u 1:2 t "OpenFOAM" with points lt 1 pt 6 ps 1.5,\"chemkinII" with lines title "Chemkin II" lt -1
EOF#------------------------------------------------------------------------------
作图结果如下:
H2计算结果(上)和C8H18计算结果(下)
详细的类见关系解读
这里挖个坑,前面介绍的是程序大概的内容,以及其使用方法。但是代码实现使用的类型其实均经过高度的封装,这些类的支持性文件非常多,反而是openFOAM的主体源码内容。这里罗列大纲,并会不断的进行补充。
- 基础的类,如整型浮点型,字符串,布尔类型
- 基础的数据结构,如向量,数组,链表,域
- 文件读取过程中文件流的获取
- Chemistry一族的类间关系和可进行操作
- therm一族的类间关系和可进行操作
openFOAM学习笔记(五)——chemFoam的运行过程相关推荐
- Python学习笔记五:控制语句
Python学习笔记五:控制语句 Pycharm 开发环境的下载安装配置_项目管理 控制语句 Pycharm 开发环境的使用 Pycharm 下载和安装 激活和选择不同UI 风格 创建项目和初始化配置 ...
- python函数是一段具有特定功能的语句组_Python学习笔记(五)函数和代码复用
本文将为您描述Python学习笔记(五)函数和代码复用,具体完成步骤: 函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Pyth ...
- StackExchange.Redis学习笔记(五) 发布和订阅
StackExchange.Redis学习笔记(五) 发布和订阅 原文:StackExchange.Redis学习笔记(五) 发布和订阅 Redis命令中的Pub/Sub Redis在 2.0之后的版 ...
- 吴恩达《机器学习》学习笔记五——逻辑回归
吴恩达<机器学习>学习笔记五--逻辑回归 一. 分类(classification) 1.定义 2.阈值 二. 逻辑(logistic)回归假设函数 1.假设的表达式 2.假设表达式的意义 ...
- 【AngularJs学习笔记五】AngularJS从构建项目开始
为什么80%的码农都做不了架构师?>>> #0 系列目录# AngularJs学习笔记 [AngularJs学习笔记一]Bower解决js的依赖管理 [AngularJs学习笔 ...
- ROS学习笔记五:理解ROS topics
ROS学习笔记五:理解ROS topics 本节主要介绍ROS topics并且使用rostopic和rqt_plot命令行工具. 例子展示 roscore 首先运行roscore系列服务,这是使用R ...
- 哈工大操作系统学习笔记五——内核级线程实现
哈工大os学习笔记五(内核级线程实现) 文章目录 哈工大os学习笔记五(内核级线程实现) 一. 中断入口.中断出口(前后两段) 1. 从int中断进入内核(中断入口第一段) 2.中断出口(最后一段) ...
- 华清远见fs4412开发板学习笔记(五)
fs4412开发板学习笔记(五) 作业1: 输入10个整数,按从小到大的顺序输出(选择排序) 每轮排序在未排序的集合中找到(最小/最大),将找到的数与未排序的 第一个数交换位置. 5 4 3 2 1 ...
- 【K210】K210学习笔记五——串口通信
[K210]K210学习笔记五--串口通信 前言 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口接收相关定义 K210串口发送接收测试 完整源码 前言 本人大四学生 ...
最新文章
- ES5 数组方法forEach
- (转载)Android进阶2之Activity之间数据交流(onActivityResult的用法)
- JavaSE_04异常处理
- .NET开发人员如何开始使用ML.NET
- Python GUI界面编程初步 05- GUI框架PyQt的运用 - 01 PyQt的详细安装和基本使用
- labview串口数据采集并显示_一种NB-IoT冶金节点温度采集与远程监测系统的设计...
- vim 快捷键_VIM学习笔记 自动补全详解(Auto-Completion Detail)
- 网站扫描服务器全部开放端口,服务器开放端口扫描
- Netty集成WebSocket实现客户端、服务端长连接
- 屏幕取色器(Qt实现)(放大镜,RGB显示,智能调节)
- 二分法查找——绝对值最小的数
- word如何设置每一章节的页眉都不同
- 32岁,我从公司离职了,是裸辞......
- html 下拉框高度,如何自定义设置select下拉框高度的优化方法
- 岭南学院python课程作业1
- 苹果、微软合作推新版iCloud for Windows app
- linux防火墙规则配置教程,linux防火墙iptables详细教程
- 四种常用的微服务架构拆分方式
- android平板 跑分软件,哪个手机跑分软件好用 这4款软件推荐给你
- 计算机辅助教学设计,计算机辅助教学设计介绍
热门文章
- C语言,Microsoft Visual C++ 2010 学习版 软件包
- Rubymine的正确打开办法 :)
- 专科段《质量管理》课程复习资料(3)——简答、计算题
- android手机短信息中心设置
- 计算机应用基础考试单选,计算机应用基础统考题库_计算机应用基础统考试题及答案(单选题)...
- 求高手带上岸,网红KOL营销行业的水太深了!!
- 国内十大无代码平台,无代码app开发平台有哪些?
- 学习AP历史有哪些建议?
- 融优学堂生物演化13.5
- vs2010 wdk c语言,Windows7+WDK+VS2010+VisualDDK驱动开发环境搭建.doc