Overview:
The analysis above was done using a homemade FEA solver written in MATLAB. The user specifies a structural frame, clamps to hold the frame, and the loads to be applied. Running the code then calculates the resulting strain in each beam and plots the deformed structure.
(Figure 1)
Theory:
The analysis is based on simple beam theory. Each element is subject to the following three equations which govern axial loading, bending loads, and bending moments.
Analysis:
The three governing equations from earlier were integrated to find displacements and rotations. Solving the system for a single element subject to unique loads and moments on each end yields the following equation.
The six by six matrix here is called the local stiffness matrix. It relates the forces experienced by two nodes to the displacement of those two nodes within the local coordinate system of its respective element.
In order to preform a multi-element analysis, one of these local stiffness matrices is assigned to each element. Applying a direction cosine matrix, rotates the local stiffness matrix from the element frame into the global frame. All local stiffness matrices are them assembled into a global stiffness matrix by mapping each component in the matrix to its specific address in the global stiffness matrix. For example, if an element spans between node one and node three, each of the four quadrants of the local stiffness matrix are assigned positions (1,1), (1,3), (3, 1), and (3,3) respectively in the global stiffness matrix. This is illustrated in Figure 2.
Once the global stiffness matrix is assembled, the rows and columns corresponding to the clamped nodes are deleted. The force vector is populated with the applied loads and displacements are solved for. The code ends by backwards calculating strains and stresses from the displacements, plotting the final result.
(Figure 2)
Code:
This is the MATLAB script that preformed the analysis shown in the cover photo. Feel free to use it and play around with it.
clear all
%Input Parameters
ult_ten = 300*10^6; %Ultimate Tensile Strength (Pa)
ult_com = 300*10^6; %Ultimate Compression Strength (Pa)
%Coordinates of nodes (m)
i = 1;
r = 10;
for theta = 0:3*pi()/15:3*pi()/2
pointt(i,:)=[r*cos(theta),r*sin(theta)];
i = i+1;
end
r = 12;
for theta = 0:3*pi()/15:3*pi()/2
pointt(i,:)=[r*cos(theta),r*sin(theta)];
i = i+1;
end
pointt = [pointt; 12, -6; 10, -6; 0, -10; 0, -12];
co = pointt;
%Clamped Nodes
clamps = [19; 20];
%Element Matrix:
%[Node Connection 1, Node Connection 2,X-section Area, Modulus, Area Moment of Inertia
A = 0.009;
EE = 190^(9);
IYY = 4.918*10^(-5);
e = [17 18 A EE IYY
9 18 A EE IYY
1 17 A EE IYY
1 9 A EE IYY
1 10 A EE IYY
2 9 A EE IYY
2 10 A EE IYY
2 11 A EE IYY
3 10 A EE IYY
3 11 A EE IYY
9 17 A EE IYY
1 18 A EE IYY
1 2 A EE IYY
9 10 A EE IYY
10 11 A EE IYY
2 3 A EE IYY
3 4 A EE IYY
11 12 A EE IYY
3 12 A EE IYY
4 11 A EE IYY
4 12 A EE IYY
4 13 A EE IYY
5 12 A EE IYY
4 5 A EE IYY
12 13 A EE IYY
5 13 A EE IYY
5 14 A EE IYY
6 13 A EE IYY
5 6 A EE IYY
13 14 A EE IYY
6 14 A EE IYY
6 7 A EE IYY
6 15 A EE IYY
7 14 A EE IYY
14 15 A EE IYY
7 15 A EE IYY
7 16 A EE IYY
8 15 A EE IYY
15 16 A EE IYY
7 8 A EE IYY
8 16 A EE IYY
8 20 A EE IYY
16 19 A EE IYY
8 19 A EE IYY
16 20 A EE IYY];
%Forces [Node, F_X (N), F_Y (N)]
External_Forces = [17 -30000 -30000;18 -20000 -20000];
%Displacement Display Exaggeration
Display_Scale = 0.2;
%Output
figure(1)
plot(co(:,1),co(:,2),'.')
title('User Defined Structure')
xlabel( 'x coordinate (meters)')
ylabel( 'y coordinate (meters)')
hold on
%Plot Forces
for pp = 1:length(External_Forces(:,1))
Force_dir = atan2(External_Forces(pp,3),External_Forces(pp,2));
x1 = [co(External_Forces(pp,1),1),6*cos(Force_dir)+co(External_Forces(pp,1),1)];
y1 = [co(External_Forces(pp,1),2),6*sin(Force_dir)+co(External_Forces(pp,1),2)];
quiver( x1(1),y1(1),x1(2)-x1(1),y1(2)-y1(1),'LineWidth',1.1,'Color',[1,0,0])
end
%Plot Clamps
plot(co(clamps(:),1),co(clamps(:),2),'s','color',[1,0,0])
%Plot Input Structure
for ww = 1:size(e(:,1))
plot([co(e(ww,1),1); co(e(ww,2),1)],[co(e(ww,1),2);co(e(ww,2),2)],'color',[0 0 0],'LineWidth',2)
end
%Calculate Element Lengths
for w = 1:size(e(:,1))
length = sqrt((co(e(w,1),1)-co(e(w,2),1))^2+(co(e(w,1),2)-co(e(w,2),2))^2 );
e(w,6) = length;
end
%Develop Local Stiffness Matrices and Assemble into Global Stiffness
%Matrix
Num_el = size(e,1);%number of elements
Num_Nodes = size(co,1); %number of nodes
Num_Nodes_el = 2; %number of nodes per element
Deg_of_Freedom = 3; %degree of freedom per node
%Initialize Matrix
K = zeros(Num_Nodes*Deg_of_Freedom,Num_Nodes*Deg_of_Freedom);
F = zeros(Num_Nodes*Deg_of_Freedom,1);
for A = 1:Num_el
%Create Direction Unit Vector For Each Element
n = (co(e(A,2),:) - co(e(A,1),:));
n = n./norm(n);%unit vector
%Calculate DCM for matrix rotation
theta = atan2(n(2),n(1));
DCM = [cos(theta) -sin(theta) 0; sin(theta) cos(theta) 0; 0 0 1];
L = e(A,6);
Area = e(A,3);
E = e(A,4);
Iyy = e(A,5);
%Calculate Stiffness matrices and rotate into proper position
k11 = DCM*[E*Area/L 0 0; 0 12*E*Iyy/(L^3) 6*E*Iyy/(L^2); 0 6*E*Iyy/(L^2) 4*E*Iyy/L]*(DCM');
k22 = DCM*[E*Area/L 0 0; 0 12*E*Iyy/(L^3) -6*E*Iyy/(L^2); 0 -6*E*Iyy/(L^2) 4*E*Iyy/L]*(DCM');
k12 = DCM*[-E*Area/L 0 0; 0 -12*E*Iyy/(L^3) 6*E*Iyy/(L^2); 0 -6*E*Iyy/(L^2) 2*E*Iyy/L]*(DCM');
%local stiffness matrix and force vector
localstiffness = [k11 k12; k12' k22];
localforce = zeros(Num_Nodes_el*Deg_of_Freedom,1);
%Assemble Local Stiffness Matrices into Global Stiffness Matrix
%Global Matrix Assembler Barrowed From AERO 315 Code
for B = 1: Num_Nodes_el
for i = 1: Deg_of_Freedom
nK1 = (e(A, B)-1)*Deg_of_Freedom+i;
nKe1 = (B-1)*Deg_of_Freedom+i;
F(nK1) = F(nK1) + localforce(nKe1);
for C = 1: Num_Nodes_el
for j = 1: Deg_of_Freedom
nK2 = (e(A, C)-1)*Deg_of_Freedom+j;
nKe2 = (C-1)*Deg_of_Freedom+j;
K(nK1, nK2) = K(nK1, nK2) + localstiffness(nKe1,nKe2);
end
end
end
end
end
%Configure Forces
for ww = 1:size(External_Forces(:,1))
F((Deg_of_Freedom*External_Forces(ww,1)-Deg_of_Freedom+1):(Deg_of_Freedom*External_Forces(ww,1)-Deg_of_Freedom+2)) = External_Forces(ww,2:3);
end
%Configure Clamps
%Delete Stiffness Matrix Rows and Columns, and Force Matrix Nodes of Clamped Nodes: Displacement = 0
del_row = [];
for ww = 1:size(clamps(:))
del_row = [del_row, (Deg_of_Freedom*clamps(ww)-Deg_of_Freedom+1), (Deg_of_Freedom*clamps(ww)-Deg_of_Freedom+2), (Deg_of_Freedom*clamps(ww)-Deg_of_Freedom+3)];
end
%Preform Deletion
K(del_row,:) = [];
K(:,del_row) = [];
F(del_row) = [];
%Solve for Vector of Displacements and Rotations
u = K\F;
%Exaggerate Displacements and Apply to Structure
% Exaggeration Scale
scale = (max(max(co(:,1)),max(co(:,2)))/max(u))*Display_Scale;
%Build co_prime, an Exaggerated Node Coordinate Matrix
%Build co_prime_true, a Non- Exaggeration Node Coordinate Matrix
n = 1;
m = 1;
for ww =1:size(co(:,1))
%If Not Clamped, Add Exaggeration Displacement
if clamps(n)~= ww
co_prime(ww,1) = co(ww,1)+u(m)*scale;
co_prime_true(ww,1) = co(ww,1)+u(m);
m = m+1;
co_prime(ww,2) = co(ww,2)+u(m)*scale;
co_prime_true(ww,2) = co(ww,2)+u(m);
m = m+2;
%If Clamped, Use Old Coordinate
else
n = n+1;
co_prime(ww,:) = co(ww,:);
co_prime_true(ww,:) = co(ww,:);
end
end
%Calculate Stresses in Each Element and Develop Color Coded Stress Display
color_maps = jet(201);
stress_val = 0;
for w = 1:size(e(:,1))
lengths(w) = sqrt((co_prime_true(e(w,1),1)-co_prime_true(e(w,2),1))^2+(co_prime_true(e(w,1),2)-co_prime_true(e(w,2),2))^2 );
%Axial stress do to tension and compression only, need to add in moment
%stress.
sigma(w) = (lengths(w)-e(w,6))*e(w,4);
if sigma(w)>=0
if (sigma(w)/ult_ten)>1
sigma(w) = ult_ten;
end
stress_val(w) = sigma(w)/ult_ten*100+100;
else
if abs(sigma(w)/ult_com) >=1
sigma(w) = ult_com;
end
stress_val(w) = -sigma(w)/ult_com*100+100;
end
end
%Plot Deformed Bars with Color Coded Stress
figure(2)
plot(co_prime(:,1),co_prime(:,2),'.')
title('Exaggerated Deformation')
xlabel( 'x coordinate (meters)')
ylabel( 'y coordinate (meters)')
colormap(jet(201))
c = colorbar('YTickLabel',{-ult_com/(10^6),'','','','','','','','','',ult_ten/(10^6)});
c.Label.String = 'Stress (MPa)';
hold on
a = [3,5]';
for ww = 1:size(e(:,1))
plot([co_prime(e(ww,1),1); co_prime(e(ww,2),1)],[co_prime(e(ww,1),2);co_prime(e(ww,2),2)],'color', color_maps(round(stress_val(ww)+1),:),'LineWidth',2)
end