0. 写在前面

本文中将对一维瞬态热传导问题进行数值求解,并基于OpenFOAM类库编写求解器。该问题参考自教科书\(^{[1]}\)示例 8.1。

1. 问题描述

一维瞬态热传导问题控制方程如下

\[\rho c \frac{\partial T}{\partial t} = \nabla\cdot \left(k\nabla T\right)
\]

其中,\(\rho c = 1.0\times10^{+7}\ \mathrm{J/m^3\cdot K}\),\(k=10\ \mathrm{W/m\cdot K}\)。

假设等截面直杆长为 \(L=0.02\ \mathrm{m}\),截面为边长 \(0.001\ \mathrm{m}\) 的正方形,全杆初始温度为 \(200 \mathrm{K}\) ,左侧边界条件为\(\nabla T = 0\),右侧边界条件为\(T=0\);杆长方向与 \(x\) 轴平行,此处一维问题不考虑 \(y\) 和 \(z\) 方向。

该问题存在解析解

\[\frac{T(x,t)}{200} = \frac{4}{\pi} \sum_{n=1}^\infty \frac{\left(-1\right)^{n+1}}{2n-1} \exp{\left(-\alpha\lambda_n^2t\right)} \cos \left(\lambda_nx\right)
\]

其中,\(\lambda_n = \frac{\left(2n-1\right)\pi}{2L}\),\(\alpha = \frac{k}{\rho c}\)。

2. 数值解法

对于该物理模型,采用均匀正六面体结构化网格,网格数量为10,相邻网格体心距离为 \(\Delta x = 0.002 \mathrm{m}\),截面面积为\(S = 1\times 10^{-6} \mathrm{m}^2\),网格体积为 \(V_P = 2\times10^{-9} \mathrm{m}^3\),网格示意图如下。

对控制方程进行离散(时间项一阶隐式欧拉格式,固定时间步\(\Delta t = 0.001 \mathrm{s}\)(满足稳定条件)、界面插值采用中心差分格式),可以得到下面线性方程

\[\frac{\rho c V_P}{\Delta t} \left( T_P - T_P^0 \right) = k\sum_N \frac{ T_N - T_P }{\Delta x} S_{N,f}
\]

其对应该问题线性方程组的矩阵形式如下

\[\begin{bmatrix}
20.005 & -0.005 & 0 & \cdots & 0 & 0 & 0 \\
-0.005 & 20.005 & -0.005 & \cdots & 0 & 0 & 0\\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots\\
0 & 0 & 0 & \cdots & -0.005 & 20.005 & -0.005 \\
0 & 0 & 0 & \cdots & 0 & -0.005 & 20.015\\
\end{bmatrix}

\begin{bmatrix}
T_0 \\ T_1 \\ \vdots \\ T_8 \\ T_9
\end{bmatrix}

=

\begin{bmatrix}
20 T_0^0 \\ 20 T_1^0 \\ \vdots \\ 20 T_8^0 \\20 T_9^0
\end{bmatrix}
\]

3. OpenFOAM求解

此处,我们把OpenFOAM作为类库使用,可以很快的完成一个求解器,不会涉及过多的底层工作。

3.1 求解器源码

#include "fvCFD.H"
#include <iostream> int main(int argc, char* argv[])
{
#include "setRootCaseLists.H"
#include "createTime.H" // 构造 runTime 对象
#include "createMesh.H" // 构造 mesh 对象
// 密度 x 热容
dimensionedScalar rhoC("rhoC", dimensionSet(1, -1, -2, 1, 0, 0, 0), scalar(1.e+7));
// 热导率
dimensionedScalar k("k", dimensionSet(1, 1, -3, 1, 0, 0, 0), scalar(10.0));
// 温度场,需要从0文件夹中读取初始值
volScalarField T(IOobject("T", "0", mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE), mesh); while ( runTime.loop() )
{
Info << "当前时间 : " << runTime.timeName() << " s" << endl << endl;
// 构造线性方程组
fvScalarMatrix TEqn(fvm::ddt(rhoC, T) == fvm::laplacian(k, T));
// 求解
TEqn.solve();
// 更新边界值
T.correctBoundaryConditions(); if ( runTime.timeIndex() == 1 )
{ // 打印方程组;这段代码放在哪里无所谓,此代码没有在时间步内再次更新 TEqn
Info << "#### UPPER\n" << TEqn.upper() << endl;
Info << "#### DIAG \n" << TEqn.D() << endl;
Info << "#### LOWER\n" << TEqn.lower() << endl;
Info << "#### SOURCE\n" << TEqn.source() << endl; // Right Hand Side
getchar(); // 此处暂停,按回车继续运行...
} if ( runTime.writeTime() )
{
runTime.write();
}
runTime.printExecutionTime(Info);
}
return 0;
}

3.2 CMakeLists.txt

cmake_minimum_required (VERSION 3.8)
project(OneDimUnsteadyFlow) # OpenFOAM 安装路径
set( FOAM_PREFIX "/opt/OpenFOAM-v2112" )
# 包含路径
set( FOAM_SRC ${FOAM_PREFIX}/OpenFOAM-v2112/src )
include_directories(
${FOAM_SRC}/atmosphericModels/lnInclude
${FOAM_SRC}/combustionModels/lnInclude
${FOAM_SRC}/conversion/lnInclude
${FOAM_SRC}/dummyThirdParty/lnInclude
${FOAM_SRC}/dynamicFaMesh/lnInclude
${FOAM_SRC}/dynamicFvMesh/lnInclude
${FOAM_SRC}/dynamicMesh/lnInclude
${FOAM_SRC}/engine/lnInclude
${FOAM_SRC}/faOptions/lnInclude
${FOAM_SRC}/fileFormats/lnInclude
${FOAM_SRC}/finiteArea/lnInclude
${FOAM_SRC}/finiteVolume/lnInclude
${FOAM_SRC}/functionObjects/lnInclude
${FOAM_SRC}/fvAgglomerationMethods/lnInclude
${FOAM_SRC}/fvMotionSolver/lnInclude
${FOAM_SRC}/genericPatchFields/lnInclude
${FOAM_SRC}/lagrangian/lnInclude
${FOAM_SRC}/lumpedPointMotion/lnInclude
${FOAM_SRC}/mesh/lnInclude
${FOAM_SRC}/meshTools/lnInclude
${FOAM_SRC}/ODE/lnInclude
${FOAM_SRC}/OpenFOAM/lnInclude
${FOAM_SRC}/optimisation/lnInclude
${FOAM_SRC}/OSspecific/POSIX/lnInclude
${FOAM_SRC}/overset/lnInclude
${FOAM_SRC}/parallel/lnInclude
${FOAM_SRC}/phaseSystemModels/lnInclude
${FOAM_SRC}/Pstream/lnInclude
${FOAM_SRC}/randomProcesses/lnInclude
${FOAM_SRC}/regionFaModels/lnInclude
${FOAM_SRC}/regionModels/lnInclude
${FOAM_SRC}/renumber/lnInclude
${FOAM_SRC}/rigidBodyDynamics/lnInclude
${FOAM_SRC}/rigidBodyMeshMotion/lnInclude
${FOAM_SRC}/sampling/lnInclude
${FOAM_SRC}/semiPermeableBaffle/lnInclude
${FOAM_SRC}/sixDoFRigidBodyMotion/lnInclude
${FOAM_SRC}/sixDoFRigidBodyState/lnInclude
${FOAM_SRC}/surfMesh/lnInclude
${FOAM_SRC}/thermophysicalModels/lnInclude
${FOAM_SRC}/topoChangerFvMesh/lnInclude
${FOAM_SRC}/transportModels/lnInclude
${FOAM_SRC}/TurbulenceModels/lnInclude
${FOAM_SRC}/waveModels/lnInclude
.
) link_directories(
${FOAM_PREFIX}/ThirdParty-v2112/platforms/linux64Gcc/boost_1_74_0/lib64
${FOAM_PREFIX}/ThirdParty-v2112/platforms/linux64Gcc/fftw-3.3.10/lib64
${FOAM_PREFIX}/ThirdParty-v2112/platforms/linux64Gcc/kahip-3.14/lib64
${FOAM_PREFIX}/ThirdParty-v2112/platforms/linux64GccDPInt32/lib
${FOAM_PREFIX}/ThirdParty-v2112/platforms/linux64GccDPInt32/lib/sys-openmpi ${FOAM_PREFIX}/OpenFOAM-v2112/platforms/linux64GccDPInt32Opt/lib
${FOAM_PREFIX}/OpenFOAM-v2112/platforms/linux64GccDPInt32Opt/lib/dummy
${FOAM_PREFIX}/OpenFOAM-v2112/platforms/linux64GccDPInt32Opt/lib/sys-openmpi
)
set(EXTRA_LIBS dl m)
set(LIBS
Pstream
OpenFOAM
finiteVolume
meshTools
fileFormats
${EXTRA_LIBS}
) set( CMAKE_CXX_STANDARD 11 )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker --no-as-needed -Xlinker --add-needed" )
add_definitions(-Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -DNoRepository -m64 -fPIC ) # 添加可执行文件
add_executable (${PROJECT_NAME} "main.cpp") # 链接库
target_link_libraries(${PROJECT_NAME} ${LIBS})

4. 算例设置

4.1 system/blockMeshDict

FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
} scale 1.0; // memter length 0.02; // 长度 nx 10; // x 方向 网格数量
ny 1;
nz 1; vertices
(
(0.0 0.0 0.0)
($length 0.0 0.0)
($length 0.001 0.0)
(0.0 0.001 0.0) (0.0 0.0 0.001)
($length 0.0 0.001)
($length 0.001 0.001)
(0.0 0.001 0.001)
); edges
(
); blocks
(
hex (0 1 2 3 4 5 6 7) ($nx $ny $nz) simpleGgrading (1 1 1)
); boundary
(
left
{
type patch;
faces
(
(0 4 7 3)
);
}
right
{
type patch;
faces
(
(1 2 6 5)
);
}
other
{
type empty;
faces
(
(2 3 7 6)
(4 5 6 7)
(0 1 5 4)
(1 0 3 2)
);
}
);

4.2 system/controDict

FoamFile
{
version 2.0;
format ascii;
class dictionary;
object controlDict;
} application OneDimUnsteadyFlow;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 125;
deltaT 0.001;
writeControl adjustableRunTime;
writeInterval 0.1; // 0.1秒为间隔输出数据
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable no;

4.3 system/fvSchemes

FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSchemes;
} ddtSchemes
{
default Euler; // \phi_t = \frac{\phi - \phi^0}{\Delta t}
} gradSchemes
{
default Gauss linear; // 基于高斯定理的梯度格式
} divSchemes
{
default Gauss linear; // \phi_f = 0.5(\phi_P + \phi_N)
} laplacianSchemes
{
default Gauss linear uncorrected; // linear:中心差分格式;uncorrected:不进行非正交性修正
}

本文中,上述ddtSchemeslaplacianSchemes 格式为离散方程时所用格式,具体细节已在前边叙述。

4.4 system/fvSolution

FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSolution;
} solvers
{
T
{
solver GAMG;
smoother GaussSeidel;
tolerance 1e-08;
relTol 0.0;
}
}

4.5 0/T

FoamFile
{
version 2.0;
format ascii;
arch "LSB;label=32;scalar=64";
class volScalarField;
location "0";
object T;
} dimensions [0 0 0 1 0 0 0]; internalField uniform 200; boundaryField
{
left
{
type zeroGradient; // 零梯度
}
right
{
type fixedValue; // 固定值
value uniform 0;
}
other
{
type empty;
}
}

5. 求解计算

文件结构如下所示。

.
├── build // build 目录,用于编译代码
├── CMakeLists.txt // 项目管理,内容见3.2节
├── main.cpp // 求解器源代码,内容见3.1节
└── OneDimUnsteadyFlowCase // 算例所在目录 ***
├── 0 // 0 文件夹,保存初始条件
│   └── T // 本示例中只有温度场 T,故此处只有 T 文件,内容见 4.5 节
├── OneDimUnsteadyFlowCase.foam // 算例目录名称+foam扩展名,空文件,仅作ParaView加载结果使用
└── system // system 目录
├── blockMeshDict // blockMesh字典文件,内容见 4.1 节
├── controlDict // 求解器运行控制字典文件,内容见 4.2 节
├── fvSchemes // 有限体积数值格式字典文件,内容见 4.3 节
└── fvSolution // 求解器参数设置字典文件,内容见 4.4 节

5.1 编译求解器

主要命令解释:

$ cd build/  # 从当前目录切换到路径 ./build
$ cmake .. # 执行 CMake 生成构建文件(当前生成的是MakefIle)
$ make # 执行 Make,编译代码

5.2 运行求解器

主要命令解释:

$ cd OneDimUnsteadyFlowCase/  # 从当前目录切换到算例目录
$ blockMesh > log.blockMesh # 运行 blockMesh 画网格,并将标准输出重定向到 log.blockMesh
$ ../build/OneDimUnsteadyFlow # 运行求解器,注意求解器的相对路径

另外,我们也可以看到求解器打印的线性方程组与数值解法中所描述的是一致的。

6. 后处理

我们对比第 \(40 \ \mathrm{s}\) 时数值结果与解析结果

云图:

曲线图:

参考文献

[1] H. Versteeg , W. Malalasekera. Introduction to Computational Fluid Dynamics, An: The Finite Volume Method 2nd Edition[M]. Pearson. 2007

OpenFOAM 编程 | One-Dimensional Transient Heat Conduction的更多相关文章

  1. OpenFOAM 编程 | 求解捕食者与被捕食者模型(predator-prey model)问题(ODEs)

    0. 写在前面 本文问题参考自文献 \(^{[1]}\) 第一章例 6,并假设了一些条件,基于 OpenFOAM-v2206 编写程序数值上求解该问题.笔者之前也写过基于 OpenFOAM 求解偏分方 ...

  2. CUDA Samples: heat conduction(模拟热传导)

    以下CUDA sample是分别用C++和CUDA实现的模拟热传导生成的图像,并对其中使用到的CUDA函数进行了解说,code参考了<GPU高性能编程CUDA实战>一书的第七章,各个文件内 ...

  3. OpenFOAM编程 | Hello OpenFOAM

    写在前面 OpenFOAM 是一个非常好用的开源程序包,笔者一直在研究和使用,其编程语言是笔者非常喜欢使用的 C++.但是笔者不是很喜欢 OpenFOAM 自己的构建工具 wmake,更倾向于使用 C ...

  4. LibTorch | 使用神经网络求解一维稳态对流扩散方程

    0. 写在前面 本文将使用基于LibTorch(PyTorch C++接口)的神经网络求解器,对一维稳态对流扩散方程进行求解.研究问题参考自教科书\(^{[1]}\)示例 8.3. 目录 0. 写在前 ...

  5. OpenFOAM 学习路线 【转载】

    "Two weeks of playing with a CFD code will save you one afternoon of reading" 什么是OpenFOAM( ...

  6. Java基础面试题(Hibernate)

    Hibernate是一个什么样的框架? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hi ...

  7. Hibernate入门(3)- 持久对象的生命周期介绍

    在hibernate中对象有三种状态:瞬时态(Transient). 持久态(Persistent).脱管态或游离态(Detached).处于持久态的对象也称为PO(Persistence Objec ...

  8. 【Java编程】volatile和transient关键字的理解

    理解volatile   volatile是java提供的一种轻量级的同步机制,所谓轻量级,是相对于synchronized(重量级锁,开销比较大)而言的.   根据java虚拟机的内存模型,我们知道 ...

  9. OpenFOAM Tutorial Standard Solvers【转载】

    转载自:http://www.cnblogs.com/fortran/articles/1996927.html boundaryFoam Steady-state solver for 1D tur ...

随机推荐

  1. 从零打造一个Web地图引擎

    说到地图,大家一定很熟悉,平时应该都使用过百度地图.高德地图.腾讯地图等,如果涉及到地图相关的开发需求,也有很多选择,比如前面的几个地图都会提供一套js API,此外也有一些开源地图框架可以使用,比如 ...

  2. Python:socket编程教程

    ocket是基于C/S架构的,也就是说进行socket网络编程,通常需要编写两个py文件,一个服务端,一个客户端. 首先,导入Python中的socket模块: import socket Pytho ...

  3. 说什么也要脱单——Python WEB开发:用Tornado框架制作简易【表白墙】网站

    先来哔哔两句:(https://jq.qq.com/?_wv=1027&k=QgGWqAVF) 今天我们要用Python做Web开发,做一个简单的[表白墙]网站.众所周知表白墙的功能普遍更多的 ...

  4. C# Winform程序界面优化实例

    进入移动互联网时代以来,Windows桌面开发已经很久不碰了.之前就是从做Windows开发入行的. 当年,还是C++ VC6, MFC的时代.那时候开发要查的是MSDN :-).内存要自己管理, 排 ...

  5. 动画 ---Animejs 简单使用与源码解析

    Anime是什么 Anime有什么用 Anime是作何做的 requireAnimationFrame() engine(){ // 处理让多个帧运动起来 ​ play() ​ step()} ani ...

  6. 1_day01_java入门

    java入门 学习目标: 1.熟悉计算机编程语言 2.熟练掌握java特点 3.熟练配置java开发环境 4.熟练编写入门程序 5.熟练编写注释信息 一.计算机语言 1.1 什么是编程语言 计算机语言 ...

  7. CMake教程——Leeds_Garden

    本系列适合 乐于学习新知识的人 想要深入学习C++的人 赞美作者的人 系列目录 初步入门 基本操作 (更新中) 创作不易,欢迎分享,把知识分享给更多有需要的人.

  8. odoo14 编辑状态和非编辑状态下隐藏

    1 <div class="oe_edit_only"> 2 <a name="remove_group_id" type="obj ...

  9. 多线程与高并发(五)—— 源码解析 ReentrantLock

    一.前言 ReentrantLock 是基于 AQS 实现的同步框架,关于 AQS 的源码在 这篇文章 已经讲解过,ReentrantLock 的主要实现都依赖AQS,因此在阅读本文前应该先了解 AQ ...

  10. pytest-fixture执行顺序

    作用域-scope 作用域越大,越先执行,session>package>module>class>function. 是否自动调用fixture 自动调用(autouse=T ...