99行代码
A 99 line topology optimization code written in Matlab(2001)
概述
最基础的拓扑优化代码
FE代码
有限元分析:计算单元刚度矩阵,组装全局刚度矩阵,求解单元位移
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | function [U]=FE(nelx,nely,x,alfa,xfar)
[KE] = lk; %单元刚度矩阵
K = sparse(2*(nelx+1)*(nely+1), 2*(nelx+1)*(nely+1));
%总体刚度矩阵的稀疏矩阵 注意节点数和单元数的关系
F = sparse(2*(nely+1)*(nelx+1),1); %载荷向量 有这么多节点(nely+1)*(nelx+1)
U = zeros(2*(nely+1)*(nelx+1),1); %位移向量 有这么多节点(nely+1)*(nelx+1)
% 总刚组装
for elx = 1:nelx % 第elx行的单元
for ely = 1:nely %第ely列的单元
n1 = (nely+1)*(elx-1)+ely;
n2 = (nely+1)* elx +ely;
edof = [2*n1-1; 2*n1; 2*n2-1; 2*n2; 2*n2+1; 2*n2+2; 2*n1+1; 2*n1+2];% 自由度编号
% K(edof,edof) = K(edof,edof) + x(ely,elx)^penal*KE;
K(edof,edof) = K(edof,edof) + (1+tanh(alfa*( x(ely,elx)-xfar)))*KE; %将单元刚度矩阵组装成总的刚度矩阵(实际是取出edof构成的8×8矩阵,然后填入)
% K(edof,edof) = K(edof,edof) + (1/(1+exp(-alfa*(x(ely,elx)-0.5))))*KE; %将单元刚度矩阵组装成总的刚度矩阵
end
end
% DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)
F(2,1) = -1; % 其他元素都是0
fixeddofs = union([1:2:2*(nely+1)],[2*(nelx+1)*(nely+1)]); % 固定左边一列+右下角顶点x坐标
alldofs = [1:2*(nely+1)*(nelx+1)]; %所有结点
freedofs = setdiff(alldofs,fixeddofs); % setdiff返回A中有,B中没有的值自由节点
% SOLVING
U(freedofs,:) = K(freedofs,freedofs) \ F(freedofs,:); %求解
U(fixeddofs,:)= 0;
|
灵敏度过滤
去除棋盘格,先设置一个过滤半径,对过滤半径内的单元与当前单元距离计算权重(与距离成反比的权重函数),对密度乘以权重然后累加,最后除以加权总和,更新灵敏度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | function [dcn]=check(nelx,nely,rmin,x,dc)
dcn=zeros(nely,nelx);
for i = 1:nelx
for j = 1:nely
sum=0.0;
for k = max(i-floor(rmin),1):min(i+floor(rmin),nelx)
for l = max(j-floor(rmin),1):min(j+floor(rmin),nely)
fac = rmin-sqrt((i-k)^2+(j-l)^2);
sum = sum+max(0,fac);
dcn(j,i) = dcn(j,i) + max(0,fac)*x(l,k)*dc(l,k);
end
end
dcn(j,i) = dcn(j,i)/(x(j,i)*sum);
end
end
|
OC法
正常情况下,对于有解析解的形式同样是构造拉格朗日函数
\[
L(x,\lambda)=c(x)+\lambda(\sum x_i-V_0)
\]
对其求极值并通过乘法形式更新,由于现在没有解析解,故采用二分查找 \(\lambda\)
\[
x_i^{new}=x_i\cdot\sqrt{-\frac{\partial c/\partial x_i}{\lambda}}
\]
1
2
3
4
5
6
7
8
9
10
11
12 | function [xnew]=OC(nelx,nely,x,volfrac,dc)
L1 = 0; L2 = 100000; move = 0.2;
while (L2-L1 > 1e-4) %l 是小写的L 不是12 11
Lmid = 0.5*(L2+L1);
xnew = max(0.001,max(x-move,min(1.,min(x+move,x.*sqrt(-dc./Lmid)))));
if sum(sum(xnew)) - volfrac*nelx*nely > 0;
L1 = Lmid;
else
L2 = Lmid;
end
end
|
论文
论文地址