编程有限元方法
Programming Finite Element Method
我正在尝试自学有限元方法。
我的所有代码都改编自以下 link 第 16-20 页
http://homepages.cae.wisc.edu/~suresh/ME964Website/M964Notes/Notes/introfem.pdf
我正在使用 Matlab 进行编程,以对单个 8 节点立方体元素执行有限元分析。我已经定义了 xi、eta、zeta 局部轴(我们现在可以将其视为 x、y、z),所以我得到以下形函数:
%%shape functions
zeta = 0:.01:1;
eta = 0:.01:1;
xi = 0:.01:1;
N1 = 1/8*(1-xi).*(1-eta).*(1-zeta);
N2 = 1/8*(1+xi).*(1-eta).*(1-zeta);
N3 = 1/8*(1+xi).*(1+eta).*(1-zeta);
N4 = 1/8*(1-xi).*(1+eta).*(1-zeta);
N5 = 1/8*(1-xi).*(1-eta).*(1+zeta);
N6 = 1/8*(1+xi).*(1-eta).*(1+zeta);
N7 = 1/8*(1+xi).*(1+eta).*(1+zeta);
N8 = 1/8*(1-xi).*(1+eta).*(1+zeta);
[N]
矩阵根据我正在阅读的文字要这样排列:
%N Matrix
N= [N1 0 0 N2 0 0 N3 0 0 N4 0 0 N5 0 0 N6 0 0 N7 0 0 N8 0 0;
0 N1 0 0 N2 0 0 N3 0 0 N4 0 0 N5 0 0 N6 0 0 N7 0 0 N8 0;
0 0 N1 0 0 N2 0 0 N3 0 0 N4 0 0 N5 0 0 N6 0 0 N7 0 0 N8];
要找到 [B]
矩阵,我必须使用以下 [D]
矩阵:
%%Del Matrix for node i
%[ d/dx 0 0
% 0 d/dy 0
% 0 0 d/dz . . .
% d/dy d/dx 0
% 0 d/dz d/dy
% d/dz 0 d/dx ]
这是一个运算符[N]
。 (B=DN
)
稍后,如文中所示,我将计算此 [B]
矩阵对该元素体积的积分。
所以,我的问题是,如何将这些多项式形状函数存储在矩阵中,对它们进行微分运算,然后对它们进行数值积分。我可以用我现在设置的方式告诉它,它不会工作,因为我已经将函数定义为区间 [0,1]
上的向量,然后将这些向量存储在 [N]
矩阵中。然后使用 diff()
函数适当微分找到 [B]
矩阵。
但是由于 [B]
的矩阵元素现在是区间 [0,1]
上的向量,我认为这会导致问题。你们如何进行我上面发布的教科书中描述的这些计算?
使用匿名函数并将多项式存储在符号矩阵中解决了我的问题。示例:
syms xi eta zeta
N1= ... %type out in terms of xi eta and zeta
.
.
.
dN1dXi = diff(N1,xi) %symbolic differentiation with respect to xi
也可以在需要的时候进行符号积分:
intN1 = int(N1,xi,lowerLimit,upperLimit) %symbolic integration with respect to xi
并准备好用实际值代替以评估符号函数时:
subs(N1,{xi,eta,zeta},{value1,value2,value3})
关于如何从参数域 ([0,1]^) 映射到物理域,您应该查看第 24 页。
虽然我觉得你可以按照你说的去做,使用symbolic。我认为 Matlab 中的符号计算非常耗时。
我会手动求导数 N 并存储为 dN,并在需要时使用它。
此致,
德语
获得形状函数后,需要将其代入刚度矩阵,刚度矩阵应为 24x24,因为您有 24 个自由度。解决你需要建立一个线性系统(Ax=b),右边是基于你正在解决的 PDE,你必须在右边加上源项包括纽曼边界条件。在 python 中,二维元素 (4 DOF) 将像:
def shapefxncoef (Valxy):
#creating a temporary metrix to store zeros and get the size of the shape
#function matrix.
n_temp = np.zeros((4,4))
#filling the values of the matrix with a loop.
for i in range(4):
#the values used in the matrix are from the Valxy x and y components.
xi = Valxy [0, i];
yi = Valxy [1, i];
n_temp[i, 0] = 1;
n_temp[i, 1] = xi;
n_temp[i, 2] = yi;
n_temp[i, 3] = xi*yi;
#this gives an identity matrix and the stiffness matric can be derived
#if we take the inverse.
n = np.linalg.inv(n_temp);
return n;
def N (Valxy, x, y):
n = shapefxncoef (Valxy);
res = n[0, :] + n[1, :]*x + n[2, :]*y + n[3, :]*x*y;
return res;
def Be (Valxy, x, y):
res = np.zeros ((2,4));
res_temp = shapefxncoef (Valxy);
for i in range (4):
res_tempi = res_temp[:, i];
dNix = res_tempi[1] + res_tempi[3]*y;
dNiy = res_tempi[2] + res_tempi[3]*x;
res[0, i] = dNix;
res[1, i] = dNiy;
return res;
def Ke (Valxy, conduct):
a = lambda x, y: conduct * np.dot ((Be(Valxy, x, y)).T, Be(Valxy, x, y));
k = intr.integrateOnQuadrangle (Valxy.T, a, np.zeros((4,4)));
return k;
我正在尝试自学有限元方法。
我的所有代码都改编自以下 link 第 16-20 页 http://homepages.cae.wisc.edu/~suresh/ME964Website/M964Notes/Notes/introfem.pdf
我正在使用 Matlab 进行编程,以对单个 8 节点立方体元素执行有限元分析。我已经定义了 xi、eta、zeta 局部轴(我们现在可以将其视为 x、y、z),所以我得到以下形函数:
%%shape functions
zeta = 0:.01:1;
eta = 0:.01:1;
xi = 0:.01:1;
N1 = 1/8*(1-xi).*(1-eta).*(1-zeta);
N2 = 1/8*(1+xi).*(1-eta).*(1-zeta);
N3 = 1/8*(1+xi).*(1+eta).*(1-zeta);
N4 = 1/8*(1-xi).*(1+eta).*(1-zeta);
N5 = 1/8*(1-xi).*(1-eta).*(1+zeta);
N6 = 1/8*(1+xi).*(1-eta).*(1+zeta);
N7 = 1/8*(1+xi).*(1+eta).*(1+zeta);
N8 = 1/8*(1-xi).*(1+eta).*(1+zeta);
[N]
矩阵根据我正在阅读的文字要这样排列:
%N Matrix
N= [N1 0 0 N2 0 0 N3 0 0 N4 0 0 N5 0 0 N6 0 0 N7 0 0 N8 0 0;
0 N1 0 0 N2 0 0 N3 0 0 N4 0 0 N5 0 0 N6 0 0 N7 0 0 N8 0;
0 0 N1 0 0 N2 0 0 N3 0 0 N4 0 0 N5 0 0 N6 0 0 N7 0 0 N8];
要找到 [B]
矩阵,我必须使用以下 [D]
矩阵:
%%Del Matrix for node i
%[ d/dx 0 0
% 0 d/dy 0
% 0 0 d/dz . . .
% d/dy d/dx 0
% 0 d/dz d/dy
% d/dz 0 d/dx ]
这是一个运算符[N]
。 (B=DN
)
稍后,如文中所示,我将计算此 [B]
矩阵对该元素体积的积分。
所以,我的问题是,如何将这些多项式形状函数存储在矩阵中,对它们进行微分运算,然后对它们进行数值积分。我可以用我现在设置的方式告诉它,它不会工作,因为我已经将函数定义为区间 [0,1]
上的向量,然后将这些向量存储在 [N]
矩阵中。然后使用 diff()
函数适当微分找到 [B]
矩阵。
但是由于 [B]
的矩阵元素现在是区间 [0,1]
上的向量,我认为这会导致问题。你们如何进行我上面发布的教科书中描述的这些计算?
使用匿名函数并将多项式存储在符号矩阵中解决了我的问题。示例:
syms xi eta zeta
N1= ... %type out in terms of xi eta and zeta
.
.
.
dN1dXi = diff(N1,xi) %symbolic differentiation with respect to xi
也可以在需要的时候进行符号积分:
intN1 = int(N1,xi,lowerLimit,upperLimit) %symbolic integration with respect to xi
并准备好用实际值代替以评估符号函数时:
subs(N1,{xi,eta,zeta},{value1,value2,value3})
关于如何从参数域 ([0,1]^) 映射到物理域,您应该查看第 24 页。
虽然我觉得你可以按照你说的去做,使用symbolic。我认为 Matlab 中的符号计算非常耗时。
我会手动求导数 N 并存储为 dN,并在需要时使用它。
此致,
德语
获得形状函数后,需要将其代入刚度矩阵,刚度矩阵应为 24x24,因为您有 24 个自由度。解决你需要建立一个线性系统(Ax=b),右边是基于你正在解决的 PDE,你必须在右边加上源项包括纽曼边界条件。在 python 中,二维元素 (4 DOF) 将像:
def shapefxncoef (Valxy):
#creating a temporary metrix to store zeros and get the size of the shape
#function matrix.
n_temp = np.zeros((4,4))
#filling the values of the matrix with a loop.
for i in range(4):
#the values used in the matrix are from the Valxy x and y components.
xi = Valxy [0, i];
yi = Valxy [1, i];
n_temp[i, 0] = 1;
n_temp[i, 1] = xi;
n_temp[i, 2] = yi;
n_temp[i, 3] = xi*yi;
#this gives an identity matrix and the stiffness matric can be derived
#if we take the inverse.
n = np.linalg.inv(n_temp);
return n;
def N (Valxy, x, y):
n = shapefxncoef (Valxy);
res = n[0, :] + n[1, :]*x + n[2, :]*y + n[3, :]*x*y;
return res;
def Be (Valxy, x, y):
res = np.zeros ((2,4));
res_temp = shapefxncoef (Valxy);
for i in range (4):
res_tempi = res_temp[:, i];
dNix = res_tempi[1] + res_tempi[3]*y;
dNiy = res_tempi[2] + res_tempi[3]*x;
res[0, i] = dNix;
res[1, i] = dNiy;
return res;
def Ke (Valxy, conduct):
a = lambda x, y: conduct * np.dot ((Be(Valxy, x, y)).T, Be(Valxy, x, y));
k = intr.integrateOnQuadrangle (Valxy.T, a, np.zeros((4,4)));
return k;