这篇文章会将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. day3 函数的定义和调用,练习编写简单的程序(记录2)

    一.值传递.指针传递.引用传递 值传递: 在值传递中,函数的形参是由实参的副本初始化的,也就是说,函数内部操作的是实参的一个拷贝.值传递适用于传递简单数据类型(如整数.浮点数.字符等)以及小型结构体等 ...

  2. 使用 diffusers 训练你自己的 ControlNet 🧨

    简介 ControlNet 这个神经网络模型使得用户可以通过施加额外条件,细粒度地控制扩散模型的生成过程.这一技术最初由 Adding Conditional Control to Text-to-I ...

  3. 使用二进制方式安装Docker

    长期使用安装工具进行安装docker,今天用二进制方式手动安装一下docker环境. 二进制包下载地址:https://download.docker.com/linux/static/stable/ ...

  4. python实现微信自动发消息功能

    import timeimport uiautomation as autofrom uiautomation.uiautomation import Bitmapimport win32clipbo ...

  5. Java语言在Spark3.2.4集群中使用Spark MLlib库完成朴素贝叶斯分类器

    一.贝叶斯定理 贝叶斯定理是关于随机事件A和B的条件概率,生活中,我们可能很容易知道P(A|B),但是我需要求解P(B|A),学习了贝叶斯定理,就可以解决这类问题,计算公式如下: P(A)是A的先验概 ...

  6. [apue] 一图读懂 Unix 时间日期例程相互关系

    概览 开门见山先上图 界定一些术语,方便后面说明: GMT:格林威治平均时,太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午 12 点,1972 年之前使用的国际标准时间,因地球在它的椭圆 ...

  7. Go语言实现协程下载器

    一般常用的下载方式是通过浏览器访问URL,然后基于HTTP进行下载.这种单线程下载方式通常比较慢,这里尝试使用Go语言实现一个多协程的下载器. 大致思路 按照传统的单线程的思路,实现下载要基于HTTP ...

  8. [MAUI]模仿网易云音乐黑胶唱片的交互实现

    @ 目录 创建页面布局 创建手势控件 创建影子控件 唱盘拨动交互 唱盘和唱针动画 项目地址 用过网易云音乐App的同学应该都比较熟悉它播放界面. 这是一个良好的交互设计,留声机的界面隐喻准确地向人们传 ...

  9. P5356 [Ynoi2017] 由乃打扑克

    md调了5h才调出来恶心坏了没想到这么快就做了第二道Ynoi 据说这题其实不卡常 屠龙宝刀点击就送 题面也很清楚,给定两种操作,一种是区间加,一种是询问区间内第 k 小的数的值是多少. 对于区间加,在 ...

  10. 通过Handsontable实现像Excel一样编辑数据

    ​一.Handsontable是指什么? 官网: http://handsontable.com Handsontable是一个JavaScript库,可以帮助您轻松实现类似Excel电子表格一样的编 ...