这篇文章会将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. freeswitch媒体协商的优先级方案

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. 不同的媒体格式各有优缺点,实际环境中的应用要根据线路和客户的实际需求确定. 本文中介绍一种较为通用的媒体配置方案,可以适配大部分场景 ...

  2. Thread 线程中的 Synchronized block and lock

    Thread Definition of Synchronized Synchronized block in java are marked with the synchronized keywor ...

  3. elk7.15.1安装部署搭建

    ELK简介 ELK是Elasticsearch.Logstash.Kibana三大开源框架首字母大写简称(但是后期出现的Filebeat(beats中的一种)可以用来替代Logstash的数据收集功能 ...

  4. [Java/LeetCode]算法练习:二进制间距(868/simple)

    1 题目描述 题目来源: https://leetcode-cn.com/problems/binary-gap/ 给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 ...

  5. [MySQL]set autocommit=0与start transaction的区别[转载]

    set autocommit=0指事务非自动提交,自此句执行以后,每个SQL语句或者语句块所在的事务都需要显示"commit"才能提交事务. 1.不管autocommit 是1还是 ...

  6. jmeter参数化导致反斜杠(\)被转义

    前情提要:在用jmeter做接口测试时,对请求体进行参数化,执行结果报错.但在不参数化的情况下,执行结果成功,而且参数化后,请求中读取到的参数是正确的(执行失败与执行成功时的参数一致). 问题排查:参 ...

  7. CRC(Cyclic Redundancy Check)

    CRC(循环冗余校验) [参考资料] https://en.wikipedia.org/wiki/Cyclic_redundancy_check https://wiki.segger.com/CRC ...

  8. flutter系列之:如何自定义动画路由

    目录 简介 自定义跳转使用 flutter动画基础 实现一个自定义的route 总结 简介 flutter中有默认的Route组件,叫做MaterialPageRoute,一般情况下我们在flutte ...

  9. AndroidApp加密数据明文抓取测试方法——hook方式

    0x00 前言 在做移动安全的app渗透或者说移动app的漏洞挖掘时,往往会碰到一种情况:好不容易绕过了app的反抓包机制,通过burp抓到了app传输的数据包,这时想对这部分数据做一些爆破.篡改之类 ...

  10. NPM 实用命令与快捷方式

    在 JavaScript 中,无论是新手还是专家都可能在命令行中使用过 NPM.在本篇文章中,我将会整理超实用的 NPM 命令.快捷方式及技巧,帮助 JavaScript 开发人员提高生产力和效率. ...