这篇文章会将FEM全流程走一遍,包括网格、矩阵组装、求解、后处理。内容是大三时的大作业,今天拿出来回顾下。

1. 问题简介

涡轮机叶片需要冷却以提高涡轮的性能和涡轮叶片的寿命。我们现在考虑一个如上图所示的叶片,叶片处在一个高温环境中,中间通有四个冷却孔。

假设为稳态,那么叶片内导热微分方程为:

内部区域:     (扩散方程)

边界:

(外表面)

(内部冷却孔)

2.模型

2.1几何模型

我们简化为二维模型,如下图所示:

点坐标:

1:0.0,0.0          6:597.6,45.9   11:344.7,50.0

2:20.9,28.8      7:870.0,0.0      12:435.8,44.5

3:117.4,62.9   8:85.0,40.0      13:521.2,37.0

4:240.4,69.6   9:174.5,49.4   14:605.0,30.0

5:417.5,62.4   10:260.0,50.0 15:694.7,22.2

2.2 单位系统和物性

长度单位:mm

温度单位: K

功率单位:W

k=14.7*10^-3 W/mm. K

hext=205.8*10^-6 W/m2.K

hint=65.8*10^-6 W/m2.K

注意:在后面的矩阵组装中的h_wall = h / k

2.3网格

用开源软件Gmsh生成网格。

首先写geo文件

注意要把外表面和中间空洞用Physical Line定义

lc = 10;
Point(1) = {0, 0, 0, lc};
Point(2) = {20.9,28.8,0, lc};
Point(3) = {117.4,62.9,0, lc};
Point(4) = {240.4,69.6,0, lc};
Point(5) = {417.5,62.4,0, lc};
Point(6) = {597.6,45.9,0, lc};
Point(7) = {870.0,0.0, 0,lc};
Point(8) = {85.0,40.0, 0,lc};
Point(9) = {174.5,49.4,0, lc};
Point(10) = {260.0,50.0,0, lc};
Point(11) = {344.7,50.0,0, lc};
Point(12) = {435.8,44.5,0, lc};
Point(13) = {521.2,37.0,0, lc};
Point(14) = {605.0,30.0,0, lc};
Point(15) = {694.7,22.2,0, lc}; //+
Spline(1) = {1, 2, 3, 4, 5, 6, 7};
//+
Symmetry {0, 1, 0, 0} {
Duplicata { Point{1}; Point{2}; Point{3}; Point{4}; Point{5}; Line{1}; Point{6}; Point{7}; Point{8}; Point{9}; Point{10}; Point{11}; Point{12}; Point{13}; Point{14}; Point{15}; }
} //+
Line Loop(1) = {1, -2};
//+
Line(3) = {8, 9};
//+
Line(4) = {9, 33};
//+
Line(5) = {33, 32};
//+
Line(6) = {32, 8};
//+
Line(7) = {10, 11};
//+
Line(8) = {11, 35};
//+
Line(9) = {35, 34};
//+
Line(10) = {34, 10};
//+
Line(11) = {12, 13};
//+
Line(12) = {13, 37};
//+
Line(13) = {37, 36};
//+
Line(14) = {36, 12};
//+
Line(15) = {14, 15};
//+
Line(16) = {15, 39};
//+
Line(17) = {39, 38};
//+
Line(18) = {38, 14};
//+
Line Loop(2) = {3, 4, 5, 6};
//+
Line Loop(3) = {7, 8, 9, 10};
//+
Line Loop(4) = {11, 12, 13, 14};
//+
Line Loop(5) = {15, 16, 17, 18};
//+
Physical Line(0)={1, -2};
Physical Line(1)={3, 4, 5, 6};
Physical Line(2)={7, 8, 9, 10};
Physical Line(3)={11, 12, 13, 14};
Physical Line(4)={15, 16, 17, 18}; Plane Surface(1) = {1, 2, 3, 4, 5};
Physical Surface(1) = {1};

边界信息如何保存?

边界edges需要用标记,

在matlab程序中用bedge(3,Nbc)存储边界信息,前两个数字代表边的两端节点编号,第三个数字代表属于哪一个边。

生成网格后导出为“blademesh.m”用以后续使用,注意不要勾选Save all elements,否则会没有边界信息。

我用gmsh-4.4.1-Windows64版本,可以导出边界信息。但是新版的gmsh导出为.m文件时,边界信息无法保存。

3. 矩阵组装和求解

3.1 控制方程

3.2 系统矩阵

其中的Ω代表全域,我们将全域分解为一个个单元,这就是有限元的思想。

计算每个单元(Ωe)的刚度矩阵,然后每项加到整体刚度矩阵:

4. 代码实现(matlab)

步骤

工具或函数

定义求解域并生成网格

gmsh导出网格为blademesh.m

读入网格信息,数据转换

bladeread

矩阵和矢量组装,线性方程组求解

bleadheat

查看结果

bladeplot

主程序:bladeheat.m 

% Clear variables

clear all;

% Set gas temperature and wall heat transfer coefficients at
% boundaries of the blade. Note: Tcool(i) and hwall(i) are the
% values of Tcool and hwall for the ith boundary which are numbered
% as follows:
%
% 1 = external boundary (airfoil surface)
% 2 = 1st internal cooling passage (from leading edge)
% 3 = 2nd internal cooling passage (from leading edge)
% 3 = 3rd internal cooling passage (from leading edge)
% 3 = 4th internal cooling passage (from leading edge) % Tcool = [1300, 200, 200, 200, 200];
% hwall = [14, 4.7, 4.7, 4.7, 4.7]; Tcool = [1573, 473, 473, 473, 473];
h = [205.8*10^-6, 65.8*10^-6, 65.8*10^-6, 65.8*10^-6, 65.8*10^-6];
k = 14.7*10^-3;
hwall = h / k; % Load in the grid file
% NOTE: after loading a gridfile using the load(fname) command,
% three important grid variables and data arrays exist. These are:
%
% Nt: Number of triangles (i.e. elements) in mesh
%
% Nv: Number of nodes (i.e. vertices) in mesh
%
% Nbc: Number of edges which lie on a boundary of the computational
% domain.
%
% tri2nod(3,Nt): list of the 3 node numbers which form the current
% triangle. Thus, tri2nod(1,i) is the 1st node of
% the i'th triangle, tri2nod(2,i) is the 2nd node
% of the i'th triangle, etc.
%
% xy(2,Nv): list of the x and y locations of each node. Thus,
% xy(1,i) is the x-location of the i'th node, xy(2,i)
% is the y-location of the i'th node, etc.
%
% bedge(3,Nbc): For each boundary edge, bedge(1,i) and bedge(2,i)
% are the node numbers for the nodes at the end
% points of the i'th boundary edge. bedge(3,i) is an
% integer which identifies which boundary the edge is
% on. In this solver, the third value has the
% following meaning:
%
% bedge(3,i) = 0: edge is on the airfoil
% bedge(3,i) = 1: edge is on the first cooling passage
% bedge(3,i) = 2: edge is on the second cooling passage
% bedge(3,i) = 3: edge is on the third cooling passage
% bedge(3,i) = 4: edge is on the fourth cooling passage
%
bladeread; % Start timer
Time0 = cputime; % Zero stiffness matrix K = zeros(Nv, Nv);
b = zeros(Nv, 1); % Zero maximum element size
hmax = 0; % Loop over elements and calculate residual and stiffness matrix for ii = 1:Nt, kn(1) = tri2nod(1,ii);
kn(2) = tri2nod(2,ii);
kn(3) = tri2nod(3,ii); xe(1) = xy(1,kn(1));
xe(2) = xy(1,kn(2));
xe(3) = xy(1,kn(3)); ye(1) = xy(2,kn(1));
ye(2) = xy(2,kn(2));
ye(3) = xy(2,kn(3)); % Calculate circumcircle radius for the element
% First, find the center of the circle by intersecting the median
% segments from two of the triangle edges. dx21 = xe(2) - xe(1);
dy21 = ye(2) - ye(1); dx31 = xe(3) - xe(1);
dy31 = ye(3) - ye(1); x21 = 0.5*(xe(2) + xe(1));
y21 = 0.5*(ye(2) + ye(1)); x31 = 0.5*(xe(3) + xe(1));
y31 = 0.5*(ye(3) + ye(1)); b21 = x21*dx21 + y21*dy21;
b31 = x31*dx31 + y31*dy31; xydet = dx21*dy31 - dy21*dx31; x0 = (dy31*b21 - dy21*b31)/xydet;
y0 = (dx21*b31 - dx31*b21)/xydet; Rlocal = sqrt((xe(1)-x0)^2 + (ye(1)-y0)^2); if (hmax < Rlocal),
hmax = Rlocal;
end % Calculate all of the necessary shape function derivatives, the
% Jacobian of the element, etc. % Derivatives of node 1's interpolant
dNdxi(1,1) = -1.0; % with respect to xi1
dNdxi(1,2) = -1.0; % with respect to xi2 % Derivatives of node 2's interpolant
dNdxi(2,1) = 1.0; % with respect to xi1
dNdxi(2,2) = 0.0; % with respect to xi2 % Derivatives of node 3's interpolant
dNdxi(3,1) = 0.0; % with respect to xi1
dNdxi(3,2) = 1.0; % with respect to xi2 % Sum these to find dxdxi (note: these are constant within an element)
dxdxi = zeros(2,2);
for nn = 1:3,
dxdxi(1,:) = dxdxi(1,:) + xe(nn)*dNdxi(nn,:);
dxdxi(2,:) = dxdxi(2,:) + ye(nn)*dNdxi(nn,:);
end % Calculate determinant for area weighting
J = dxdxi(1,1)*dxdxi(2,2) - dxdxi(1,2)*dxdxi(2,1);
A = 0.5*abs(J); % Area is half of the Jacobian % Invert dxdxi to find dxidx using inversion rule for a 2x2 matrix
dxidx = [ dxdxi(2,2)/J, -dxdxi(1,2)/J; ...
-dxdxi(2,1)/J, dxdxi(1,1)/J]; % Calculate dNdx
dNdx = dNdxi*dxidx; % Add contributions to stiffness matrix for node 1 weighted residual
K(kn(1), kn(1)) = K(kn(1), kn(1)) + (dNdx(1,1)*dNdx(1,1) + dNdx(1,2)*dNdx(1,2))*A;
K(kn(1), kn(2)) = K(kn(1), kn(2)) + (dNdx(1,1)*dNdx(2,1) + dNdx(1,2)*dNdx(2,2))*A;
K(kn(1), kn(3)) = K(kn(1), kn(3)) + (dNdx(1,1)*dNdx(3,1) + dNdx(1,2)*dNdx(3,2))*A; % Add contributions to stiffness matrix for node 2 weighted residual
K(kn(2), kn(1)) = K(kn(2), kn(1)) + (dNdx(2,1)*dNdx(1,1) + dNdx(2,2)*dNdx(1,2))*A;
K(kn(2), kn(2)) = K(kn(2), kn(2)) + (dNdx(2,1)*dNdx(2,1) + dNdx(2,2)*dNdx(2,2))*A;
K(kn(2), kn(3)) = K(kn(2), kn(3)) + (dNdx(2,1)*dNdx(3,1) + dNdx(2,2)*dNdx(3,2))*A; % Add contributions to stiffness matrix for node 3 weighted residual
K(kn(3), kn(1)) = K(kn(3), kn(1)) + (dNdx(3,1)*dNdx(1,1) + dNdx(3,2)*dNdx(1,2))*A;
K(kn(3), kn(2)) = K(kn(3), kn(2)) + (dNdx(3,1)*dNdx(2,1) + dNdx(3,2)*dNdx(2,2))*A;
K(kn(3), kn(3)) = K(kn(3), kn(3)) + (dNdx(3,1)*dNdx(3,1) + dNdx(3,2)*dNdx(3,2))*A; end % Loop over boundary edges and account for bc's
% Note: the bc's are all convective heat transfer coefficient bc's
% so the are of 'Robin' form. This requires modification of the
% stiffness matrix as well as impacting the right-hand side, b.
% for ii = 1:Nbc, % Get node numbers on edge
kn(1) = bedge(1,ii);
kn(2) = bedge(2,ii); % Get node coordinates
xe(1) = xy(1,kn(1));
xe(2) = xy(1,kn(2)); ye(1) = xy(2,kn(1));
ye(2) = xy(2,kn(2)); % Calculate edge length
ds = sqrt((xe(1)-xe(2))^2 + (ye(1)-ye(2))^2); % Determine the boundary number
bnum = bedge(3,ii) + 1; % Based on boundary number, set heat transfer bc
K(kn(1), kn(1)) = K(kn(1), kn(1)) + hwall(bnum)*ds*(1/3);
K(kn(1), kn(2)) = K(kn(1), kn(2)) + hwall(bnum)*ds*(1/6);
b(kn(1)) = b(kn(1)) + hwall(bnum)*ds*0.5*Tcool(bnum); K(kn(2), kn(1)) = K(kn(2), kn(1)) + hwall(bnum)*ds*(1/6);
K(kn(2), kn(2)) = K(kn(2), kn(2)) + hwall(bnum)*ds*(1/3);
b(kn(2)) = b(kn(2)) + hwall(bnum)*ds*0.5*Tcool(bnum); end % Solve for temperature
Tsol = K\b; % Finish timer
Time1 = cputime; % Plot solution
bladeplot; % Report outputs
Tmax = max(Tsol);
Tmin = min(Tsol); fprintf('Number of nodes = %i\n',Nv);
fprintf('Number of elements = %i\n',Nt);
fprintf('Maximum element size = %5.3f\n',hmax);
fprintf('Minimum temperature = %6.1f\n',Tmin);
fprintf('Maximum temperature = %6.1f\n',Tmax);
fprintf('CPU Time (secs) = %f\n',Time1 - Time0);

bladeread.m

% Read three important grid variables and data arrays
% Nt: Number of triangles (i.e. elements) in mesh
% Nv: Number of nodes (i.e. vertices) in mesh
% Nbc: Number of edges which lie on a boundary of the computational
% domain.
% tri2nod(3,Nt): list of the 3 node numbers which form the current
% triangle. Thus, tri2nod(1,i) is the 1st node of
% the i'th triangle, tri2nod(2,i) is the 2nd node
% of the i'th triangle, etc.
% xy(2,Nv): list of the x and y locations of each node. Thus,
% xy(1,i) is the x-location of the i'th node, xy(2,i)
% is the y-location of the i'th node, etc.
% bedge(3,Nbc): For each boundary edge, bedge(1,i) and bedge(2,i)
% are the node numbers for the nodes at the end
% points of the i'th boundary edge. bedge(3,i) is an
% integer which identifies which boundary the edge is
% on. In this solver, the third value has the
% following meaning:
%
% bedge(3,i) = 0: edge is on the airfoil
% bedge(3,i) = 1: edge is on the first cooling passage
% bedge(3,i) = 2: edge is on the second cooling passage
% bedge(3,i) = 3: edge is on the third cooling passage
% bedge(3,i) = 4: edge is on the fourth cooling passage
% clc
run('blademesh.m');
Nv=msh.nbNod;
Nt=size(msh.TRIANGLES,1);
Nbc=size(msh.LINES,1);
for i=1:Nt
tri2nod(1,i)=msh.TRIANGLES(i,1);
tri2nod(2,i)=msh.TRIANGLES(i,2);
tri2nod(3,i)=msh.TRIANGLES(i,3);
end
for i=1:Nv
xy(1,i)=msh.POS(i,1);
xy(2,i)=msh.POS(i,2);
end
for i=1:Nbc
bedge(1,i)=msh.LINES(i,1);
bedge(2,i)=msh.LINES(i,2);
bedge(3,i)=msh.LINES(i,3);
end

bladeplot.m

% Plot T in triangles
figure;
for ii = 1:Nt,
for nn = 1:3,
xtri(nn,ii) = xy(1,tri2nod(nn,ii));
ytri(nn,ii) = xy(2,tri2nod(nn,ii));
Ttri(nn,ii) = Tsol(tri2nod(nn,ii));
end
end
HT = patch(xtri,ytri,Ttri);
axis('equal');
set(HT,'LineStyle','none');
title('Temperature (K)');
% caxis([298,1573]);
colormap(jet);
HC = colorbar;
hold on; bladeplotgrid; hold off;

5. 计算结果

A First course in FEM —— matlab代码实现求解传热问题(稳态)的更多相关文章

  1. 如何加速MATLAB代码运行

    学习笔记 V1.0 2015/4/17 如何加速MATLAB代码运行 概述 本文源于LDPCC的MATLAB代码,即<CCSDS标准的LDPC编译码仿真>.由于代码的问题,在信息位长度很长 ...

  2. 多分类问题中,实现不同分类区域颜色填充的MATLAB代码(demo:Random Forest)

    之前建立了一个SVM-based Ordinal regression模型,一种特殊的多分类模型,就想通过可视化的方式展示模型分类的效果,对各个分类区域用不同颜色表示.可是,也看了很多代码,但基本都是 ...

  3. 卷积相关公式的matlab代码

    取半径=3 用matlab代码实现上式公式: length=3;for Ki = 1:length for Kj = 1:length for Kk = 1:length Ksigma(Ki,Kj,K ...

  4. JAVA调用matlab代码

    做实验一直用的matlab代码,需要嵌入到java项目中,matlab代码拼拼凑凑不是很了解,投机取巧采用java调用matlab的方式解决. 1.    matlab版本:matlabR2014a ...

  5. 调试和运行matlab代码(源程序)的技巧和教程

    转载请标明出处:专注matlab代码下载的网站http://www.downma.com/ 本文主要给大家分享使用matlab编写代码,完成课程设计.毕业设计或者研究项目时,matlab调试程序的技巧 ...

  6. 直方图均衡化与Matlab代码实现

    昨天说了,今天要好好的来解释说明一下直方图均衡化.并且通过不调用histeq函数来实现直方图的均衡化. 一.直方图均衡化概述 直方图均衡化(Histogram Equalization) 又称直方图平 ...

  7. 将labelme 生成的.json文件进行可视化的代码+label.png 对比度处理的matlab代码

    labelme_to_dataset 指令的代码实现: show.py文件 #!E:\Anaconda3\python.exe import argparse import json import o ...

  8. SVM实例及Matlab代码

    ******************************************************** ***数据集下载地址 :http://pan.baidu.com/s/1geb8CQf ...

  9. Latex中Matlab代码的环境

    需要用到listings宏包 使用方法: 导言区\usepackage{listings}\lstset{language=Matlab}      %代码语言使用的是matlab\lstset{br ...

  10. Frequency-tuned Salient Region Detection MATLAB代码出错修改方法

    论文:Frequency-tuned Salient Region Detection.CVPR.2009 MATLAB代码运行出错如下: Error using makecform>parse ...

随机推荐

  1. 关于Docker compose值IP与域名的映射 之 extra_host

    公司的所有项目都是采用Docker容器化部署,最近有一个项目需要使用定时任务调用第三方Api,正式web环境服务器的网络与第三方网络是通畅的,但是当将代码发布到正式环境,调用接口却显示 System. ...

  2. pandas之画图

    Pandas 在数据分析.数据可视化方面有着较为广泛的应用,Pandas 对 Matplotlib 绘图软件包的基础上单独封装了一个plot()接口,通过调用该接口可以实现常用的绘图操作.本节我们深入 ...

  3. Hugging News #0407: Google AI 的 Pix2Struct 来啦、开发者资源页面发布

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  4. ChatGPT API接口编程基础与使用技巧

    总结/朱季谦 趁着这周末空闲时间,在研读完OpenAi官网文档的基础上,及时总结了这篇<ChatGPT API接口编程基础与使用技巧>. 本文大部分内容是围绕编程方面,包括ChatGPT模 ...

  5. Awesome GPT 来了!

    大家好!我是韩老师. GPT, ChatGPT, OpenAI, LLM(大语言模型)等等技术的出现与应用,改变了许多的行业和人. 长期来看,类 GPT 的技术会对整个世界有着持续的改变. 我们几乎每 ...

  6. java调用https接口导入证书认证

    1.获取证书 浏览器访问需要调用的接口路径 如图导出证书. 2.进入java目录 jre/lib/security 导入证书 keytool -import -alias name -keystore ...

  7. mybatis xml 中 大于、小于、等于 写法

    在 *.xml 中使用常规的 < > = <= >= 会与xml的语法存在冲突 方法一:使用xml 原生转义的方式进行转义 字符名称 sql符号 转义字符 大于号 > & ...

  8. Appweb交叉编译

    Appweb交叉编译 编译环境:ubuntu-12.04 x64 开发平台:Hi3535 arm版 编译版本:appweb-6.1.1.zip 下载地址=> Appweb web site: h ...

  9. 小知识:使用errorstack定位特定问题

    有客户遇到ORA-2289的报错,同事协助去现场排查,我帮着远程共同check下. 客户只是应用端报出的错误,为了进一步定位,服务端需要开errorstack协助定位具体问题. 下面就以这个ORA-2 ...

  10. ts中抽象类、继承、多态

    ts中类抽象类.多态: 抽象类: abstract 修饰, 里面可以没有抽象方法.但有抽象方法(abstract method)的类必须声明为抽象类(abstract class) 多态:父类定义一个 ...