Durée 3 heures, documents fournis en cours et TP, notes manuscrites autorisés. Tout autre document est interdit (en particulier tout livre). Calculatrices autorisées. Vous pouvez répondre aux questions dans l'ordre qui vous convient. Le sujet est certes long mais la notation le prendra en compte.
On désire faire un programme d'analyse de liaisons cinématiques de systèmes mécaniques (efforts transmissibles, mouvements relatifs entre pièces, hyperstatismes...). Comment pourrait-on stocker un mémoire un système tel que celui schématisé ci-dessous ? Expliquez vos choix, ne proposez que de "bonnes" solutions, si vous en proposez plusieurs expliquez leurs avantages et différences.
On désire étudier l'équilibre d'un système mécanique (en statique). Nous allons avant tout créer une bibliothèque de calculs vectoriels. Soient les déclarations suivantes :
#define DIM 3 typedef float vecteur[DIM];
écrire les fonctions de calcul vectoriel dont voici les entêtes :
void v_zero(vecteur res) /* met toutes les composantes du vecteur res à 0 */ void v_copi(vecteur src,vecteur res) /* copie le vecteur src dans le vecteur res */ void v_addi(vecteur v1,vecteur v2,vecteur res) /* additionne v1+v2, résultat dans res */ void v_sous(vecteur v1,vecteur v2,vecteur res) /* soustrait v1-v2, résultat dans res */ void v_vect(vecteur v1,vecteur v2,vecteur res) /* produit vectoriel v1^v2, résultat dans res */ void v_mult(float lambda,vecteur v,vecteur res) /* multiplie v par le scalaire lambda, résultat dans res */ float v_scal(vecteur v1,vecteur v2) /* produit scalaire, résultat (flottant) retourné par la fonction */ int v_egal(vecteur v1,vecteur v2) /* dit si les deux vecteurs sont égaux (retour 1) ou non (retour 0)*/
Toujours dans le même but, on crée une bibliothèque de calculs tensoriels. On suppose que les déclarations et fonctions de la question précédente sont connues (et fonctionnent, contrairement à ce que vous avez peut-être répondu). Soient les déclarations :
typedef struct { vecteur F; vecteur M; }torseur; typedef torseur * adr_t;
écrire les fonctions de calcul tensoriel dont voici les entêtes :
void t_zero(adr_t z) /* met à 0 les six composantes du torseur Z */ void t_copi(adr_t ini,adr_t fin) /* recopie le torseur "ini", dans "fin" */ void t_addi(adr_t t1,adr_t t2,adr_t res) /* additionne les composantes de T1 et T2, résultat dans res. Ceci corres- pond à l'addition de deux torseurs, s'ils sont donnés AU MEME POINT */ void t_depl(vecteur pos_ini,adr_t ini,vecteur pos_fin,adr_t fin) /* déplace le torseur "ini", donné en "pos_ini", en position "pos_fin". Le torseur résultat est "fin" */
Remarque 1 : Dans cette question on essayera de ne travailler que sur des vecteurs (déclarations et fonctions de la question 2), et pas directement sur les composantes, ce qui permettrait de changer de type de vecteurs sans changer le calcul tensoriel (par exemple changement de dimension).
Remarque 2 : On passe tous les arguments de type torseur par adresse.
Que fait ce programme ?
#include <conio.h> #include <stdio.h> #include <ctype.h> /* pour toupper */ #include <stdlib.h> /* pour malloc, NULL,... */ #include "bibli" /* la bibliothèque définie aux questions 2 et 3 */ typedef struct boite { torseur T; vecteur pos; struct boite * suiv; }boite; typedef boite * adr_b; void v_sais(vecteur v) { int i; char axe[]="XYZ"; for(i=0;i<DIM;i++) { printf("entrez la coordonnée suivant %c : ",axe[i]); scanf("%f",v+i); } } void v_affi(vecteur v) { int i; char axe[]="XYZ"; printf("["); for(i=0;i<DIM;i++) printf(" %c=%f",axe[i],v[i]); printf(" ]\n"); } void t_sais(adr_t v) { printf("Résultante : "); v_sais(v->F); printf("Moment : "); v_sais(v->M); } void t_affi(adr_t v) { printf("Résultante : "); v_affi(v->F); printf("Moment : "); v_affi(v->M); } void b_ajou(adr_t t,adr_b b,vecteur pos) { if(v_egal(b->pos,pos)) t_addi(t,&(b->T),t); else { torseur translat; t_depl(b->pos,&(b->T),pos,&translat); t_addi(t,&translat,t); } } adr_b b_sais(void) { adr_b nouveau; nouveau=malloc(sizeof(boite)); t_sais(&(nouveau->T)); printf("point d'application : "); v_sais(nouveau->pos); puts("encore (O/N) ? "); nouveau->suiv=(toupper(getch())=='O')?b_sais():NULL; return(nouveau); } void b_affi(adr_b v) { while(v!=NULL) { t_affi(&(v->T)); printf("point d'application : "); v_affi(v->pos); v=v->suiv; } } void main(void) { adr_b actu,prem=NULL; char c; torseur res; vecteur pdc; prem=b_sais(); puts("vérification : "); b_affi(prem); do { printf("Veuillez me donner un point de calcul : "); v_sais(pdc); t_zero(&res); actu=prem; while(actu!=NULL) { b_ajou(&res,actu,pdc); actu=actu->suiv; } puts("Résultat : "); t_affi(&res); puts("nouveau calcul (O/N) ?"); c=toupper(getch()); } while (c!='N'); }
Quels résultats donnerait-il si on entre les données suivantes ? Détaillez ce qui se passe en mémoire, les liens créés, les affichages obtenus et si possible une interprétation physique.
100 0 0 0 0 0 0 0 0 o -100 0 0 0 0 0 0 2 0 n 0 1 0 n
Certains calculs (RdM poutres par exemple) nécessitent que les différentes "boites" créées par la fonction b_sais ci-dessus soient triées suivant une direction donnée. Ecrivez une fonction triant ces boites. Pour simplifier, vous les classerez d'après leur position suivant Y, c'est à dire la deuxième composante du champ "pos" (en fait, pour utiliser une autre direction de classement, il suffirait de faire une projection donc un produit scalaire). Vous utiliserez l'algorithme de tri que vous préférez. S'il vous manque du temps, limitez vous à une description de l'algorithme.
Soient les vecteurs :
Le produit vectoriel est
Le produit scalaire vaut
La norme d'un vecteur est la racine carrée de
Un torseur d'actions mécaniques est lui composé de deux vecteurs (une résultante et un moment), et est associé à un point d'application. Ces torseurs peuvent s'additionner à condition d'être définis au même point. Notons {T}A un torseur défini au point A, et {T}B le torseur des mêmes actions mécaniques, mais calculé au point B.
{T}A = {T}B =
En statique, un solide indéformable est en équilibre si et seulement si la somme des torseurs des actions mécaniques qui lui sont appliquées est nulle, en tout point. Tous ces torseurs doivent être définis au même point d'application avant de pouvoir être additionnés.
Une liaison entre deux solides peut être représentée par un torseur des efforts transmissibles, en un point généralement choisi au centre de la liaison, dans un repère aligné généralement avec "l'axe" de la liaison. On appelle liaison équivalente le torseur résultant (somme) de toutes les liaisons entre deux pièces (souvent en prenant également en compte les petites pièces intermédiaires). Mais une liaison peut également être représentée par un torseur cinématique , où chaque terme nul (pas de mouvement possible) correspond à un terme non nul (effort transmissible) du torseur statique.
pour des pistes de solutions, cliquez ici. Pour retourner au sommaire des sujets d'examens, cliquez là.