-
Amira Abdel-Rahman authoredAmira Abdel-Rahman authored
multimaterial.jl 36.46 KiB
# Amira Abdel-Rahman
# (c) Massachusetts Institute of Technology 2020
#############################################multimaterial############################################################
#Based on: https://link.springer.com/article/10.1007/s00158-013-0999-1
function multitop(nx,ny,tol_out,tol_f,iter_max_in,iter_max_out,p,q,e,v,rf)
anim=Animation()
alpha = zeros(Float64,nx*ny,p)
for i = 1:p
alpha[:,i] .= v[i]
end
# MAKE FILTER
H,Hs = make_filter(nx,ny,rf)
obj=0
change_out = 2*tol_out; iter_out = 0;
while (iter_out < iter_max_out) && (change_out > tol_out)
alpha_old = copy(alpha)
for a = 1:p
for b = a+1:p
obj,alpha = bi_top(a,b,nx,ny,p,v,e,q,alpha,H,Hs,iter_max_in);
end
end
iter_out = iter_out + 1;
change_out = norm(alpha[:].-alpha_old[:],Inf);
display("Iter:$iter_out Obj.:$obj change:$change_out");
# UPDATE FILTER
if (change_out < tol_f) && (rf>3)
tol_f = 0.99*tol_f; rf = 0.99*rf;
H,Hs = make_filter(nx,ny,rf);
end
# SCREEN OUT TEMPORAL TOPOLOGY EVERY 5 ITERATIONS
if mod(iter_out,5)==0
I = make_bitmap(p,nx,ny,alpha);
display(RGB.(I[:,:,1],I[:,:,2],I[:,:,3]))
I = permutedims(I, [3, 1, 2])
img = colorview(RGB, I)
heatmap(img,xaxis=nothing,yaxis=nothing,aspect_ratio=:equal)
frame(anim)
end
end
return anim,alpha
end
function bi_top(a,b,nx,ny,p,v,e,q,alpha_old,H,Hs,maxIter)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
A11 = [12 3 -6 -3; 3 12 3 0; -6 3 12 -3; -3 0 -3 12];
A12 = [-6 -3 0 3; -3 -6 -3 -6; 0 -3 -6 3; 3 -6 3 -6];
B11 = [-4 3 -2 9; 3 -4 -9 4; -2 -9 -4 -3; 9 4 -3 -4];
B12 = [ 2 -3 4 -9; -3 2 9 -2; 4 9 2 3; -9 -2 3 2];
KE = 1/(1-nu^2)/24*([A11 A12;A12' A11]+nu*[B11 B12;B12' B11]);
nelx=nx
nely=ny
nodenrs = reshape(1:(1+nelx)*(1+nely),1+nely,1+nelx)
edofVec = reshape(2*nodenrs[1:end-1,1:end-1].+1,nelx*nely,1)
edofMat = repeat(edofVec,1,8).+repeat([0 1 2*nely.+[2 3 0 1] -2 -1],nelx*nely,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(8,1))',64*nelx*nely,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,8))',64*nelx*nely,1))
# DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)
F = sparse([2],[1],[-1.0],2*(nely+1)*(nelx+1),1)
U = zeros(2*(nely+1)*(nelx+1),1)
fixeddofs = union(1:2:2*(nely+1),2*(nelx+1)*(nely+1))
alldofs = 1:(2*(nely+1)*(nelx+1))
freedofs = setdiff(alldofs,fixeddofs)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
E = e[1]*alpha[:,1].^q
for phase = 2:p
E = E + e[phase]*alpha[:,phase].^q;
end
sK = reshape(KE[:]*E[:]',64*nelx*nely,1)
K = sparse(vec(iK),vec(jK),vec(sK)); K = (K+K')/2
@timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
# Objective function and sensitivity analysis
ce = sum((U[edofMat]*KE).*U[edofMat],dims=2)
o = sum(sum(E.*ce))
# FILTERING OF SENSITIVITIES
dc = 0.0 .-(q .*(e[a].-e[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move = 0.2;
r = ones(nx*ny,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
while (l2-l1)/(l1+l2) > 1e-3
lmid = 0.5*(l2+l1)
alpha_a = max.(l,min.(u,alpha[:,a].*sqrt.(-dc./lmid)));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end
########
function multitop_compliant(nx,ny,tol_out,tol_f,iter_max_in,iter_max_out,p,q,e,v,rf,Load,Support,Spring,DOut)
anim=Animation()
alpha = zeros(Float64,nx*ny,p)
for i = 1:p
alpha[:,i] .= v[i]
end
# MAKE FILTER
H,Hs = make_filter(nx,ny,rf)
obj=0
change_out = 2*tol_out; iter_out = 0;
while (iter_out < iter_max_out) && (change_out > tol_out)
alpha_old = copy(alpha)
for a = 1:p
for b = a+1:p
obj,alpha = bi_top_compliant(a,b,nx,ny,p,v,e,q,alpha,H,Hs,iter_max_in);
end
end
iter_out = iter_out + 1;
change_out = norm(alpha[:].-alpha_old[:],Inf);
display("Iter:$iter_out Obj.:$obj change:$change_out");
# UPDATE FILTER
if (change_out < tol_f) && (rf>3)
tol_f = 0.99*tol_f; rf = 0.99*rf;
H,Hs = make_filter(nx,ny,rf);
end
# SCREEN OUT TEMPORAL TOPOLOGY EVERY 5 ITERATIONS
if mod(iter_out,5)==0
I = make_bitmap_compliant(p,nx,ny,alpha);
display(RGB.(I[:,:,1],I[:,:,2],I[:,:,3]))
I = permutedims(I, [3, 1, 2])
img = colorview(RGB, I)
heatmap(img,xaxis=nothing,yaxis=nothing,aspect_ratio=:equal)
frame(anim)
end
end
return anim,alpha
end
function bi_top_compliant(a,b,nx,ny,p,v,e,q,alpha_old,H,Hs,maxIter,Load,Support,Spring,DOut)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
A11 = [12 3 -6 -3; 3 12 3 0; -6 3 12 -3; -3 0 -3 12];
A12 = [-6 -3 0 3; -3 -6 -3 -6; 0 -3 -6 3; 3 -6 3 -6];
B11 = [-4 3 -2 9; 3 -4 -9 4; -2 -9 -4 -3; 9 4 -3 -4];
B12 = [ 2 -3 4 -9; -3 2 9 -2; 4 9 2 3; -9 -2 3 2];
KE = 1/(1-nu^2)/24*([A11 A12;A12' A11]+nu*[B11 B12;B12' B11]);
nelx=nx
nely=ny
nodenrs = reshape(1:(1+nelx)*(1+nely),1+nely,1+nelx)
edofVec = reshape(2*nodenrs[1:end-1,1:end-1].+1,nelx*nely,1)
edofMat = repeat(edofVec,1,8).+repeat([0 1 2*nely.+[2 3 0 1] -2 -1],nelx*nely,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(8,1))',64*nelx*nely,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,8))',64*nelx*nely,1))
# # DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)
# F = sparse([2],[1],[-1.0],2*(nely+1)*(nelx+1),1)
# U = zeros(2*(nely+1)*(nelx+1),1)
# fixeddofs = union(1:2:2*(nely+1),2*(nelx+1)*(nely+1))
# alldofs = 1:(2*(nely+1)*(nelx+1))
# freedofs = setdiff(alldofs,fixeddofs)
# DEFINE LOADS AND SUPPORTS
F = sparse(2 .*Load[:,1] .-2 .+ Load[:,2],ones(size(Load,1)),Load[:,3],2*(nely+1)*(nelx+1),2)
DofDOut = 2 * DOut[1] - 2 +DOut[2]; #only one
F=Array(F)
F[DofDOut,2]=-1
fixeddofs = 2 .*Support[:,1] .-2 .+ Support[:,2]
NSpring = size(Spring,1);
s = sparse(2 .*Spring[:,1] .-2 .+ Spring[:,2],ones(size(Spring,1)),Spring[:,3],2*(nely+1)*(nelx+1),2)
m=Array(s)[:,1]
S= sparse(diagm(m))
U = zeros(2*(nely+1)*(nelx+1),2)
alldofs = 1:(2*(nely+1)*(nelx+1))
freedofs = setdiff(alldofs,fixeddofs)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
E = e[1]*alpha[:,1].^q
for phase = 2:p
E = E + e[phase]*alpha[:,phase].^q;
end
sK = reshape(KE[:]*E[:]',64*nelx*nely,1)
K = sparse(vec(iK),vec(jK),vec(sK));
K[din,din] = K[din,din] + 0.1;
K[dout,dout] = K[dout,dout] + 0.1;
K = (K+K')/2
# @timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
@timed U[freedofs,:] = K[freedofs,freedofs] \ Array(F[freedofs,:])
U1=U[:,1]
U2=U[:,2]
# Objective function and sensitivity analysis
# ce = sum((U[edofMat]*KE).*U[edofMat],dims=2)
ce =-sum((U1[edofMat]*KE).*U2[edofMat],dims=2)
# o = sum(sum(E.*ce))
o=U[DofDOut,1]
# FILTERING OF SENSITIVITIES
dc = 0.0 .-(q .*(e[a].-e[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move=0.1;
r = ones(nx*ny,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
while (l2-l1)/(l2+l1) > 1e-4 && l2>1e-40
# while (l2-l1)/(l1+l2) > 1e-3
lmid = 0.5*(l2+l1)
alpha_a = max.(l,min.(u,alpha[:,a].*((max.(1e-10,-dc./lmid)).^0.3 )));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end
########
function multitop3D(nx,ny,nz,tol_out,tol_f,iter_max_in,iter_max_out,p,q,e,v,rf)
anim=Animation()
alpha = zeros(Float64,nx*ny*nz,p)
for i = 1:p
alpha[:,i] .= v[i]
end
# MAKE FILTER
H,Hs = make_filter3D(nx,ny,nz,rf)
obj=0
change_out = 2*tol_out; iter_out = 0;
while (iter_out < iter_max_out) && (change_out > tol_out)
alpha_old = copy(alpha)
for a = 1:p
for b = a+1:p
obj,alpha = bi_top3D(a,b,nx,ny,nz,p,v,e,q,alpha,H,Hs,iter_max_in);
end
end
iter_out = iter_out + 1;
change_out = norm(alpha[:].-alpha_old[:],Inf);
display("Iter:$iter_out Obj.:$obj change:$change_out");
# UPDATE FILTER
if (change_out < tol_f) && (rf>3)
tol_f = 0.99*tol_f; rf = 0.99*rf;
H,Hs = make_filter3D(nx,ny,nz,rf)
end
# SCREEN OUT TEMPORAL TOPOLOGY EVERY 5 ITERATIONS
if mod(iter_out,5)==0
I = make_bitmap_3d(p,nx,ny,nz,alpha)
threshold=0.05
display(topplotmulti3d(nx,ny,nz,I,threshold))
frame(anim)
end
end
return anim,alpha
end
function bi_top3D(a,b,nx,ny,nz,p,v,e,q,alpha_old,H,Hs,maxIter)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
KE=lk_H8(nu)
nelx=nx
nely=ny
nelz=nz
nele = nelx*nely*nelz
ndof = 3*(nelx+1)*(nely+1)*(nelz+1)
nodenrs = reshape(1:(1+nelx)*(1+nely)*(1+nelz),1+nely,1+nelx,1+nelz)
edofVec = reshape(3*nodenrs[1:end-1,1:end-1,1:end-1].+1,nelx*nely*nelz,1)
edofMat = repeat(edofVec,1,24).+repeat([0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1 3*(nely+1)*(nelx+1).+[0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1]],nelx*nely*nelz,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(24,1))',24*24*nele,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,24))',24*24*nele,1))
# USER-DEFINED LOAD DOFs
m= Matlab.meshgrid(nelx:nelx, 0:0, 0:nelz)
il=m[1]
jl=m[2]
kl=m[3]
loadnid = kl.*(nelx+1).*(nely+1).+il.*(nely+1).+(nely+1 .-jl)
loaddof = 3 .*loadnid[:] .- 1;
# USER-DEFINED SUPPORT FIXED DOFs
m= Matlab.meshgrid(0:0,0:nely,0:nelz)# Coordinates
iif=m[1]
jf=m[2]
kf=m[3]
fixednid = kf.*(nelx+1).*(nely+1) .+iif .*(nely .+1) .+(nely .+1 .-jf) # Node IDs
fixeddof = [3 .*fixednid[:]; 3 .*fixednid[:].-1; 3 .*fixednid[:].-2] # DOFs
# DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)
F= sparse(loaddof,fill(1,length(loaddof)),fill(-1,length(loaddof)),ndof,1);
U = zeros(ndof,1)
alldofs = 1:ndof
freedofs = setdiff(1:ndof,fixeddof)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
E = e[1]*alpha[:,1].^q
for phase = 2:p
E = E + e[phase]*alpha[:,phase].^q;
end
sK = reshape(KE[:]*E[:]',24*24*nelx*nely*nelz,1)
K = sparse(vec(iK),vec(jK),vec(sK)); K = (K+K')/2
@timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
# Objective function and sensitivity analysis
ce = sum((U[edofMat]*KE).*U[edofMat],dims=2)
o = sum(sum(E.*ce))
# FILTERING OF SENSITIVITIES
dc = 0.0 .-(q .*(e[a].-e[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move = 0.2;
r = ones(nx*ny*nz,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
while (l2-l1)/(l1+l2) > 1e-3
lmid = 0.5*(l2+l1)
alpha_a = max.(l,min.(u,alpha[:,a].*sqrt.(-dc./lmid)));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end
########
function multitop3D_compliant(nx,ny,nz,tol_out,tol_f,iter_max_in,iter_max_out,p,q,e,v,rf,getProblem=inverter)
anim=Animation()
alpha = zeros(Float64,nx*ny*nz,p)
for i = 1:p
alpha[:,i] .= v[i]
end
# MAKE FILTER
H,Hs = make_filter3D(nx,ny,nz,rf)
obj=0
change_out = 2*tol_out; iter_out = 0;
while (iter_out < iter_max_out) && (change_out > tol_out)
alpha_old = copy(alpha)
for a = 1:p
for b = a+1:p
obj,alpha = bi_top3D_compliant(a,b,nx,ny,nz,p,v,e,q,alpha,H,Hs,iter_max_in,getProblem);
end
end
iter_out = iter_out + 1;
change_out = norm(alpha[:].-alpha_old[:],Inf);
display("Iter:$iter_out Obj.:$obj change:$change_out");
# UPDATE FILTER
if (change_out < tol_f) && (rf>3)
tol_f = 0.99*tol_f; rf = 0.99*rf;
H,Hs = make_filter3D(nx,ny,nz,rf)
end
# SCREEN OUT TEMPORAL TOPOLOGY EVERY 5 ITERATIONS
if mod(iter_out,5)==0
I = make_bitmap_3d(p,nx,ny,nz,alpha)
threshold=0.05
display(topplotmulti3d(nx,ny,nz,I,threshold))
frame(anim)
end
end
return anim,alpha
end
function bi_top3D_compliant(a,b,nx,ny,nz,p,v,e,q,alpha_old,H,Hs,maxIter,getProblem=inverter)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
KE=lk_H8(nu)
nelx=nx
nely=ny
nelz=nz
nele = nelx*nely*nelz
ndof = 3*(nelx+1)*(nely+1)*(nelz+1)
nodenrs = reshape(1:(1+nelx)*(1+nely)*(1+nelz),1+nely,1+nelx,1+nelz)
edofVec = reshape(3*nodenrs[1:end-1,1:end-1,1:end-1].+1,nelx*nely*nelz,1)
edofMat = repeat(edofVec,1,24).+repeat([0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1 3*(nely+1)*(nelx+1).+[0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1]],nelx*nely*nelz,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(24,1))',24*24*nele,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,24))',24*24*nele,1))
# # USER-DEFINED LOAD DOFs
# il = [0 nelx]; jl = [nely nely]; kl = [0 0];
# loadnid = kl .*(nelx+1) .*(nely+1) .+il .*(nely .+1) .+(nely+1 .-jl);
# loaddof = 3 .*loadnid[:] .- 2;
# din = loaddof[1]; dout = loaddof[2];
# F = sparse(loaddof,[1;2],[1;-1],ndof,2);
# # USER-DEFINED SUPPORT FIXED DOFs
# # Top face
# m = Matlab.meshgrid(0:nelx,0:nelz)
# iif=m[1]
# kf=m[2]
# fixednid = kf .*(nelx+1) .*(nely+1) .+iif .*(nely+1) .+1;
# fixeddof_t = 3 .*fixednid[:] .-1;
# # Side face
# m = Matlab.meshgrid(0:nelx,0:nely)
# iif=m[1]
# jf=m[2]
# fixednid = iif .*(nely+1) .+(nely+1 .-jf);
# fixeddof_s = 3*fixednid[:];
# # Two pins
# iif = [0;0]; jf = [0;1]; kf = [nelz;nelz];
# fixednid = kf .*(nelx+1) .*(nely .+1) .+iif .*(nely .+1) .+(nely+1 .-jf)
# fixeddof_p = [3 .*fixednid[:]; 3 .*fixednid[:].-1; 3 .*fixednid[:].-2] # DOFs
# # Fixed DOFs
# fixeddof = union(fixeddof_t,fixeddof_s);
# fixeddof = union(fixeddof, fixeddof_p);
# fixeddof = sort(fixeddof);
# # Displacement vector
# U = zeros(ndof,2);
# freedofs = setdiff(1:ndof,fixeddof)
U,F,freedofs,din,dout=getProblem(nelx,nely,nelz)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
E = e[1]*alpha[:,1].^q
for phase = 2:p
E = E + e[phase]*alpha[:,phase].^q;
end
sK = reshape(KE[:]*E[:]',24*24*nelx*nely*nelz,1)
K = sparse(vec(iK),vec(jK),vec(sK));
K[din,din] = K[din,din] + 0.1;
K[dout,dout] = K[dout,dout] + 0.1;
K = (K+K')/2;
# @timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
@timed U[freedofs,:] = K[freedofs,freedofs] \ Array(F[freedofs,:])
U1 = U[:,1]
U2 = U[:,2]
# Objective function and sensitivity analysis
ce = -sum((U1[edofMat]*KE).*U2[edofMat],dims=2)
# o = sum(sum(E.*ce))
o = U[dout,1]
# FILTERING OF SENSITIVITIES
dc = 0.0 .-(q .*(e[a].-e[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move = 0.1;
r = ones(nx*ny*nz,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
# while (l2-l1)/(l1+l2) > 1e-3
while (l2-l1)/(l1+l2) > 1e-4 && l2 > 1e-40
lmid = 0.5*(l2+l1)
# alpha_a = max.(l,min.(u,alpha[:,a].*sqrt.(-dc./lmid)));
alpha_a = max.(l,min.(u,alpha[:,a].*((max.(1e-10,-dc./lmid)).^0.3 )));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end
########
function multitop3DKE(nx,ny,nz,tol_out,tol_f,iter_max_in,iter_max_out,p,q,KEs,Es,v,rf)
anim=Animation()
alpha = zeros(Float64,nx*ny*nz,p)
for i = 1:p
alpha[:,i] .= v[i]
end
# MAKE FILTER
H,Hs = make_filter3D(nx,ny,nz,rf)
obj=0
change_out = 2*tol_out; iter_out = 0;
while (iter_out < iter_max_out) && (change_out > tol_out)
alpha_old = copy(alpha)
for a = 1:p
for b = a+1:p
obj,alpha = bi_top3DKE(a,b,nx,ny,nz,p,v,KEs,Es,q,alpha,H,Hs,iter_max_in);
end
end
iter_out = iter_out + 1;
change_out = norm(alpha[:].-alpha_old[:],Inf);
display("Iter:$iter_out Obj.:$obj change:$change_out");
# UPDATE FILTER
if (change_out < tol_f) && (rf>3)
tol_f = 0.99*tol_f; rf = 0.99*rf;
H,Hs = make_filter3D(nx,ny,nz,rf)
end
# SCREEN OUT TEMPORAL TOPOLOGY EVERY 5 ITERATIONS
if mod(iter_out,5)==0
I = make_bitmap_3d(p,nx,ny,nz,alpha)
threshold=0.05*2.0
display(topplotmulti3d(nx,ny,nz,I,threshold))
frame(anim)
end
end
return anim,alpha
end
function bi_top3DKE(a,b,nx,ny,nz,p,v,KEs,Es,q,alpha_old,H,Hs,maxIter)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
# KE=lk_H8(nu)
nelx=nx
nely=ny
nelz=nz
nele = nelx*nely*nelz
ndof = 3*(nelx+1)*(nely+1)*(nelz+1)
nnx = nelx+1; nny = nely+1; nnz = nelz+1;
nodenrs = reshape(1:(1+nelx)*(1+nely)*(1+nelz),1+nely,1+nelx,1+nelz)
edofVec = reshape(3*nodenrs[1:end-1,1:end-1,1:end-1].+1,nelx*nely*nelz,1)
edofMat = repeat(edofVec,1,24).+repeat([0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1 3*(nely+1)*(nelx+1).+[0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1]],nelx*nely*nelz,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(24,1))',24*24*nele,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,24))',24*24*nele,1))
# USER-DEFINED LOAD DOFs
m= Matlab.meshgrid(nelx:nelx, 0:0, 0:nelz)
il=m[1]
jl=m[2]
kl=m[3]
loadnid = kl.*(nelx+1).*(nely+1).+il.*(nely+1).+(nely+1 .-jl)
loaddof = 3 .*loadnid[:] .- 1;
# USER-DEFINED SUPPORT FIXED DOFs
m= Matlab.meshgrid(0:0,0:nely,0:nelz)# Coordinates
iif=m[1]
jf=m[2]
kf=m[3]
fixednid = kf.*(nelx+1).*(nely+1) .+iif .*(nely .+1) .+(nely .+1 .-jf) # Node IDs
fixeddof = [3 .*fixednid[:]; 3 .*fixednid[:].-1; 3 .*fixednid[:].-2] # DOFs
# DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)
F= sparse(loaddof,fill(1,length(loaddof)),fill(-1,length(loaddof)),ndof,1);
U = zeros(ndof,1)
alldofs = 1:ndof
freedofs = setdiff(1:ndof,fixeddof)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
# KE[:]*E[:]'
KEE = KEs[1][:]*alpha[:,1][:]'.^q
for phase = 2:p
KEE = KEE + KEs[phase][:]*alpha[:,phase][:]'.^q;
end
EE = mean(Es[1])*alpha[:,1].^q
for phase = 2:p
EE = EE + mean(Es[phase])*alpha[:,phase].^q;
end
sK = reshape(KEE[:],24*24*nelx*nely*nelz,1)
K = sparse(vec(iK),vec(jK),vec(sK)); K = (K+K')/2
@timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
KE=reshape(sum(KEE,dims=2),24,24)
# dc=zeros(nelx* nely* nelz)
# for i=1:Int(nelx* nely* nelz)
# KE=(q .*(KEs[a].-KEs[b]).*alpha[i,a].^(q-1))
# # ce[i]=sum((U[edofMat][i,:]'*KE).*U[edofMat][i,:]')
# dc[i]=-sum((U[edofMat][i,:]'*KE).*U[edofMat][i,:]')
# end
ce=zeros(nelx* nely* nelz)
for i=1:Int(nelx* nely* nelz)
KE = KEs[1].*alpha[i,1]
for phase = 2:p
KE = KE + KEs[phase].*alpha[i,phase]
end
ce[i]=sum((U[edofMat][i,:]'*KE).*U[edofMat][i,:]')
end
# display(size(KEE))
# OBJECTIVE FUNCTION AND SENSITIVITY ANALYSIS
# cc = 0.0;
# dc = zeros(nelx, nely, nelz);
# for elz = 1:nelz
# for ely = 1:nely
# for elx = 1:nelx
# # KE = get_KE(truss, x, Es, vs, Gs, elx, ely, elz, false);
# # DKE = get_KE(truss, x, Es, vs, Gs, elx, ely, elz, true);
# # KE=reshape(KEEE[:,get_num(nelx, nely, nelz, elx, ely, elz)] ,24,24)
# # display(get_num1(nelx, nely, nelz, elx, ely, elz))
# # display(get_num(nnx, nny, nnz, elx, ely, elz))
# # KE = (KEs[a].*reshape(alpha[:,a][:],nelx, nely, nelz)[elx, ely, elz])-(KEs[b].*reshape(alpha[:,b][:],nelx, nely, nelz)[elx, ely, elz])
# # KE = KEs[1].*reshape(alpha[:,1][:],nelx, nely, nelz)[elx, ely, elz]
# # for phase = 2:p
# # KE = KE + KEs[phase].*reshape(alpha[:,phase][:],nelx, nely, nelz)[elx, ely, elz];
# # end
# DKE=KE
# dofs1 = get_elem_dofs(nnx, nny, nnz, elx, ely, elz);
# dofs1 = get_elem_dofs(nelx, nely, nelz, elx, ely, elz);
# # display(dofs1)
# Ue = U[dofs1];
# cc = cc + Ue'*KE*Ue;
# dc[elx,ely,elz] = Ue'*DKE*Ue;
# end
# end
# end
# display(size(dc))
# display(c)
# ce=dc[:]
# o=cc
# display(ce)
# display(sum(o))
# dc=dc[:]
# Objective function and sensitivity analysis
# ce= sum((U[edofMat]*KE).*U[edofMat],dims=2)
o = sum(sum(EE.*ce))
# o = sum(sum(-dc))
# display(ce)
# display(sum(o1))
# display(size(ce))
# display(size(EE))
# FILTERING OF SENSITIVITIES
dc = 0.0 .-(q .*mean(Es[a].-Es[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move = 0.2;
r = ones(nx*ny*nz,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
while (l2-l1)/(l1+l2) > 1e-3
lmid = 0.5*(l2+l1)
alpha_a = max.(l,min.(u,alpha[:,a].*sqrt.(-dc./lmid)));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end
function bi_top3DKEOldKindofWorking(a,b,nx,ny,nz,p,v,KEs,Es,q,alpha_old,H,Hs,maxIter)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
# KE=lk_H8(nu)
nelx=nx
nely=ny
nelz=nz
nele = nelx*nely*nelz
ndof = 3*(nelx+1)*(nely+1)*(nelz+1)
nnx = nelx+1; nny = nely+1; nnz = nelz+1;
nodenrs = reshape(1:(1+nelx)*(1+nely)*(1+nelz),1+nely,1+nelx,1+nelz)
edofVec = reshape(3*nodenrs[1:end-1,1:end-1,1:end-1].+1,nelx*nely*nelz,1)
edofMat = repeat(edofVec,1,24).+repeat([0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1 3*(nely+1)*(nelx+1).+[0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1]],nelx*nely*nelz,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(24,1))',24*24*nele,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,24))',24*24*nele,1))
# USER-DEFINED LOAD DOFs
m= Matlab.meshgrid(nelx:nelx, 0:0, 0:nelz)
il=m[1]
jl=m[2]
kl=m[3]
loadnid = kl.*(nelx+1).*(nely+1).+il.*(nely+1).+(nely+1 .-jl)
loaddof = 3 .*loadnid[:] .- 1;
# USER-DEFINED SUPPORT FIXED DOFs
m= Matlab.meshgrid(0:0,0:nely,0:nelz)# Coordinates
iif=m[1]
jf=m[2]
kf=m[3]
fixednid = kf.*(nelx+1).*(nely+1) .+iif .*(nely .+1) .+(nely .+1 .-jf) # Node IDs
fixeddof = [3 .*fixednid[:]; 3 .*fixednid[:].-1; 3 .*fixednid[:].-2] # DOFs
# DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)
F= sparse(loaddof,fill(1,length(loaddof)),fill(-1,length(loaddof)),ndof,1);
U = zeros(ndof,1)
alldofs = 1:ndof
freedofs = setdiff(1:ndof,fixeddof)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
# KE[:]*E[:]'
KEE = KEs[1][:]*alpha[:,1][:]'.^q
for phase = 2:p
KEE = KEE + KEs[phase][:]*alpha[:,phase][:]'.^q;
end
EE = mean(Es[1])*alpha[:,1].^q
for phase = 2:p
EE = EE + mean(Es[phase])*alpha[:,phase].^q;
end
sK = reshape(KEE[:],24*24*nelx*nely*nelz,1)
K = sparse(vec(iK),vec(jK),vec(sK)); K = (K+K')/2
@timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
KE=reshape(sum(KEE,dims=2),24,24)
ce=zeros(nelx* nely* nelz)
# display(size(U[edofMat]))
for i=1:Int(nelx* nely* nelz)
KE = KEs[1].*alpha[i,1]
for phase = 2:p
KE = KE + KEs[phase].*alpha[i,phase]
end
# ce[i]=sum((U[edofMat][i,:]'*reshape(KE[:,i],24,24)).*U[edofMat][i,:]')
ce[i]=sum((U[edofMat][i,:]'*KE).*U[edofMat][i,:]')
end
# display(size(KEE))
# OBJECTIVE FUNCTION AND SENSITIVITY ANALYSIS
# cc = 0.0;
# dc = zeros(nelx, nely, nelz);
# for elz = 1:nelz
# for ely = 1:nely
# for elx = 1:nelx
# # KE = get_KE(truss, x, Es, vs, Gs, elx, ely, elz, false);
# # DKE = get_KE(truss, x, Es, vs, Gs, elx, ely, elz, true);
# # KE=reshape(KEEE[:,get_num(nelx, nely, nelz, elx, ely, elz)] ,24,24)
# # display(get_num1(nelx, nely, nelz, elx, ely, elz))
# # display(get_num(nnx, nny, nnz, elx, ely, elz))
# # KE = (KEs[a].*reshape(alpha[:,a][:],nelx, nely, nelz)[elx, ely, elz])-(KEs[b].*reshape(alpha[:,b][:],nelx, nely, nelz)[elx, ely, elz])
# # KE = KEs[1].*reshape(alpha[:,1][:],nelx, nely, nelz)[elx, ely, elz]
# # for phase = 2:p
# # KE = KE + KEs[phase].*reshape(alpha[:,phase][:],nelx, nely, nelz)[elx, ely, elz];
# # end
# DKE=KE
# dofs1 = get_elem_dofs(nnx, nny, nnz, elx, ely, elz);
# dofs1 = get_elem_dofs(nelx, nely, nelz, elx, ely, elz);
# # display(dofs1)
# Ue = U[dofs1];
# cc = cc + Ue'*KE*Ue;
# dc[elx,ely,elz] = Ue'*DKE*Ue;
# end
# end
# end
# display(size(dc))
# display(c)
# ce=dc[:]
# o=cc
# display(ce)
# display(sum(o))
# dc=dc[:]
# Objective function and sensitivity analysis
# ce= sum((U[edofMat]*KE).*U[edofMat],dims=2)
o = sum(sum(EE.*ce))
# display(ce)
# display(sum(o1))
# display(size(ce))
# display(size(EE))
# FILTERING OF SENSITIVITIES
dc = 0.0 .-(q .*mean(Es[a].-Es[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move = 0.2;
r = ones(nx*ny*nz,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
while (l2-l1)/(l1+l2) > 1e-3
lmid = 0.5*(l2+l1)
alpha_a = max.(l,min.(u,alpha[:,a].*sqrt.(-dc./lmid)));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end
####
########
function multitop3D_compliantKE(nx,ny,nz,tol_out,tol_f,iter_max_in,iter_max_out,p,q,KEs,Es,v,rf,getProblem=inverter)
anim=Animation()
alpha = zeros(Float64,nx*ny*nz,p)
for i = 1:p
alpha[:,i] .= v[i]
end
# MAKE FILTER
H,Hs = make_filter3D(nx,ny,nz,rf)
obj=0
change_out = 2*tol_out; iter_out = 0;
while (iter_out < iter_max_out) && (change_out > tol_out)
alpha_old = copy(alpha)
for a = 1:p
for b = a+1:p
obj,alpha = bi_top3D_compliantKE(a,b,nx,ny,nz,p,v,KEs,Es,q,alpha,H,Hs,iter_max_in,getProblem);
end
end
iter_out = iter_out + 1;
change_out = norm(alpha[:].-alpha_old[:],Inf);
display("Iter:$iter_out Obj.:$obj change:$change_out");
# UPDATE FILTER
if (change_out < tol_f) && (rf>3)
tol_f = 0.99*tol_f; rf = 0.99*rf;
H,Hs = make_filter3D(nx,ny,nz,rf)
end
# SCREEN OUT TEMPORAL TOPOLOGY EVERY 5 ITERATIONS
if mod(iter_out,5)==0
I = make_bitmap_3d(p,nx,ny,nz,alpha)
threshold=0.05
display(topplotmulti3d(nx,ny,nz,I,threshold))
frame(anim)
end
end
return anim,alpha
end
function bi_top3D_compliantKE(a,b,nx,ny,nz,p,v,KEs,Es,q,alpha_old,H,Hs,maxIter,getProblem=inverter)
alpha = copy(alpha_old)
nu = 0.3;
# PREPARE FINITE ELEMENT ANALYSIS
# KE=lk_H8(nu)
nelx=nx
nely=ny
nelz=nz
nele = nelx*nely*nelz
ndof = 3*(nelx+1)*(nely+1)*(nelz+1)
nodenrs = reshape(1:(1+nelx)*(1+nely)*(1+nelz),1+nely,1+nelx,1+nelz)
edofVec = reshape(3*nodenrs[1:end-1,1:end-1,1:end-1].+1,nelx*nely*nelz,1)
edofMat = repeat(edofVec,1,24).+repeat([0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1 3*(nely+1)*(nelx+1).+[0 1 2 3*nely.+[3 4 5 0 1 2] -3 -2 -1]],nelx*nely*nelz,1)
iK = convert(Array{Int},reshape(kron(edofMat,ones(24,1))',24*24*nele,1))
jK = convert(Array{Int},reshape(kron(edofMat,ones(1,24))',24*24*nele,1))
# # USER-DEFINED LOAD DOFs
# il = [0 nelx]; jl = [nely nely]; kl = [0 0];
# loadnid = kl .*(nelx+1) .*(nely+1) .+il .*(nely .+1) .+(nely+1 .-jl);
# loaddof = 3 .*loadnid[:] .- 2;
# din = loaddof[1]; dout = loaddof[2];
# F = sparse(loaddof,[1;2],[1;-1],ndof,2);
# # USER-DEFINED SUPPORT FIXED DOFs
# # Top face
# m = Matlab.meshgrid(0:nelx,0:nelz)
# iif=m[1]
# kf=m[2]
# fixednid = kf .*(nelx+1) .*(nely+1) .+iif .*(nely+1) .+1;
# fixeddof_t = 3 .*fixednid[:] .-1;
# # Side face
# m = Matlab.meshgrid(0:nelx,0:nely)
# iif=m[1]
# jf=m[2]
# fixednid = iif .*(nely+1) .+(nely+1 .-jf);
# fixeddof_s = 3*fixednid[:];
# # Two pins
# iif = [0;0]; jf = [0;1]; kf = [nelz;nelz];
# fixednid = kf .*(nelx+1) .*(nely .+1) .+iif .*(nely .+1) .+(nely+1 .-jf)
# fixeddof_p = [3 .*fixednid[:]; 3 .*fixednid[:].-1; 3 .*fixednid[:].-2] # DOFs
# # Fixed DOFs
# fixeddof = union(fixeddof_t,fixeddof_s);
# fixeddof = union(fixeddof, fixeddof_p);
# fixeddof = sort(fixeddof);
# # Displacement vector
# U = zeros(ndof,2);
# freedofs = setdiff(1:ndof,fixeddof)
U,F,freedofs,din,dout=getProblem(nelx,nely,nelz)
o=0;alpha_a=0
# inner iteration
for i =0: (maxIter-1)
# FE-ANALYSIS
# E = e[1]*alpha[:,1].^q
# for phase = 2:p
# E = E + e[phase]*alpha[:,phase].^q;
# end
KEE = KEs[1][:]*alpha[:,1][:]'.^q
for phase = 2:p
KEE = KEE + KEs[phase][:]*alpha[:,phase][:]'.^q
end
# EE = mean(Es[1])*alpha[:,1].^q
# for phase = 2:p
# EE = EE + mean(Es[phase])*alpha[:,phase].^q;
# end
sK = reshape(KEE[:],24*24*nelx*nely*nelz,1)
# sK = reshape(KE[:]*E[:]',24*24*nelx*nely*nelz,1)
K = sparse(vec(iK),vec(jK),vec(sK));
K[din,din] = K[din,din] + 0.1;
K[dout,dout] = K[dout,dout] + 0.1;
K = (K+K')/2;
# @timed U[freedofs] = K[freedofs,freedofs] \ Array(F[freedofs])
@timed U[freedofs,:] = K[freedofs,freedofs] \ Array(F[freedofs,:])
U1 = U[:,1]
U2 = U[:,2]
KE=reshape(sum(KEE,dims=2),24,24)
# ce=zeros(nelx* nely* nelz)
# for i=1:Int(nelx* nely* nelz)
# KE = KEs[1].*alpha[i,1]
# for phase = 2:p
# KE = KE + KEs[phase].*alpha[i,phase]
# end
# ce[i]=-sum((U1[edofMat][i,:]'*KE).*U2[edofMat][i,:]')
# end
ce=zeros(nelx* nely* nelz)
for i=1:Int(nelx* nely* nelz)
KE = KEs[1].*alpha[i,1]
for phase = 2:p
KE = KE + KEs[phase].*alpha[i,phase]
end
ce[i]=-sum((U1[edofMat][i,:]'*KE).*U2[edofMat][i,:]')
end
# Objective function and sensitivity analysis
# ce = -sum((U1[edofMat]*KE).*U2[edofMat],dims=2)
# o = sum(sum(E.*ce))
o = U[dout,1]
# FILTERING OF SENSITIVITIES
# dc = 0.0 .-(q .*(e[a].-e[b]).*alpha[:,a].^(q-1)).*ce;
dc = 0.0 .-(q .*mean(Es[a].-Es[b]).*alpha[:,a].^(q-1)).*ce;
dc = H*(alpha[:,a].*dc)./Hs./max.(1e-3,alpha[:,a])
dc = min.(dc,0.0)
# UPDATE LOWER AND UPPER BOUNDS OF DESIGN VARIABLES
move = 0.1;
r = ones(nx*ny*nz,1)
for k = 1:p
#if (k ~= a) && (k ~= b)
if (k != a) && (k != b)
# display("k $k a $a b $b")
r = r .- alpha[:,k]
end
end
l = max.(0,alpha[:,a] .-move)
u = min.(r,alpha[:,a] .+move)
# OPTIMALITY CRITERIA UPDATE OF DESIGN VARIABLES
l1 = 0; l2 = 1e9
# while (l2-l1)/(l1+l2) > 1e-3
while (l2-l1)/(l1+l2) > 1e-4 && l2 > 1e-40
lmid = 0.5*(l2+l1)
# alpha_a = max.(l,min.(u,alpha[:,a].*sqrt.(-dc./lmid)));
alpha_a = max.(l,min.(u,alpha[:,a].*((max.(1e-10,-dc./lmid)).^0.3 )));
if sum(alpha_a) > nx*ny*v[a]
l1 = lmid
else
l2 = lmid
end
end
alpha[:,a] = alpha_a
alpha[:,b] = r .-alpha_a
end
return o,alpha
end