Skip to main content

Implementation MMA Code (Svanberg) in 88 line code (Andreassen, Sigmund) with Heaviside projection method

Submitted by Pollepep on

Dear members, 

 

I'm strugling with implementing the MMA code (Svanberg) in the 88 line code with Heaviside projection method.

The sensitivity and density filter both work correctly, but when ft == 3 (Heaviside) my volfrac goes to 1 (when it's supposed to be 0.5 or something else)

Can somebody help me with this?

 

I just paste the code here (without the MMA part, mmasub & subsolv, because its too long and I have not changed anything different than the original of Svanberg)

function top110MMA(nelx,nely,volfrac,penal,rmin,ft)

%% MATERIAL PROPERTIES

E0 = 1;

Emin = 1e-9;

nu = 0.3;

%% PREPARE FINITE ELEMENT ANALYSIS//blijft

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]);

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 = repmat(edofVec,1,8)+repmat([0 1 2*nely+[2 3 0 1] -2 -1],nelx*nely,1);

iK = reshape(kron(edofMat,ones(8,1))',64*nelx*nely,1);

jK = reshape(kron(edofMat,ones(1,8))',64*nelx*nely,1);

% DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM)//blijft

F = sparse(2,1,-1,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);

%% PREPARE FILTER ///blijft

iH = ones(nelx*nely*(2*(ceil(rmin)-1)+1)^2,1);

jH = ones(size(iH));

sH = zeros(size(iH));

k = 0;

for i1 = 1:nelx

  for j1 = 1:nely

    e1 = (i1-1)*nely+j1;

    for i2 = max(i1-(ceil(rmin)-1),1):min(i1+(ceil(rmin)-1),nelx)

      for j2 = max(j1-(ceil(rmin)-1),1):min(j1+(ceil(rmin)-1),nely)

        e2 = (i2-1)*nely+j2;

        k = k+1;

        iH(k) = e1;

        jH(k) = e2;

        sH(k) = max(0,rmin-sqrt((i1-i2)^2+(j1-j2)^2));

      end

    end

  end

end

H = sparse(iH,jH,sH);

Hs = sum(H,2);

%% INITIALIZE ITERATION

x = repmat(volfrac,nely,nelx);

beta = 1;

if ft == 1 || ft == 2

  xPhys = x;

elseif ft == 3

  xTilde = x;

  xPhys = 1-exp(-beta*xTilde)+xTilde*exp(-beta);

end

loopbeta = 0;

loop = 0;

change = 1;

m       = 1;                        % number of general constraints

n       = nely*nelx;                % Number of design variables

nelm    = nely*nelx;

xmin    = 1e-9*ones(nelm,1);        % Minimum value of each DV

xmax    = ones(nelm,1);             % Maximum value of each DV

xval    = reshape(x,nelm,1);        % Initial value of each DV

xold1   = xval;                     % Previous value of each DV

xold2   = xval;                     % Previous previous value of each DV

u       = xval;                     % Extra vector used to determine xold1 and xold2

a0      = 1;                        % Vector of constants (set to 1 fronm exercise description)

ai      = 0; 

ci      = 1000;                     % Vector of constants >= 0

di      = 0;                        % Vector of constants >= 0

low     = ones(nelm,1);

upp     = ones(nelm,1);

%% START ITERATION

while change > 0.01

  loopbeta = loopbeta+1;

  loop = loop+1;

  iter = loop;

  %% FE-ANALYSIS

  sK = reshape(KE(:)*(Emin+xPhys(:)'.^penal*(E0-Emin)),64*nelx*nely,1);

  K = sparse(iK,jK,sK); K = (K+K')/2;

  U(freedofs) = K(freedofs,freedofs)\F(freedofs);

  %% OBJECTIVE FUNCTION AND SENSITIVITY ANALYSIS

  ce = reshape(sum((U(edofMat)*KE).*U(edofMat),2),nely,nelx);

  c = sum(sum((Emin+xPhys.^penal*(E0-Emin)).*ce));

  dc = -penal*(E0-Emin)*xPhys.^(penal-1).*ce;

  dv = ones(nely,nelx);

  fscale = c/10;  

  c = fscale;

  %% FILTERING/MODIFICATION OF SENSITIVITIES

  if ft == 1

    dc(:) = H*(x(:).*dc(:))./Hs./max(1e-3,x(:));

  elseif ft == 2

    dc(:) = H*(dc(:)./Hs);

    dv(:) = H*(dv(:)./Hs);

  elseif ft == 3

    dx = beta*exp(-beta*xTilde)+exp(-beta);

    dc(:) = H*(dc(:).*dx(:)./Hs);

    dv(:) = H*(dv(:).*dx(:)./Hs); 

  end

  %% MMA Update

  xval = reshape(x,nelm,1);

  fval = sum(sum(x(:)))/(volfrac*nely*nelx)-1;

  dfdx = ones(1,nelm)*1/(volfrac*nely*nelx);

  f0val = c;

  df0dx = reshape(dc,nelm,1);

  df0dx2 = 0*df0dx;

  dfdx2 = 0*dfdx;

  

  

  [xmma,~,~,~,~,~,~,~,~,low,upp] = ...

      mmasub(m,n,iter,xval,xmin,xmax,xold1,xold2, ...

      f0val,df0dx,df0dx2,fval,dfdx,dfdx2,low,upp,a0,ai,ci,di);

  

  

  xnew = reshape(xmma,nely,nelx);

  if ft == 1

    xPhys = xnew;

  elseif ft == 2

    xPhys(:) = (H*xnew(:))./Hs;

  elseif ft == 3

    xTilde(:) = (H*xnew(:))./Hs;

    xPhys = 1-exp(-beta*xTilde)+xTilde*exp(-beta);

  end

  xold2 = xold1(:);

  xold1 = x(:);

  

  change = max(abs(xnew(:)-x(:)));

  x = xnew;

  %% PRINT RESULTS

  fprintf(' It.:%5i Obj.:%11.4f Vol.:%7.3f ch.:%7.3f\n',loop,c, ...

   sum(xPhys(:))/(nelx*nely),change);

  %% PLOT DENSITIES

  colormap(gray); imagesc(1-xPhys); caxis([0 1]); axis equal; axis off; drawnow;

  %% UPDATE HEAVISIDE REGULARIZATION PARAMETER

  if ft == 3 && beta < 512 && (loopbeta >= 50 || change <= 0.01)

    beta = 2*beta;

    loopbeta = 0;

    change = 1;

    fprintf('Parameter beta increased to %g.\n',beta);

  end

 

end