Projet : étape 4 (semaine 6 du semestre)

Buts

Cette semaine est une étape importante (et aussi plus conséquente) de notre projet. Nous allons en effet mettre en place toute la conception qui nous permettra dans la suite d'enrichir notre projet. Nous allons donc mettre en place les quatre éléments clés de notre projet : les différents types d'objets, le moyen de les faire évoluer les objets (intégrateur), ainsi que les champs de forces et les contraintes que ces objets subiront.

Préliminaires :

Cette semaine est une grosse semaine en terme de travail. À partir de maintenant, il est en effet prévu que vous soyez mis en équipe et que vous travaillez en binôme de sorte à vous répartir les tâches. Je rappelle que chacun doit faire environ la moitié du travail lié au projet.

Je vous rappelle également tous les autres conseils donnés en semaine 3.

Le travail de cette semaine est découpé en deux sujets qui sont très dépendants l'un de l'autre au niveau conception mais qui peuvent être réalisés indépendemment. Je vous propose donc de réfléchir ensemble à la conception (en ayant tous les deux parcouru les deux sujet), puis de vous séparer le travail de réalisation.


[2*] Exercice P6 : objets et intégrateurs

Pour l'instant notre système ne bouge pas beaucoup. Et pour cause !
Pour le faire évoluer, il est nécessaire de calculer les solutions aux équations du mouvement. Pour cela, nous avons besoin d'un intégrateur numérique et des équations en questions.

Nous avons aussi jusqu'ici que deux objets simples du système: GravitationConstante et PointMateriel. Essayons d'abstraire un peu plus...

Objets mobiles (« intégrables »)

Au niveau le plus abstrait, ce que nous voulons « simplement » faire c'est faire évoluer des objets ayant des degrés de liberté et une équation d'évolution:
E'' = f(t, E, E')
(avec E un vecteur [dans le cas le plus général, ce qui ne l'empêche pas d'être de dimension 1 dans les case les plus simples, à un seul degré de liberté]).
(voir le descriptif général et les compléments mathématiques du projet). C'est ça la seule abstraction de plus haut niveau.

De l'autre côté, nous avons un PointMateriel.

Entre deux, vous êtes libres de créer autant de degrés d'abstraction intermédiaires qui vous semblent pertinents (p.ex. la notion général d'objet physique comme ci-dessous, qui serait plus qu'un simple « objet intégrable », mais pas aussi précis qu'un PointMateriel). Vous pourrez aussi réviser/enrichir votre conception plus tard, en suivant la même méthodologique que celle présentée ci-dessous.

L'idée est donc ici de représenter dans une classe ObjetMobile, le strict minimum pour pouvoir décrire un objet que l'on fait évoluer au moyen d'un intégrateur numérique.

Cette classe devra posséder au moins les membres suivants :

Vous doterez votre classe des constructeurs et des méthodes qui vous semblent adéquats (et du destructeur si nécessaire).

Vous associerez de plus à votre classe une surcharge de l'opérateur << permettant d'afficher des informations de base sur les objets mobiles (utile pour «déboguer» le programme). Vous êtes libres de faire cet affichage selon le format que vous souhaitez (voir un exemple plus bas).

Intégrateurs

La seconde partie nécessaire pour faire évoluer le système est un intégrateur numérique.

Un tel intégrateur utilise une équation différentielle (dans notre cas, celle-ci sera donnée par la « fonction d'évolution f » d'un objet; voir p. 4 du complément mathématique) et calcule, pour des paramètres reçus à un instant t, leur valeurs à un instant t+dt, où dt est un « pas de temps ».

Concrètement, un intégrateur aura donc une méthode (par exemple « integre() », ou « evolue() », « avance() », « deplace() », ...) qui recevra un « objet intégrable », un temps (t) et un « pas de temps » (dt) et qui fera évoluer cet objet d'un pas de temps.

Note : ce n'est pas de la responsabilité de l'intégrateur que de faire avancer le temps. [fin de note]

Implémentez une classe Integrateur représentant un intégrateur numérique quelconque.

[Question P6.1] Comment avez vous conçu votre classe Integrateur ?
Expliquez votre conception (attributs, interface, ...) dans votre fichier REPONSES.

Le plus simple des intégrateurs numériques (mais qui n'est pas très « stable », nous y reviendrons plus tard dans le projet) est l'intégrateur d'Euler-Cromer. Il calcule les nouvelles valeurs des paramètres de l'objet comme décrit dans les compléments mathématiques du projet.

Implémentez une classe IntegrateurEulerCromer.

[Question P6.2] Quelle est la relation entre les classes Integrateur et IntegrateurEulerCromer ?

Répondez à cette question dans votre fichier REPONSES.

Premier test simple

L'intégrateur étant un élément fondamental de notre système, je vous propose pour cet exercice de créer deux programmes de test progressifs, à commencer par testIntegrateur1.cc, test très simple avec un « PointMateriel » qui est simplement une masse en chute libre (trajectoire parabolique).

Notes :

Important! pour réaliser ce test, vous devrez certainement attendre plusieurs révisions proposée dans l'exercice suivant. Vous pouvez, soit effectivement les attendre et revenir ici une fois celles-ci effectuées, soit changer pour le moment un peu le prototype de votre méthode d'intégration pour faire tout de suite quelques tests, puis revenir plus tard pour remettre le bon prototype.

vous pouvez aussi vous répartir ici le travail ; il n'est pas nécessaire que ce soit celui qui fait la classe IntegrateurEulerCrommer qui écrive le code des tests.

Pour vérifier vos programmes, je vous conseille deux méthodes complémentaires (c.-à-d. faites les deux !) :

  1. vérifier localement, ponctuellement sur quelques valeurs exactes, comme celles données ci-dessous, que les résultats correspondent (aux erreurs de représentation près ; rappelez-vous votre cours ICC..., disons 1e-9 ici) ;

  2. vérifier globalement sur des cas connus que le comportement à long terme est cohérent. Par exemple dans ce cas présent, vous savez que la trajectoire doit être une parabole.

    Le plus simple pour cela est d'utiliser un outil de dessin externe, comme par exemple gnuplot, un programme qui permet de dessiner facilement des données. Pour ceux que cela intéresse, je détaille ci-dessous comment faire.

Commencez donc par produire un programme de test testIntegrateur1.cc dans lequel sont créés :

Intégrez ce point matériel sur plusieurs pas de temps consécutifs. Vous devriez trouver les résultats suivants :

0 0 1 # parametre
0 1 2 # vitesse 

========================
t = 0.01
0 0.01 1.01902 # parametre
0 1 1.9019 # vitesse 

========================
t = 0.02
0 0.02 1.03706 # parametre
0 1 1.8038 # vitesse 

Vous pouvez retrouver ces résultats sur plusieurs pas de temps dans le fichier fourni en suivant ce lien.

Pensez également à tester plusieurs cas : vitesse initiale nulle, uniquement vers le haut...

gnuplot [optionnel]

gnuplot est un programme (à lancer depuis la ligne de commande) de dessin de données et de fonctions. Pour dessiner des données, il faut d'abord les écrire dans un fichier. gnuplot lit des fichiers dont chaque ligne contient un point à dessiner, les coordonnées étant par colonnes. Par exemple (le caractère # indique des commentaires en gnuplot) :

# x y
2.2 4.4 # point 1
2.3 5.5 # point 2
1.3 3.3 # point 3
# etc..

Il vous faut donc tout d'abord créer un tel fichier. Il y a plein de façons de faire, mais pour votre projet j'en vois essentiellement deux :

Pour la première façon, il suffit de lancer votre programme dans la ligne de commande et d'utiliser « des petits programmes Unix » pour faire le travail. Par exemple avec la sortie de l'intégrateur donnée plus haut, on pourrait faire (dans un terminal) :

./testIntegrateur1 | grep '# parametre'

qui ne laissera plus sortir que les lignes contenant la chaîne « # parametre ».

NOTE : si je mets ces commandes sur une seule ligne, c'est pour que vous puissiez facilement les copier-coller à la souris : cliquez trois fois (clic droit) sur la ligne en question pour la sélectionner ; puis aller sur le terminal et cliquez 1 fois sur le clic du milieu (la roulette) pour faire la copie de la ligne sélectionnée. [fin de note]

Pour mettre ce résultat dans dans un fichier test.txt, il suffit alors de faire :

./testIntegrateur1 | grep '# parametre' > test.txt

C'est aussi simple que cela ! Avec ça, vous devriez avoir un fichier test.txt dans le répertoire courant, qui contient :

0 0 1 # parametre
0 0.01 1.01902 # parametre
0 0.02 1.03706 # parametre
0 0.03 1.05411 # parametre
0 0.04 1.07019 # parametre
0 0.05 1.08529 # parametre
0 0.06 1.0994 # parametre
0 0.07 1.11253 # parametre
0 0.08 1.12468 # parametre
0 0.09 1.13586 # parametre
0 0.1 1.14604 # parametre

Ce qui est au bon format pour gnuplot.

Si ce n'est pas le cas de vos programmes, en raison d'un affichage différent, je vous propose de :

Une fois que vous avez un tel fichier (bon pour gnuplot), il suffit de lancer la commande gnuplot dans le terminal, puis, dans gnuplot, de taper

plot "test.txt" u 2:3 w linesp 

Note :si vous souhaitez dessiner la courbe avec d'autres paires de coordonnées (lorsqu'il y en a plusieurs), vous pouvez changer les valeurs de l'option « u i:j » pour les préciser ; par exemple :

plot "test.txt" u 1:3 w linesp 

où le « u 1:3 » signifierait que l'on utilise la 1ère et la 3e colonne pour dessiner (ce qui n'est pas pertinent pour nous ici). Par défaut, gnuplot utilise les deux premières (c.-à-d. qu'il fait un « u 1:2 »). [fin de note]

Pour comparer vos données à une courbe connue, par exemple la parabole ici, vous pouvez faire (toujours dans gnuplot) :

plot "test.txt" u 2:3 w linesp, 1. + (2.-9.81*0.01/2.)*x - (9.81/2.)*x*x

qui vous donnera quelque chose comme cela :

[Figure : parabole + données]

(J'ai déplacé la légende avec la commande gnuplot : set key bottom left.)

Note : si nécessaire, vous pouvez aussi dessiner en 3D avec splot (toujours dans gnuplot) :

splot "test.txt" w linesp 

en cliquant sur l'image et bougeant la souris, vous pouvez changer le point de vue. [fin de note]

Vous pouvez bien sûr faire ce genre de dessins avec beaucoup beaucoup plus de points, ce qui permet d'avoir une vue globale de l'évolution du système.

Pour quitter gnuplot : simplement quit ou 'Control-D'.

Autres tests

Dans un second temps, une fois que vous aurez terminé toute la conception et les modifications du prochain exercices, je vous recommande de mettre à jour testIntegrateur1.cc suivant ces modifications et de revérifier que tout fonctionne bien.

Je vous encourage par ailleurs à écrire d'autres tests, p.ex. testIntegrateur2.cc avec d'autres situations, d'autres valeurs, peut être plusieurs points matériels évoluant en même temps (pour vérifier qu'il n'y a pas d'interférence entre leurs intégrations), etc.


[2*] Exercice P7 : forces et contraintes

Objets physiques

Après les ObjetMobile de l'exercice précédent, la seconde abstraction dont nous avons besoin sont des objets physiques. En effet, l'abstraction précédente (ObjetMobile) n'est en fait finalement qu'un objet, je dirais, « purement mathématique » : une solution d'une équation différentielle du second ordre.

Les objets physiques ont pour but de nous permettre de décrire les objets que vous rencontrerez dans vos exercices de Physique. Ils sont pour cela des ObjetMobile, mais ont en plus au minimum:

Il serait par ailleurs peut être utile d'avoir un attribut « dimension » représentant la dimension de l'espace physique dans lequel nous souhaitons faire évoluer l'objet. Attention ! cela n'est pas la dimension de l'espace d'état E: si je reprends l'exemple du wagonnet de «grand-huit» donné en annexe C du complément mathématique du projet, la dimension de son espace d'état est 1 mais la dimension de son espace physique est 3. La raison d'introduire ici un tel attribut est par exemple pour les exercices de Physique dans lesquels on décrit un objet physique restant dans un plan de dimension 2. Mais c'est optionnel.

Ces objets physiques auront par ailleurs au minimum comme méthodes:

Vous pouvez également ajouter à vos objets physiques toutes les grandeurs physiques qui vous semblent pertinentes à ce niveau d'abstraction (p.ex. est-ce que tout objet physique a une masse ?(ou est-ce une propriété plus particulière d'objets physiques plus particuliers?), une charge ? de l'énergie ? etc. Et à noter qu'il n'est pas nécessaire que ce soient des attributs... (pensez p.ex. à la notion de surface pour une forme géométrique abstraite quelconque).

Vous doterez votre classe des constructeurs et des méthodes supplémentaires qui vous semblent adéquates (et du destructeur si nécessaire).

Vous associerez de plus à votre classe une surcharge de l'opérateur << permettant d'afficher des informations de base sur les objets physiques.

Contraintes

Les contraintes sont une abstraction qui force un objet physique à évoluer sous contrainte, p.ex. rester sur un plan, être maintenu par une tige (pendule pesant ou pendule sphérique), etc.
Concrètement ces contraintes modifient les forces subies par les objets. Par exemple, la contrainte consistant à rester à la surface d'une sphère modifiera l'équation d'évolution simple sans contrainte 1/m Fext dans les équations données en annexe B.3, p.14 des compléments mathématiques du projet.

Définissez pour cela la classe Contrainte au minimum les trois méthode suivantes:

Contrainte libre

La plus simple des contraintes est celle qui ne contraint rien du tout. Créez pour cela une classe Libre (ou ContrainteLibre ou SansContrainte, ...) dont :

Note: il ne sera peut être (certainement?) pas nécessaire d'avoir un fichier Libre.cc, le fichier Libre.h pouvant certainement suffire pour un cas aussi simple.

Champs de forces

La dernière abstraction à réaliser est celle de « champ de forces », c.-à-d. mathématique une fonction qui à chaque point d'espace et chaque temps t associe un vecteur (une force). Pour nous, le « point d'espace » sera simplement donné comme la position d'un objet.

Définissez pour cela la classe ChampForces qui comprend (au moins) une méthode force() qui prend en paramètre un objet physique (qu'elle ne modifiera pas) et un temps t et qui retourne un vecteur (force subie par l'objet, hors contraintes, à ce moment là).

À noter que la GravitationConstante définie les semaines passées est un champs de forces. Traduisez ce fait dans votre conception.

[Question P7.1] Comment avez vous traduit le fait que la GravitationConstante est un champs de force ?

Répondez à cette question dans votre fichier REPONSES.

Révision des PointMateriel

Les points matériels de la semaine passée sont (doivent être) des objets physiques...

[Question P7.2] Comment cela doit-il se traduire dans votre projet ?

Répondez à cette question dans votre fichier REPONSES

Ce faisant (modifications nécessaires), vous risquez de dupliquer certaines informations. Ce qu'il faut, bien sûr, absolument éviter ! Il faut donc réviser cette classe.

[ Remarque : ce genre de problèmes (modifier la conception d'un code existant) est typique de l'évolution d'un logiciel. On appelle cela le refactoring (et il y a des livres entiers à ce sujet).
Ce n'est donc pas par erreur de conception du projet que je vous fait modifier votre code, mais bien pour
(1) voir l'introduction des nouveaux concepts vus en cours et leur importance, leurs implications ; et
(2) pratiquer ce type de révisions/modifications de code (refactoring).
Nous le ferrons encore quelques fois au fur et à mesure des nouveaux concepts. Si votre conception du projet est claire et cohérente, cela ne devrait pas poser plus de problème que de déplacer/remplacer quelques lignes de code.
]

Note : tout ce qui suit dans cette partie (« Révision des points matériels ») est en fait assez simple (déplacement de code, et peut être remplacement de quelque noms) et ne devrait pas prendre plus de 10-20 min en tout.

Le plus simple dans notre cas consiste simplement à supprimer les attributs et les méthodes que nous avons déjà mis ailleurs. En fait, c'est aussi un bon moyen de voir si l'on a fait une bonne conception: pour chaque attribut et chaque méthode il faut se demander à quel niveau d'abstraction il/elle appartient: est-ce une propriété propre aux points matériels ou est-ce quelque chose de plus abstrait ?

Au final, je pense qu'il ne reste plus grand chose dans vos points matériels. Mais c'est bien sûr à vous de voir/décider: vous êtes responsables de votre conception.

Pour finir, modifiez le Makefile pour établir le lien entre ces différents nouveaux fichiers et procéder aux modifications nécessaires.
Au final, lorsque votre binôme aura terminé les champs de forces, les contraintes et la contrainte Libre, modifiez testPointMateriel.cc en conséquence puis vérifiez qu'il compile et s'exécute encore correctement.

La chute des pommes

Pour finir et bien illustrer les différentes classes introduites cette semaine, je vous propose de coder votre premier exercice de Physique : quelle est la trajectoire d'une pomme de 0.1 kg tombant sur la Terre (rayon = 6371e3 m, masse = 5.972e24 kg), depuis une altitude de 10 m?

La Terre et la pomme seront considérées comme des points matériels. Au niveau des contraintes, les deux sont libres. Par contre, on introduit ici un nouveau champ de forces: la gravité newtonienne entre masses.

Commencez pour cela par définir une classe ForceCentrale qui est un champ de forces central, c.-à-d. défini par un point.

Dans notre cas, le point central de ce champ de forces sera donné par un objet physique dont la classe ForceCentrale aura une référence (comme attribut, donc).

Nous vous proposons également d'ajouter une méthode quadratique_inverse() non publique (private ou protected suivant votre choix) qui prend un autre objet et retourne le vecteur nul si cet autre objet est trop proche (précision numérique) du point central du champ de force, et sinon, le vecteur de norme l'inverse du carré des distances et de direction de l'autre objet vers le point central du champ de force.

Définissez ensuite une classe ChampNewtonien, qui est un champ de forces central dont la méthode force() retourne la force de gravité suivant la formule de Newton.
On veillera à ce que la dimension de cette force soit celle de l'objet reçu en paramètre (c.-à-d. la même dimension que celle choisie pour la représentation physique de cet objet).

Rappel : G, la constante universelle de gravitation, a pour valeur 6,674 3015 × 10−11 m3 kg−1 s−2.

Pour tester, créer un fichier testPomme.cc qui effectue la simulation décrite plus haut (une pomme de 0.1 kg tombant sur la Terre (rayon = 6371e3 m, masse = 5.972e24 kg), depuis une altitude de 10 m).

Vous pouvez retrouver les résultats sur plusieurs pas de temps (avec dt=1e-3) dans les fichiers suivants :


Dernière mise à jour le 7 février 2025
Last modified: Fri Feb 7, 2025