function dallot_gui()
% Création de la fenêtre principale
fig = uifigure('Name', 'Dimensionnement Dallot en Bois', ...
'Position', [100 100 450 550]);
% Titre
uilabel(fig, 'Position', [20 500 410 30], ...
'Text', 'DIMENSIONNEMENT DALLOT EN BOIS', ...
'FontSize', 18, 'FontWeight', 'bold', ...
'HorizontalAlignment', 'center');
% ==================== CHAMPS DE SAISIE ====================
y_pos = 450;
vertical_spacing = 35;
% Longueur L
uilabel(fig, 'Position', [20 y_pos 200 22], 'Text', 'Longueur L (m):');
edit_L = uieditfield(fig, 'numeric', ...
'Position', [250 y_pos 100 22], ...
'Value', 1.0);
y_pos = y_pos - vertical_spacing;
% Module d'Young E
uilabel(fig, 'Position', [20 y_pos 200 22], 'Text', 'Module E (Pa):');
edit_E = uieditfield(fig, 'numeric', ...
'Position', [250 y_pos 100 22], ...
'Value', 10e9);
y_pos = y_pos - vertical_spacing;
% Section A
uilabel(fig, 'Position', [20 y_pos 200 22], 'Text', 'Section A (m²):');
edit_A = uieditfield(fig, 'numeric', ...
'Position', [250 y_pos 100 22], ...
'Value', 0.01);
y_pos = y_pos - vertical_spacing;
% Inertie I
uilabel(fig, 'Position', [20 y_pos 200 22], 'Text', 'Inertie I (m⁴):');
edit_I = uieditfield(fig, 'numeric', ...
'Position', [250 y_pos 100 22], ...
'Value', 8.33e-6);
uilabel(fig, 'Position', [20 y_pos-20 350 22], ...
'Text', '(Pour section rectangulaire: I = b×h³/12)', ...
'FontSize', 8, 'FontColor', 'blue');
y_pos = y_pos - vertical_spacing;
% Force F
uilabel(fig, 'Position', [20 y_pos 200 22], 'Text', 'Force F (N):');
edit_F = uieditfield(fig, 'numeric', ...
'Position', [250 y_pos 100 22], ...
'Value', 1000);
y_pos = y_pos - vertical_spacing;
% Facteur d'échelle visualisation
uilabel(fig, 'Position', [20 y_pos 200 22], 'Text', 'Échelle déplacement:');
edit_scale = uieditfield(fig, 'numeric', ...
'Position', [250 y_pos 100 22], ...
'Value', 50);
y_pos = y_pos - vertical_spacing;
% ==================== BOUTON DIMENSIONNER ====================
btn_dimensionner = uibutton(fig, 'push', ...
'Position', [175 y_pos-10 100 30], ...
'Text', 'DIMENSIONNER', ...
'FontWeight', 'bold', ...
'ButtonPushedFcn', @(btn,event) calculer_dallot());
% Zone d'information
info_label = uilabel(fig, 'Position', [50 y_pos-60 350 40], ...
'Text', 'Cliquez sur "DIMENSIONNER" pour lancer le calcul', ...
'FontSize', 11, ...
'HorizontalAlignment', 'center');
% ==================== FONCTION DE CALCUL DALLOT ====================
function calculer_dallot()
% Récupération des valeurs saisies
L = edit_L.Value;
E = edit_E.Value;
A = edit_A.Value;
I = edit_I.Value;
F = edit_F.Value;
scale_factor = edit_scale.Value;
% Validation des données
if L <= 0 || E <= 0 || A <= 0 || I <= 0 || F <= 0
info_label.Text = 'ERREUR: Toutes les valeurs doivent être > 0';
info_label.FontColor = 'red';
return;
end
info_label.Text = 'Calcul en cours... (Modèle Dallot)';
info_label.FontColor = 'blue';
drawnow;
try
% ==================== GÉOMÉTRIE ====================
H = (2/3)*L;
coords = [
0, 0; % Nœud 1
0, H; % Nœud 2
L, H; % Nœud 3
L, 0; % Nœud 4
2*L, 0; % Nœud 5
2*L, H; % Nœud 6
3*L, H; % Nœud 7
3*L, 0; % Nœud 8
4*L, H; % Nœud 9
4*L, 0 % Nœud 10
];
elements = [
1, 2; 2, 3; 3, 4; 4, 1; 1, 3;
4, 5; 5, 6; 6, 3; 3, 5;
5, 8; 8, 7; 7, 6; 5, 7;
8, 10; 10, 9; 9, 7; 7, 10
];
% ==================== INITIALISATION DALLOT ====================
n_nodes = size(coords, 1);
n_elems = size(elements, 1);
dof_per_node = 3; % ux, uy, θz
dof = n_nodes * dof_per_node; % 30 DOF
K_global = zeros(dof);
F_global = zeros(dof, 1);
% ==================== CHARGEMENT ====================
% Charges verticales aux nœuds 4, 5, 8 (indices: 3*n, 3*n-1, 3*n-2)
F_global(3*4 - 1) = F_global(3*4 - 1) - F; % Nœud 4: F ↓ (uy)
F_global(3*5 - 1) = F_global(3*5 - 1) - 2*F; % Nœud 5: 2F ↓ (uy)
F_global(3*8 - 1) = F_global(3*8 - 1) - F; % Nœud 8: F ↓ (uy)
% ==================== ASSEMBLAGE MATRICE RIGIDITÉ DALLOT
====================
for i = 1:n_elems
n1 = elements(i, 1);
n2 = elements(i, 2);
x1 = coords(n1, 1); y1 = coords(n1, 2);
x2 = coords(n2, 1); y2 = coords(n2, 2);
L_elem = sqrt((x2 - x1)^2 + (y2 - y1)^2);
c = (x2 - x1) / L_elem;
s = (y2 - y1) / L_elem;
% Matrice de rigidité élémentaire pour poutre 2D (6 DOF)
% [ux1, uy1, θ1, ux2, uy2, θ2]
k_axial = (E * A / L_elem);
k_flexion = (E * I / L_elem^3);
% Matrice en coordonnées locales
k_local = zeros(6);
% Termes axiaux
k_local([1,4],[1,4]) = k_axial * [1, -1; -1, 1];
% Termes de flexion
k_local([2,3,5,6],[2,3,5,6]) = k_flexion * [
12, 6*L_elem, -12, 6*L_elem;
6*L_elem, 4*L_elem^2, -6*L_elem, 2*L_elem^2;
-12, -6*L_elem, 12, -6*L_elem;
6*L_elem, 2*L_elem^2, -6*L_elem, 4*L_elem^2
];
% Matrice de rotation
T = [c, s, 0, 0, 0, 0;
-s, c, 0, 0, 0, 0;
0, 0, 1, 0, 0, 0;
0, 0, 0, c, s, 0;
0, 0, 0, -s, c, 0;
0, 0, 0, 0, 0, 1];
% Transformation en coordonnées globales
k_global_elem = T' * k_local * T;
% Degrés de liberté globaux
dofs = [3*n1-2, 3*n1-1, 3*n1, 3*n2-2, 3*n2-1, 3*n2];
% Assemblage
K_global(dofs, dofs) = K_global(dofs, dofs) + k_global_elem;
end
% ==================== CONDITIONS AUX LIMITES ====================
% Nœud 1: appui double (encastrement) - blocage ux, uy, θz
fixed_dofs = [3*1-2, 3*1-1, 3*1];
% Nœud 10: appui simple - blocage uy seulement
fixed_dofs = [fixed_dofs, 3*10-1];
free_dofs = setdiff(1:dof, fixed_dofs);
% ==================== RÉSOLUTION ====================
K_red = K_global(free_dofs, free_dofs);
F_red = F_global(free_dofs);
% Vérification du conditionnement
cond_K = cond(K_red);
if cond_K > 1e12
warning('Matrice mal conditionnée. Vérifiez les conditions aux limites.');
end
U_red = K_red \ F_red;
U = zeros(dof, 1);
U(free_dofs) = U_red;
R = K_global * U - F_global;
% ==================== CALCUL DES EFFORTS INTERNES ====================
efforts = zeros(n_elems, 6); % [N, V, M_début, N, V, M_fin]
for i = 1:n_elems
n1 = elements(i, 1);
n2 = elements(i, 2);
x1 = coords(n1, 1); y1 = coords(n1, 2);
x2 = coords(n2, 1); y2 = coords(n2, 2);
L_elem = sqrt((x2 - x1)^2 + (y2 - y1)^2);
c = (x2 - x1) / L_elem;
s = (y2 - y1) / L_elem;
% Matrice de rotation
T = [c, s, 0, 0, 0, 0;
-s, c, 0, 0, 0, 0;
0, 0, 1, 0, 0, 0;
0, 0, 0, c, s, 0;
0, 0, 0, -s, c, 0;
0, 0, 0, 0, 0, 1];
% Déplacements globaux
U_elem_global = U([3*n1-2, 3*n1-1, 3*n1, 3*n2-2, 3*n2-1, 3*n2]);
% Déplacements locaux
U_elem_local = T * U_elem_global;
% Calcul des efforts dans le repère local
k_axial = (E * A / L_elem);
k_flexion = (E * I / L_elem^3);
% Efforts locaux
N1 = k_axial * (U_elem_local(4) - U_elem_local(1));
V1 = k_flexion * (12*U_elem_local(2) + 6*L_elem*U_elem_local(3) -
12*U_elem_local(5) + 6*L_elem*U_elem_local(6));
M1 = k_flexion * (6*L_elem*U_elem_local(2) + 4*L_elem^2*U_elem_local(3) -
6*L_elem*U_elem_local(5) + 2*L_elem^2*U_elem_local(6));
N2 = -N1;
V2 = -V1;
M2 = k_flexion * (6*L_elem*U_elem_local(2) + 2*L_elem^2*U_elem_local(3) -
6*L_elem*U_elem_local(5) + 4*L_elem^2*U_elem_local(6));
efforts(i, :) = [N1, V1, M1, N2, V2, M2];
end
% ==================== AFFICHAGE CONSOLE ====================
fprintf('\n=== RÉSULTATS DU DALLOT ===\n');
fprintf('Paramètres: L=%.2f m, E=%.2e Pa, A=%.4f m², I=%.2e m⁴, F=%.0f N\n', ...
L, E, A, I, F);
fprintf('\n--- DÉPLACEMENTS ET ROTATIONS ---\n');
for i = 1:n_nodes
ux = U(3*i-2);
uy = U(3*i-1);
theta = U(3*i);
fprintf('Nœud %2d: ux = %10.3e m, uy = %10.3e m, θz = %10.3e rad\n', ...
i, ux, uy, theta);
end
fprintf('\n--- RÉACTIONS ---\n');
fprintf('Nœud 1: Rx = %10.2f N, Ry = %10.2f N, Mz = %10.2f N.m\n', ...
R(1), R(2), R(3));
fprintf('Nœud 10: Ry = %10.2f N\n', R(29));
fprintf('\n--- EFFORTS MAXIMAUX ---\n');
N_max = max(abs(efforts(:,1)));
V_max = max(abs(efforts(:,2)));
M_max = max(abs([efforts(:,3); efforts(:,6)]));
fprintf('Effort normal max: %.2f N\n', N_max);
fprintf('Effort tranchant max: %.2f N\n', V_max);
fprintf('Moment fléchissant max: %.2f N.m\n', M_max);
% ==================== VISUALISATION ====================
figure('Name', 'Résultats du Dallot - Déplacements et Efforts', ...
'Position', [100 100 1200 800]);
% Sous-figure 1: Déplacements
subplot(2,2,1);
hold on; axis equal; grid on;
title('Déformée de la structure');
coords_def = coords + scale_factor * [U([Link]nd), U([Link]nd)];
% Structure initiale et déformée
for i = 1:n_elems
n1 = elements(i, 1);
n2 = elements(i, 2);
plot([coords(n1,1), coords(n2,1)], [coords(n1,2), coords(n2,2)], 'b-', 'LineWidth', 2);
plot([coords_def(n1,1), coords_def(n2,1)], [coords_def(n1,2), coords_def(n2,2)],
'r--', 'LineWidth', 1.5);
end
% Nœuds et annotations
plot(coords(:,1), coords(:,2), 'bo', 'MarkerSize', 6, 'MarkerFaceColor', 'b');
plot(coords_def(:,1), coords_def(:,2), 'ro', 'MarkerSize', 4, 'MarkerFaceColor', 'r');
% Charges et réactions
arrow_scale = 0.1 * L;
load_nodes = [4, 5, 8];
for i = 1:length(load_nodes)
node = load_nodes(i);
x = coords(node, 1); y = coords(node, 2);
quiver(x, y, 0, -arrow_scale, 0, 'm', 'LineWidth', 2, 'MaxHeadSize', 0.5);
if node == 5
label = '2F';
else
label = 'F';
end
text(x, y-0.15, label, 'Color', 'm', 'FontWeight', 'bold', 'HorizontalAlignment',
'center');
end
legend('Initiale', 'Déformée', 'Location', 'best');
xlabel('X (m)'); ylabel('Y (m)');
text(0.1, -0.2, sprintf('Échelle déplacements: ×%g', scale_factor), 'Color', 'red');
% Sous-figure 2: Diagramme des moments
subplot(2,2,2);
hold on; grid on;
title('Diagramme des moments fléchissants');
for i = 1:n_elems
n1 = elements(i, 1);
n2 = elements(i, 2);
x1 = coords(n1, 1); y1 = coords(n1, 2);
x2 = coords(n2, 1); y2 = coords(n2, 2);
% Moment moyen pour l'affichage
M_moy = (abs(efforts(i,3)) + abs(efforts(i,6))) / 2;
% Tracé avec épaisseur proportionnelle au moment
line_width = 1 + 3 * M_moy / max(1, M_max);
plot([x1, x2], [y1, y2], 'g-', 'LineWidth', line_width);
% Annotation du moment
x_mid = (x1 + x2)/2; y_mid = (y1 + y2)/2;
text(x_mid, y_mid+0.05, sprintf('M=%.0f', M_moy), ...
'FontSize', 7, 'HorizontalAlignment', 'center');
end
xlabel('X (m)'); ylabel('Y (m)');
% Sous-figure 3: Rotations
subplot(2,2,3);
rotations = U([Link]nd) * 180/pi; % Conversion en degrés
bar(rotations);
title('Rotations aux nœuds (degrés)');
xlabel('Nœud'); ylabel('Rotation (°)');
grid on;
% Sous-figure 4: Efforts normaux
subplot(2,2,4);
efforts_normaux = efforts(:,1);
bar(efforts_normaux);
title('Efforts normaux dans les barres');
xlabel('Barre'); ylabel('Effort normal (N)');
grid on;
info_label.Text = 'Calcul DALLOT terminé avec succès!';
info_label.FontColor = 'green';
fprintf('\n=== CALCUL TERMINÉ ===\n');
fprintf('Les rotations sont bien calculées (colonne θz)\n');
fprintf('Conditionnement de la matrice: %.2e\n', cond_K);
catch ME
info_label.Text = 'ERREUR lors du calcul du dallot';
info_label.FontColor = 'red';
fprintf('Erreur: %s\n', [Link]);
fprintf('Détail: %s\n', [Link]());
end
end
end