Programmation pour les sciences physiques

Programmation pour les sciences physiques

Quel langage informatique choisir pour programmer en sciences physiques?

Vaste question qui amène beaucoup de réponses! Tout dépend en fait de l'objectif recherché. Pour ma part, après avoir utilisé beaucoup de langages informatiques (Basic, Pascal, Fortran, IDL, Python, Java...), j'ai découvert que le duo HTML 5/Javascript répondait assez bien à mes besoins pour réaliser les petites animations de ce site:
_ Gratuité!
_ Aucune interface dédiée à installer
_ Exécution du code sur n'importe quel système d'exploitation
_ Syntaxe pas trop obscure!
_ Facilité des représentations/sorties graphiques
_ Facilité pour trouver des ressources (en français!) du langage sur le net.
Un simple traitement de texte suffit pour écrire du code HTML et Javascript. J'utilise cependant Notepad++, qui a l'avantage d'offrir la coloration syntaxique du code (les instructions du langage apparaissent en couleur) et l'exécution directe dans n'importe quel navigateur. Le code reste accessible par un simple clic droit sur la page web qui l'exécute. La console du navigateur permet également de "débugger" le code et d'afficher toutes les variables (clic droit puis "inspecter" avec le navigateur Chrome ou "examiner l'élément" avec le navigateur Firefox).
Pour télécharger notepad++, c'est par ce lien
Le but de cette page est donc d'exposer les rudiments de ces langages pour programmer. Rappelons qu'il est toujours nécessaire d'écrire au prélable son programme "en clair" sur papier (ou traitement de texte) puis de le "traduire" dans le langage choisi.

Pour une consultation plus pratique, j'ai rassemblé l'ensemble de cette page dans un fichier texte (OpenOffice).

Pour commencer: la structure minimale d'une page web

Voici un exemple minimal de page dont on peut récupérer le code par un clic droit sur la page.
Le document doit être enregistré avec l'extension .html pour être lu par les navigateurs.

Les instructions ou balises pour ce document:
<html> : indique le début d'une page HTML.
<head> : indique le début de l'entête de la page.
<title>Titre de la page</title>: qui s'affiche dans l'onglet du navigateur (mais pas dans la page!).
<font size="3" face="arial" color="yellow"> qui indique respectivement la taille, la police de caractère et sa couleur.
<meta charset="utf-8"> qui permet de coder l'ensemble des caractères (accents, cédille...)
<body style="background:silver"> qui colore le fond de la page (ici en gris)
</head> : marque la fin de l'entête de la page
<body> : indique le début du corps de la page
</body> : marque la fin du corps de la page
</html> : marque la fin d'une page HTML
Il est possible d'ajouter une image en fond de page avec:
<body background="image_fond.jpg">
Il faut indiquer le chemin vers votre image de fond si elle n'est pas dans le même dossier que la page.
Si celle-ci se trouve dans le dossier images, on écrira "images/image_fond.jpg". Les navigateurs acceptent les formats courants d'image: gif, png, bmp...
Attention à la taille de votre image! Une image trop "volumineuse" (en Mo) peut ralentir le chargement de la page.

On peut ajouter des commentaires dans le code qui ne seront pas interprétés par le navigateur: <!-- ceci est un commentaire-->

Pour ajouter un lien vers une autre page: <a href= dossier1/la_page_en_lien.html > Lien vers la page </a>
Pour ajouter un lien vers un site web: <a href= http://le_site_en_lien.org > Lien vers le site </a>

Quelques instructions supplémentaires:

Passer à la ligne: <br> A noter que les puristes du HTML déconseillent cette balise pour lui préférer celle des paragraphes (voir plus bas). Elle est cependant bien pratique!

Les titres de page ou de paragraphe:
<h1>Titre de niveau 1</h1>
<h2>Titre de niveau 2</h2>
<h3>Titre de niveau 3</h3>
...
On pourra ajouter à l'intérieur de chacune de ces balises des instructions d'alignement et de couleur de police...
Exemple: <h1 align="center" style="color: yellow">Un titre de niveau 1 centré de couleur jaune</h1>
Pour changer la police de caractère du titre, insérer le titre entre les balises <font face="Nom de la police"> et </font>

Faire une tabulation (retrait du bord) du texte: <dd> au début du texte et </dd> à la fin.

Définir un paragraphe: <p> au début du texte et </p> à la fin.

Modifier ponctuellement la couleur et la taille du texte: <font size=+3 color="darkviolet"> au début du texte et </font> à la fin.
Le code des couleurs est consultable sur cette page.

Mettre en caractère gras: <b> au début du texte et </b> à la fin.

Mettre en italique: <i> au début du texte et </i> à la fin.

Souligner: <u> au début du texte et </u> à la fin.

Mettre en indice: <sub> au début du texte et </sub> à la fin.

Mettre en exposant: <sup> au début du texte et </sup> à la fin.

Caractères spéciaux: On trouvera comment coder ces caractères (alphabet grec, symboles mathématiques...) sur sur cette page Wikipédia.
Pour des notations ou formules mathématiques, les méthodes sont hélas moins directes. Après des recherches intensives, j'ai trouvé que le passage par la librairie Mathjax offre une méthode assez économe en moyens pour écrire des formules. Elle a cependant deux inconvénients: faire appel à une librairie extérieure (il faut donc être connecté au net pour que les formules s'affichent) et d'afficher les formules dans une seule police de caractères (je n'ai pas encore trouvé comment la changer).
Il faut insérer la ligne suivante dans l'en-tête de la page (ouverte par la balise </head>):
< script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS_CHTML'> </script>
La formule elle-même va s'écrire là où l'on souhaite dans la page en language TeX, bien connu des scientifiques. La formule s'écrira entre les caractères \ ( et \ ).
Attention, pas d'espace entre les deux caractères antislash \ et parenthèse ouvrante ( ou fermante ) ! Ces deux caractères ne figurent pas dans l'expression ci-dessous car le navigateur les aurait interprété donc fait disparaître.
Un exemple avec l'expression de la période T0 d'un pendule simple le longueur l: T_{0} = 2\pi \sqrt{\frac{l}{g}} Cela donne:
\( T_{0} = 2 \pi \sqrt{\frac{l}{g}} \)

L'expression sous la racine carrée n'étant pas de la même taille que T0, on ajoute \Large devant \sqrt : T_{0} = \Large\sqrt{\frac{l}{g}}. On obtient alors:
\( T_{0} = 2 \pi \Large \sqrt{\frac{l}{g}} \)

Pour d'autres éléments de syntaxe TeX, voir sur cette page Wikipédia.

Pour tracer un tableau:
<table border="2" align="center">: définit le tableau, l'épaisseur du cadre et sa position dans la page (ici centrée).
<tr> <td> Cellule 1 </td> <td> Cellule 2 </td> </tr>
<tr> <td> Cellule 3 </td> <td> Cellule 4 </td> </tr>
<tr> <td colspan="2"> Cellule 5 qui occupe toute la ligne 3 du tableau </td> </tr>
</table> : ferme le tableau
Résultat:
Cellule 1 Cellule 2
Cellule 3 Cellule 4
Cellule 5 qui occupe toute la ligne 3 du tableau

Il est possible de mettre des images (ou des vidéos) dans les cellules d'un tableau (voir ci-dessous). Cela permet de disposer du texte à côté des images ou des vidéos.

Insérer une image: < img src="images/mon_image.jpg" align=middle width="300" height="200">
L'attribut align permet de positionner l'image par rapport au texte (ici au milieu). Les attributs width et height donnent respectivement la largeur et la hauteur de l'image.
Les grandes images doivent souvent être réduites pour ne pas occuper trop de place sur la page. Utiliser un logiciel de traitement d'images pour déterminer sa largeur et sa hauteur puis diviser ces valeurs par le même nombre. Indiquer ces valeurs pour les mots clés width et height précédents.
Si l'image doit être montrée dans ses dimensions originales, il suffit d'ajouter un lien vers une page où cette image sera visible sans réduction de taille.

Insérer une vidéo: Voir sur cette page et faire un clic droit pour accéder au code. Il est nécessaire de convertir la vidéo en plusieurs formats différents pour être certain qu'elle soit lisible par tous les navigateurs.

Pour dessiner et animer: la balise canvas
<canvas id="dessin" width="1000" height="600"> : définit un rectangle de 1000 pixels de large sur 600 pixels de haut dans lequel on va pouvoir desssiner.
</canvas> : ferme la balise
Le dessin s'effectue avec des instructions en javascript une fois l'espace de travail défini avec canvas.

Pour entrer des valeurs dans un programme: les champs de saisie
Un champ de saisie va permettre à l'utilisateur d'entrer les valeurs des grandeurs qu'il souhaite que le programme utilise. S'il y a plusieurs champs de saisie à représenter, on peut les insérer dans un tableau suivant la syntaxe ci-dessous:
<form method="post" action="" name="SaisieValeurs">
  <table>
    <tr>
      <th>Grandeur 1:</th>
      <td><input type="text" name="grandeur1" value="10"></td>
    </tr>
    <tr>
      <th>Grandeur 2:</th>
      <td><input type="text" name="grandeur2" value="1.23E-11"></td>
    </tr>
    ...
</table>

Les nombres indiqués entre guillements après le mot clé value sont des valeurs par défaut qui apparaitront dans le champ mais que l'utilisateur peut changer en les effaçant. Rappelons qu'un nombre en notation scientifique tel que 1,23x10-25 s'écrit 1.23E-25 dans n'importe quel (ou presque!) language informatique.
Pour que le programme (en javascript) puisse récupérer les grandeurs entrées par l'utilisateur:
var grandeur1 = document.SaisieValeurs.grandeur1.value; Attention: cette instruction est à placer dans la partie javascript de la page web!

Pour une présentation de page plus élaborée: les feuilles de style (CSS)

Le lien vers cette page propose un aperçu de modification de l'aspect de vos pages web.

Premiers pas de dessin avec Javascript

Les instructions en javascript s'écrivent après la balise <script> puis une fois celles-ci écrites, on referme la balise avec </script>

Attention, les instructions javascript doivent se terminer par un point virgule.

L'instruction suivante définit une variable appelée monCanvas permettant d'accéder à l'espace nommé "dessin" créé lors de l'ouverture de la balise canvas.
var monCanvas = document.getElementById('dessin');
La ligne suivante permet d'indiquer qu'on travaille en 2 dimensions:
var ctx = monCanvas.getContext('2d');

Les coordonnées de l'espace de dessin

Les coordonnées de l'espace de dessin ont pour origine le coin supérieur gauche. Ce point a donc pour coordonnées (0,0).
L'abscisse x augmente vers la droite et l'ordonnée y augmente vers le bas.

Tracer une zone de dessin rectangulaire

ctx.fillRect(0,0,1000,600);. Les deux premiers nombres sont les coordonnées du coin supérieur gauche du rectangle et les deux derniers, la largeur et la hauteur du rectangle.
L'instruction ci-dessous permet de colorer le rectangle:
ctx.fillStyle = "yellow"; indique la couleur de remplissage des figures qui seront dessinées (ici en jaune). Cette instruction est à placer avant la précédente pour obtenir le remplissage de la couleur désirée.
Pour un simple cadre rectangulaire:
ctx.lineWidth = 5; définit l'épaisseur du cadre,
ctx.strokRect(0,0,1000,600); trace le cadre rectangulaire.

Insérer une image (dans la zone de dessin)

var monCanvas1 = document.getElementById('dessin');
var ctx1 = monCanvas1.getContext('2d');
var mon_image = new Image();
mon_image.src = "images/mon_image"; : emplacement de l'image à insérer.
mon_image.onload = function() {
ctx1.drawImage(this,0,0,200,100); image de 200 par 100 pixels positionnée en haut à gauche de l'espace de dessin.
}

Tracer un trait

ctx.lineWidth = 5; définit l'épaisseur du trait.
ctx.strokeStyle ="red"; définit la couleur du trait.
ctx.beginPath(); commence le tracé.
ctx.movTo(10,10); le trait part du point de coordonnées (10,10).
ctx.lineTo(10,150); le trait arrive au point de coordonnées (10,100).
ctx.stroke();
Pour tracer une figure fermée par une succession de traits, on termine par l'instruction ctx.closePath(); qui trace un trait entre le point de départ et le point d'arrivée.

Tracer un cercle ou un arc de cercle

ctx.lineWidth = 4;
ctx.strokeStyle ="green";
ctx.beginPath();
arc(x,y,rayon,angleDépart,angleFin);
ctx.stroke();
ctx.closePath();
x et y sont les coordonnées du centre du cercle. Pour un cercle, remplacer angleDépart par 0 et angleFin par 2*Math.PI.
Pour un arc de cercle, donner les valeurs d'angle de départ et de fin en radian ou écrire (Math.PI/180)*angle(en degré).

Courbes de Bézier

ctx.lineWidth = 4;
ctx.strokeStyle ="green";
ctx.beginPath();
ctx.movTo(10,30); point de départ de la courbe.
ctx.bezierCurveTo(x1,y1,x2,y2,x3,y3); en argument, les coordonnées des 3 points qui définissent la courbe.
ctx.stroke();
ctx.closePath();

Ecrire dans la zone de dessin

ctx.font = "14pt arial"; indique la taille et la police de caractère.
ctx.fillText("Mon texte",x,y); x et y les coordonnées du coin inférieur gauche du texte.

Pour aller plus loin, je recommande ce site

Premiers pas de programmation avec Javascript

Les commentaires
Plus encore que pour HTML, il est indispensable de commenter son programme! Afin de se rappeller l'objectif des différentes opérations lorsqu'on s'y replonge après plusieurs mois et permettre aux autres utilisateurs de le comprendre. Rien n'est plus pénible que de devoir comprendre un programme sans commentaires écrit par quelqu'un qu'on ne peut pas interroger sur son travail!
Un commentaire sur une seule ligne est précédé d'un double "slash": // ceci est un commentaire monoligne.
Un commentaire sur plusieurs lignes est précédé de /* et se termine par */

Les variables
Déclaration d'une variable: var ma_variable;
Déclaration d'une constante: const ma_constante = 3.14; (Un point à la place de la virgule pour les décimaux)
Pour les puissances de 10: 6.67E-11
Déclaration d'un tableau à une dimension (un vecteur) de n éléments: var mon_vecteur = new Array(n);
Le premier élément de ce vecteur est mon_vecteur[0] et le dernier est mon_vecteur[n-1] (indice de position entre crochets et non entre parenthèses).
Pour s'assurer du format d'une variable ou d'une constante:
var entier = ParseInt(3.14): entier vaut 3
var réel = ParseFloat(3.14): réel vaut 3.14
Pour obtenir la valeur d'une variable:
console.log(ma_variable); la valeur est affichée dans la console du navigateur accessible par un clic droit sur la page puis sélectionner inspecter. S'il y a plusieurs variables à afficher, on peut faire précéder l'instruction précédente par console.log("ma_variable:"); pour s'y retrouver.

Les fonctions mathématiques
Pas de programmation en physique sans fonctions mathématiques! Voici les plus courantes:

Math.abs(a) prend la valeur absolue de a
Math.round(a) prend l'entier le plus proche de a
Math.sqrt(a) prend la racine carrée de a
Math.ln(a) prend le logarithme népérien de a
Math.log(a) prend le logarithme décimal de a
Math.exp(a) prend l'exponentielle de a
Math.pow(a,b) élève a à la puissance b
Math.cos(a) prend le cosinus de a (a en radian, valable pour toutes les fonctions trigo suivantes)
Math.sin(a) prend le sinus de a
Math.tan(a) prend la tangente de a
Math.asin(a) prend l'inverse du sinus de a (donne un angle en radians)
Math.acos(a) prend l'inverse du cosinus de a
Math.atan(a) prend l'inverse de la tangente de a

La boucle de compteur "for"
Cette boucle permet d'exécuter une ou plusieurs instructions autant de fois que la condition remplie par le compteur est vérifiée.
for (var i = 0; i < n; i++ ) {
instruction 1;
instruction 2;
....
}
Le compteur i (entier) peut être défini avant la boucle, dans ce cas on enlève var devant i. L'entier n doit être défini avant la boucle.
i++ indique que le compteur est augmenté d'une unité à chaque itération.
Pour arrêter la boucle si une condition est vérifiée:
if (condition vraie)
break;

La condition "si... sinon..." (if... else...)
Cette instruction permet d'exécuter une ou plusieurs instructions si une condition est vérifiée. Dans le cas contraire, une autre instruction peut être exécutée à la place:
if (condition vraie) {
instruction 1;
instruction 2;
....
}
else {
instruction 3;
instruction 4;
...
}

La condition "tant que" (while)
Tant qu'une condition est vérifiée, le programme exécute une ou des instructions. Il s'arête lorsqu'elle ne l'est plus.
while (condition vraie) {
instruction 1;
instruction 2;
....
}

Les fonctions
Lorsqu'un programme doit réaliser un ensemble d'instructions à plusieurs reprises mais avec des variables différentes, il est souhaitable de regrouper ces instructions dans une fonction qui pourra être appelée à tout moment dans le programme.
function nom_de_la_fonction(arguments) {
instruction 1;
instruction 2;
....
}
Les arguments contiennent les variables d'entrée de la fonction.
L'appel à la fonction dans le programme se fait avec:
nom_de_la_fonction(argument1, argument2,...);

L'utilisation d'une fonction se justifie également pour récupérer les grandeurs entrées par l'utilisateur dans les champs de saisie définis dans la partie HTML du programme. Dans ce cas, on crée une fonction qu'on peut appeler Calcul par exemple et dont l'argument est SaisieValeurs, vu précédemment dans la partie création de champ de saisie en HTML:
function Calcul(SaisieValeurs);
Après la déclaration de cette fonction, on ajoute un bouton d'éxécution de la fonction Calcul dans la partie HTML de la page:
<input type="button" value="Entrée" onClick="Calcul(SaisieValeurs)">
Un clic de souris sur ce bouton Entrée déclenche l'exécution de la fonction Calcul et la saisie des valeurs entrées par l'utilisateur dans les champs de saisie.

Application 1: Simuler le mouvement d'un objet ponctuel soumis à une (des) force(s) constante(s)

Un objet ponctuel de masse m soumis à une force F constante décrit un mouvement dont la trajectoire s'obtient à partir de la 2ème loi de Newton: m.a = F, avec a, le vecteur accélération de l'objet.
Le vecteur accélération étant égal à la dérivée du vecteur vitesse v par rapport au temps t (a = dv/dt), on a alors: v = a.t = (F/m).t (si a est constant, ce qui est le cas si la force appliquée est constante au cours du temps).
Si x et y sont l'abscisse et l'ordonnée de l'objet, Fx et Fy les coordonnées de la force F, vx0 et vy0 les coordonnées du vecteur vitesse v0 au point de départ M0 de coordonnées x0 et y0, on a:
x = (Fx/2m).t² + vx0.t + x0
y = (Fy/2m).t² + vy0.t + y0

Exemple: pour un mouvement dans le champ de pesanteur g (uniforme) dirigé vers le sol, l'axe des ordonnées étant orienté vers le haut
Fx = 0
Fy = -mg
On a alors:
x = vx0.t + x0
y = (-g/2).t² + vy0.t + y0
Si on appelle α l'angle entre l'axe horizontal Ox et le vecteur vitesse v0, on peut écrire les deux équations précédentes sous la forme:
x = (v0cosα).t + x0
y = (-g/2).t² + (v0sinα).t + y0

Un programme qui représente la trajectoire d'un objet soumis au champ de pesanteur comporte les étapes suivantes:
_Définition de l'espace de dessin avec la balise canvas et représentation des axes Ox et Oy;
_Création de champs de saisie pour la position de départ (x0,y0) et de la vitesse de départ v0 de l'objet;
_Définition de la fonction Calcul qui récupère les valeurs des champs de saisie, effectue le calcul de la trajectoire point par point et la trace sur l'espace de dessin.
_Ecriture sur la page des coordonnées du point d'impact sur le sol et la vitesse en ce point le cas échéant.

Voici le résultat sur ce lien (un clic droit permet d'accéder au code de la page).
Exercice à partir de ce programme: ajouter un bouton pour changer l'intensité de la pesanteur.


Application 2: Simuler le mouvement d'un objet ponctuel soumis à une (des) force(s) non constante(s)

Dans ce cas, on effectue une approximation en considérant ces forces constantes pendant la durée Δt du pas de calcul (durée petite devant la durée totale du mouvement). La valeur des forces est donc (re)calculée à chaque itération du programme (méthode d'Euler). Plus ce pas de calcul est petit devant la durée du mouvement, plus l'approximation sera fidèle mais le temps de calcul se ralonge.
L'algorithme est le suivant:
_Définition du point de départ M0 de coordonnées x0 et y0 et de la vitesse v0 en ce point de composantes vx0 et vy0.
_Définition de la durée du pas de calcul Δt.
_Calcul de la (des) force(s) F0 en ce point (de composantes F0x et F0y) et de l'accélération initiale a0 de coordonnées a0x = F0x/m et a0y = F0y/m.
_Définition d'une boucle for de i = 1 à n dans laquelle s'effectue les calculs suivants:
Calcul des composantes de la vitesse v[i] au point Mi, connaissant sa valeur v[i-1] au point Mi-1:
vx[i] = ax[i-1]*t + vx[i-1]
vy[i] = ay[i-1]*t + vy[i-1]
Calcul de la position du point Mi:
x[i] = vx[i]*t + x[i-1]
y[i] = vy[i]*t + y[i-1]
Calcul de la valeur de la force F[i] au point Mi et de l'accélération en ce point a[i] = F[i]/m.
Tracé du segment Mi-1Mi
Test de fin de boucle.

Ce type d'algorithme est utilisé dans trois simulations de la page principale (trajet Terre-Lune, rentrée atmosphérique et mouvement dans un champ électrique).