Asked by Maryam
on 17 Oct 2018

Hello all,

I am writing an optimization code, in which three variables are considered. The variables are used to find eigenpairs of the problem, and lately, eigenpairs are developing objective function. The objective fuction part of my code is as below.

function [y] = obj_func(x)

%Input.........................................................

%..............................................................

%number of nodes

num_nod=6;

% nodes coordinates

nod_coor=[720 0;720 360;360 0;360 360;0 0;0 360];

% connectivity table

ele_nod=[6 4;4 2;5 3;3 1;3 4;1 2;6 3;5 4;4 1;3 2;5 6];

%number of elements

num_ele=size(ele_nod,1);

% elements degree of freedom (DOF)

ele_dof=[11 12 7 8;7 8 3 4;9 10 5 6;...

5 6 1 2;5 6 7 8;1 2 3 4;11 12 5 6;...

9 10 7 8;7 8 1 2;5 6 3 4;9 10 11 12];

% A, E, L are cross sectional area, Young's modulus, length of elements,respectively.

A(1)=14;

A(2)=1;

A(3)=11;

A(4)=7;

A(5)=1;

A(6)=1;

A(7)=6;

A(8)=3;

A(9)=14;

A(10)=1;

A(11)=1;

E(1)=30000;

E(2)=30000;

E(3)=30000;

E(4)=30000;

E(5)=30000;

E(6)=30000;

E(7)=30000;

E(8)=30000;

E(9)=30000;

E(10)=30000;

E(11)=30000;

rho = 9.8759999999999994e-3;

stiffness_damage=zeros(2*num_nod);

mass=zeros(2*num_nod);

%applied loads at DOFs

force(2)=-10;

force(6)=-10;

%Boundary conditions

BC = [9;10;11;12];

%Variables from Phase I

global f_uD;

global f_DM;

global vec_D

global val_D

V_0_col = 2*num_nod - size(BC,1);

%..............................................................

%..............................................................

x1 = x(1);

x2 = x(2);

x3 = x(3);

damage_ele_size = 3;

damage_ele_1 = @(x)[1,x1;5,x2;10,x3];

%Compute stiffness matrix for damaged structure

for e=1:num_ele

L(e)=sqrt((nod_coor(ele_nod(e,2),1)-nod_coor(ele_nod(e,1),1))^2+...

(nod_coor(ele_nod(e,2),2)-nod_coor(ele_nod(e,1),2))^2);

C(e)=(nod_coor(ele_nod(e,2),1)-nod_coor(ele_nod(e,1),1))/L(e);

S(e)=(nod_coor(ele_nod(e,2),2)-nod_coor(ele_nod(e,1),2))/L(e);

k_1=(A(e)*E(e)/L(e)*[C(e)*C(e) C(e)*S(e) -C(e)*C(e) -C(e)*S(e);C(e)*S(e) ...

S(e)*S(e) -C(e)*S(e) -S(e)*S(e);-C(e)*C(e) -C(e)*S(e) C(e)*C(e) ...

C(e)*S(e); -C(e)*S(e) -S(e)*S(e) C(e)*S(e) S(e)*S(e)]);

for kk = 1:damage_ele_size

if e == damage_ele_1(kk,1)

k_1 = k_1*(1-damage_ele_1(kk,2));

end

end

% Develope mass matrix

m(e) = rho*L(e)*A(e);

m_local = [m(e)/2 0 0 0;0 m(e)/2 0 0;0 0 m(e)/2 0;0 0 0 m(e)/2];

% extract the rows of ele_dof (for each element e)

ele_dof_vec=ele_dof(e,:);

for i=1:4

for j=1:4

stiffness_damage(ele_dof_vec(1,i),ele_dof_vec(1,j))=...

stiffness_damage(ele_dof_vec(1,i),ele_dof_vec(1,j))+k_1(i,j);

mass(ele_dof_vec(1,i),ele_dof_vec(1,j))=...

mass(ele_dof_vec(1,i),ele_dof_vec(1,j))+m_local(i,j);

end

end

end

%Damaged Stiffness matrix after applying B.C.

for i = 1:size(BC,1)

stiffness_damage(BC,:)=0;

stiffness_damage(:,BC)=0;

end

for j = 1:size(BC)

stiffness_damage(BC(j),BC(j))=1;

end

%Calculate Eigenpairs

[vec_D_m,val_D_m] = eig(stiffness_damage, mass, 'vector');

f_DA = val_D_m*(1/(2*pi));

%Define change in frequencies

delta_f = (f_uD - f_DM)/norm(f_uD);

round_f = (f_uD - f_DA)/norm(f_uD);

MDLAC = (abs(delta_f'*round_f)^2)/((delta_f'*delta_f)*(round_f'*round_f));

% Define Objective function

sum = zeros(2*num_nod,1);

for ki=1:V_0_col

sum = sum + (vec_D(:,ki)-vec_D_m(:,ki)/norm(vec_D(:,ki)));

end

y = 1 - MDLAC + sum + 10e4*(MDLAC+abs(MDLAC));

end

The optimization line I use for solving the problem is as follow:

{[x,fval] = ga(@obj_func,3);}

The code is not working and gives me this error:

Error using obj_func>@(x)[1,x1;5,x2;10,x3]

Too many input arguments.

Error in obj_func (line 85) if e == damage_ele_1(kk,1)

Answer by Maryam
on 18 Oct 2018

Edited by Maryam
on 18 Oct 2018

Accepted Answer

So I was able to change the format of my code and I do not get the error again. However, it gives me a new error:

Error using makeState (line 56)

Your fitness function must return a scalar value.

Error in gaunc (line 40)

state = makeState(GenomeLength,FitnessFcn,Iterate,output.problemtype,options);

Error in ga (line 356)

[x,fval,exitFlag,output,population,scores] = gaunc(FitnessFcn,nvars,

...

Error in complete_code (line 266)

[x,fval] = ga(@obj_func,3);

Can anyone please tell me what this means? And possibly what do you recommend me to do to make it right? Thank you so very much.

Matt J
on 18 Oct 2018

Alan Weiss
on 18 Oct 2018

"Your fitness function must return a scalar value" means your fitness function should return a scalar, as opposed to a vector or matrix or array. To see what your fitness function is returning, evaluate

y = obj_func(x)

for some appropriate input vector x.

Alan Weiss

MATLAB mathematical toolbox documentation

Maryam
on 18 Oct 2018

Thank you so much for the comments. They were really helpful!

Sign in to comment.

Answer by Matt J
on 17 Oct 2018

Edited by Matt J
on 17 Oct 2018

You have called the function damage_ele_1 with two arguments kk and 1 in the line

if e == damage_ele_1(kk,1)

However, you have defined damage_ele_1 as a function of only one argument, x,

damage_ele_1 = @(x)[1,x1;5,x2;10,x3];

It is not at all clear what damage_ele_1 is really supposed to compute. It returns the same 1x6 vector for every input x that you provide. The if statement condition above will never evaluate true.

Maryam
on 18 Oct 2018

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.