# Amira Abdel-Rahman # (c) Massachusetts Institute of Technology 2020 # based on https://curate.nd.edu/show/dv13zs28316 function hcastruc1(X, E, nu, p, tgS, s, scond, k, neighbors, bcond, itmax, vtol, ctype, ttype, T, xfilter, sfilter) states=[] anim=Animation() # INPUT PARAMETERS nelx, nely = size(X); # CORRECT DENSITY X[X .< 0.001] .= 0.001; X[X .> 1.000] .= 1.000; # START HCA ALGORITHM println("running hca...") # FE-ANALYSIS #SED = fea(copy(X), fxF, fxU, Ymod, nu, p); SED,U = fea(copy(X), p,E,nu) # MECHANICAL STIMULUS S=zeros(size(X)) if ttype==1 S = SED; else S = SED./X; end # PLOT it = 0; SE = sum(sum(SED,dims=1)); M = sum(sum(X,dims=1)); println("t: $it, SE: $SE, M: $M") efX=zeros(size(X)) efS=zeros(size(X)) # EFFECTIVE RELATIVE MASS if xfilter if bcond==1 #fixed bcond efX = doavgf(X,neighbors,0); elseif bcond==2 #periodic bcond bcond==1 #fixed bcond efX = doavgp(X,neighbors); end else efX .= X; end # EFFECTIVE STIMULUS if sfilter if bcond==1 #fixed bcond efS = doavgf(S,neighbors,0); elseif bcond==2 #periodic bcond efS = doavgp(S,neighbors); end else efS = copy(S); end # EFFECTIVE ERROR SIGNAL efE = zeros(size(efS)); efE[efS .> tgS] .= efS[efS .> tgS] .- (1+s)*tgS[efS .> tgS]; efE[efS .< tgS] .= efS[efS .< tgS] .- (1-s)*tgS[efS .< tgS]; # FOR INTEGRAL CONTROL: CREATE HISTORY OF STATES FOR INTEGRAL CONTROL efEhis = zeros(size(efE,1),size(efE,2),T+2); efEsum = zeros(size(efE,1),size(efE,2)); # FOR CONVERGENCE Mtol = Inf; # FOR CONVERGENCE PLOT ITplt = 0; SEplt = SE; Mplt = M; # FOR DERIVATIVE CONTROL efEold = efE; #default #efEold = zeros(size(efE)); #modified # LOOP Xnew = copy(X); Mold = 0; while (it<itmax ) # while (it<itmax && Mtol>vtol) it = it + 1; # SURFACE CONDITION xid = efE .!=0; sneighbors = 4; if scond==2 #soft surface condition if bcond==1 #fixed bcond sfX = doavgf(X,sneighbors,0); #average in N+1 neighbors elseif bcond==2 #periodic bcond sfX = doavgf(X,sneighbors,0); #average in N+1 neighbors end xid=(sfX.<1.000) .& (sfX.>0.001) #x=[1 2 3;5 3 1] #m=(x.<3) .& (x.>1) #yyy=zeros(Int,size(sfX));zzz=zeros(Int,size(sfX)) #yyy[sfX.<1.000 ].=1;zzz[sfX.>0.001].=1 #xid = yyy .& zzz #xid .= (sfX.<1.000 .& sfX.>0.001); elseif scond==3 #strict surface condition if bcond==1 #fixed bcond sfX = doavgf(X,sneighbors,0); #avg in N+1 neighbors lzX = lookznf(X,sneighbors,0); #look for zeros around loX = lookonf(X,sneighbors,0); #look for ones around elseif bcond==2 #periodic bcond sfX = doavgp(X,sneighbors); #average in N+1 neighbors lzX = lookznp(X,sneighbors); #look for zeros around loX = lookonp(X,sneighbors); #look for ones around end xid=(sfX.<0.999) .& (sfX.>0.001) #xid .= (sfX.<0.999 .& sfX.>0.001);# | (X<0.999 & X>0.001); xid[X.<=0.001] .= loX[X.<=0.001]; xid[X.>=1.000] .= lzX[X.>=1.000]; end # UPDATE RULE if ctype== "f" #display("SED") #display(heatmap(SED',xaxis=nothing,yaxis=nothing,legend=nothing,c=:greys,title="it: $it")) #display("Xnew") #display(heatmap(Xnew',xaxis=nothing,yaxis=nothing,legend=nothing,c=:greys,title="it: $it")) #display("efX") #display(heatmap(efX',xaxis=nothing,yaxis=nothing,legend=nothing,c=:greys,title="it: $it")) #display("efE") #display(heatmap(efE',xaxis=nothing,yaxis=nothing,legend=nothing,c=:greys,title="it: $it")) Xnew[xid] .= efX[xid] + k[1]*sign.(efE[xid]); elseif ctype== "p" Xnew[xid] .= efX[xid] + k[2]*efE[xid]./tgS[xid]; elseif ctype== "i" Xnew[xid] .= efX[xid] + k[3]*efEsum[xid]./tgS[xid]; elseif ctype== "d" Xnew[xid] .= efX[xid] + k[4]*(efE[xid] - efEold[xid])./tgS[xid]; elseif ctype=="e" #ratio approach if ttype==1 Xnew[xid] = k[5]*efX[xid].*(efS[xid]./tgS[xid]).^(1.0/p); elseif ttype==2 Xnew[xid] = k[5]*efX[xid].*(tgS[xid]./efS[xid]).^(1.0/p-1.0); end elseif ctype== "n" #ratio approach variable set point if ttype==1 Xnew[xid] .= k[5].*efX[xid].*(S[xid]./efS[xid]).^(1/p); elseif ttype==2 Xnew[xid] .= k[5].*efX[xid].*(efS[xid]./S[xid]).^(1.0/p-1.0); end elseif ctype== "pi" Xnew[xid] = efX[xid] + k[2]*efE[xid]./tgS[xid]; Xnew[xid] = Xnew[xid] + k[3]*efEsum[xid]./tgS[xid]; elseif ctype== "pd" Xnew[xid] = efX[xid] + k[2]*efE[xid]./tgS[xid]; Xnew[xid] = Xnew[xid] + k[4]*(efE[xid] - efEold[xid])./tgS[xid]; elseif ctype== "id" Xnew[xid] = efX[xid] + k[3]*efEsum[xid]./tgS[xid]; Xnew[xid] = Xnew[xid] + k[4]*(efE[xid] - efEold[xid])./tgS[xid]; elseif ctype== "pid" Xnew[xid] = efX[xid] + k[2]*efE[xid]./tgS[xid]; Xnew[xid] = Xnew[xid] + k[3]*efEsum[xid]./tgS[xid]; Xnew[xid] = Xnew[xid] + k[4]*(efE[xid] - efEold[xid])./tgS[xid]; end # FE-ANALYSIS #println(efE); # println(Xnew); #if(minimum(Xnew)<0.0) # Xnew.=Xnew.-minimum(Xnew).+s#amira added to remove negative values TODO make sure right ?? //or add xmin? #end Xnew[Xnew.<=0.0].=s #amira added to remove negative values TODO make sure right ?? //or add xmin? if(minimum(Xnew)>0) SEDnew,U = fea(copy(Xnew), p,E,nu); # MECHANICAL STIMULUS if ttype==1 Snew = SEDnew; else Snew = SEDnew./Xnew; end # CONVERGENCE Mnew = sum(sum(Xnew,dims=1)); Mtol = (abs(Mnew - M) .+ abs(M - Mold))./2.0; # UPDATE SED = SEDnew; X = Xnew; S = Snew; Mold = M; M = Mnew; # FOR DERIVATIVE CONTROL efEold = efE; # EFFECTIVE RELATIVE MASS if xfilter if bcond==1 #fixed bcond efX = doavgf(X,neighbors,0); elseif bcond==2 #periodic bcond efX = doavgp(X,neighbors); end else efX = X; end # EFFECTIVE STIMULUS if sfilter if bcond==1 #fixed bcond efS = doavgf(S,neighbors,0); elseif bcond==2 #periodic bcond efS = doavgp(S,neighbors); end else efS = S; end # EFFECTIVE ERROR SIGNAL efE = zeros(size(S)); efE[efS .> tgS] .= efS[efS .> tgS] .- (1+s).*tgS[efS .> tgS]; efE[efS .< tgS] .= efS[efS .< tgS] .- (1-s).*tgS[efS .< tgS]; # FOR INTEGRAL CONTROL: SUM OF STORED EFFECTIVE STIMULI EST efEsum .= efEsum .+ efE .- efEhis[:,:,1]; efEhis[:,:,T+2] .= efE; for t in 1:T+1 efEhis[:,:,t] .= efEhis[:,:,t+1]; end # PLOT DENSITIES SE = sum(sum(SED)); println("t: $it, SE: $SE, M: $M") # STORE FOR CONVERGENCE PLOT display(Gray.(Xnew')) display(heatmap(Xnew',xaxis=nothing,yaxis=nothing,legend=nothing,c=:greys,title="it: $it")) heatmap(clamp.(Xnew',0,1),xaxis=nothing,yaxis=nothing,legend=nothing,c=:greys,title="it: $it") append!(states,[clamp.(Xnew',0,1)]) frame(anim) else display("ERROR Xnew has negative values!!") it=itmax+1 end end # SAVE FINAL RESULTS cells = Xnew; return anim,cells,states end ############################################# function doavgf(c,neighbors,val) # DOAVGF(X, neighbors,val) sums around each X using fixed boundary # conditions. val is the fixed value. nely,nelx = size(c); cext=zeros(nely+2,nelx+2); cextm=zeros(nely+4,nelx+4); if neighbors > 24 # Global (nelx*ney-1) csum = ones(size(c))*sum(sum(c)); else csum = c; # no neighbors (N=0) if neighbors > 0 # von Newmann (N=4) > 24 # Global (nelx*ney-1) # extends c field for fixed BC cext[nely+2, nelx+2] = val; cext[2:nely+1, 2:nelx+1] = c; x = 2:nelx+1; y = 2:nely+1; csum = csum + cext[y,x.+1] + cext[y,x.-1] + cext[y.+1,x] + cext[y.-1,x]; if neighbors > 4 # Moore (N=8)von Newmann (N=4) > 24 # Global (nelx*ney-1) csum = csum + cext[y.+1,x.+1] + cext[y.-1,x.-1] + cext[y.+1,x.-1] + cext[y.-1,x.+1]; if neighbors > 8 # MvonN (N=12)Moore (N=8)von Newmann (N=4) > 24 # Global (nelx*ney-1) cextm[nely+4, nelx+4] = val; cextm[3:nely+2, 3:nelx+2] = c; y = 3:nely+2; x = 3:nelx+2; csum = csum + cextm[y.-2, x] + cextm[y.+2, x] + cextm[y, x.-2] + cextm[y, x.+2]; if neighbors > 12 # Extended Moore (N=24)MvonN (N=12)Moore (N=8)von Newmann (N=4) > 24 # Global (nelx*ney-1) csum = csum + cextm[y.-2, x.-2] + cextm[y.-2, x.-1] + cextm[y.-2, x.+1] + cextm[y.-2, x.+2] + cextm[y.+2, x.-2] + cextm[y.+2, x.-1] + cextm[y.+2, x.+1] + cextm[y.+2, x.+2] + cextm[y.-1, x.-2] + cextm[y.+1, x.-2] + cextm[y.-1, x.+2] + cextm[y.+1, x.+2]; end end end end end cavg = csum./(neighbors+1); # average csum (matrix) return cavg end #----------------------------------------------------------------- function doavgp(c,neighbors) # DOAVGNP(X, neighbors) sums around each X using fixed periodic # conditions nely,nelx = size(c); x = 1:nelx; y = 1:nely; if neighbors > 24 # Global (nelx*ney-1) csum = ones(size(c))*sum(sum(c))-c; else csum = zeros(size(c)); # no neighbors (N=0) if neighbors > 0 # von Newmann (N=4) csum[mod.(y,nely).+1, mod.(x,nelx).+1] = csum[mod.(y,nely).+1, mod.(x,nelx).+1] + c[mod.(y,nely).+1, mod.(x.+1,nelx).+1] + c[mod.(y,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x,nelx).+1]; if neighbors > 4 # Moore (N=8) csum[mod.(y,nely).+1, mod.(x,nelx).+1] = csum[mod.(y,nely).+1, mod.(x,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x.+1,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x.+1,nelx).+1]; if neighbors > 8 # MvonN (N=12) csum[mod.(y,nely).+1, mod.(x,nelx).+1] = csum[mod.(y,nely).+1, mod.(x,nelx).+1] .+ c[mod.(y.-2,nely).+1, mod.(x,nelx).+1] .+ c[mod.(y.+2,nely).+1, mod.(x,nelx).+1] .+ c[mod.(y,nely).+1, mod.(x.-2,nelx).+1] .+ c[mod.(y,nely).+1, mod.(x.+2,nelx).+1]; if neighbors > 12 # Extended Moore (N=24) csum[mod.(y,nely)+1, mod.(x,nelx)+1] = csum[mod.(y,nely)+1, mod.(x,nelx)+1] + c[mod.(y.-2,nely)+1, mod.(x.-2,nelx)+1] + c[mod.(y.-2,nely)+1, mod.(x.-1,nelx)+1] + c[mod.(y.-2,nely)+1, mod.(x.+1,nelx)+1] + c[mod.(y.-2,nely)+1, mod.(x.+2,nelx)+1] + c[mod.(y.+2,nely)+1, mod.(x.-2,nelx)+1] + c[mod.(y.+2,nely)+1, mod.(x.-1,nelx)+1] + c[mod.(y.+2,nely)+1, mod.(x.+1,nelx)+1] + c[mod.(y.+2,nely)+1, mod.(x.+2,nelx)+1] + c[mod.(y.-1,nely)+1, mod.(x.-2,nelx)+1] + c[mod.(y.+1,nely)+1, mod.(x.-2,nelx)+1] + c[mod.(y.-1,nely)+1, mod.(x.+2,nelx)+1] + c[mod.(y.+1,nely)+1, mod.(x.+2,nelx)+1]; end end end end end cavg = csum./(neighbors); # average csum (matrix) return cavg end ############################################### function lookznf(c,neighbors,val) # LOOKZNF(X, neighbors) products around each X using fixed boundary # conditions # if nargin <3 # val=0; # end c[c.<=0.001].=0; nely,nelx = size(c); cext=zeros(nely+2,nelx+2); cextm=zeros(nely+4,nelx+4); cpro = copy(c); if neighbors <= 24 cpro = c; # no neighbors (N=0) if neighbors > 0 # von Newmann (N=4) # extends c field for fixed BC cext[nely+2, nelx+2] = val; cext[2:nely+1, 2:nelx+1] = c; x = 2:nelx+1; y = 2:nely+1; cpro = 1* cext[y,x.+1] .* cext[y,x.-1] .* cext[y.+1,x] .* cext[y.-1,x]; if neighbors > 4 # Moore (N=8) cpro = cpro .* cext[y.+1,x.+1] .* cext[y.-1,x.-1] .* cext[y.+1,x.-1] .* cext[y.-1,x.+1]; if neighbors > 8 # MvonN (N=12) cextm[nely+4, nelx+4] = val; cextm[3:nely+2, 3:nelx+2] = c; y = 3:nely+2; x = 3:nelx+2; cpro = cpro .* cextm[y.-2, x] .* cextm[y.+2, x] .* cextm[y, x.-2] .* cextm[y, x.+2]; if neighbors > 12 # Extended Moore (N=24) csum = csum .* cextm[y.-2, x.-2] .* cextm[y.-2, x.-1] .* cextm[y.-2, x.+1] .* cextm[y.-2, x.+2] .* cextm[y.+2, x.-2] .* cextm[y.+2, x.-1] .* cextm[y.+2, x.+1] .* cextm[y.+2, x.+2] .* cextm[y.-1, x.-2] .* cextm[y.+1, x.-2] .* cextm[y.-1, x.+2] .* cextm[y.+1, x.+2]; end end end end end cproy=copy(cpro) cpro[cproy.>0].=0 cpro[cproy.==0].=1 return cpro end #----------------------------------------------------------------- function lookznp(c,neighbors) # LOOKZNP(X, neighbors) products around each X using fixed periodic # conditions c[c.<=0.001].=0; nely,nelx = size(c); x = 1:nelx; y = 1:nely; cpro = copy(c); if neighbors <= 24 if neighbors > 0 # von Newmann (N=4) cpro[mod.(y,nely).+1, mod.(x,nelx).+1] = c[mod.(y,nely).+1, mod.(x+1,nelx).+1] .* c[mod.(y,nely).+1, mod.(x-1,nelx).+1] .* c[mod.(y.+1,nely).+1, mod.(x,nelx).+1] .* c[mod.(y.-1,nely).+1, mod.(x,nelx).+1]; if neighbors > 4 # Moore (N=8) cpro[mod(y,nely)+1, mod(x,nelx)+1] = cpro[mod.(y,nely).+1, mod.(x,nelx).+1] .* c[mod.(y.+1,nely).+1, mod.(x.+1,nelx).+1] .* c[mod.(y.-1,nely).+1, mod.(x.-1,nelx).+1] .* c[mod.(y.+1,nely).+1, mod.(x.-1,nelx).+1] .* c[mod.(y.-1,nely).+1, mod.(x.+1,nelx).+1]; if neighbors > 8 # MvonN (N=12) cpro[mod(y,nely)+1, mod(x,nelx)+1] = cpro[mod(y,nely)+1, mod.(x,nelx)+1] .* c[mod.(y.-2,nely)+1, mod.(x,nelx)+1] .* c[mod.(y.+2,nely)+1, mod.(x,nelx)+1] .* c[mod.(y,nely)+1, mod.(x.-2,nelx)+1] .* c[mod.(y,nely)+1, mod.(x.+2,nelx)+1]; if neighbors > 12 # Extended Moore (N=24) cpro[mod(y,nely)+1, mod(x,nelx)+1] = cpro[mod(y,nely)+1, mod(x,nelx)+1] .* c[mod.(y.-2,nely).+1, mod.(x.-2,nelx).+1] .* c[mod.(y.-2,nely).+1, mod.(x.-1,nelx).+1] .* c[mod.(y.-2,nely).+1, mod.(x.+1,nelx).+1] .* c[mod.(y.-2,nely).+1, mod.(x.+2,nelx).+1] .* c[mod.(y.+2,nely).+1, mod.(x.-2,nelx).+1] .* c[mod.(y.+2,nely).+1, mod.(x.-1,nelx).+1] .* c[mod.(y.+2,nely).+1, mod.(x.+1,nelx).+1] .* c[mod.(y.+2,nely).+1, mod.(x.+2,nelx).+1] .* c[mod.(y.-1,nely).+1, mod.(x.-2,nelx).+1] .* c[mod.(y.+1,nely).+1, mod.(x.-2,nelx).+1] .* c[mod.(y.-1,nely).+1, mod.(x.+2,nelx).+1] .* c[mod.(y.+1,nely).+1, mod.(x.+2,nelx).+1]; end end end end end cproy=copy(cpro) cpro[cproy.>0].=0 cpro[cproy.==0].=1 return cpro end ##################################### function lookonf(c,neighbors,val) # LOOKONF(X, neighbors) sums around each X using fixed boundary # conditions # if nargin <3 # val=0; # end c[c.>=0.999].=1; c[c.<0.999].=0; nely,nelx = size(c); cext=zeros(nely+2,nelx+2); cextm=zeros(nely+4,nelx+4); if neighbors <= 24 # Global (nelx*ney-1) csum = zeros(size(c)); # no neighbors (N=0) if neighbors > 0 # von Newmann (N=4) # extends c field for fixed BC cext[nely+2, nelx+2] = val; cext[2:nely+1, 2:nelx+1] = c; x = 2:nelx+1; y = 2:nely+1; csum = csum + cext[y,x+1] + cext[y,x-1] + cext[y.+1,x] + cext[y.-1,x]; if neighbors > 4 # Moore (N=8) csum = csum + cext[y.+1,x.+1] + cext[y.-1,x.-1] + cext[y.+1,x.-1] + cext[y.-1,x.+1]; if neighbors > 8 # MvonN (N=12) cextm[nely+4, nelx+4] = val; cextm[3:nely+2, 3:nelx+2] = c; y = 3:nely+2; x = 3:nelx+2; csum = csum + cextm[y-2, x] + cextm[y+2, x] + cextm[y, x.-2] + cextm[y, x.+2]; if neighbors > 12 # Extended Moore (N=24) csum = csum + cextm[y.-2, x.-2] + cextm[y.-2, x.-1] + cextm[y.-2, x.+1] + cextm[y.-2, x.+2] + cextm[y.+2, x.-2] + cextm[y.+2, x.-1] + cextm[y.+2, x.+1] + cextm[y.+2, x.+2] + cextm[y.-1, x.-2] + cextm[y.+1, x.-2] + cextm[y.-1, x.+2] + cextm[y.+1, x.+2]; end end end end end cavg = csum./(neighbors); # average csum (matrix) cout = cavg > 0; return cout end #----------------------------------------------------------------- function looknp(c,neighbors) # LOOKONP(X, neighbors) sums around each X using fixed periodic # conditions c[c.>=0.999].=1; c[c.<0.999].=0; nely,nelx = size(c); x = 1:nelx; y = 1:nely; if neighbors <= 24 csum = zeros(size(c)); # no neighbors (N=0) if neighbors > 0 # von Newmann (N=4) csum[mod.(y,nely).+1, mod.(x,nelx)+1] = csum[mod(y,nely).+1, mod.(x,nelx).+1] + c[mod.(y,nely).+1, mod.(x.+1,nelx).+1] + c[mod.(y,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x,nelx).+1]; if neighbors > 4 # Moore (N=8) csum[mod.(y,nely)+1, mod.(x,nelx).+1] = csum[mod.(y,nely).+1, mod.(x,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x.+1,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x.+1,nelx).+1]; if neighbors > 8 # MvonN (N=12) csum[mod(y,nely)+1, mod(x,nelx)+1] = csum[mod.(y,nely).+1, mod.(x,nelx).+1] + c[mod.(y.-2,nely).+1, mod.(x,nelx).+1] + c[mod.(y.+2,nely).+1, mod.(x,nelx).+1] + c[mod.(y,nely).+1, mod.(x.-2,nelx).+1] + c[mod.(y,nely).+1, mod.(x.+2,nelx).+1]; if neighbors > 12 # Extended Moore (N=24) csum[mod(y,nely)+1, mod(x,nelx)+1] = csum[mod(y,nely)+1, mod(x,nelx)+1] + c[mod.(y.-2,nely).+1, mod.(x.-2,nelx).+1] + c[mod.(y.-2,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.-2,nely).+1, mod.(x.+1,nelx).+1] + c[mod.(y.-2,nely).+1, mod.(x.+2,nelx).+1] + c[mod.(y.+2,nely).+1, mod.(x.-2,nelx).+1] + c[mod.(y.+2,nely).+1, mod.(x.-1,nelx).+1] + c[mod.(y.+2,nely).+1, mod.(x.+1,nelx).+1] + c[mod.(y.+2,nely).+1, mod.(x.+2,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x.-2,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x.-2,nelx).+1] + c[mod.(y.-1,nely).+1, mod.(x.+2,nelx).+1] + c[mod.(y.+1,nely).+1, mod.(x.+2,nelx).+1]; end end end end end cavg = csum./(neighbors); # average csum (matrix) cout = cavg>0; return cout end ###################################### function fea(x, p,E,nu) nelx = size(x,1)+1; nely = size(x,2)+1; latticeSize=2 setup=getSetup(latticeSize) maxNumTimeSteps=5000 maxNumFiles=200 saveEvery=round(maxNumTimeSteps/maxNumFiles) maxNumFiles=round(maxNumTimeSteps/saveEvery)-2 setup["maxNumFiles"]=maxNumFiles save=false metavoxel,displacements=runMetavoxel2DGPULive!(setup,x,nelx,nely,p,E,nu,maxNumTimeSteps,saveEvery,maxNumFiles,save) k=[1/2-nu/6,1/8+nu/8,-1/4-nu/12,-1/8+3*nu/8,-1/4+nu/12,-1/8-nu/8,nu/6,1/8-3*nu/8] KE = E/(1-nu^2)*[ k[0+1] k[1+1] k[2+1] k[3+1] k[4+1] k[5+1] k[6+1] k[7+1]; k[1+1] k[0+1] k[7+1] k[6+1] k[5+1] k[4+1] k[3+1] k[2+1]; k[2+1] k[7+1] k[0+1] k[5+1] k[6+1] k[3+1] k[4+1] k[1+1]; k[3+1] k[6+1] k[5+1] k[0+1] k[7+1] k[2+1] k[1+1] k[4+1]; k[4+1] k[5+1] k[6+1] k[7+1] k[0+1] k[1+1] k[2+1] k[3+1]; k[5+1] k[4+1] k[3+1] k[2+1] k[1+1] k[0+1] k[7+1] k[6+1]; k[6+1] k[3+1] k[4+1] k[1+1] k[2+1] k[7+1] k[0+1] k[5+1]; k[7+1] k[2+1] k[1+1] k[4+1] k[3+1] k[6+1] k[5+1] k[0+1] ] SED = zeros(nelx-1,nely-1) U = zeros(nelx,nely,2) for ii in 0:(nelx-1) for jj in 0:(nely-1) i=((ii)*nely +(jj))+1 if(ii<nelx-1&&jj<nely-1) Ue=[displacements[i].x;displacements[i].y; displacements[((ii+1)*nely +(jj))+1].x;displacements[((ii+1)*nely +(jj))+1].y; displacements[((ii+1)*nely +(jj+1))+1].x;displacements[((ii+1)*nely +(jj+1))+1].y; displacements[((ii)*nely +(jj+1))+1].x;displacements[((ii)*nely +(jj+1))+1].y] SEDi = 1/2*x[ii+1,jj+1]^p*Ue'*KE*Ue; SED[ii+1,jj+1]=SED[ii+1,jj+1]+SEDi end U[ii+1,jj+1,1]=displacements[i].x U[ii+1,jj+1,2]=displacements[i].y end end # return SED return SED,U end #####################