?? exam4_2.m
字號:
function exam4_2( file_in )
% 本程序為第四章的第二個算例,采用三角形單元計算隧道在自重作用下的變形和應力
% exam4_2( filename )
% 輸入參數:
% file_in ---------- 有限元模型文件
% 定義全局變量
% gNode ------------- 節點坐標
% gElement ---------- 單元定義
% gMaterial --------- 材料性質
% gBC1 -------------- 第一類約束條件
% gK ---------------- 整體剛度矩陣
% gDelta ------------ 整體節點坐標
% gNodeStress ------- 節點應力
% gElementStress ---- 單元應力
global gNode gElement gMaterial gBC1 gK gDelta gNodeStress gElementStress
if nargin < 1
file_in = 'exam4_2.dat' ;
end
% 檢查文件是否存在
if exist( file_in ) == 0
disp( sprintf( '錯誤:文件 %s 不存在', file_in ) )
disp( sprintf( '程序終止' ) )
return ;
end
% 根據輸入文件名稱生成輸出文件名稱
[path_str,name_str,ext_str] = fileparts( file_in ) ;
ext_str_out = '.mat' ;
file_out = fullfile( path_str, [name_str, ext_str_out] ) ;
% 檢查輸出文件是否存在
if exist( file_out ) ~= 0
answer = input( sprintf( '文件 %s 已經存在,是否覆蓋? ( Yes / [No] ): ', file_out ), 's' ) ;
if length( answer ) == 0
answer = 'no' ;
end
answer = lower( answer ) ;
if answer ~= 'y' | answer ~= 'yes'
disp( sprintf( '請使用另外的文件名,或備份已有的文件' ) ) ;
disp( sprintf( '程序終止' ) );
return ;
end
end
% 建立有限元模型并求解,保存結果
FemModel( file_in ) ; % 定義有限元模型
SolveModel ; % 求解有限元模型
SaveResults( file_out ) ; % 保存計算結果
% 計算結束
disp( sprintf( '計算正常結束,結果保存在文件 %s 中', file_out ) ) ;
disp( sprintf( '可以使用后處理程序 exam4_2_post.m 顯示計算結果' ) ) ;
return ;
function FemModel(filename)
% 定義有限元模型
% 輸入參數:
% filename --- 有限元模型文件
% 返回值:
% 無
% 說明:
% 該函數定義平面問題的有限元模型數據:
% gNode ------- 節點定義
% gElement ---- 單元定義
% gMaterial --- 材料定義,包括彈性模量,梁的截面積和梁的抗彎慣性矩
% gBC1 -------- 約束條件
global gNode gElement gMaterial gBC1
% 打開文件
fid = fopen( filename, 'r' ) ;
% 讀取節點坐標
node_number = fscanf( fid, '%d', 1 ) ;
gNode = zeros( node_number, 2 ) ;
for i=1:node_number
dummy = fscanf( fid, '%d', 1 ) ;
gNode( i, : ) = fscanf( fid, '%f', [1, 2] ) ;
end
% 讀取單元定義
element_number = fscanf( fid, '%d', 1 ) ;
gElement = zeros( element_number, 4 ) ;
for i=1:element_number
dummy = fscanf( fid, '%d', 1 ) ;
gElement( i, : ) = fscanf( fid, '%d', [1, 4] ) ;
end
% 讀取材料信息
material_number = fscanf( fid, '%d', 1 ) ;
gMaterial = zeros( material_number, 4 ) ;
for i=1:material_number
dummy = fscanf( fid, '%d', 1 ) ;
gMaterial( i, : ) = fscanf( fid, '%f', [1,4] ) ;
end
% 讀取邊界條件
bc1_number = fscanf( fid, '%d', 1 ) ;
gBC1 = zeros( bc1_number, 3 ) ;
for i=1:bc1_number
gBC1( i, 1 ) = fscanf( fid, '%d', 1 ) ;
gBC1( i, 2 ) = fscanf( fid, '%d', 1 ) ;
gBC1( i, 3 ) = fscanf( fid, '%f', 1 ) ;
end
% 關閉文件
fclose( fid ) ;
return
function SolveModel
% 求解有限元模型
% 輸入參數:
% 無
% 返回值:
% 無
% 說明:
% 該函數求解有限元模型,過程如下
% 1. 計算單元剛度矩陣,集成整體剛度矩陣
% 2. 計算單元的等效節點力,集成整體節點力向量
% 3. 處理約束條件,修改整體剛度矩陣和節點力向量
% 4. 求解方程組,得到整體節點位移向量
% 5. 計算單元應力和節點應力
global gNode gElement gMaterial gBC1 gK gDelta gNodeStress gElementStress
% step1. 定義整體剛度矩陣和節點力向量
[node_number,dummy] = size( gNode ) ;
gK = sparse( node_number * 2, node_number * 2 ) ;
f = sparse( node_number * 2, 1 ) ;
% step2. 計算單元剛度矩陣,并集成到整體剛度矩陣中
[element_number,dummy] = size( gElement ) ;
for ie=1:1:element_number
disp( sprintf( '計算剛度矩陣,當前單元: %d', ie ) ) ;
k = StiffnessMatrix( ie ) ;
AssembleStiffnessMatrix( ie, k ) ;
end
% step3. 計算自重產生的等效節點力
for ie=1:1:element_number
disp( sprintf( '計算自重的等效節點力,當前單元: %d', ie ) ) ;
egf = EquivalentGravityForce( ie ) ;
i = gElement( ie, 1 ) ;
j = gElement( ie, 2 ) ;
m = gElement( ie, 3 ) ;
f( (i-1)*2+1 : (i-1)*2+2 ) = f( (i-1)*2+1 : (i-1)*2+2 ) + egf( 1:2 ) ;
f( (j-1)*2+1 : (j-1)*2+2 ) = f( (j-1)*2+1 : (j-1)*2+2 ) + egf( 3:4 ) ;
f( (m-1)*2+1 : (m-1)*2+2 ) = f( (m-1)*2+1 : (m-1)*2+2 ) + egf( 5:6 ) ;
end
% step4. 處理約束條件,修改剛度矩陣和節點力向量。采用乘大數法
[bc_number,dummy] = size( gBC1 ) ;
for ibc=1:1:bc_number
n = gBC1(ibc, 1 ) ;
d = gBC1(ibc, 2 ) ;
m = (n-1)*2 + d ;
f(m) = gBC1(ibc, 3)* gK(m,m) * 1e15 ;
gK(m,m) = gK(m,m) * 1e15 ;
end
% step 5. 求解方程組,得到節點位移向量
gDelta = gK \ f ;
% step 6. 計算單元應力
gElementStress = zeros( element_number, 6 ) ;
for ie=1:element_number
disp( sprintf( '計算單元應力,當前單元: %d', ie ) ) ;
es = ElementStress( ie ) ;
gElementStress( ie, : ) = es ;
end
% step 7. 計算節點應力(采用繞節點加權平均)
gNodeStress = zeros( node_number, 6 ) ;
for i=1:node_number
disp( sprintf( '計算節點應力,當前結點: %d', i ) ) ;
S = zeros( 1, 3 ) ;
A = 0 ;
for ie=1:1:element_number
for k=1:1:3
if i == gElement( ie, k )
area= ElementArea( ie ) ;
S = S + gElementStress(ie,1:3 ) * area ;
A = A + area ;
break ;
end
end
end
gNodeStress(i,1:3) = S / A ;
gNodeStress(i,6) = 0.5*sqrt( (gNodeStress(i,1)-gNodeStress(i,2))^2 + 4*gNodeStress(i,3)^2 ) ;
gNodeStress(i,4) = 0.5*(gNodeStress(i,1)+gNodeStress(i,2)) + gNodeStress(i,6) ;
gNodeStress(i,5) = 0.5*(gNodeStress(i,1)+gNodeStress(i,2)) - gNodeStress(i,6) ;
end
return
function k = StiffnessMatrix( ie )
% 計算單元剛度矩陣
% 輸入參數:
% ie ---- 單元號
% 返回值:
% k ---- 單元剛度矩陣
global gNode gElement gMaterial
k = zeros( 6, 6 ) ;
E = gMaterial( gElement(ie, 4), 1 ) ;
mu = gMaterial( gElement(ie, 4), 2 ) ;
h = gMaterial( gElement(ie, 4), 3 ) ;
xi = gNode( gElement( ie, 1 ), 1 ) ;
yi = gNode( gElement( ie, 1 ), 2 ) ;
xj = gNode( gElement( ie, 2 ), 1 ) ;
yj = gNode( gElement( ie, 2 ), 2 ) ;
xm = gNode( gElement( ie, 3 ), 1 ) ;
ym = gNode( gElement( ie, 3 ), 2 ) ;
ai = xj*ym - xm*yj ;
aj = xm*yi - xi*ym ;
am = xi*yj - xj*yi ;
bi = yj - ym ;
bj = ym - yi ;
bm = yi - yj ;
ci = -(xj-xm) ;
cj = -(xm-xi) ;
cm = -(xi-xj) ;
area = (ai+aj+am)/2 ;
B = [bi 0 bj 0 bm 0
0 ci 0 cj 0 cm
ci bi cj bj cm bm] ;
B = B/2/area ;
D = [ 1-mu mu 0
mu 1-mu 0
0 0 (1-2*mu)/2] ;
D = D*E/(1-2*mu)/(1+mu) ;
k = transpose(B)*D*B*h*abs(area) ;
return
function B = MatrixB( ie )
% 計算單元的應變矩陣B
% 輸入參數:
% ie ---- 單元號
% 返回值:
% B ---- 單元應變矩陣
global gNode gElement
xi = gNode( gElement( ie, 1 ), 1 ) ;
yi = gNode( gElement( ie, 1 ), 2 ) ;
xj = gNode( gElement( ie, 2 ), 1 ) ;
yj = gNode( gElement( ie, 2 ), 2 ) ;
xm = gNode( gElement( ie, 3 ), 1 ) ;
ym = gNode( gElement( ie, 3 ), 2 ) ;
ai = xj*ym - xm*yj ;
aj = xm*yi - xi*ym ;
am = xi*yj - xj*yi ;
bi = yj - ym ;
bj = ym - yi ;
bm = yi - yj ;
ci = -(xj-xm) ;
cj = -(xm-xi) ;
cm = -(xi-xj) ;
area = (ai+aj+am)/2 ;
B = [bi 0 bj 0 bm 0
0 ci 0 cj 0 cm
ci bi cj bj cm bm] ;
B = B/2/area ;
return
function area = ElementArea( ie )
% 計算單元面積
% 輸入參數:
% ie ---- 單元號
% 返回值:
% area ---- 單元面積
global gNode gElement gMaterial
xi = gNode( gElement( ie, 1 ), 1 ) ;
yi = gNode( gElement( ie, 1 ), 2 ) ;
xj = gNode( gElement( ie, 2 ), 1 ) ;
yj = gNode( gElement( ie, 2 ), 2 ) ;
xm = gNode( gElement( ie, 3 ), 1 ) ;
ym = gNode( gElement( ie, 3 ), 2 ) ;
ai = xj*ym - xm*yj ;
aj = xm*yi - xi*ym ;
am = xi*yj - xj*yi ;
area = abs((ai+aj+am)/2) ;
return
function AssembleStiffnessMatrix( ie, k )
% 把單元剛度矩陣集成到整體剛度矩陣
% 輸入參數:
% ie --- 單元號
% k --- 單元剛度矩陣
% 返回值:
% 無
global gElement gK
for i=1:1:3
for j=1:1:3
for p=1:1:2
for q=1:1:2
m = (i-1)*2+p ;
n = (j-1)*2+q ;
M = (gElement(ie,i)-1)*2+p ;
N = (gElement(ie,j)-1)*2+q ;
gK(M,N) = gK(M,N) + k(m,n) ;
end
end
end
end
return
function egf = EquivalentGravityForce( ie )
% 計算單元自重的等效節點力
% 輸入參數
% ie ----- 單元號
% 返回值
% egf ----- 自重的等效節點力
global gElement gMaterial
area = ElementArea( ie ) ;
h = gMaterial( gElement( ie, 4 ), 3 ) ;
ro = gMaterial( gElement( ie, 4 ), 4 ) ;
w = area * h * ro ;
egf = -w/3 * [0; 1; 0; 1; 0; 1] ;
return
function es = ElementStress( ie )
% 計算單元的應力分量
% 輸入參數
% ie ----- 單元號
% 返回值
% es ----- 單元應力分量列陣(1×6): [sx, sy, txy, s1, s2, tmax]
global gElement gDelta gMaterial
es = zeros( 1, 6 ) ; % 單元的應力分量
de = zeros( 6, 1 ) ; % 單元節點位移列陣
E = gMaterial( gElement(ie, 4), 1 ) ;
mu = gMaterial( gElement(ie, 4), 2 ) ;
D = [ 1-mu mu 0
mu 1-mu 0
0 0 (1-2*mu)/2] ;
D = D*E/(1-2*mu)/(1+mu) ;
B = MatrixB( ie ) ;
for j=1:1:3
de( 2*j-1 ) = gDelta( 2*gElement( ie, j )-1 ) ;
de( 2*j ) = gDelta( 2*gElement( ie, j ) ) ;
end
es(1:3) = D * B * de ;
es(6) = 0.5*sqrt((es(1)-es(2))^2 + 4*es(3)^2 ) ;
es(4) = 0.5*(es(1)+es(2)) + es(6) ;
es(5) = 0.5*(es(1)+es(2)) - es(6) ;
return
function SaveResults( file_out )
% 顯示計算結果
% 輸入參數:
% file_out --- 保存結果文件
% 返回值:
% 無
global gNode gElement gMaterial gBC1 gDelta gNodeStress gElementStress
save( file_out, 'gNode', 'gElement', 'gMaterial', 'gBC1', 'gDelta', 'gNodeStress', 'gElementStress' ) ;
return
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -