Code
Part 1: A point load P = 100 KN acts at the free end vertically
downwards.
% Part a
clear all; clc;
nodes = [0, 0;
0.25, 0;
0.50, 0;
0.75, 0;
1.00, 0;
0, 0.10;
0.25, 0.075;
0.50, 0.05;
0.75, 0.025];
elements = [1, 6, 7;
1, 2, 7;
2, 7, 8;
2, 3, 8;
3, 8, 9;
3, 4, 9;
4, 9, 5];
E = [4000, 4000, 3000, 3000, 2000, 2000, 1000];
nu = 0.3;
t = 1;
n_nodes = size(nodes, 1);
n_dof = n_nodes * 2;
K = zeros(n_dof, n_dof);
F = zeros(n_dof, 1);
for e = 1:7
n1 = elements(e, 1);
n2 = elements(e, 2);
n3 = elements(e, 3);
x1 = nodes(n1, 1); y1 = nodes(n1, 2);
x2 = nodes(n2, 1); y2 = nodes(n2, 2);
x3 = nodes(n3, 1); y3 = nodes(n3, 2);
A = 0.5 * abs(x1*(y2-y3) + x2*(y3-y1) +
x3*(y1-y2));
fprintf('Element %d: Nodes (%d,%d,%d), Area =
%.4f m^2\n', e, n1, n2, n3, A);
if A == 0
error('Element %d has zero area', e);
end
b1 = y2 - y3; c1 = x3 - x2;
b2 = y3 - y1; c2 = x1 - x3;
b3 = y1 - y2; c3 = x2 - x1;
B = (1/(2*A)) * [b1, 0, b2, 0, b3, 0;
0, c1, 0, c2, 0, c3;
c1, b1, c2, b2, c3, b3];
D = (E(e)/(1-nu^2)) * [1, nu, 0;
nu, 1, 0;
0, 0, (1-nu)/2];
k_e = t * A * B' * D * B;
dof = [2*n1-1, 2*n1, 2*n2-1, 2*n2, 2*n3-1,
2*n3];
K(dof, dof) = K(dof, dof) + k_e;
F_e = zeros(6, 1);
F(dof) = F(dof) + F_e;
end
F(10) = -100;
fixed_dofs = [1, 2, 11, 12];
free_dofs = setdiff(1:n_dof, fixed_dofs);
if isempty(free_dofs)
error('No free DOFs to solve');
end
K_red = K(free_dofs, free_dofs);
F_red = F(free_dofs);
cond_K = cond(K_red);
fprintf('Condition number of K_red: %.4e\n',
cond_K);
if cond_K > 1e12
K_red = K_red + 1e-8 * eye(size(K_red));
fprintf('Applied regularization to K_red\n');
end
u_red = K_red \ F_red;
u = zeros(n_dof, 1);
u(free_dofs) = u_red;
fprintf('\nNodal Displacements:\n');
for i = 1:n_nodes
fprintf('Node %d: u_x = %.4e m, u_y = %.4e m\n',
i, u(2*i-1), u(2*i));
end
stress_xx = zeros(7, 1);
centroids_x = zeros(7, 1);
for e = 1:7
n1 = elements(e, 1);
n2 = elements(e, 2);
n3 = elements(e, 3);
x1 = nodes(n1, 1); y1 = nodes(n1, 2);
x2 = nodes(n2, 1); y2 = nodes(n2, 2);
x3 = nodes(n3, 1); y3 = nodes(n3, 2);
A = 0.5 * abs(x1*(y2-y3) + x2*(y3-y1) +
x3*(y1-y2));
if A == 0
error('Element %d has zero area in stress
calculation', e);
end
b1 = y2 - y3; c1 = x3 - x2;
b2 = y3 - y1; c2 = x1 - x3;
b3 = y1 - y2; c3 = x2 - x1;
B = (1/(2*A)) * [b1, 0, b2, 0, b3, 0;
0, c1, 0, c2, 0, c3;
c1, b1, c2, b2, c3, b3];
D = (E(e)/(1-nu^2)) * [1, nu, 0;
nu, 1, 0;
0, 0, (1-nu)/2];
dof = [2*n1-1, 2*n1, 2*n2-1, 2*n2, 2*n3-1,
2*n3];
u_e = u(dof);
epsilon = B * u_e;
sigma = D * epsilon;
stress_xx(e) = sigma(1); % sigma_xx (MPa)
centroids_x(e) = (x1 + x2 + x3)/3;
end
[centroids_sorted, idx] = sort(centroids_x);
stress_xx_sorted = stress_xx(idx);
fprintf('\nElement Stresses:\n');
for e = 1:7
fprintf('Element %d: sigma_xx = %.4e MPa,
Centroid x = %.2f m\n', ...
e, stress_xx(e), centroids_x(e));
end
if any(isnan(stress_xx_sorted)) ||
any(isinf(stress_xx_sorted))
error('Invalid stress values detected');
end
if isempty(centroids_sorted) ||
isempty(stress_xx_sorted)
error('Stress or centroid arrays are empty');
end
figure;
plot(centroids_sorted, stress_xx_sorted, 'bo-',
'LineWidth', 2, 'MarkerSize', 8);
xlabel('x-coordinate (m)', fontsize=20);
ylabel('Normal Stress \sigma_{xx} (MPa)',
fontsize=20);
title('Stress Distribution along Cantilever Plate',
fontsize=20);
grid on;
max_abs_stress = max(abs(stress_xx_sorted));
if max_abs_stress == 0
max_abs_stress = 1;
end
axis([0 1 -max_abs_stress*1.2 max_abs_stress*1.2]);
Part 2: A point load P = 100 KN acts at the free end making an
angle θ with the vertical. Compare results for varying angle
values.
% Part b
clear all; clc;
nodes = [0, 0;
0.25, 0;
0.50, 0;
0.75, 0;
1.00, 0;
0, 0.10;
0.25, 0.075;
0.50, 0.05;
0.75, 0.025];
elements = [1, 6, 7;
1, 2, 7;
2, 7, 8;
2, 3, 8;
3, 8, 9;
3, 4, 9;
4, 9, 5];
E = [4000, 4000, 3000, 3000, 2000, 2000, 1000];
nu = 0.3;
t = 1;
n_nodes = size(nodes, 1);
n_dof = n_nodes * 2;
K = zeros(n_dof, n_dof);
for e = 1:7
n1 = elements(e, 1);
n2 = elements(e, 2);
n3 = elements(e, 3);
x1 = nodes(n1, 1); y1 = nodes(n1, 2);
x2 = nodes(n2, 1); y2 = nodes(n2, 2);
x3 = nodes(n3, 1); y3 = nodes(n3, 2);
A = 0.5 * abs(x1*(y2-y3) + x2*(y3-y1) +
x3*(y1-y2));
fprintf('Element %d: Nodes (%d,%d,%d), Area =
%.4f m^2\n', e, n1, n2, n3, A);
if A == 0
error('Element %d has zero area', e);
end
b1 = y2 - y3; c1 = x3 - x2;
b2 = y3 - y1; c2 = x1 - x3;
b3 = y1 - y2; c3 = x2 - x1;
B = (1/(2*A)) * [b1, 0, b2, 0, b3, 0;
0, c1, 0, c2, 0, c3;
c1, b1, c2, b2, c3, b3];
D = (E(e)/(1-nu^2)) * [1, nu, 0;
nu, 1, 0;
0, 0, (1-nu)/2];
k_e = t * A * B' * D * B;
dof = [2*n1-1, 2*n1, 2*n2-1, 2*n2, 2*n3-1,
2*n3];
K(dof, dof) = K(dof, dof) + k_e;
end
theta_deg = [30, 45, 60, 90];
n_angles = length(theta_deg);
stress_xx_all = zeros(7, n_angles);
centroids_x = zeros(7, 1);
for t = 1:n_angles
F = zeros(n_dof, 1);
theta = deg2rad(theta_deg(t));
F(9) = 100 * sin(theta);
F(10) = -100 * cos(theta);
fixed_dofs = [1, 2, 11, 12];
free_dofs = setdiff(1:n_dof, fixed_dofs);
if isempty(free_dofs)
error('No free DOFs to solve');
end
K_red = K(free_dofs, free_dofs);
F_red = F(free_dofs);
cond_K = cond(K_red);
fprintf('Theta = %d deg, Condition number of
K_red: %.4e\n', theta_deg(t), cond_K);
if cond_K > 1e12
K_red = K_red + 1e-8 * eye(size(K_red));
fprintf('Applied regularization to
K_red\n');
end
u_red = K_red \ F_red;
u = zeros(n_dof, 1);
u(free_dofs) = u_red;
for e = 1:7
n1 = elements(e, 1);
n2 = elements(e, 2);
n3 = elements(e, 3);
x1 = nodes(n1, 1); y1 = nodes(n1, 2);
x2 = nodes(n2, 1); y2 = nodes(n2, 2);
x3 = nodes(n3, 1); y3 = nodes(n3, 2);
A = 0.5 * abs(x1*(y2-y3) + x2*(y3-y1) +
x3*(y1-y2));
if A == 0
error('Element %d has zero area in
stress calculation', e);
end
b1 = y2 - y3; c1 = x3 - x2;
b2 = y3 - y1; c2 = x1 - x3;
b3 = y1 - y2; c3 = x2 - x1;
B = (1/(2*A)) * [b1, 0, b2, 0, b3, 0;
0, c1, 0, c2, 0, c3;
c1, b1, c2, b2, c3, b3];
D = (E(e)/(1-nu^2)) * [1, nu, 0;
nu, 1, 0;
0, 0, (1-nu)/2];
dof = [2*n1-1, 2*n1, 2*n2-1, 2*n2, 2*n3-1,
2*n3];
u_e = u(dof);
epsilon = B * u_e;
sigma = D * epsilon;
stress_xx_all(e, t) = sigma(1);
if t == 1
centroids_x(e) = (x1 + x2 + x3)/3;
end
end
end
[centroids_sorted, idx] = sort(centroids_x);
stress_xx_sorted = stress_xx_all(idx, :);
for t = 1:n_angles
fprintf('\nElement Stresses for theta = %d
deg:\n', theta_deg(t));
for e = 1:7
fprintf('Element %d: sigma_xx = %.4e MPa,
Centroid x = %.2f m\n', ...
e, stress_xx_all(e, t),
centroids_x(e));
end
end
if any(isnan(stress_xx_sorted(:))) ||
any(isinf(stress_xx_sorted(:)))
error('Invalid stress values detected');
end
if isempty(centroids_sorted) ||
isempty(stress_xx_sorted)
error('Stress or centroid arrays are empty');
end
figure;
hold on;
colors = ['b', 'r', 'g', 'k'];
for t = 1:n_angles
plot(centroids_sorted, stress_xx_sorted(:, t),
[colors(t) 'o-'], ...
'LineWidth', 2, 'MarkerSize', 8, ...
'DisplayName', sprintf('theta = %d deg',
theta_deg(t)));
end
hold off;
xlabel('x-coordinate (m)', fontsize=15);
ylabel('Normal Stress \sigma_{xx} (MPa)',
fontsize=15);
title('Stress Distribution along Cantilever Plate',
FontSize=15);
legend('show');
grid on;
max_abs_stress = max(abs(stress_xx_sorted(:)));
if max_abs_stress == 0
max_abs_stress = 1;
end
axis([0 1 -max_abs_stress*1.2 max_abs_stress*1.2]);
Part 3: Under body weight
% Part c
clear all; clc;
nodes = [0, 0;
0.25, 0;
0.50, 0;
0.75, 0;
1.00, 0;
0, 0.1;
0.25, 0.075;
0.50, 0.05;
0.75, 0.025];
elements = [1, 6, 7;
1, 2, 7;
2, 7, 8;
2, 3, 8;
3, 8, 9;
3, 4, 9;
4, 9, 5];
E = [4000, 4000, 3000, 3000, 2000, 2000, 1000];
rho = [8000, 8000, 6000, 6000, 4000, 4000, 2000];
nu = 0.3;
t = 1;
g = 9.81;
n_nodes = size(nodes, 1);
n_dof = n_nodes * 2;
K = zeros(n_dof, n_dof);
F = zeros(n_dof, 1);
for e = 1:7
n1 = elements(e, 1);
n2 = elements(e, 2);
n3 = elements(e, 3);
x1 = nodes(n1, 1); y1 = nodes(n1, 2);
x2 = nodes(n2, 1); y2 = nodes(n2, 2);
x3 = nodes(n3, 1); y3 = nodes(n3, 2);
A = 0.5 * abs(x1*(y2-y3) + x2*(y3-y1) +
x3*(y1-y2));
fprintf('Element %d: Nodes (%d,%d,%d), Area =
%.4e m^2\n', e, n1, n2, n3, A);
if A == 0
error('Element %d has zero area', e);
end
b1 = y2 - y3; c1 = x3 - x2;
b2 = y3 - y1; c2 = x1 - x3;
b3 = y1 - y2; c3 = x2 - x1;
B = (1/(2*A)) * [b1, 0, b2, 0, b3, 0;
0, c1, 0, c2, 0, c3;
c1, b1, c2, b2, c3, b3];
D = (E(e)/(1-nu^2)) * [1, nu, 0;
nu, 1, 0;
0, 0, (1-nu)/2];
k_e = t * A * B' * D * B;
dof = [2*n1-1, 2*n1, 2*n2-1, 2*n2, 2*n3-1,
2*n3];
K(dof, dof) = K(dof, dof) + k_e;
f_y = -rho(e) * g;
F_e = (A * t * f_y / 3) * [0; 1; 0; 1; 0; 1];
F(dof) = F(dof) + F_e;
end
fixed_dofs = [1, 2, 11, 12];
free_dofs = setdiff(1:n_dof, fixed_dofs);
if isempty(free_dofs)
error('No free DOFs to solve');
end
K_red = K(free_dofs, free_dofs);
F_red = F(free_dofs);
cond_K = cond(K_red);
fprintf('Condition number of K_red: %.4e\n',
cond_K);
if cond_K > 1e12
K_red = K_red + 1e-8 * eye(size(K_red));
fprintf('Applied regularization to K_red\n');
end
u_red = K_red \ F_red;
u = zeros(n_dof, 1);
u(free_dofs) = u_red;
fprintf('\nNodal Displacements:\n');
for i = 1:n_nodes
fprintf('Node %d: u_x = %.4e m, u_y = %.4e m\n',
i, u(2*i-1), u(2*i));
end
stress_xx = zeros(7, 1);
centroids_x = zeros(7, 1);
for e = 1:7
n1 = elements(e, 1);
n2 = elements(e, 2);
n3 = elements(e, 3);
x1 = nodes(n1, 1); y1 = nodes(n1, 2);
x2 = nodes(n2, 1); y2 = nodes(n2, 2);
x3 = nodes(n3, 1); y3 = nodes(n3, 2);
A = 0.5 * abs(x1*(y2-y3) + x2*(y3-y1) +
x3*(y1-y2));
if A == 0
error('Element %d has zero area in stress
calculation', e);
end
b1 = y2 - y3; c1 = x3 - x2;
b2 = y3 - y1; c2 = x1 - x3;
b3 = y1 - y2; c3 = x2 - x1;
B = (1/(2*A)) * [b1, 0, b2, 0, b3, 0;
0, c1, 0, c2, 0, c3;
c1, b1, c2, b2, c3, b3];
D = (E(e)/(1-nu^2)) * [1, nu, 0;
nu, 1, 0;
0, 0, (1-nu)/2];
dof = [2*n1-1, 2*n1, 2*n2-1, 2*n2, 2*n3-1,
2*n3];
u_e = u(dof);
epsilon = B * u_e;
sigma = D * epsilon;
stress_xx(e) = sigma(1); % sigma_xx (MPa)
centroids_x(e) = (x1 + x2 + x3)/3;
end
[centroids_x_sorted, idx_x] = sort(centroids_x);
stress_xx_x_sorted = stress_xx(idx_x);
fprintf('\nElement Stresses:\n');
for e = 1:7
fprintf('Element %d: sigma_xx = %.4e MPa,
Centroid x = %.2f m\n', ...
e, stress_xx(e), centroids_x(e));
end
figure;
plot(centroids_x_sorted, stress_xx_x_sorted, 'bo-',
'LineWidth', 2, 'MarkerSize', 8);
xlabel('x-coordinate (m)', 'FontSize', 15);
ylabel('Normal Stress \sigma_{xx} (MPa)',
'FontSize', 15);
title('Stress Distribution along Cantilever Plate',
'FontSize', 15);
grid on;
max_abs_stress = max(abs(stress_xx_x_sorted));
if max_abs_stress == 0
max_abs_stress = 1;
end
axis([0 1 -max_abs_stress*1.2 max_abs_stress*1.2]);