Skip to content
Snippets Groups Projects
concurrent3d.jl 18.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • function ConTop3D(Macro_struct, Micro_struct, penal, rmin)
        # USER-DEFINED LOOP PARAMETERS
        maxloop = 200; displayflag = 1; E0 = 1; Emin = 1e-9; nu = 0.3;
        Macro_length = Macro_struct[1]; Macro_width = Macro_struct[2]; Macro_Height = Macro_struct[3];
        Micro_length = Micro_struct[1]; Micro_width = Micro_struct[2]; Micro_Height = Micro_struct[3];
        Macro_nelx   = Macro_struct[4]; Macro_nely  = Macro_struct[5]; Macro_nelz   = Macro_struct[6];
        Micro_nelx   = Micro_struct[4]; Micro_nely  = Micro_struct[5]; Micro_nelz   = Micro_struct[6];
        Macro_Vol = Macro_struct[7]; Micro_Vol = Micro_struct[7];
        Macro_Elex   = Macro_length/Macro_nelx; Macro_Eley = Macro_width/Macro_nely; Macro_Elez = Macro_Height/Macro_nelz;
        Macro_nele = Macro_nelx*Macro_nely*Macro_nelz; Micro_nele = Micro_nelx*Micro_nely*Micro_nelz;
        Macro_ndof = 3*(Macro_nelx+1)*(Macro_nely+1)*(Macro_nelz+1);
        # PREPARE FINITE ELEMENT ANALYSIS
        [load_x,load_y,load_z] = meshgrid(Macro_nelx/2, Macro_nely, Macro_nelz/2);
        loadnid = load_z*(Macro_nelx+1)*(Macro_nely+1)+load_x*(Macro_nely+1)+(Macro_nely+1-load_y);
        F = sparse(3*loadnid[:] - 1,1,-1,Macro_ndof,1);
        U = zeros(Macro_ndof,1);
        [fixed_x,fixed_y,fixed_z] = meshgrid( [0 Macro_nelx],0,[0 Macro_nelz] );
        fixednid = fixed_z*(Macro_nelx+1)*(Macro_nely+1)+fixed_x*(Macro_nely+1)+(Macro_nely+1-fixed_y);
        fixeddofs = [3*fixednid[:]; 3*fixednid[:]-1; 3*fixednid[:]-2];
        freedofs = setdiff(1:Macro_ndof,fixeddofs);
        nodegrd = reshape(1:(Macro_nely+1)*(Macro_nelx+1),Macro_nely+1,Macro_nelx+1);
        nodeids = reshape(nodegrd[1:end-1,1:end-1],Macro_nely*Macro_nelx,1);
        nodeidz = 0:(Macro_nely+1)*(Macro_nelx+1):(Macro_nelz-1)*(Macro_nely+1)*(Macro_nelx+1);
        nodeids = repmat(nodeids,size(nodeidz))+repmat(nodeidz,size(nodeids));
        edofMat = repmat(3*nodeids[:]+1,1,24)+ repmat( [0 1 2 3*Macro_nely + [3 4 5 0 1 2] -3 -2 -1  
            3*(Macro_nely+1)*(Macro_nelx+1)+[0 1 2 3*Macro_nely + [3 4 5 0 1 2] -3 -2 -1]],Macro_nele,1);
        iK = reshape(kron(edofMat,ones(24,1))',24*24*Macro_nele,1);
        jK = reshape(kron(edofMat,ones(1,24))',24*24*Macro_nele,1);
        # PREPARE FILTER
        Macro_H,Macro_Hs = filtering3d(Macro_nelx, Macro_nely, Macro_nelz, Macro_nele, rmin);
        Micro_H,Micro_Hs = filtering3d(Micro_nelx, Micro_nely, Micro_nelz, Micro_nele, rmin);
        # INITIALIZE ITERATION
        Macro_x = repmat(Macro_Vol,[Macro_nely,Macro_nelx,Macro_nelz] );
        Micro_x = ones(Micro_nely,Micro_nelx,Micro_nelz);
        Micro_x[Micro_nely/2:Micro_nely/2+1,Micro_nelx/2:Micro_nelx/2+1,Micro_nelz/2:Micro_nelz/2+1] = 0;
        beta = 1;
        Macro_xTilde = Macro_x; Micro_xTilde = Micro_x;
        Macro_xPhys = 1-exp(-beta*Macro_xTilde)+Macro_xTilde*exp(-beta);
        Micro_xPhys = 1-exp(-beta*Micro_xTilde)+Micro_xTilde*exp(-beta);
        loopbeta = 0; loop = 0; Macro_change = 1; Micro_change = 1;
        while loop < maxloop || Macro_change > 0.01 || Micro_change > 0.01
            loop = loop+1; loopbeta = loopbeta+1;
            # FE-ANALYSIS AT TWO SCALES
            DH, dDH = EBHM3D(Micro_xPhys, Micro_length, Micro_width, Micro_Height, E0, Emin, nu, penal);
            Ke = elementMatVec3D(Macro_Elex/2, Macro_Eley/2, Macro_Elez/2, DH);
            sK = reshape(Ke[:]*(Emin+Macro_xPhys[:]'.^penal*(1-Emin)),24*24*Macro_nele,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),[Macro_nely,Macro_nelx,Macro_nelz] );
            c = sum(sum(sum((Emin+Macro_xPhys.^penal*(1-Emin)).*ce)));
            Macro_dc = -penal*(1-Emin)*Macro_xPhys.^(penal-1).*ce;
            Macro_dv = ones(Macro_nely, Macro_nelx, Macro_nelz);
            Micro_dc = zeros(Micro_nely, Micro_nelx, Micro_nelz);
            for i = 1:Micro_nele
                dDHe = [dDH[1,1][i] dDH[1,2][i] dDH[1,3][i] dDH[1,4][i] dDH[1,5][i] dDH[1,6][i];
                        dDH[2,1][i] dDH[2,2][i] dDH[2,3][i] dDH[2,4][i] dDH[2,5][i] dDH[2,6][i];
                        dDH[3,1][i] dDH[3,2][i] dDH[3,3][i] dDH[3,4][i] dDH[3,5][i] dDH[3,6][i];
                        dDH[4,1][i] dDH[4,2][i] dDH[4,3][i] dDH[4,4][i] dDH[4,5][i] dDH[4,6][i];
                        dDH[5,1][i] dDH[5,2][i] dDH[5,3][i] dDH[5,4][i] dDH[5,5][i] dDH[5,6][i];
                        dDH[6,1][i] dDH[6,2][i] dDH[6,3][i] dDH[6,4][i] dDH[6,5][i] dDH[6,6][i]];
                dKE = elementMatVec3D(Macro_Elex, Macro_Eley, Macro_Elez, dDHe);
                dce = reshape(sum((U[edofMat]*dKE).*U[edofMat],2),[Macro_nely,Macro_nelx,Macro_nelz] );
                Micro_dc[i] = -sum(sum(sum((Emin+Macro_xPhys.^penal*(1-Emin)).*dce)));
            end
            Micro_dv = ones(Micro_nely, Micro_nelx, Micro_nelz);
            # FILTERING AND MODIFICATION OF SENSITIVITIES
            Macro_dx = beta*exp(-beta*Macro_xTilde)+exp(-beta); Micro_dx = beta*exp(-beta*Micro_xTilde)+exp(-beta);
            Macro_dc[:] = Macro_H*(Macro_dc[:].*Macro_dx[:]./Macro_Hs); Macro_dv[:] = Macro_H*(Macro_dv[:].*Macro_dx[:]./Macro_Hs);
            Micro_dc[:] = Micro_H*(Micro_dc[:].*Micro_dx[:]./Micro_Hs); Micro_dv[:] = Micro_H*(Micro_dv[:].*Micro_dx[:]./Micro_Hs);
            # OPTIMALITY CRITERIA UPDATE MACRO AND MICRO ELELMENT DENSITIES
            Macro_x, Macro_xPhys, Macro_change = OC(Macro_x, Macro_dc, Macro_dv, Macro_H, Macro_Hs, Macro_Vol, Macro_nele, 0.02, beta);
            Micro_x, Micro_xPhys, Micro_change = OC(Micro_x, Micro_dc, Micro_dv, Micro_H, Micro_Hs, Micro_Vol, Micro_nele, 0.02, beta);
            Macro_xPhys = reshape(Macro_xPhys, Macro_nely, Macro_nelx, Macro_nelz);
            Micro_xPhys = reshape(Micro_xPhys, Micro_nely, Micro_nelx, Micro_nelz);
            # PRINT RESULTS
            # display(' It.:#5i Obj.:#11.4f Macro_Vol.:#7.3f Micro_Vol.:#7.3f Macro_ch.:#7.3f Micro_ch.:#7.3f\n', loop,c,mean(Macro_xPhys[:] ),mean(Micro_xPhys[:] ), Macro_change, Micro_change);
            # if displayflag, clf; display_3D(Macro_xPhys); end
            # if displayflag, clf; display_3D(Micro_xPhys); end
            # UPDATE HEAVISIDE REGULARIZATION PARAMETER
            if beta < 512 && (loopbeta >= 50 || Macro_change <= 0.01 || Micro_change <= 0.01 )
                beta = 2*beta; loopbeta = 0; Macro_change = 1; Micro_change = 1;
                display("Parameter beta increased to $beta.");
            end
        end
    end
    
    ## SUB FUNCTION:filtering3D
    function filtering3d(nelx, nely, nelz, nele, rmin)
        iH = ones(nele*(2*(ceil(rmin)-1)+1)^2,1);
        jH = ones(size(iH));
        sH = zeros(size(iH));
        k = 0;
        for k1 = 1:nelz
            for i1 = 1:nelx
                for j1 = 1:nely
                    e1 = (k1-1)*nelx*nely + (i1-1)*nely+j1;
                    for k2 = max(k1-(ceil(rmin)-1),1):min(k1+(ceil(rmin)-1),nelz)
                        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 = (k2-1)*nelx*nely + (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+(k1-k2)^2));
                            end
                        end
                    end
                end
            end
        end
        H = sparse(iH,jH,sH); Hs = sum(H,2);
        return H,Hs
    end
    
    
    ## SUB FUNCTION: EBHM3D
    function EBHM3D(den, lx, ly, lz, E0, Emin, nu, penal)
        # the initial definitions of the PUC
        D0 = E0/(1+nu)/(1-2*nu)*
            [ 1-nu   nu   nu     0          0          0     ;
                nu 1-nu   nu     0          0          0     ;
                nu   nu 1-nu     0          0          0     ;
                 0    0    0 (1-2*nu)/2     0          0     ;
                 0    0    0     0      (1-2*nu)/2     0     ;
                 0    0    0     0          0      (1-2*nu)/2];
        nely, nelx, nelz = size(den); nele = nelx*nely*nelz;
        dx = lx/nelx; dy = ly/nely; dz = lz/nelz;
        Ke = elementMatVec3D(dx/2, dy/2, dz/2, D0);
        Num_node = (1+nely)*(1+nelx)*(1+nelz);
        nodenrs = reshape(1:Num_node,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 = repmat(edofVec,1,24)+repmat( [0 1 2 3*nely+[3 4 5 0 1 2] -3 -2 -1 
            3*(nelx+1)*(nely+1)+[0 1 2 3*nely+[3 4 5 0 1 2] -3 -2 -1]], nele, 1);
        # 3D periodic boundary formulation
        # the nodes classification
        n1 = [nodenrs[end, [1 end], 1] nodenrs[1, [end 1], 1] nodenrs[end, [1 end], end] nodenrs[1, [end 1], end]];
        d1 = reshape( [3*n1-2; 3*n1-1; 3*n1],3*numel(n1),1);
        n3 = [reshape(squeeze(nodenrs[end,1,2:end-1] ),1,numel(squeeze(nodenrs[end,1,2:end-1] )))               # AE
              reshape(squeeze(nodenrs[1, 1, 2:end-1] ),1,numel(squeeze(nodenrs[1, 1, 2:end-1] )))               # DH
              reshape(squeeze(nodenrs[end,2:end-1,1] ),1,numel(squeeze(nodenrs[end,2:end-1,1] )))               # AB
              reshape(squeeze(nodenrs[1, 2:end-1, 1] ),1,numel(squeeze(nodenrs[1, 2:end-1, 1] )))               # DC
              reshape(squeeze(nodenrs[2:end-1, 1, 1] ),1,numel(squeeze(nodenrs[2:end-1, 1, 1] )))               # AD
              reshape(squeeze(nodenrs[2:end-1,1,end] ),1,numel(squeeze(nodenrs[2:end-1,1,end] )))               # EH
              reshape(squeeze(nodenrs[2:end-1, 2:end-1, 1] ),1,numel(squeeze(nodenrs[2:end-1, 2:end-1, 1] )))   # ABCD
              reshape(squeeze(nodenrs[2:end-1, 1, 2:end-1] ),1,numel(squeeze(nodenrs[2:end-1, 1, 2:end-1] )))   # ADHE
              reshape(squeeze(nodenrs[end,2:end-1,2:end-1] ),1,numel(squeeze(nodenrs[end,2:end-1,2:end-1] )))];   # ABFE                   
        d3 = reshape( [3*n3-2; 3*n3-1; 3*n3],3*numel(n3),1);
        n4 = [reshape(squeeze(nodenrs[1, end, 2:end-1] ),1,numel(squeeze(nodenrs[1, end, 2:end-1] )))           # CG
              reshape(squeeze(nodenrs[end,end,2:end-1] ),1,numel(squeeze(nodenrs[end,end,2:end-1] )))           # BF
              reshape(squeeze(nodenrs[1, 2:end-1, end] ),1,numel(squeeze(nodenrs[1, 2:end-1, end] )))           # HG
              reshape(squeeze(nodenrs[end,2:end-1,end] ),1,numel(squeeze(nodenrs[end,2:end-1,end] )))           # EF
              reshape(squeeze(nodenrs[2:end-1,end,end] ),1,numel(squeeze(nodenrs[2:end-1,end,end] )))           # FG
              reshape(squeeze(nodenrs[2:end-1, end, 1] ),1,numel(squeeze(nodenrs[2:end-1, end, 1] )))           # BC
              reshape(squeeze(nodenrs[2:end-1,2:end-1,end] ),1,numel(squeeze(nodenrs[2:end-1,2:end-1,end] )))   # EFGH
              reshape(squeeze(nodenrs[2:end-1,end,2:end-1] ),1,numel(squeeze(nodenrs[2:end-1,end,2:end-1] )))   # BCGF
              reshape(squeeze(nodenrs[1, 2:end-1, 2:end-1] ),1,numel(squeeze(nodenrs[1, 2:end-1, 2:end-1] )))];   # DCGH
        d4 = reshape( [3*n4-2; 3*n4-1; 3*n4],3*numel(n4),1);
        n2 = setdiff(nodenrs[:],[n1[:];n3[:];n4[:]] ); d2 = reshape( [3*n2-2; 3*n2-1; 3*n2],3*numel(n2),1);
        # the imposing of six linearly independent unit test strains
        e = Matrix(1.0I, 6, 6); 
        ufixed = zeros(24,6);
        vert_cor = [0  lx lx  0  0 lx lx  0;
                    0   0 ly ly  0  0 ly ly;
                    0   0  0  0 lz lz lz lz];
        for i = 1:6
            epsilon = [  e[i,1] e[i,4]/2 e[i,6]/2;
                       e[i,4]/2   e[i,2] e[i,5]/2;
                       e[i,6]/2 e[i,5]/2   e[i,3]];
            ufixed[:,i] = reshape(epsilon*vert_cor,24,1);
        end
        # 3D boundary constraint equations
        wfixed = [repmat(ufixed[  7:9,:],numel(squeeze(nodenrs[end,1,2:end-1] )),1);                    # C
                  repmat(ufixed[  4:6,:]-ufixed[10:12,:],numel(squeeze(nodenrs[1, 1, 2:end-1] )),1);    # B-D
                  repmat(ufixed[22:24,:],numel(squeeze(nodenrs[end,2:end-1,1] )),1);                    # H
                  repmat(ufixed[13:15,:]-ufixed(10:12,:),numel(squeeze(nodenrs[1, 2:end-1, 1] )),1);    # E-D
                  repmat(ufixed[16:18,:],numel(squeeze(nodenrs[2:end-1, 1, 1] )),1);                    # F
                  repmat(ufixed[  4:6,:]-ufixed[13:15,:],numel(squeeze(nodenrs[2:end-1,1,end] )),1);    # B-E
                  repmat(ufixed[13:15,:],numel(squeeze(nodenrs[2:end-1, 2:end-1, 1] )),1);              # E
                  repmat(ufixed[  4:6,:],numel(squeeze(nodenrs[2:end-1, 1, 2:end-1] )),1);              # B
                  repmat(ufixed[10:12,:],numel(squeeze(nodenrs[end,2:end-1,2:end-1] )),1)];             # D
        # the reduced elastic equilibrium equation to compute the induced displacement field
        iK = reshape(kron(edofMat,ones(24,1))',24*24*nele,1);
        jK = reshape(kron(edofMat,ones(1,24))',24*24*nele,1);
        sK = reshape(Ke[:]*(Emin+den[:]'.^penal*(1-Emin)),24*24*nele,1);
        K = sparse(iK[:], jK[:], sK[:] ); K = (K+K')/2;
        Kr = [K[d2,d2], K[d2,d3]+K[d2,d4]; K[d3,d2]+K[d4,d2],K[d3,d3]+K[d4,d3]+K[d3,d4]+K[d4,d4]];
        U[d1,:]= ufixed;
        U[ [d2;d3],:] = Kr\(-[K[d2,d1];K[d3,d1]+K[d4,d1]]*ufixed-[K[d2,d4];K[d3,d4]+K[d4,d4]]*wfixed);
        U[d4,:] = U[d3,:] + wfixed;
    
        # homogenization to evaluate macroscopic effective properties
        qe = Array{Any,2}(undef, 6, 6);
        DH = zeros(6,6); 
        dDH = Array{Any,2}(undef, 6, 6);
        cellVolume = lx*ly*lz;
        for i = 1:6
            for j = 1:6
                U1 = U[:,i]; U2 = U[:,j];
                qe[i,j] = reshape(sum((U1[edofMat]*Ke).*U2[edofMat],dims=2),nely,nelx,nelz);
                DH[i,j] = 1/cellVolume*sum(sum(sum((Emin+den.^penal*(1-Emin)).*qe{i,j})));
                dDH[i,j] = 1/cellVolume*(penal*(1-Emin)*den.^(penal-1).*qe{i,j});
            end
        end
        # disp('--- Homogenized elasticity tensor ---'); disp(DH)
        return DH, dDH
    end
    
    
    ## SUB FUNCTION: elementMatVec3D
    function elementMatVec3D(a, b, c, DH)
        GN_x=[-1/sqrt(3),1/sqrt(3)]; GN_y=GN_x; GN_z=GN_x; GaussWeigh=[1,1];
        Ke = zeros(24,24); L = zeros(6,9);
        L[1,1] = 1; L[2,5] = 1; L[3,9] = 1;
        L[4,2] = 1; L[4,4] = 1; L[5,6] = 1;
        L[5,8] = 1; L[6,3] = 1; L[6,7] = 1;
        for ii=1:length(GN_x)
            for jj=1:length(GN_y)
                for kk=1:length(GN_z)
                    x = GN_x[ii];y = GN_y[jj];z = GN_z[kk];
                    dNx = 1/8*[-(1-y)*(1-z)  (1-y)*(1-z)  (1+y)*(1-z) -(1+y)*(1-z) -(1-y)*(1+z)  (1-y)*(1+z)  (1+y)*(1+z) -(1+y)*(1+z)];
                    dNy = 1/8*[-(1-x)*(1-z) -(1+x)*(1-z)  (1+x)*(1-z)  (1-x)*(1-z) -(1-x)*(1+z) -(1+x)*(1+z)  (1+x)*(1+z)  (1-x)*(1+z)];
                    dNz = 1/8*[-(1-x)*(1-y) -(1+x)*(1-y) -(1+x)*(1+y) -(1-x)*(1+y)  (1-x)*(1-y)  (1+x)*(1-y)  (1+x)*(1+y)  (1-x)*(1+y)];
                    J = [dNx;dNy;dNz]*[ -a  a  a  -a  -a  a  a  -a ;  -b  -b  b  b  -b  -b  b  b; -c -c -c -c  c  c  c  c]';
                    G = [inv(J) zeros(3) zeros(3);zeros(3) inv(J) zeros(3);zeros(3) zeros(3) inv(J)];
                    dN=zeros(9,24)
                    dN[1,1:3:24] = dNx; dN[2,1:3:24] = dNy; dN[3,1:3:24] = dNz;
                    dN[4,2:3:24] = dNx; dN[5,2:3:24] = dNy; dN[6,2:3:24] = dNz;
                    dN[7,3:3:24] = dNx; dN[8,3:3:24] = dNy; dN[9,3:3:24] = dNz;
                    Be = L*G*dN;
                    Ke = Ke + GaussWeigh[ii]*GaussWeigh[jj]*GaussWeigh[kk]*det(J)*(Be'*DH*Be);
                end
            end
        end
        return Ke
    end
    
    
    ## SUB FUNCTION: OC
    function OC(x, dc, dv, H, Hs, volfrac, nele, move, beta)
        l1 = 0; l2 = 1e9;
        while (l2-l1)/(l1+l2) > 1e-3
            lmid = 0.5*(l2+l1);
            xnew = max(0,max(x-move,min(1,min(x+move,x.*sqrt(-dc./dv/lmid)))));
            xTilde[:] = (H*xnew[:] )./Hs; xPhys = 1-exp(-beta*xTilde)+xTilde*exp(-beta);
            if sum(xPhys[:] ) > volfrac*nele
                l1 = lmid; 
            else
                l2 = lmid; 
            end
        end
        change = max(abs(xnew[:]-x[:] )); x = xnew;
        return x, xPhys, change
    end
    
    
    ## SUB FUNCTION: display_3D
    function display_3D(rho)
        [nely,nelx,nelz] = size(rho);
        hx = 1; hy = 1; hz = 1;
        face = [1 2 3 4; 2 6 7 3; 4 3 7 8; 1 5 8 4; 1 2 6 5; 5 6 7 8];
        # set(gcf,'Name','ISO display','NumberTitle','off');
        for k = 1:nelz
            z = (k-1)*hz;
            for i = 1:nelx
                x = (i-1)*hx;
                for j = 1:nely
                    y = nely*hy - (j-1)*hy;
                    if (rho[j,i,k] > 0)
                        vert = [x y z; x y-hx z; x+hx y-hx z; x+hx y z; x y z+hx;x y-hx z+hx; x+hx y-hx z+hx;x+hx y z+hx];
                        vert[:,[2 3]] = vert[:,[3 2]]; vert[:,2,:] = -vert[:,2,:];
                        # patch('Faces',face,'Vertices',vert,'FaceColor',[0.2+0.8*(1-rho(j,i,k)),0.2+0.8*(1-rho(j,i,k)),0.2+0.8*(1-rho(j,i,k))] );
                        # hold on;
                    end
                end
            end
        end
        # axis equal; axis tight; axis off; box on; view( [30,30] ); pause(1e-6);
    end
    #======================================================================================================================#
    # Function ConTop3D:                                                                                                   #
    # A compact and efficient MATLAB code for Concurrent topology optimization of multiscale composite structures          #
    # in Matlab.                                                                                                           #
    #                                                                                                                      #
    # Developed by: Jie Gao, Zhen Luo, Liang Xia and Liang Gao*                                                            #
    # Email: gaoliang@mail.hust.edu.cn (GabrielJie_Tian@163.com)                                                           #
    #                                                                                                                      #
    # Main references:                                                                                                     #
    #                                                                                                                      #
    # (1) Jie Gao, Zhen Luo, Liang Xia, Liang Gao. Concurrent topology optimization of multiscale composite structures     #
    # in Matlab. Accepted in Structural and multidisciplinary optimization.                                                #
    #                                                                                                                      #
    # (2) Xia L, Breitkopf P. Design of materials using topology optimization and energy-based homogenization approach in  #
    # Matlab. # Structural and multidisciplinary optimization, 2015, 52(6): 1229-1241.                                     #
    #                                                                                                                      #
    # *********************************************   Disclaimer   ******************************************************* #
    # The authors reserve all rights for the programs. The programs may be distributed and used for academic and           #
    # educational purposes. The authors do not guarantee that the code is free from errors,and they shall not be liable    #
    # in any event caused by the use of the program.                                                                       #
    #======================================================================================================================#