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. centos通过日志查入侵

    1. Linux查看/var/log/wtmp文件查看可疑IP登陆 last -f /var/log/wtmp 该日志文件永久记录每个用户登录.注销及系统的启动.停机的事件.因此随着系统正常运行时间的 ...

  2. Python实现哈希表(分离链接法)

    一.python实现哈希表 只使用list,构建简单的哈希表(字典对象) # 不使用字典构造的分离连接法版哈希表 class HashList(): """ Simple ...

  3. RS485 MODBUS RTU通信协议

    1.RS485接口标准 RS485由RS232和RS422发展而来,弥补了抗干扰能力差.通信距离短.速率低的缺点,增加了多点.双向通信能力,即允许多个发送器连接在同一条主线上,同时增加了发送器的驱动能 ...

  4. 从傅里叶级数(Fourier series)到离散傅里叶变换(Discrete Fourier transform)

    从傅里叶级数(Fourier series)到离散傅里叶变换(Discrete Fourier transform) 一. 傅里叶级数(FS) 首先从最直观的开始,我们有一个信号\(x(t)\)(满足 ...

  5. RESTAPI 版本控制策略【eolink 翻译】

    微服务,是现阶段开发建设云原生应用程序的流行趋向.API 版本控制有益于在辨别出所需要的调节时加速迭代更新的速度. 根据微服务架构的关键构件其一,是 API 的设计和规范.针对 API,版本控制是不可 ...

  6. Template -「平衡树」

    Fhq-Treap. // Fhq-Treap const int MAXN = 1e5 + 5; struct Fhq_Treap { #define Lson Tr[p].l #define Rs ...

  7. CF455ABoredom

    题目大意: 给你一个由 \(n\) 个整数构成的序列 \(a\),玩家可以进行几个步骤,每一步他可以选择序列中的一个元素(我们把它的值定义为 \(a_k\))并删除它,此时值等于 \(a_{k + 1 ...

  8. mysql开发实战8问

    mysql读写性能是多少,有哪些性能相关的配置参数? Mysql负载高时,如何找到是由哪些SQL引起的? 如何针对具体的SQL做优化? SQL层面已难以优化,请求量继续增大时的应对策略? Mysql如 ...

  9. IDEA Git缓慢

    有的公司电脑会强制安装一些特定的杀毒软件或者监控软件. 在安装后,我们的 IDEA 可能会出现 Git 相关操作非常缓慢的情况. 虽然用 Git 命令操作不受影响,但终究没有可视化界面直观方便. 解决 ...

  10. Go 语言图片处理简明教程

    虽然 Go 语言主要用于 Web 后端以及各类中间件和基础设施开发,也难免遇到一些图像处理的需求.Go 语言提供的 image 标准库提供了基本的图片加载.裁剪.绘制等能力,可以帮助我们实现一些绘图需 ...