├── FE.m ├── FEL.m ├── GaussQuad.m ├── IntEqSolver1d.m ├── KL.m ├── LICENSE ├── README.md ├── dto.m ├── mmasub.m ├── rbto_den.m ├── rbto_den_L.m ├── rbto_mc.m ├── rbto_mc_L.m └── subsolv.m /FE.m: -------------------------------------------------------------------------------- 1 | %%% FE-ANALYSIS 2 | function [U]=FE(nelx,nely,x,penal,KE,E,dof) 3 | K = sparse(2*(nelx+1)*(nely+1),2*(nelx+1)*(nely+1)); 4 | F = sparse(2*(nely+1)*(nelx+1),1); 5 | U = zeros(2*(nely+1)*(nelx+1),1); 6 | for elx = 1:nelx 7 | for ely = 1:nely 8 | n1 = (nely+1)*(elx-1)+ely; 9 | n2 = (nely+1)* elx +ely; 10 | edof = [2*n1-1; 2*n1; 2*n2-1; 2*n2; 2*n2+1; 2*n2+2; 2*n1+1; 2*n1+2]; 11 | K(edof,edof) = K(edof,edof) + x(ely,elx)^penal*E(ely,elx)*KE; 12 | end 13 | end 14 | % DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM) 15 | F(dof,1) = 1; 16 | fixeddofs = union(1:2:2*(nely+1), 2*(nelx+1)*(nely+1)); 17 | alldofs = 1:2*(nely+1)*(nelx+1); 18 | freedofs = setdiff(alldofs,fixeddofs); 19 | % SOLVING 20 | U(freedofs,:) = K(freedofs,freedofs) \ F(freedofs,:); 21 | U(fixeddofs,:) = 0; 22 | end -------------------------------------------------------------------------------- /FEL.m: -------------------------------------------------------------------------------- 1 | %%% FE-ANALYSIS 2 | function [U]=FEL(nelx,nely,x,penal,KE,E,dof) 3 | K = sparse(2*(nelx+1)*(nely+1),2*(nelx+1)*(nely+1)); 4 | F = sparse(2*(nely+1)*(nelx+1),1); 5 | U = zeros(2*(nely+1)*(nelx+1),1); 6 | for elx = 1:nelx 7 | for ely = 1:nely 8 | n1 = (nely+1)*(elx-1)+ely; 9 | n2 = (nely+1)* elx +ely; 10 | edof = [2*n1-1; 2*n1; 2*n2-1; 2*n2; 2*n2+1; 2*n2+2; 2*n1+1; 2*n1+2]; 11 | K(edof,edof) = K(edof,edof) + x(ely,elx)^penal*E(ely,elx)*KE; 12 | end 13 | end 14 | % DEFINE LOADS AND SUPPORTS (HALF MBB-BEAM) 15 | F(dof,1) = 1; 16 | fixeddofs = union(1:2*(nely+1):(nelx/2)*(nely+1)*2+1,2:2*(nely+1):(nelx/2)*(nely+1)*2+2); 17 | alldofs = 1:2*(nely+1)*(nelx+1); 18 | freedofs = setdiff(alldofs,fixeddofs); 19 | % SOLVING 20 | U(freedofs,:) = K(freedofs,freedofs) \ F(freedofs,:); 21 | U(fixeddofs,:) = 0; 22 | end -------------------------------------------------------------------------------- /GaussQuad.m: -------------------------------------------------------------------------------- 1 | function [roots,weights] = GausQuadBasics(p,type,varargin) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | %% returns the roots and weights needed to implement Gaussian quadrature 4 | %% corresponding to the orthogonal polynomials 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | %% p - degree of the polynomial used for the approximation 7 | %% 8 | %% type - type of polynomial 9 | %% 'Hermite': weight function is w(x)=exp(-x^2/2)/(2pi)^.5 10 | %% 'Legendre': weight function is w(x)=1 11 | %% 12 | %% in the case of type = 'Legendre' it's possible to change the interval of 13 | %% integration to [a,b] 14 | %% 15 | %% varargin - optional list of arguments 16 | %% contains the endpoints [a,b] of the interval of integration 17 | %% for type = 'Legendre' 18 | %% if varargin is empty and type = 'Legendre', [a,b] is assumed [-1,1] 19 | %% 20 | %% examples of run: 21 | %% [roots,weights] = GausQuadBasics(3,'legendre'); 22 | %% [roots,weights] = GausQuadBasics(2,'hermite'); 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | 25 | if (nargin == 2)&& strcmpi(type,'Legendre') 26 | a = -1; b = 1; 27 | elseif (nargin > 2) 28 | a = varargin{1}; 29 | b = varargin{2}; 30 | end 31 | 32 | roots = zeros(p,1); 33 | weights = zeros(p,1); 34 | switch lower(type) 35 | case 'legendre' 36 | switch p 37 | case 1 38 | roots(1) = 0; weights(1) = 2; 39 | case 2 40 | roots(1) = 1/sqrt(3); weights(1) = 1; 41 | roots(2) = -roots(1); weights(2) = weights(1); 42 | case 3 43 | roots(1) = sqrt(3/5); weights(1) = 5/9; 44 | roots(2) = -roots(1); weights(2) = weights(1); 45 | roots(3) = 0; weights(3) = 8/9; 46 | case 4 47 | roots(1) = sqrt((3-2*sqrt(6/5))/7); weights(1) = (18+sqrt(30))/36; 48 | roots(2) = -roots(1); weights(2) = weights(1); 49 | roots(3) = sqrt((3+2*sqrt(6/5))/7); weights(3) = (18-sqrt(30))/36; 50 | roots(4) = -roots(3); weights(4) = weights(3); 51 | case 5 52 | roots(1) = sqrt(5-2*sqrt(10/7))/3; weights(1) = (322+13*sqrt(70))/900; 53 | roots(2) = -roots(1); weights(2) = weights(1); 54 | roots(3) = sqrt(5+2*sqrt(10/7))/3; weights(3) = (322-13*sqrt(70))/900; 55 | roots(4) = -roots(3); weights(4) = weights(3); 56 | roots(5) = 0; weights(5) = 128/225; 57 | otherwise 58 | u = 1:p-1; 59 | u = u./sqrt(4*u.^2 - 1); 60 | 61 | A = zeros(p,p); 62 | A(2:p+1:p*(p-1)) = u; 63 | A(p+1:p+1:p^2-1) = u; 64 | 65 | [v,roots] = eig(A); 66 | [roots,k] = sort(diag(roots)); 67 | weights = 2*v(1,k)'.^2; 68 | 69 | end 70 | roots = 0.5*((b-a)*roots+(b+a)); 71 | weights = 0.5*weights; 72 | 73 | case 'hermite' 74 | switch p 75 | case 1 76 | roots(1) = 0; weights(1) = 1; 77 | case 2 78 | roots(1) = 1; weights(1) = 0.5; 79 | roots(2) = -roots(1); weights(2) = weights(1); 80 | case 3 81 | roots(1) = sqrt(3); weights(1) = 1/6; 82 | roots(2) = -roots(1); weights(2) = weights(1); 83 | roots(3) = 0; weights(3) = 2/3; 84 | case 4 85 | roots(1) = sqrt((3-sqrt(6))); weights(1) = 1/(4*(3-sqrt(6))); 86 | roots(2) = -roots(1); weights(2) = weights(1); 87 | roots(3) = sqrt((3+sqrt(6))); weights(3) = 1/(4*(3+sqrt(6))); 88 | roots(4) = -roots(3); weights(4) = weights(3); 89 | case 5 90 | roots(1) = 0.958572464613819*sqrt(2); weights(1) = 0.3936193231522/sqrt(pi); 91 | roots(2) = -roots(1); weights(2) = weights(1); 92 | roots(3) = 2.020182870456086*sqrt(2); weights(3) = 0.01995324205905/sqrt(pi); 93 | roots(4) = -roots(3); weights(4) = weights(3); 94 | roots(5) = 0; weights(5) = 0.9453087204829/sqrt(pi); 95 | case 6 96 | roots(1) = 0.436077411927617*sqrt(2); weights(1) = 0.7246295952244/sqrt(pi); 97 | roots(2) = -roots(1); weights(2) = weights(1); 98 | roots(3) = 1.335849074013697*sqrt(2); weights(3) = 0.1570673203229/sqrt(pi); 99 | roots(4) = -roots(3); weights(4) = weights(3); 100 | roots(5) = 2.350604973674492*sqrt(2); weights(5) = 0.00453000995509/sqrt(pi); 101 | roots(6) = -roots(5); weights(6) = weights(5); 102 | 103 | case 7 104 | roots(1) = 0.816287882858965*sqrt(2); weights(1) = 0.4256072526101/sqrt(pi); 105 | roots(2) = -roots(1); weights(2) = weights(1); 106 | roots(3) = 1.673551628767471*sqrt(2); weights(3) = 0.05451558281913/sqrt(pi); 107 | roots(4) = -roots(3); weights(4) = weights(3); 108 | roots(5) = 2.651961356835233*sqrt(2); weights(5) = 0.0009717812450995/sqrt(pi); 109 | roots(6) = -roots(3); weights(6) = weights(5); 110 | roots(7) = 0; weights(7) = 0.8102646175568/sqrt(pi); 111 | 112 | end 113 | end -------------------------------------------------------------------------------- /IntEqSolver1d.m: -------------------------------------------------------------------------------- 1 | function [lambda,phi] = IntEqSolver1d(a,b,n,Cd,neig,method,p,ToPlot) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % returns solution of the Fredholm integral equation of the second kind 4 | % [a,b] - interval of integration 5 | % n - grid size = total number of nodes including endpoints 6 | % neig - number of eigenpairs required 7 | % 8 | % method: 'collocation' or 'galerkin' 9 | % p - degree of the polynomials in Lagrange basis: either 1 or 2 10 | % 11 | % varargin - optional list of arguments 12 | % contains parameters for the kernels that need it: eta, sigma 13 | % 14 | % examples of run: 15 | % [lambda,phi] = IntEqSolver1d(0,1,50,10,'exponential','collocation',2,1,1/10,1) 16 | % Written by Veronika Vasylkivska 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | 19 | warning off all 20 | 21 | h = (b-a)/(n-1); 22 | 23 | if p == 1 %% piecewise linear functions are used for basis 24 | nodes = a:h:b; %% grid nodes 25 | nnodes = n; 26 | 27 | elseif p == 2 %% piecewise quadratic functions are used for basis 28 | nodes = a:h/2:b; %% grid nodes 29 | nnodes = 2*n-1; 30 | else 31 | error('Not valid degree of polynomials: should be 1 or 2'); 32 | end 33 | 34 | % find matrices for the generalized eigenvalue problem 35 | % using one of the methods: collocation or Galerkin 36 | 37 | D = zeros(nnodes,nnodes); 38 | switch lower(method) 39 | case 'collocation' 40 | %% set up number of integration points nw, nodes xw, and weights w 41 | nw = 11; 42 | [xw,w] = GaussQuad(nw,'legendre'); 43 | 44 | %% for the first element the weights and roots are different 45 | xw1 = 0.5*(xw+1); w1 = 0.5*w; 46 | C = StatCov1d(nodes,h*xw1+nodes(1),nodes,Cd,0); 47 | psi = shapefun(xw1,p,1); %% calculations on ref.element 48 | D(:,1) = C*(w1.*psi); 49 | 50 | %% for the last element the weights and roots are different as well 51 | xw2 = 0.5*(xw-1); w2 = w1; 52 | C = StatCov1d(nodes,h*xw2+nodes(nnodes),nodes,Cd,0); 53 | psi = shapefun(xw2,p,1); %% calculations on ref.element 54 | D(:,nnodes) = C*(w2.*psi); 55 | 56 | psi = shapefun(xw,p,1); %% calculations on ref.element 57 | if p == 2; psi2 = shapefun(xw,p,0); end 58 | 59 | for j = 2:nnodes-1 60 | C = StatCov1d(nodes,h*xw+nodes(j),nodes,Cd,0); 61 | if p == 1 62 | D(:,j) = C*(w.*psi); 63 | else 64 | if mod(j,2)==0 65 | D(:,j) = C*(w.*psi2); 66 | else 67 | D(:,j) = C*(w.*psi); 68 | end 69 | end 70 | end 71 | 72 | D = 2*h*D; 73 | L = eye(nnodes,nnodes); 74 | 75 | case 'galerkin' 76 | nw = 11; 77 | [xw,w] = GaussQuad(nw,'legendre'); 78 | xw1 = 0.5*(xw+1); w1 = 0.5*w; %% weights and roots for the first element 79 | xw2 = 0.5*(xw-1); w2 = w1; %% weights and roots for the last element 80 | 81 | psi1 = shapefun(xw1,p,1); psi2 = shapefun(xw2,p,1); %% shape function on the 1st and last element 82 | 83 | %% shape functions on other elements 84 | if p == 1 85 | psi(:,1) = shapefun(xw,p,1); 86 | psi(:,2) = psi(:,1); 87 | elseif p == 2 88 | psi(:,1) = shapefun(xw,p,0); psi(:,2) = shapefun(xw,p,1); 89 | end 90 | 91 | %% calculations of the matrix D entries 92 | W = w1*w1'; 93 | C = StatCov1d(h*xw1+nodes(1),h*xw1+nodes(1),nodes,Cd,0); 94 | D(1,1) = sum(sum(C.*W.*(psi1*psi1'))); 95 | 96 | W = w1*w2'; 97 | C = StatCov1d(h*xw1+nodes(1),h*xw2+nodes(nnodes),nodes,Cd,0); 98 | D(1,nnodes) = sum(sum(C.*W.*(psi1*psi2'))); 99 | D(nnodes,1) = D(1,nnodes); 100 | 101 | W = w1*w'; 102 | for j = 2:nnodes-1 103 | C = StatCov1d(h*xw1+nodes(1),h*xw+nodes(j),nodes,Cd,0); 104 | D(1,j) = sum(sum(C.*W.*(psi1*psi(:,mod(j,2)+1)'))); 105 | D(j,1) = D(1,j); 106 | end 107 | 108 | W = w2*w2'; 109 | C = StatCov1d(h*xw2+nodes(nnodes),h*xw2+nodes(nnodes),nodes,Cd,0); 110 | D(nnodes,nnodes) = sum(sum(C.*W.*(psi2*psi2'))); 111 | 112 | W = w2*w'; 113 | for j = 2:nnodes-1 114 | C = StatCov1d(h*xw2+nodes(nnodes),h*xw+nodes(j),nodes,Cd,0); 115 | D(nnodes,j) = sum(sum(C.*W.*(psi2*psi(:,mod(j,2)+1)'))); 116 | D(j,nnodes) = D(nnodes,j); 117 | end 118 | 119 | W = w*w'; 120 | for j = 2:nnodes-1 121 | for k = j:nnodes-1 122 | C = StatCov1d(h*xw+nodes(j),h*xw+nodes(k),nodes,Cd,0); 123 | D(j,k) = sum(sum(C.*W.*(psi(:,mod(j,2)+1)*psi(:,mod(k,2)+1)'))); 124 | D(k,j) = D(j,k); 125 | end 126 | end 127 | D = 4*h*h*D; 128 | L = GalerkinL(n,h,p); 129 | 130 | end 131 | 132 | % get eigenpairs 133 | [phi,lambda] = eigs(D,L,neig); 134 | 135 | % improve approximation of the eigenfunctions 136 | res = -(D*phi-L*phi*lambda); %% find residual first 137 | lambda = diag(lambda,0); 138 | 139 | % for j = 1:neig 140 | % M = D - lambda(j)*L; 141 | % phi(:,j) = phi(:,j) + M\res(:,j); 142 | % end 143 | 144 | % get rid of 0 complex part (needed for gaussian kernels) 145 | lambda = abs(real(lambda)); 146 | 147 | % sort found eigenvalues in descending order 148 | [lambda,ix] = sort(lambda,'descend'); 149 | 150 | % rearrange the eigenfunctions in the corresponding order 151 | Nphi = phi; 152 | for j = 1:neig 153 | phi(:,ix(j)) = Nphi(:,j); 154 | end 155 | phi = signchange(phi); 156 | 157 | % normalize found eigenfunctions 158 | if p == 1 159 | for j = 1:neig 160 | v = phi(:,j); 161 | vnorm = sqrt(h/3*(v(1)^2+v(n)^2+2*sum(v(2:n-1).*v(2:n-1))+sum(v(1:n-1).*v(2:n)))); 162 | phi(:,j) = phi(:,j)/vnorm; 163 | end 164 | else 165 | for j = 1:neig 166 | v = phi(:,j); 167 | vnorm = sqrt(h/15*(2*v(1)^2+2*v(nnodes)^2+8*sum(v(2:2:nnodes-1).^2)+4*sum(v(3:2:nnodes-1).^2)+... 168 | 2*sum(v(1:nnodes-1).*v(2:nnodes))-sum(v(1:2:nnodes-2).*v(3:2:nnodes)))); 169 | phi(:,j) = phi(:,j)/vnorm; 170 | end 171 | end 172 | 173 | % make sure to get rid of complex zero part for some kernels 174 | for j = 1:neig 175 | phi(:,j) = real(phi(:,j)); 176 | end 177 | 178 | % plot eigenvalues if needed 179 | if ToPlot 180 | plot(lambda,'-sk','LineWidth',1.5); 181 | end 182 | 183 | end 184 | 185 | %%%%%%%%%%%%%%%%%%%% SUBFUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 186 | 187 | function f = shapefun(x,p,mode) %%%%% shape function for reference element 188 | 189 | lenx = length(x); 190 | f = zeros(lenx,1); 191 | 192 | if p == 1 %% piecewise linear 193 | for j = 1:lenx 194 | if (x(j)<0)&&(x(j)>=-1) 195 | f(j) = 1+x(j); 196 | elseif (x(j)>=0)&&(x(j)<=1) 197 | f(j) = 1-x(j); 198 | else 199 | f(j) = 0; 200 | end 201 | end 202 | 203 | elseif p == 2 %% piecewise quadratic 204 | switch mode 205 | case 1 %% mesh vertices 206 | for j = 1:lenx 207 | if (x(j)<0)&&(x(j)>=-1) 208 | f(j) = (1+x(j)).*(1+2*x(j)); 209 | elseif (x(j)>=0)&&(x(j)<=1) 210 | f(j) = (1-x(j)).*(1-2*x(j)); 211 | else 212 | f(j) = 0; 213 | end 214 | end 215 | case 0 %% midpoints 216 | for j = 1:lenx 217 | if abs(x(j)) < 0.5 218 | f(j) = 1-4*x(j).*x(j); 219 | else 220 | f(j) = 0; 221 | end 222 | end 223 | end 224 | end 225 | end 226 | 227 | 228 | function ResF = signchange(F) 229 | ResF = F; 230 | n = size(F,2); 231 | for j = 1:n 232 | if F(1,j) < 0 233 | ResF(:,j) = -F(:,j); 234 | end 235 | end 236 | end 237 | 238 | 239 | function L = GalerkinL(n,h,p) 240 | 241 | switch p 242 | case 1 243 | L = zeros(n,n); 244 | 245 | 246 | L(1,1) = 1/3; 247 | L(n,n) = 1/3; 248 | for k = 2:n-1 249 | L(k,k) = 2/3; 250 | end 251 | for k = 1:n-1 252 | L(k,k+1) = 1/6; 253 | L(k+1,k) = 1/6; 254 | end 255 | L = h*L; 256 | % A = h/6*[2 1; 1 2]; 257 | % for k = 1:n-1 258 | % for i = 1:2 259 | % for j = 1:2 260 | % ig = k+i-1; 261 | % jg = k+j-1; 262 | % L(ig,jg) = L(ig,jg) + A(i,j); 263 | % end 264 | % end 265 | % end 266 | case 2 267 | L = zeros(2*n-1,2*n-1); 268 | A = h/30*[4 2 -1; 2 16 2; -1 2 4]; 269 | 270 | for k = 1:n-1 271 | for i = 1:3 272 | for j = 1:3 273 | ig = 2*k+i-2; 274 | jg = 2*k+j-2; 275 | L(ig,jg) = L(ig,jg) + A(i,j); 276 | end 277 | end 278 | end 279 | end 280 | end 281 | 282 | function M = StatCov1d(x,y,xdata,C,ToPlot) 283 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 284 | %% returns the covariance function 285 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 286 | 287 | [X,Y] = meshgrid(xdata); 288 | 289 | M = interp2(X,Y,C,x,y); 290 | M = M'; 291 | 292 | % plot the covariance if needed 293 | if ToPlot 294 | figure; 295 | surf(x,y,M); 296 | title(strcat(kernel,' model'),'fontsize',20); 297 | end 298 | end -------------------------------------------------------------------------------- /KL.m: -------------------------------------------------------------------------------- 1 | %% KL EXPANSION 2 | function [eigV,eigF] = KL(nelx,nely,nKL) 3 | 4 | lenX = nelx+1+nelx*3; 5 | x = linspace(0,nelx,nelx+1+nelx*3); 6 | corrLenX = 0.6; 7 | Cx(1:lenX, 1:lenX) = 0; 8 | 9 | for k = 1:lenX 10 | for l = 1:lenX 11 | Cx(k,l) = exp(-abs(x(k) - x(l))/corrLenX); 12 | end 13 | end 14 | 15 | [lambdax,phix] = IntEqSolver1d(x(1),x(end),lenX,Cx,nKL,'collocation',1,0); 16 | 17 | lenY = nely+1+nely*3; 18 | y = linspace(0,nely,lenY); 19 | corrLenY = 0.6; 20 | Cy(1:lenY, 1:lenY) = 0; 21 | 22 | for k = 1:lenY 23 | for l = 1:lenY 24 | Cy(k,l) = exp(-abs(y(k) - y(l))/corrLenY); 25 | end 26 | end 27 | 28 | [lambday,phiy] = IntEqSolver1d(y(1),y(end),lenY,Cy,nKL,'collocation',1,0); 29 | 30 | eigV = lambdax.*lambday; 31 | eigF(1:nKL,1:nely,1:nelx) = 0; 32 | 33 | for k = 1:nKL 34 | xx = phix(3:4:end-2,k); 35 | yy = phiy(3:4:end-2,k); 36 | [XX,YY] = meshgrid(xx,yy); 37 | eigF(k,:,:) = XX.*YY; 38 | end 39 | 40 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Design Engineering Lab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RBTO 2 | Reliability-based Topology Optimization 3 | -------------------------------------------------------------------------------- /dto.m: -------------------------------------------------------------------------------- 1 | %%% dto(60,20,3,1.5,dismax) 2 | function dto(nelx,nely,penal,rmin,dismax) 3 | %%% Initial values 4 | init_val = 0.5; 5 | x(1:nely,1:nelx) = init_val; 6 | xphy(1:nely,1:nelx) = init_val; 7 | 8 | nu = 0.3; 9 | k = [ 1/2-nu/6 1/8+nu/8 -1/4-nu/12 -1/8+3*nu/8 ... 10 | -1/4+nu/12 -1/8-nu/8 nu/6 1/8-3*nu/8]; 11 | KE = 1/(1-nu^2)*[ k(1) k(2) k(3) k(4) k(5) k(6) k(7) k(8) 12 | k(2) k(1) k(8) k(7) k(6) k(5) k(4) k(3) 13 | k(3) k(8) k(1) k(6) k(7) k(4) k(5) k(2) 14 | k(4) k(7) k(6) k(1) k(8) k(3) k(2) k(5) 15 | k(5) k(6) k(7) k(8) k(1) k(2) k(3) k(4) 16 | k(6) k(5) k(4) k(3) k(2) k(1) k(8) k(7) 17 | k(7) k(4) k(5) k(2) k(3) k(8) k(1) k(6) 18 | k(8) k(3) k(2) k(5) k(4) k(7) k(6) k(1)]; 19 | %%% MMA 20 | m = 1; 21 | n = nelx*nely; 22 | xmin(1:n,1) = 0.001; 23 | xmax(1:n,1) = 1; 24 | low = xmin; 25 | upp = xmax; 26 | a0 = 1; 27 | a(1:m,1) = 0; 28 | ci(1:m,1) = 1000; 29 | d(1:m,1) = 0; 30 | xold1 = x; 31 | xold2 = x; 32 | 33 | dof = 2; 34 | 35 | %%% Prepare filter 36 | iH = ones(nelx*nely*(2*(ceil(rmin)-1)+1)^2,1); 37 | jH = ones(size(iH)); 38 | sH = zeros(size(iH)); 39 | k = 0; 40 | for i1 = 1:nelx 41 | for j1 = 1:nely 42 | e1 = (i1-1)*nely+j1; 43 | for i2 = max(i1-(ceil(rmin)-1),1):min(i1+(ceil(rmin)-1),nelx) 44 | for j2 = max(j1-(ceil(rmin)-1),1):min(j1+(ceil(rmin)-1),nely) 45 | e2 = (i2-1)*nely+j2; 46 | k = k+1; 47 | iH(k) = e1; 48 | jH(k) = e2; 49 | sH(k) = max(0,rmin-sqrt((i1-i2)^2+(j1-j2)^2)); 50 | end 51 | end 52 | end 53 | end 54 | H = sparse(iH,jH,sH); 55 | Hs = sum(H,2); 56 | 57 | fval(1,1) = 1; 58 | change = 1.; 59 | loop = 0; 60 | E(1:nely,1:nelx) = 1.35; 61 | while (change > 0.001) 62 | loop = loop + 1; 63 | [U] = FE(nelx,nely,xphy,penal,KE,E,dof); 64 | 65 | dcf(1:nely,1:nelx) = 0; 66 | for ely = 1:nely 67 | for elx = 1:nelx 68 | n1 = (nely+1)*(elx-1)+ely; 69 | n2 = (nely+1)* elx +ely; 70 | Ue = U([2*n1-1;2*n1; 2*n2-1;2*n2; 2*n2+1;2*n2+2; 2*n1+1;2*n1+2],1); 71 | dcf(ely,elx) = -Ue'*penal*xphy(ely,elx)^(penal-1)*E(ely,elx)*KE*Ue; 72 | end 73 | end 74 | c = sum(xphy(:)); 75 | dc(1:nely,1:nelx) = 1; 76 | dc(:) = H*(dc(:)./Hs); 77 | 78 | f0val = c; 79 | df0dx = dc(:); 80 | fval(1,1) = U(dof)/dismax -1; 81 | dcf(:) = H*(dcf(:)./Hs); 82 | dfdx(1,1:n) = dcf(:)/dismax; 83 | 84 | %%% The MMA subproblem is solved at the point xval: 85 | outeriter = loop; 86 | [xmma,~,~,~,~,~,~,~,~,low,upp] = ... 87 | mmasub(m,n,outeriter,x(:),xmin,xmax,xold1(:),xold2(:), ... 88 | f0val,df0dx,fval,dfdx,low,upp,a0,a,ci,d); 89 | 90 | %%% Update 91 | xold2 = xold1; 92 | xold1 = x; 93 | xnew = reshape(xmma,nely,nelx); 94 | xphy(:) = (H*xnew(:))./Hs; 95 | 96 | change = max(abs(xnew(:)-x(:))); 97 | x = xnew; 98 | 99 | % Results 100 | disp([' It.: ' sprintf('%4i',loop) ' Obj.: ' sprintf('%10.4f',c) ... 101 | ' Vol Frac.: ' sprintf('%6.4f',sum(sum(xphy))/(nelx*nely)) ... 102 | ' ch.: ' sprintf('%6.3f',change )]) 103 | % PLOT DENSITIES 104 | colormap(gray); 105 | imagesc(1-xphy); 106 | axis equal; 107 | axis tight; 108 | axis off; 109 | pause(1e-6); 110 | end 111 | 112 | % fig = figure; 113 | % colormap(gray); 114 | % imagesc(1-xphy); 115 | % axis equal; 116 | % axis tight; 117 | % axis off; 118 | % 119 | % fig.PaperPositionMode = 'auto'; 120 | % fig_pos = fig.PaperPosition; 121 | % fig.PaperSize = [fig_pos(3) fig_pos(4)]; 122 | % print(fig,'MySavedFile','-dbmp','-r0') 123 | disp('END OPTIMIZATION'); 124 | %rbto_mc(nelx, nely, penal, xphy, dismax, dof, 1, 1.5); 125 | end -------------------------------------------------------------------------------- /mmasub.m: -------------------------------------------------------------------------------- 1 | %------------------------------------------------------- 2 | % This is the file mmasub.m 3 | % 4 | function [xmma,ymma,zmma,lam,xsi,eta,mu,zet,s,low,upp] = ... 5 | mmasub2(m,n,iter,xval,xmin,xmax,xold1,xold2, ... 6 | f0val,df0dx,fval,dfdx,low,upp,a0,a,c,d); 7 | % 8 | % Version September 2007 (and a small change August 2008) 9 | % 10 | % Krister Svanberg 11 | % Department of Mathematics, SE-10044 Stockholm, Sweden. 12 | % 13 | % This function mmasub performs one MMA-iteration, aimed at 14 | % solving the nonlinear programming problem: 15 | % 16 | % Minimize f_0(x) + a_0*z + sum( c_i*y_i + 0.5*d_i*(y_i)^2 ) 17 | % subject to f_i(x) - a_i*z - y_i <= 0, i = 1,...,m 18 | % xmin_j <= x_j <= xmax_j, j = 1,...,n 19 | % z >= 0, y_i >= 0, i = 1,...,m 20 | %*** INPUT: 21 | % 22 | % m = The number of general constraints. 23 | % n = The number of variables x_j. 24 | % iter = Current iteration number ( =1 the first time mmasub is called). 25 | % xval = Column vector with the current values of the variables x_j. 26 | % xmin = Column vector with the lower bounds for the variables x_j. 27 | % xmax = Column vector with the upper bounds for the variables x_j. 28 | % xold1 = xval, one iteration ago (provided that iter>1). 29 | % xold2 = xval, two iterations ago (provided that iter>2). 30 | % f0val = The value of the objective function f_0 at xval. 31 | % df0dx = Column vector with the derivatives of the objective function 32 | % f_0 with respect to the variables x_j, calculated at xval. 33 | % fval = Column vector with the values of the constraint functions f_i, 34 | % calculated at xval. 35 | % dfdx = (m x n)-matrix with the derivatives of the constraint functions 36 | % f_i with respect to the variables x_j, calculated at xval. 37 | % dfdx(i,j) = the derivative of f_i with respect to x_j. 38 | % low = Column vector with the lower asymptotes from the previous 39 | % iteration (provided that iter>1). 40 | % upp = Column vector with the upper asymptotes from the previous 41 | % iteration (provided that iter>1). 42 | % a0 = The constants a_0 in the term a_0*z. 43 | % a = Column vector with the constants a_i in the terms a_i*z. 44 | % c = Column vector with the constants c_i in the terms c_i*y_i. 45 | % d = Column vector with the constants d_i in the terms 0.5*d_i*(y_i)^2. 46 | % 47 | %*** OUTPUT: 48 | % 49 | % xmma = Column vector with the optimal values of the variables x_j 50 | % in the current MMA subproblem. 51 | % ymma = Column vector with the optimal values of the variables y_i 52 | % in the current MMA subproblem. 53 | % zmma = Scalar with the optimal value of the variable z 54 | % in the current MMA subproblem. 55 | % lam = Lagrange multipliers for the m general MMA constraints. 56 | % xsi = Lagrange multipliers for the n constraints alfa_j - x_j <= 0. 57 | % eta = Lagrange multipliers for the n constraints x_j - beta_j <= 0. 58 | % mu = Lagrange multipliers for the m constraints -y_i <= 0. 59 | % zet = Lagrange multiplier for the single constraint -z <= 0. 60 | % s = Slack variables for the m general MMA constraints. 61 | % low = Column vector with the lower asymptotes, calculated and used 62 | % in the current MMA subproblem. 63 | % upp = Column vector with the upper asymptotes, calculated and used 64 | % in the current MMA subproblem. 65 | % 66 | %epsimin = sqrt(m+n)*10^(-9); 67 | epsimin = 10^(-7); 68 | raa0 = 0.00001; 69 | albefa = 0.1; 70 | asyinit = 0.5; 71 | asyincr = 1.2; 72 | asydecr = 0.7; 73 | move = 0.2; 74 | %move = 1.0; %one can try for different move value 75 | eeen = ones(n,1); 76 | eeem = ones(m,1); 77 | zeron = zeros(n,1); 78 | %%% these lines are required to reshape so that matrix dimensions 79 | %%% satisfied for solving four, nine and six node problems with MMA. 80 | %xval = reshape(xval,m*n,1); 81 | %xold1 = reshape(xold1,m*n,1); 82 | %xold2 = reshape(xold2,m*n,1); 83 | % Calculation of the asymptotes low and upp : 84 | if iter < 2.5 85 | low = xval - asyinit*(xmax-xmin); 86 | upp = xval + asyinit*(xmax-xmin); 87 | else 88 | zzz = (xval-xold1).*(xold1-xold2); 89 | factor = eeen; 90 | factor(find(zzz > 0)) = asyincr; 91 | factor(find(zzz < 0)) = asydecr; 92 | low = xval - factor.*(xold1 - low); 93 | upp = xval + factor.*(upp - xold1); 94 | lowmin = xval - 10*(xmax-xmin); %10 95 | lowmax = xval - 0.01*(xmax-xmin); 96 | uppmin = xval + 0.01*(xmax-xmin); 97 | uppmax = xval + 10*(xmax-xmin); %10 98 | low = max(low,lowmin); 99 | low = min(low,lowmax); 100 | upp = min(upp,uppmax); 101 | upp = max(upp,uppmin); 102 | end 103 | 104 | % Calculation of the bounds alfa and beta : 105 | zzz1 = low + albefa*(xval-low); 106 | zzz2 = xval - move*(xmax-xmin); 107 | zzz = max(zzz1,zzz2); 108 | alfa = max(zzz,xmin); 109 | zzz1 = upp - albefa*(upp-xval); 110 | zzz2 = xval + move*(xmax-xmin); 111 | zzz = min(zzz1,zzz2); 112 | beta = min(zzz,xmax); 113 | 114 | % Calculations of p0, q0, P, Q and b. 115 | 116 | xmami = xmax-xmin; 117 | xmamieps = 0.00001*eeen; 118 | xmami = max(xmami,xmamieps); 119 | xmamiinv = eeen./xmami; 120 | ux1 = upp-xval; 121 | ux2 = ux1.*ux1; 122 | xl1 = xval-low; 123 | xl2 = xl1.*xl1; 124 | uxinv = eeen./ux1; 125 | xlinv = eeen./xl1; 126 | % 127 | p0 = zeron; 128 | q0 = zeron; 129 | p0 = max(df0dx,0); 130 | q0 = max(-df0dx,0); 131 | 132 | %%% these lines are required to reshape so that matrix dimensions 133 | %%% satisfied for solving four,nine and six node problems with MMA. 134 | %p0 = reshape(p0,m*n,1); 135 | %q0 = reshape(q0,m*n,1); 136 | 137 | %p0(find(df0dx > 0)) = df0dx(find(df0dx > 0)); 138 | %q0(find(df0dx < 0)) = -df0dx(find(df0dx < 0)); 139 | pq0 = 0.001*(p0 + q0) + raa0*xmamiinv; 140 | p0 = p0 + pq0; 141 | q0 = q0 + pq0; 142 | p0 = p0.*ux2; 143 | q0 = q0.*xl2; 144 | % 145 | P = sparse(m,n); 146 | Q = sparse(m,n); 147 | P = max(dfdx,0); 148 | Q = max(-dfdx,0); 149 | %P(find(dfdx > 0)) = dfdx(find(dfdx > 0)); 150 | %Q(find(dfdx < 0)) = -dfdx(find(dfdx < 0)); 151 | PQ = 0.001*(P + Q) + raa0*eeem*xmamiinv'; 152 | P = P + PQ; 153 | Q = Q + PQ; 154 | P = P * spdiags(ux2,0,n,n); 155 | Q = Q * spdiags(xl2,0,n,n); 156 | b = P*uxinv + Q*xlinv - fval; 157 | % 158 | %%% Solving the subproblem by a primal-dual Newton method 159 | [xmma,ymma,zmma,lam,xsi,eta,mu,zet,s] = ... 160 | subsolv(m,n,epsimin,low,upp,alfa,beta,p0,q0,P,Q,a0,a,b,c,d); -------------------------------------------------------------------------------- /rbto_den.m: -------------------------------------------------------------------------------- 1 | %%% rbto_den(60,20,3,1.5,dismax) 2 | function rbto_den(nelx,nely,penal,rmin,dismax) 3 | 4 | %%% Initial values 5 | nKL = 2; 6 | 7 | init_val = 0.5; 8 | x(1:nely,1:nelx) = init_val; 9 | xphy(1:nely,1:nelx) = init_val; 10 | 11 | nu = 0.3; 12 | k = [ 1/2-nu/6 1/8+nu/8 -1/4-nu/12 -1/8+3*nu/8 ... 13 | -1/4+nu/12 -1/8-nu/8 nu/6 1/8-3*nu/8]; 14 | KE = 1/(1-nu^2)*[ k(1) k(2) k(3) k(4) k(5) k(6) k(7) k(8) 15 | k(2) k(1) k(8) k(7) k(6) k(5) k(4) k(3) 16 | k(3) k(8) k(1) k(6) k(7) k(4) k(5) k(2) 17 | k(4) k(7) k(6) k(1) k(8) k(3) k(2) k(5) 18 | k(5) k(6) k(7) k(8) k(1) k(2) k(3) k(4) 19 | k(6) k(5) k(4) k(3) k(2) k(1) k(8) k(7) 20 | k(7) k(4) k(5) k(2) k(3) k(8) k(1) k(6) 21 | k(8) k(3) k(2) k(5) k(4) k(7) k(6) k(1)]; 22 | %%% MMA 23 | m = 1; 24 | n = nelx*nely; 25 | xmin(1:n,1) = 0.001; 26 | xmax(1:n,1) = 1; 27 | low = xmin; 28 | upp = xmax; 29 | a0 = 1; 30 | a(1:m,1) = 0; 31 | ci(1:m,1) = 1000; 32 | d(1:m,1) = 0; 33 | xold1 = x; 34 | xold2 = x; 35 | 36 | [eigV,eigF] = KL(nelx,nely,nKL); 37 | 38 | dof = 2; 39 | upE = 1; 40 | lwE = 1.5; 41 | 42 | roots = [sqrt(3 + sqrt(6))... 43 | -sqrt(3 + sqrt(6))... 44 | sqrt(3 - sqrt(6))... 45 | -sqrt(3 - sqrt(6))]; 46 | colPoints = [ 0 0;... 47 | roots(1) 0;... 48 | 0 roots(1);... 49 | roots(2) 0;... 50 | 0 roots(2);... 51 | roots(3) 0;... 52 | 0 roots(3);... 53 | roots(4) 0;... 54 | 0 roots(4);... 55 | roots(3) roots(3);... 56 | roots(4) roots(4);... 57 | roots(3) roots(4);... 58 | roots(4) roots(3);... 59 | roots(1) roots(3);... 60 | roots(1) roots(4);... 61 | roots(3) roots(1);... 62 | roots(4) roots(1);... 63 | roots(2) roots(3);... 64 | roots(3) roots(2);... 65 | roots(2) roots(4);... 66 | roots(4) roots(2);... 67 | roots(1) roots(2);... 68 | roots(2) roots(1)]; 69 | 70 | %%% Prepare filter 71 | iH = ones(nelx*nely*(2*(ceil(rmin)-1)+1)^2,1); 72 | jH = ones(size(iH)); 73 | sH = zeros(size(iH)); 74 | k = 0; 75 | for i1 = 1:nelx 76 | for j1 = 1:nely 77 | e1 = (i1-1)*nely+j1; 78 | for i2 = max(i1-(ceil(rmin)-1),1):min(i1+(ceil(rmin)-1),nelx) 79 | for j2 = max(j1-(ceil(rmin)-1),1):min(j1+(ceil(rmin)-1),nely) 80 | e2 = (i2-1)*nely+j2; 81 | k = k+1; 82 | iH(k) = e1; 83 | jH(k) = e2; 84 | sH(k) = max(0,rmin-sqrt((i1-i2)^2+(j1-j2)^2)); 85 | end 86 | end 87 | end 88 | end 89 | H = sparse(iH,jH,sH); 90 | Hs = sum(H,2); 91 | 92 | mpp = [0 0]; 93 | mpptol = 1.; 94 | 95 | fval(1,1) = 1; 96 | main_loop = 0; 97 | while mpptol > 0.001 98 | mppold = mpp; 99 | main_loop = main_loop + 1; 100 | loop = 0; 101 | change = 1.; 102 | x(1:nely,1:nelx) = init_val; 103 | xphy = x; 104 | E = update_E(eigV, eigF, mpp, nKL, upE, lwE, nelx, nely); 105 | 106 | while change > 0.001 107 | loop = loop + 1; 108 | [U] = FE(nelx,nely,xphy,penal,KE,E,dof); 109 | 110 | dcf(1:nely,1:nelx) = 0; 111 | for ely = 1:nely 112 | for elx = 1:nelx 113 | n1 = (nely+1)*(elx-1)+ely; 114 | n2 = (nely+1)* elx +ely; 115 | Ue = U([2*n1-1;2*n1; 2*n2-1;2*n2; 2*n2+1;2*n2+2; 2*n1+1;2*n1+2],1); 116 | dcf(ely,elx) = -Ue'*penal*xphy(ely,elx)^(penal-1)*E(ely,elx)*KE*Ue; 117 | end 118 | end 119 | c = sum(xphy(:)); 120 | dc(1:nely,1:nelx) = 1; 121 | dc(:) = H*(dc(:)./Hs); 122 | 123 | f0val = c; 124 | df0dx = dc(:); 125 | fval(1,1) = U(dof)/dismax -1; 126 | dcf(:) = H*(dcf(:)./Hs); 127 | dfdx(1,1:n) = dcf(:)/dismax; 128 | 129 | %%% The MMA subproblem is solved at the point xval: 130 | outeriter = loop; 131 | [xmma,~,~,~,~,~,~,~,~,low,upp] = ... 132 | mmasub(m,n,outeriter,x(:),xmin,xmax,xold1(:),xold2(:), ... 133 | f0val,df0dx,fval,dfdx,low,upp,a0,a,ci,d); 134 | 135 | %%% Update 136 | xold2 = xold1; 137 | xold1 = x; 138 | xnew = reshape(xmma,nely,nelx); 139 | xphy(:) = (H*xnew(:))./Hs; 140 | 141 | change = max(abs(xnew(:)-x(:))); 142 | x = xnew; 143 | 144 | % Results 145 | disp([' It.: ' sprintf('%4i',loop) ' Obj.: ' sprintf('%10.4f',c) ... 146 | ' Vol Frac.: ' sprintf('%6.4f',sum(sum(xphy))/(nelx*nely)) ... 147 | ' ch.: ' sprintf('%6.3f',change )]) 148 | % PLOT DENSITIES 149 | colormap(gray); 150 | imagesc(1-xphy); 151 | axis equal; 152 | axis tight; 153 | axis off; 154 | pause(1e-6); 155 | end 156 | 157 | mpp = find_mpp(colPoints, eigV, eigF, nKL, nelx, nely, xphy, penal,... 158 | KE, dof, upE, lwE, dismax); 159 | mpptol = max(abs(mpp(:)-mppold(:))); 160 | end 161 | 162 | %%% 163 | main_loop 164 | disp('END OPTIMIZATION'); 165 | rbto_mc(nelx, nely, penal, xphy, dismax, dof, upE, lwE); 166 | 167 | end 168 | 169 | function newE = update_E(eigV, eigF, mpp, nKL, c, d, nelx, nely) 170 | 171 | Z = sqrt(eigV).* mpp'; 172 | E(1:nely,1:nelx) = 0; 173 | for j = 1:nKL 174 | E = E + Z(j)*squeeze(eigF(j,:,:)); 175 | end 176 | newE = c + (d-c)*normcdf(E); 177 | 178 | end 179 | 180 | function mpp = find_mpp(colPoints, eigV, eigF, nKL, nelx, nely, x, penal,... 181 | KE, dof, c, d, dismax) 182 | 183 | s = length(colPoints); 184 | v(1:s) = 0; 185 | 186 | for i = 1:s 187 | Z = sqrt(eigV).*colPoints(i,:)'; 188 | E(1:nely,1:nelx) = 0; 189 | for j = 1:nKL 190 | E = E + Z(j)*squeeze(eigF(j,:,:)); 191 | end 192 | E = c + (d-c)*normcdf(E); 193 | [U] = FE(nelx,nely,x,penal,KE,E,dof); 194 | v(i) = U(dof); 195 | end 196 | 197 | numVar = 10; 198 | N(1:s,1:numVar) = 0; 199 | for i = 1:s 200 | N(i,1) = 1; 201 | N(i,2) = colPoints(i, 1); 202 | N(i,3) = colPoints(i, 2); 203 | N(i,4) = colPoints(i, 1)^2 - 1; 204 | N(i,5) = colPoints(i,2)^2 - 1; 205 | N(i,6) = colPoints(i,1)*colPoints(i,2); 206 | N(i,7) = colPoints(i,1)^3 - 3*colPoints(i,1); 207 | N(i,8) = colPoints(i,2)^3 - 3*colPoints(i,2); 208 | N(i,9) = colPoints(i,1)*colPoints(i,2)^2 - colPoints(i,1); 209 | N(i,10) = colPoints(i,2)*colPoints(i,1)^2 - colPoints(i,2); 210 | end 211 | 212 | a = N'*N \ N'*v'; 213 | 214 | h = @(x) a(1) + a(2)*x(:,1) + a(3)*x(:,2) +... 215 | a(4)*(x(:,1)^2 - 1) + a(5)*(x(:,2)^2 - 1) +... 216 | a(6)*x(:,1)*x(:,2) +... 217 | a(7)*(x(:,1)^3 - 3*x(:,1)) + a(8)*(x(:,2)^3 - 3*x(:,2)) +... 218 | a(9)*(x(:,1)*(x(:,2)^2) - x(:,1)) + a(10)*((x(:,1)^2)*x(:,2) - x(:,2)); 219 | %g = @(x) h(x)/dismax - 1; 220 | g = @(x) dismax/h(x) - 1; 221 | %T = @(x) x; 222 | Tinv = @(u) u; 223 | 224 | res = CODES.reliability.iform(g,2,2.5,'solver','hmv','Tinv',Tinv); 225 | disp(res) 226 | mpp = res.MPTP; 227 | 228 | end -------------------------------------------------------------------------------- /rbto_den_L.m: -------------------------------------------------------------------------------- 1 | %%% rbto_den_L(60,60,3,1.5,dismax) 2 | function rbto_den_L(nelx,nely,penal,rmin,dismax,reli,lwE,fn,title) 3 | 4 | %%% Initial values 5 | nKL = 2; 6 | 7 | init_val = 0.5; 8 | x(1:nely,1:nelx) = init_val; 9 | xphy(1:nely,1:nelx) = init_val; 10 | 11 | passive=zeros(nely,nelx); 12 | for i=1:nelx 13 | for j=1:nely 14 | if (i > nelx/2) && (j <= nely/2) 15 | passive(j,i)=1; 16 | end 17 | end 18 | end 19 | 20 | nu = 0.3; 21 | k = [ 1/2-nu/6 1/8+nu/8 -1/4-nu/12 -1/8+3*nu/8 ... 22 | -1/4+nu/12 -1/8-nu/8 nu/6 1/8-3*nu/8]; 23 | KE = 1/(1-nu^2)*[ k(1) k(2) k(3) k(4) k(5) k(6) k(7) k(8) 24 | k(2) k(1) k(8) k(7) k(6) k(5) k(4) k(3) 25 | k(3) k(8) k(1) k(6) k(7) k(4) k(5) k(2) 26 | k(4) k(7) k(6) k(1) k(8) k(3) k(2) k(5) 27 | k(5) k(6) k(7) k(8) k(1) k(2) k(3) k(4) 28 | k(6) k(5) k(4) k(3) k(2) k(1) k(8) k(7) 29 | k(7) k(4) k(5) k(2) k(3) k(8) k(1) k(6) 30 | k(8) k(3) k(2) k(5) k(4) k(7) k(6) k(1)]; 31 | %%% MMA 32 | m = 1; 33 | n = nelx*nely; 34 | xmin(1:n,1) = 0.001; 35 | xmax(1:n,1) = 1; 36 | low = xmin; 37 | upp = xmax; 38 | a0 = 1; 39 | a(1:m,1) = 0; 40 | ci(1:m,1) = 1000; 41 | d(1:m,1) = 0; 42 | xold1 = x; 43 | xold2 = x; 44 | 45 | [eigV,eigF] = KL(nelx,nely,nKL); 46 | 47 | dof = 2*(nelx)*(nely+1)+2*(nely*3/4+1); 48 | upE = 1; 49 | 50 | roots = [sqrt(3 + sqrt(6))... 51 | -sqrt(3 + sqrt(6))... 52 | sqrt(3 - sqrt(6))... 53 | -sqrt(3 - sqrt(6))]; 54 | colPoints = [ 0 0;... 55 | roots(1) 0;... 56 | 0 roots(1);... 57 | roots(2) 0;... 58 | 0 roots(2);... 59 | roots(3) 0;... 60 | 0 roots(3);... 61 | roots(4) 0;... 62 | 0 roots(4);... 63 | roots(3) roots(3);... 64 | roots(4) roots(4);... 65 | roots(3) roots(4);... 66 | roots(4) roots(3);... 67 | roots(1) roots(3);... 68 | roots(1) roots(4);... 69 | roots(3) roots(1);... 70 | roots(4) roots(1);... 71 | roots(2) roots(3);... 72 | roots(3) roots(2);... 73 | roots(2) roots(4);... 74 | roots(4) roots(2);... 75 | roots(1) roots(2);... 76 | roots(2) roots(1)]; 77 | 78 | %%% Prepare filter 79 | iH = ones(nelx*nely*(2*(ceil(rmin)-1)+1)^2,1); 80 | jH = ones(size(iH)); 81 | sH = zeros(size(iH)); 82 | k = 0; 83 | for i1 = 1:nelx 84 | for j1 = 1:nely 85 | e1 = (i1-1)*nely+j1; 86 | for i2 = max(i1-(ceil(rmin)-1),1):min(i1+(ceil(rmin)-1),nelx) 87 | for j2 = max(j1-(ceil(rmin)-1),1):min(j1+(ceil(rmin)-1),nely) 88 | e2 = (i2-1)*nely+j2; 89 | k = k+1; 90 | iH(k) = e1; 91 | jH(k) = e2; 92 | sH(k) = max(0,rmin-sqrt((i1-i2)^2+(j1-j2)^2)); 93 | end 94 | end 95 | end 96 | end 97 | H = sparse(iH,jH,sH); 98 | Hs = sum(H,2); 99 | 100 | mpp = [0 0]; 101 | mpptol = 1.; 102 | 103 | fval(1,1) = 1; 104 | main_loop = 0; 105 | while mpptol > 0.001 && main_loop < 20 106 | mppold = mpp; 107 | loop = 0; 108 | main_loop = main_loop + 1; 109 | change = 1.; 110 | x(1:nely,1:nelx) = init_val; 111 | x(passive == 1) = 0.001; 112 | xphy = x; 113 | E = update_E(eigV, eigF, mpp, nKL, upE, lwE, nelx, nely); 114 | 115 | while change > 0.001 116 | loop = loop + 1; 117 | [U] = FEL(nelx,nely,xphy,penal,KE,E,dof); 118 | 119 | dcf(1:nely,1:nelx) = 0; 120 | for ely = 1:nely 121 | for elx = 1:nelx 122 | n1 = (nely+1)*(elx-1)+ely; 123 | n2 = (nely+1)* elx +ely; 124 | Ue = U([2*n1-1;2*n1; 2*n2-1;2*n2; 2*n2+1;2*n2+2; 2*n1+1;2*n1+2],1); 125 | dcf(ely,elx) = -Ue'*penal*xphy(ely,elx)^(penal-1)*E(ely,elx)*KE*Ue; 126 | end 127 | end 128 | c = sum(xphy(:)); 129 | dc(1:nely,1:nelx) = 1; 130 | dc(:) = H*(dc(:)./Hs); 131 | 132 | f0val = c; 133 | df0dx = dc(:); 134 | fval(1,1) = U(dof)/dismax -1; 135 | dcf(:) = H*(dcf(:)./Hs); 136 | dfdx(1,1:n) = dcf(:)/dismax; 137 | 138 | %%% The MMA subproblem is solved at the point xval: 139 | outeriter = loop; 140 | [xmma,~,~,~,~,~,~,~,~,low,upp] = ... 141 | mmasub(m,n,outeriter,x(:),xmin,xmax,xold1(:),xold2(:), ... 142 | f0val,df0dx,fval,dfdx,low,upp,a0,a,ci,d); 143 | 144 | %%% Update 145 | xold2 = xold1; 146 | xold1 = x; 147 | xnew = reshape(xmma,nely,nelx); 148 | xphy(:) = (H*xnew(:))./Hs; 149 | 150 | change = max(abs(xnew(:)-x(:))); 151 | x = xnew; 152 | xphy(passive == 1) = 0.001; 153 | 154 | % Results 155 | disp([' It.: ' sprintf('%4i',loop) ' Obj.: ' sprintf('%6.4f',c) ... 156 | ' Vol Frac.: ' sprintf('%6.4f',sum(sum(xphy))/(3/4*nelx*nely)) ... 157 | ' ch.: ' sprintf('%6.3f',change )]) 158 | 159 | % PLOT DENSITIES 160 | % colormap(gray); 161 | % imagesc(1-xphy); 162 | % axis equal; 163 | % axis tight; 164 | % axis off; 165 | % pause(1e-6); 166 | end 167 | 168 | mpp = find_mpp(colPoints, eigV, eigF, nKL, nelx, nely, xphy, penal,... 169 | KE, dof, upE, lwE, dismax,reli); 170 | mpptol = max(abs(mpp(:)-mppold(:))); 171 | end 172 | 173 | figure 174 | colormap(gray); 175 | imagesc(1-xphy); 176 | axis equal; 177 | axis tight; 178 | axis off; 179 | savefig(fn); 180 | close all; 181 | fileID = fopen('data.txt','a+'); 182 | fprintf(fileID,'%s',title); 183 | fprintf(fileID,'\nVol Frac.: %6.4f',sum(sum(xphy))/(3/4*nelx*nely)); 184 | fprintf(fileID,'\nmain_loop: %4i',main_loop); 185 | fclose(fileID); 186 | %%% 187 | disp('END OPTIMIZATION'); 188 | rbto_mc_L(nelx, nely, penal, xphy, dismax, dof, upE, lwE); 189 | 190 | end 191 | 192 | function newE = update_E(eigV, eigF, mpp, nKL, c, d, nelx, nely) 193 | 194 | Z = sqrt(eigV).* mpp'; 195 | E(1:nely,1:nelx) = 0; 196 | for j = 1:nKL 197 | E = E + Z(j)*squeeze(eigF(j,:,:)); 198 | end 199 | newE = c + (d-c)*normcdf(E); 200 | 201 | end 202 | 203 | function mpp = find_mpp(colPoints, eigV, eigF, nKL, nelx, nely, x, penal,... 204 | KE, dof, c, d, dismax,reli) 205 | 206 | s = length(colPoints); 207 | v(1:s) = 0; 208 | 209 | for i = 1:s 210 | Z = sqrt(eigV).*colPoints(i,:)'; 211 | E(1:nely,1:nelx) = 0; 212 | for j = 1:nKL 213 | E = E + Z(j)*squeeze(eigF(j,:,:)); 214 | end 215 | E = c + (d-c)*normcdf(E); 216 | [U] = FEL(nelx,nely,x,penal,KE,E,dof); 217 | v(i) = U(dof); 218 | end 219 | 220 | numVar = 10; 221 | N(1:s,1:numVar) = 0; 222 | for i = 1:s 223 | N(i,1) = 1; 224 | N(i,2) = colPoints(i, 1); 225 | N(i,3) = colPoints(i, 2); 226 | N(i,4) = colPoints(i, 1)^2 - 1; 227 | N(i,5) = colPoints(i,2)^2 - 1; 228 | N(i,6) = colPoints(i,1)*colPoints(i,2); 229 | N(i,7) = colPoints(i,1)^3 - 3*colPoints(i,1); 230 | N(i,8) = colPoints(i,2)^3 - 3*colPoints(i,2); 231 | N(i,9) = colPoints(i,1)*colPoints(i,2)^2 - colPoints(i,1); 232 | N(i,10) = colPoints(i,2)*colPoints(i,1)^2 - colPoints(i,2); 233 | end 234 | 235 | a = N'*N \ N'*v'; 236 | 237 | h = @(x) a(1) + a(2)*x(:,1) + a(3)*x(:,2) +... 238 | a(4)*(x(:,1)^2 - 1) + a(5)*(x(:,2)^2 - 1) +... 239 | a(6)*x(:,1)*x(:,2) +... 240 | a(7)*(x(:,1)^3 - 3*x(:,1)) + a(8)*(x(:,2)^3 - 3*x(:,2)) +... 241 | a(9)*(x(:,1)*(x(:,2)^2) - x(:,1)) + a(10)*((x(:,1)^2)*x(:,2) - x(:,2)); 242 | %g = @(x) h(x)/dismax - 1; 243 | g = @(x) dismax/h(x) - 1; 244 | %T = @(x) x; 245 | Tinv = @(u) u; 246 | 247 | res = CODES.reliability.iform(g,2,reli,'solver','hmv','Tinv',Tinv); 248 | disp(res) 249 | mpp = res.MPTP; 250 | 251 | end -------------------------------------------------------------------------------- /rbto_mc.m: -------------------------------------------------------------------------------- 1 | %%% use Monte Carlo 2 | function rbto_mc(nelx, nely, penal, x, dismax, dof, a,b) 3 | 4 | rng(0); 5 | nKL = 2; 6 | 7 | nu = 0.3; 8 | k = [ 1/2-nu/6 1/8+nu/8 -1/4-nu/12 -1/8+3*nu/8 ... 9 | -1/4+nu/12 -1/8-nu/8 nu/6 1/8-3*nu/8]; 10 | KE = 1/(1-nu^2)*[ k(1) k(2) k(3) k(4) k(5) k(6) k(7) k(8) 11 | k(2) k(1) k(8) k(7) k(6) k(5) k(4) k(3) 12 | k(3) k(8) k(1) k(6) k(7) k(4) k(5) k(2) 13 | k(4) k(7) k(6) k(1) k(8) k(3) k(2) k(5) 14 | k(5) k(6) k(7) k(8) k(1) k(2) k(3) k(4) 15 | k(6) k(5) k(4) k(3) k(2) k(1) k(8) k(7) 16 | k(7) k(4) k(5) k(2) k(3) k(8) k(1) k(6) 17 | k(8) k(3) k(2) k(5) k(4) k(7) k(6) k(1)]; 18 | 19 | numSamples = 100000/2; 20 | u(1:numSamples) = 0; 21 | [eigV, eigF] = KL(nelx, nely, nKL); 22 | 23 | roots = [sqrt(3 + sqrt(6))... 24 | -sqrt(3 + sqrt(6))... 25 | sqrt(3 - sqrt(6))... 26 | -sqrt(3 - sqrt(6))]; 27 | colPoints = [ 0 0;... 28 | roots(1) 0;... 29 | 0 roots(1);... 30 | roots(2) 0;... 31 | 0 roots(2);... 32 | roots(3) 0;... 33 | 0 roots(3);... 34 | roots(4) 0;... 35 | 0 roots(4);... 36 | roots(3) roots(3);... 37 | roots(4) roots(4);... 38 | roots(3) roots(4);... 39 | roots(4) roots(3);... 40 | roots(1) roots(3);... 41 | roots(1) roots(4);... 42 | roots(3) roots(1);... 43 | roots(4) roots(1);... 44 | roots(2) roots(3);... 45 | roots(3) roots(2);... 46 | roots(2) roots(4);... 47 | roots(4) roots(2);... 48 | roots(1) roots(2);... 49 | roots(2) roots(1)]; 50 | 51 | data = randn(numSamples,nKL); 52 | % data = rand(numSamples,nKL); 53 | % for i = 1:nKL 54 | % index = randperm(numSamples); 55 | % prob = (index'-data(:,i))/numSamples; 56 | % data(:,i) = sqrt(2)*erfinv(2*prob-1); 57 | % end 58 | 59 | tic 60 | parfor i = 1:numSamples 61 | Z = sqrt(eigV) .* data(i, :)'; 62 | E(1:nely, 1:nelx) = 0; 63 | for j = 1:nKL 64 | E = E + Z(j) * squeeze(eigF(j, :, :)); 65 | end 66 | E = a + (b - a) * normcdf(E); 67 | [U] = FE(nelx, nely, x, penal, KE, E, dof); 68 | u(i) = U(dof); 69 | end 70 | toc 71 | 72 | disp('Prob: '); 73 | sum(abs(u) - dismax >= 0)/numSamples 74 | % disp('1 - Prob: '); 75 | % 1 - sum(dismax - abs(u) <= 0)/numSamples 76 | 77 | disp('mean: '); mean(u) 78 | disp('std: '); std(u) 79 | 80 | s = length(colPoints); 81 | v(1:s) = 0; 82 | 83 | for i = 1:s 84 | Z = sqrt(eigV) .* colPoints(i, :)'; 85 | E(1:nely, 1:nelx) = 0; 86 | for j = 1:nKL 87 | E = E + Z(j) * squeeze(eigF(j, :, :)); 88 | end 89 | E = a + (b - a) * normcdf(E); 90 | [U] = FE(nelx, nely, x, penal, KE, E, dof); 91 | v(i) = U(dof); 92 | end 93 | 94 | numVar = 10; 95 | N(1:s, 1:numVar) = 0; 96 | for i = 1:s 97 | N(i, 1) = 1; 98 | N(i, 2) = colPoints(i, 1); 99 | N(i, 3) = colPoints(i, 2); 100 | N(i, 4) = colPoints(i, 1) ^ 2 - 1; 101 | N(i, 5) = colPoints(i, 2) ^ 2 - 1; 102 | N(i, 6) = colPoints(i, 1) * colPoints(i, 2); 103 | N(i, 7) = colPoints(i, 1) ^ 3 - 3 * colPoints(i, 1); 104 | N(i, 8) = colPoints(i, 2) ^ 3 - 3 * colPoints(i, 2); 105 | N(i, 9) = colPoints(i, 1) * colPoints(i, 2) ^ 2 - colPoints(i, 1); 106 | N(i, 10) = colPoints(i, 2) * colPoints(i, 1) ^ 2 - colPoints(i, 2); 107 | end 108 | 109 | a = N'*N \ N' * v'; 110 | 111 | disp1(1:numSamples) = 0; 112 | tic 113 | for i = 1:numSamples 114 | x = data(i, :); 115 | disp1(i) = a(1) + a(2) * x(1) + a(3) * x(2) + ... 116 | a(4) * (x(1) ^ 2 - 1) + a(5) * (x(2) ^ 2 - 1) + ... 117 | a(6) * x(1) * x(2) + ... 118 | a(7) * (x(1) ^ 3 - 3 * x(1)) + a(8) * (x(2) ^ 3 - 3 * x(2)) + ... 119 | a(9) * (x(1) * (x(2) ^ 2) - x(1)) + a(10) * ((x(1) ^ 2) * x(2) - x(2)); 120 | end 121 | toc 122 | mean(disp1) 123 | std(disp1) 124 | %colormap(gray); imagesc(-x); axis equal; axis tight; axis off; pause(1e-6); 125 | [f1,x1] = ecdf(u); 126 | [f2,x2] = ecdf(disp1); 127 | 128 | figure 129 | hold on 130 | r = length(x1)-10:length(x1); 131 | plot(x1(r),f1(r),'-ob') 132 | plot(x2(r),f2(r),'--r*') 133 | legend('MCS','SRSM','Location','best') 134 | xlabel('Displacement') 135 | ylabel('Cumulative probability') 136 | box on 137 | hold off 138 | 139 | figure 140 | hold on 141 | plot(x1,f1,'-b') 142 | plot(x2,f2,'--r') 143 | legend('MCS','SRSM','Location','best') 144 | xlabel('Displacement') 145 | ylabel('Cumulative probability') 146 | box on 147 | hold off 148 | 149 | end -------------------------------------------------------------------------------- /rbto_mc_L.m: -------------------------------------------------------------------------------- 1 | %%% use Monte Carlo 2 | function rbto_mc_L(nelx, nely, penal, x, dismax, dof, a,b) 3 | 4 | rng(0); 5 | nKL = 2; 6 | 7 | nu = 0.3; 8 | k = [ 1/2-nu/6 1/8+nu/8 -1/4-nu/12 -1/8+3*nu/8 ... 9 | -1/4+nu/12 -1/8-nu/8 nu/6 1/8-3*nu/8]; 10 | KE = 1/(1-nu^2)*[ k(1) k(2) k(3) k(4) k(5) k(6) k(7) k(8) 11 | k(2) k(1) k(8) k(7) k(6) k(5) k(4) k(3) 12 | k(3) k(8) k(1) k(6) k(7) k(4) k(5) k(2) 13 | k(4) k(7) k(6) k(1) k(8) k(3) k(2) k(5) 14 | k(5) k(6) k(7) k(8) k(1) k(2) k(3) k(4) 15 | k(6) k(5) k(4) k(3) k(2) k(1) k(8) k(7) 16 | k(7) k(4) k(5) k(2) k(3) k(8) k(1) k(6) 17 | k(8) k(3) k(2) k(5) k(4) k(7) k(6) k(1)]; 18 | 19 | numSamples = 100000/2; 20 | u(1:numSamples) = 0; 21 | [eigV, eigF] = KL(nelx, nely, nKL); 22 | 23 | roots = [sqrt(3 + sqrt(6))... 24 | -sqrt(3 + sqrt(6))... 25 | sqrt(3 - sqrt(6))... 26 | -sqrt(3 - sqrt(6))]; 27 | colPoints = [ 0 0;... 28 | roots(1) 0;... 29 | 0 roots(1);... 30 | roots(2) 0;... 31 | 0 roots(2);... 32 | roots(3) 0;... 33 | 0 roots(3);... 34 | roots(4) 0;... 35 | 0 roots(4);... 36 | roots(3) roots(3);... 37 | roots(4) roots(4);... 38 | roots(3) roots(4);... 39 | roots(4) roots(3);... 40 | roots(1) roots(3);... 41 | roots(1) roots(4);... 42 | roots(3) roots(1);... 43 | roots(4) roots(1);... 44 | roots(2) roots(3);... 45 | roots(3) roots(2);... 46 | roots(2) roots(4);... 47 | roots(4) roots(2);... 48 | roots(1) roots(2);... 49 | roots(2) roots(1)]; 50 | 51 | data = randn(numSamples,nKL); 52 | % data = rand(numSamples,nKL); 53 | % for i = 1:nKL 54 | % index = randperm(numSamples); 55 | % prob = (index'-data(:,i))/numSamples; 56 | % data(:,i) = sqrt(2)*erfinv(2*prob-1); 57 | % end 58 | 59 | tic 60 | parfor i = 1:numSamples 61 | Z = sqrt(eigV) .* data(i, :)'; 62 | E(1:nely, 1:nelx) = 0; 63 | for j = 1:nKL 64 | E = E + Z(j) * squeeze(eigF(j, :, :)); 65 | end 66 | E = a + (b - a) * normcdf(E); 67 | [U] = FEL(nelx, nely, x, penal, KE, E, dof); 68 | u(i) = U(dof); 69 | end 70 | toc 71 | 72 | disp('Prob: '); 73 | prob = sum(abs(u) - dismax >= 0)/numSamples 74 | % disp('1 - Prob: '); 75 | % 1 - sum(dismax - abs(u) <= 0)/numSamples 76 | 77 | disp('mean: '); mcsu = mean(u) 78 | disp('std: '); mcsstd = std(u) 79 | 80 | s = length(colPoints); 81 | v(1:s) = 0; 82 | 83 | for i = 1:s 84 | Z = sqrt(eigV) .* colPoints(i, :)'; 85 | E(1:nely, 1:nelx) = 0; 86 | for j = 1:nKL 87 | E = E + Z(j) * squeeze(eigF(j, :, :)); 88 | end 89 | E = a + (b - a) * normcdf(E); 90 | [U] = FEL(nelx, nely, x, penal, KE, E, dof); 91 | v(i) = U(dof); 92 | end 93 | 94 | numVar = 10; 95 | N(1:s, 1:numVar) = 0; 96 | for i = 1:s 97 | N(i, 1) = 1; 98 | N(i, 2) = colPoints(i, 1); 99 | N(i, 3) = colPoints(i, 2); 100 | N(i, 4) = colPoints(i, 1) ^ 2 - 1; 101 | N(i, 5) = colPoints(i, 2) ^ 2 - 1; 102 | N(i, 6) = colPoints(i, 1) * colPoints(i, 2); 103 | N(i, 7) = colPoints(i, 1) ^ 3 - 3 * colPoints(i, 1); 104 | N(i, 8) = colPoints(i, 2) ^ 3 - 3 * colPoints(i, 2); 105 | N(i, 9) = colPoints(i, 1) * colPoints(i, 2) ^ 2 - colPoints(i, 1); 106 | N(i, 10) = colPoints(i, 2) * colPoints(i, 1) ^ 2 - colPoints(i, 2); 107 | end 108 | 109 | a = N'*N \ N' * v'; 110 | 111 | disp1(1:numSamples) = 0; 112 | tic 113 | for i = 1:numSamples 114 | x = data(i, :); 115 | disp1(i) = a(1) + a(2) * x(1) + a(3) * x(2) + ... 116 | a(4) * (x(1) ^ 2 - 1) + a(5) * (x(2) ^ 2 - 1) + ... 117 | a(6) * x(1) * x(2) + ... 118 | a(7) * (x(1) ^ 3 - 3 * x(1)) + a(8) * (x(2) ^ 3 - 3 * x(2)) + ... 119 | a(9) * (x(1) * (x(2) ^ 2) - x(1)) + a(10) * ((x(1) ^ 2) * x(2) - x(2)); 120 | end 121 | toc 122 | mdis = mean(disp1) 123 | stddis = std(disp1) 124 | 125 | fileID = fopen('data.txt','a+'); 126 | fprintf(fileID,'\nprob: %4.7f',prob); 127 | fprintf(fileID,'\nMCS mean: %4.7f',mcsu); 128 | fprintf(fileID,'\nMCS std: %4.7f',mcsstd); 129 | fprintf(fileID,'\nSRSM mean: %4.7f',mdis); 130 | fprintf(fileID,'\nSRSM std: %4.7f',stddis); 131 | fprintf(fileID,'\n\n'); 132 | fclose(fileID); 133 | %colormap(gray); imagesc(-x); axis equal; axis tight; axis off; pause(1e-6); 134 | 135 | [f1,x1] = ecdf(u); 136 | [f2,x2] = ecdf(disp1); 137 | 138 | figure 139 | hold on 140 | r = length(x1)-10:length(x1); 141 | plot(x1(r),f1(r),'-ob') 142 | plot(x2(r),f2(r),'--r*') 143 | legend('MCS','SRSM','Location','best') 144 | xlabel('Displacement') 145 | ylabel('Cumulative probability') 146 | box on 147 | hold off 148 | 149 | figure 150 | hold on 151 | plot(x1,f1,'-b') 152 | plot(x2,f2,'--r') 153 | legend('MCS','SRSM','Location','best') 154 | xlabel('Displacement') 155 | ylabel('Cumulative probability') 156 | box on 157 | hold off 158 | 159 | end -------------------------------------------------------------------------------- /subsolv.m: -------------------------------------------------------------------------------- 1 | %------------------------------------------------------------- 2 | % This is the file subsolv.m 3 | % 4 | % Version Dec 2006. 5 | % Krister Svanberg 6 | % Department of Mathematics, KTH, 7 | % SE-10044 Stockholm, Sweden. 8 | % 9 | function [xmma,ymma,zmma,lamma,xsimma,etamma,mumma,zetmma,smma] = ... 10 | subsolv(m,n,epsimin,low,upp,alfa,beta,p0,q0,P,Q,a0,a,b,c,d) 11 | % 12 | % This function subsolv solves the MMA subproblem: 13 | % 14 | % minimize SUM[ p0j/(uppj-xj) + q0j/(xj-lowj) ] + a0*z + 15 | % + SUM[ ci*yi + 0.5*di*(yi)^2 ], 16 | % 17 | % subject to SUM[ pij/(uppj-xj) + qij/(xj-lowj) ] - ai*z - yi <= bi, 18 | % alfaj <= xj <= betaj, yi >= 0, z >= 0. 19 | % 20 | % Input: m, n, low, upp, alfa, beta, p0, q0, P, Q, a0, a, b, c, d. 21 | % Output: xmma,ymma,zmma, slack variables and Lagrange multiplers. 22 | % 23 | een = ones(n,1); 24 | eem = ones(m,1); 25 | epsi = 1; 26 | epsvecn = epsi*een; 27 | epsvecm = epsi*eem; 28 | x = 0.5*(alfa+beta); 29 | y = eem; 30 | z = 1; 31 | lam = eem; 32 | xsi = een./(x-alfa); 33 | xsi = max(xsi,een); 34 | eta = een./(beta-x); 35 | eta = max(eta,een); 36 | mu = max(eem,0.5*c); 37 | zet = 1; 38 | s = eem; 39 | itera = 0; 40 | while epsi > epsimin 41 | epsvecn = epsi*een; 42 | epsvecm = epsi*eem; 43 | ux1 = upp-x; 44 | xl1 = x-low; 45 | ux2 = ux1.*ux1; 46 | xl2 = xl1.*xl1; 47 | uxinv1 = een./ux1; 48 | xlinv1 = een./xl1; 49 | plam = p0 + P'*lam ; 50 | qlam = q0 + Q'*lam ; 51 | gvec = P*uxinv1 + Q*xlinv1; 52 | dpsidx = plam./ux2 - qlam./xl2 ; 53 | rex = dpsidx - xsi + eta; 54 | rey = c + d.*y - mu - lam; 55 | rez = a0 - zet - a'*lam; 56 | relam = gvec - a*z - y + s - b; 57 | rexsi = xsi.*(x-alfa) - epsvecn; 58 | reeta = eta.*(beta-x) - epsvecn; 59 | remu = mu.*y - epsvecm; 60 | rezet = zet*z - epsi; 61 | res = lam.*s - epsvecm; 62 | residu1 = [rex' rey' rez]'; 63 | residu2 = [relam' rexsi' reeta' remu' rezet res']'; 64 | residu = [residu1' residu2']'; 65 | residunorm = sqrt(residu'*residu); 66 | residumax = max(abs(residu)); 67 | ittt = 0; 68 | while residumax > 0.9*epsi & ittt < 200 69 | ittt=ittt + 1; 70 | itera=itera + 1; 71 | ux1 = upp-x; 72 | xl1 = x-low; 73 | ux2 = ux1.*ux1; 74 | xl2 = xl1.*xl1; 75 | ux3 = ux1.*ux2; 76 | xl3 = xl1.*xl2; 77 | uxinv1 = een./ux1; 78 | xlinv1 = een./xl1; 79 | uxinv2 = een./ux2; 80 | xlinv2 = een./xl2; 81 | plam = p0 + P'*lam; 82 | qlam = q0 + Q'*lam; 83 | gvec = P*uxinv1 + Q*xlinv1; 84 | GG = P*spdiags(uxinv2,0,n,n) - Q*spdiags(xlinv2,0,n,n); 85 | dpsidx = plam./ux2 - qlam./xl2 ; 86 | delx = dpsidx - epsvecn./(x-alfa) + epsvecn./(beta-x); 87 | dely = c + d.*y - lam - epsvecm./y; 88 | delz = a0 - a'*lam - epsi/z; 89 | dellam = gvec - a*z - y - b + epsvecm./lam; 90 | diagx = plam./ux3 + qlam./xl3; 91 | diagx = 2*diagx + xsi./(x-alfa) + eta./(beta-x); 92 | diagxinv = een./diagx; 93 | diagy = d + mu./y; 94 | diagyinv = eem./diagy; 95 | diaglam = s./lam; 96 | diaglamyi = diaglam+diagyinv; 97 | if m < n 98 | blam = dellam + dely./diagy - GG*(delx./diagx); 99 | bb = [blam' delz]'; 100 | Alam = spdiags(diaglamyi,0,m,m) + GG*spdiags(diagxinv,0,n,n)*GG'; 101 | AA = [Alam a 102 | a' -zet/z ]; 103 | solut = AA\bb; 104 | dlam = solut(1:m); 105 | dz = solut(m+1); 106 | dx = -delx./diagx - (GG'*dlam)./diagx; 107 | else 108 | diaglamyiinv = eem./diaglamyi; 109 | dellamyi = dellam + dely./diagy; 110 | Axx = spdiags(diagx,0,n,n) + GG'*spdiags(diaglamyiinv,0,m,m)*GG; 111 | azz = zet/z + a'*(a./diaglamyi); 112 | axz = -GG'*(a./diaglamyi); 113 | bx = delx + GG'*(dellamyi./diaglamyi); 114 | bz = delz - a'*(dellamyi./diaglamyi); 115 | AA = [Axx axz 116 | axz' azz ]; 117 | bb = [-bx' -bz]'; 118 | solut = AA\bb; 119 | dx = solut(1:n); 120 | dz = solut(n+1); 121 | dlam = (GG*dx)./diaglamyi - dz*(a./diaglamyi) + dellamyi./diaglamyi; 122 | end 123 | % 124 | dy = -dely./diagy + dlam./diagy; 125 | dxsi = -xsi + epsvecn./(x-alfa) - (xsi.*dx)./(x-alfa); 126 | deta = -eta + epsvecn./(beta-x) + (eta.*dx)./(beta-x); 127 | dmu = -mu + epsvecm./y - (mu.*dy)./y; 128 | dzet = -zet + epsi/z - zet*dz/z; 129 | ds = -s + epsvecm./lam - (s.*dlam)./lam; 130 | xx = [ y' z lam' xsi' eta' mu' zet s']'; 131 | dxx = [dy' dz dlam' dxsi' deta' dmu' dzet ds']'; 132 | % 133 | stepxx = -1.01*dxx./xx; 134 | stmxx = max(stepxx); 135 | stepalfa = -1.01*dx./(x-alfa); 136 | stmalfa = max(stepalfa); 137 | stepbeta = 1.01*dx./(beta-x); 138 | stmbeta = max(stepbeta); 139 | stmalbe = max(stmalfa,stmbeta); 140 | stmalbexx = max(stmalbe,stmxx); 141 | stminv = max(stmalbexx,1); 142 | steg = 1/stminv; 143 | % 144 | xold = x; 145 | yold = y; 146 | zold = z; 147 | lamold = lam; 148 | xsiold = xsi; 149 | etaold = eta; 150 | muold = mu; 151 | zetold = zet; 152 | sold = s; 153 | % 154 | itto = 0; 155 | resinew = 2*residunorm; 156 | while resinew > residunorm & itto < 50 157 | itto = itto+1; 158 | x = xold + steg*dx; 159 | y = yold + steg*dy; 160 | z = zold + steg*dz; 161 | lam = lamold + steg*dlam; 162 | xsi = xsiold + steg*dxsi; 163 | eta = etaold + steg*deta; 164 | mu = muold + steg*dmu; 165 | zet = zetold + steg*dzet; 166 | s = sold + steg*ds; 167 | ux1 = upp-x; 168 | xl1 = x-low; 169 | ux2 = ux1.*ux1; 170 | xl2 = xl1.*xl1; 171 | uxinv1 = een./ux1; 172 | xlinv1 = een./xl1; 173 | plam = p0 + P'*lam ; 174 | qlam = q0 + Q'*lam ; 175 | gvec = P*uxinv1 + Q*xlinv1; 176 | dpsidx = plam./ux2 - qlam./xl2; 177 | rex = dpsidx - xsi + eta; 178 | rey = c + d.*y - mu - lam; 179 | rez = a0 - zet - a'*lam; 180 | relam = gvec - a*z - y + s - b; 181 | rexsi = xsi.*(x-alfa) - epsvecn; 182 | reeta = eta.*(beta-x) - epsvecn; 183 | remu = mu.*y - epsvecm; 184 | rezet = zet*z - epsi; 185 | res = lam.*s - epsvecm; 186 | residu1 = [rex' rey' rez]'; 187 | residu2 = [relam' rexsi' reeta' remu' rezet res']'; 188 | residu = [residu1' residu2']'; 189 | resinew = sqrt(residu'*residu); 190 | steg = steg/2; 191 | end 192 | residunorm=resinew; 193 | residumax = max(abs(residu)); 194 | steg = 2*steg; 195 | end 196 | if ittt > 198 197 | epsi 198 | ittt 199 | end 200 | epsi = 0.1*epsi; 201 | end 202 | %x(find(passive)) = 0.001; %(cantilever beam with a fixed round hole) 203 | xmma = x; 204 | ymma = y; 205 | zmma = z; 206 | lamma = lam; 207 | xsimma = xsi; 208 | etamma = eta; 209 | mumma = mu; 210 | zetmma = zet; 211 | smma = s; 212 | %------------------------------------------------------------- --------------------------------------------------------------------------------