Trying to solve for a number of variables in a matrix. Getting a structfun error.
Show older comments
Tyring to solve the below matrix for u variables. Getting a structfun error - unsure what is causing this. Error message below. Does anybody have an insight as to how to fix the structfun error? Setting uniform output to 'false' does not resolve the error.
E = 10;
v = 0.4;
rho = 950;
Lt = 2000;
Li = 250;
A = 7853.98;
u1=0;
S = (A*E/Li);
K = [1 -1 0 0 0 0 0 0 0; -1 2 -1 0 0 0 0 0 0; 0 -1 2 -1 0 0 0 0 0; 0 0 -1 2 -1 0 0 0 0; 0 0 0 -1 2 -1 0 0 0; 0 0 0 0 -1 2 -1 0 0; 0 0 0 0 0 -1 2 -1 0; 0 0 0 0 0 0 -1 2 -1; 0 0 0 0 0 0 0 -1 1]
F1=146.37;
F2=18.3;
F3=18.3;
F4=18.3;
F5=18.3;
F6=18.3;
F7=18.3;
F8=18.3;
F9=9.15;
syms u2 u3 u4 u5 u6 u7 u8 u9 real;
F = [F1; F2; F3; F4; F5; F6; F7; F8; F9];
d = [u1; u2; u3; u4; u5; u6; u7; u8; u9];
RHS = S*K*d
for i = 1:length(F)
eqn(i,1) = F(i) == RHS(i);
end
unknowns = [u2, u3, u4, u5, u6, u7, u8, u9];
solution = solve(eqn, unknowns);
solution = vpa(structfun(@double,solution))
K =
1 -1 0 0 0 0 0 0 0
-1 2 -1 0 0 0 0 0 0
0 -1 2 -1 0 0 0 0 0
0 0 -1 2 -1 0 0 0 0
0 0 0 -1 2 -1 0 0 0
0 0 0 0 -1 2 -1 0 0
0 0 0 0 0 -1 2 -1 0
0 0 0 0 0 0 -1 2 -1
0 0 0 0 0 0 0 -1 1
RHS =
-(2763373546982447*u2)/8796093022208
(2763373546982447*u2)/4398046511104 - (2763373546982447*u3)/8796093022208
(2763373546982447*u3)/4398046511104 - (2763373546982447*u2)/8796093022208 - (2763373546982447*u4)/8796093022208
(2763373546982447*u4)/4398046511104 - (2763373546982447*u3)/8796093022208 - (2763373546982447*u5)/8796093022208
(2763373546982447*u5)/4398046511104 - (2763373546982447*u4)/8796093022208 - (2763373546982447*u6)/8796093022208
(2763373546982447*u6)/4398046511104 - (2763373546982447*u5)/8796093022208 - (2763373546982447*u7)/8796093022208
(2763373546982447*u7)/4398046511104 - (2763373546982447*u6)/8796093022208 - (2763373546982447*u8)/8796093022208
(2763373546982447*u8)/4398046511104 - (2763373546982447*u7)/8796093022208 - (2763373546982447*u9)/8796093022208
(2763373546982447*u9)/8796093022208 - (2763373546982447*u8)/8796093022208
Error using structfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
Answers (2)
You have 9 equations but only 8 unknowns (u2–u9). Since u1=0 is already substituted in, MATLAB's solve sees an overconstrained system, finds no exact solution, and returns empty.
This is a classic FEM boundary condition issue. The correct approach is to partition the stiffness matrix : remove the row/column corresponding to the known DOF (u1=0) and solve the reduced 8×8 system:
E = 10;
Li = 250;
A = 7853.98;
u1 = 0;
S = (A*E/Li);
K = [1 -1 0 0 0 0 0 0 0; -1 2 -1 0 0 0 0 0 0; 0 -1 2 -1 0 0 0 0 0;
0 0 -1 2 -1 0 0 0 0; 0 0 0 -1 2 -1 0 0 0; 0 0 0 0 -1 2 -1 0 0;
0 0 0 0 0 -1 2 -1 0; 0 0 0 0 0 0 -1 2 -1; 0 0 0 0 0 0 0 -1 1];
F = [146.37; 18.3; 18.3; 18.3; 18.3; 18.3; 18.3; 18.3; 9.15];
% --- Partition: remove row 1 & col 1 (known DOF u1=0) ---
K_red = S * K(2:end, 2:end); % 8x8 reduced stiffness matrix
F_red = F(2:end) - S*K(2:end,1)*u1; % 8x1 reduced force vector (u1 term = 0 here)
% Solve the 8x8 system directly
u_free = K_red \ F_red;
% Assemble full displacement vector
u_all = [u1; u_free]
% Reaction force at node 1
R1 = S * K(1,:) * u_all
Let's look at what solution is after the call to solve. I just added in a few semicolons to suppress some of the output.
E = 10;
v = 0.4;
rho = 950;
Lt = 2000;
Li = 250;
A = 7853.98;
u1=0;
S = (A*E/Li);
K = [1 -1 0 0 0 0 0 0 0; -1 2 -1 0 0 0 0 0 0; 0 -1 2 -1 0 0 0 0 0; 0 0 -1 2 -1 0 0 0 0; 0 0 0 -1 2 -1 0 0 0; 0 0 0 0 -1 2 -1 0 0; 0 0 0 0 0 -1 2 -1 0; 0 0 0 0 0 0 -1 2 -1; 0 0 0 0 0 0 0 -1 1];
F1=146.37;
F2=18.3;
F3=18.3;
F4=18.3;
F5=18.3;
F6=18.3;
F7=18.3;
F8=18.3;
F9=9.15;
syms u2 u3 u4 u5 u6 u7 u8 u9 real;
F = [F1; F2; F3; F4; F5; F6; F7; F8; F9];
d = [u1; u2; u3; u4; u5; u6; u7; u8; u9];
RHS = S*K*d;
for i = 1:length(F)
eqn(i,1) = F(i) == RHS(i);
end
unknowns = [u2, u3, u4, u5, u6, u7, u8, u9];
solution = solve(eqn, unknowns)
% solution = vpa(structfun(@double,solution))
Your system doesn't appear to have any solutions. I would expect the structfun call to work if there was a unique solution, or in this case if you told MATLAB to return a non-uniform output.
structfun(@double, solution, UniformOutput = false)
If the solution is unique and convertible to double:
syms a b
sol = solve(a+b==6, a-b==0)
structfun(@double, sol)
Categories
Find more on Symbolic Math Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!