<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://www.meteo-blois.fr/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.meteo-blois.fr/" rel="alternate" type="text/html" hreflang="fr" /><updated>2026-07-17T20:48:20+02:00</updated><id>https://www.meteo-blois.fr/feed.xml</id><title type="html">Météo Blois</title><subtitle>Météo, informatique et autres choses.</subtitle><author><name>Nicolas Gasnier</name></author><entry><title type="html">Mini-grille N°1</title><link href="https://www.meteo-blois.fr/2026/07/16/mini-grid-1/" rel="alternate" type="text/html" title="Mini-grille N°1" /><published>2026-07-16T00:00:00+02:00</published><updated>2026-07-16T00:00:00+02:00</updated><id>https://www.meteo-blois.fr/2026/07/16/mini-grille-n-1</id><content type="html" xml:base="https://www.meteo-blois.fr/2026/07/16/mini-grid-1/"><![CDATA[<p>Pendant la canicule, il fallait bien s’occuper… alors je me suis amusé à créer des grilles de mots fléchés.</p>

<p>Amusez-vous bien !</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="jeux" /><category term="mots fléchés" /><summary type="html"><![CDATA[Pendant la canicule, il fallait bien s’occuper… alors je me suis amusé à créer des grilles de mots fléchés.]]></summary></entry><entry><title type="html">A propos de la condition aux limites</title><link href="https://www.meteo-blois.fr/2018/09/01/partie5/" rel="alternate" type="text/html" title="A propos de la condition aux limites" /><published>2018-09-01T00:00:00+02:00</published><updated>2018-09-01T00:00:00+02:00</updated><id>https://www.meteo-blois.fr/2018/09/01/partie5</id><content type="html" xml:base="https://www.meteo-blois.fr/2018/09/01/partie5/"><![CDATA[<p>Dans le tutoriel sur le modèle barotrope, que nous avons implémenté sur une aire limitée, on a discuté de la manière de définir les conditions aux bords du domaine et de coupler avec un modèle global. J’ai expliqué rapidement la technique consistant à créer une zone de transition avec un coefficient alpha décroissant qui permet de faire un rappel  progressif vers les valeurs que l’on souhaite imposer.</p>

<p><img src="/wp-content/uploads/2018/03/zone-de-relaxation.png" alt="Zone de relaxation" /></p>

<p>Au début, j’ai été peu regardant sur la largeur de la zone de transition. En partant sur une décroissance linéaire et une zone de transition de 4 points de grille, j’ai fin par m’apercevoir que c’était peu optimal. Rapidement, on remarque une discontinuité qui apparaît entre la zone de relaxation et le bord de la zone de simulation, qui créé des valeurs de vent et de tourbillon élevées. Sur des simulations assez courtes, cela ne pose pas de problème majeur, mais si l’on prolonge, cela peut compromettre la stabilité ou le réalisme du modèle. Voici le résultat au bout de 72 heures de simulation, on voit bien la ligne de vent fort en bordure de zone :</p>

<p><img src="/wp-content/uploads/2018/08/zone-4-lineaire.png" alt="Zone de relaxation de 4, décroissance linéaire" /></p>

<p>.</p>

<p>Il s’avère que ce problème de conditions aux limites a été étudié [1] : on apprend dans les articles scientifiques que de mauvaises conditions peuvent générer du bruit, en raison du rebond d’ondes sur les bords notamment. Il faut donc faire en sorte que la zone de relaxation se comporte comme un ressort qui amortit le flux qui rentre et sort du domaine (damping), tout en assurant la transition vers les valeurs imposées aux bords. La qualité du damping est impactée par la taille de la zone et par la manière dont le paramètre alpha décroit. Une zone de 6 à 8 mailles est optimale, en dessous c’est pas assez, au-delà ça n’apporte rien. Une décroissance linéaire du paramètre alpha donne des résultats satisfaisants, mais une décroissance non linéaire est bien meilleure, en utilisant une fonction du type arc tangente. Quelle que soit la fonction utilisée, une zone de moins de 6 mailles produit l’effet de discontinuité illustré. Après modification, il suffit de constater la différence avec l’ancienne méthode, la discontinuité a disparu et la transition est plus douce :</p>

<p><img src="/wp-content/uploads/2018/09/zone-8-atan.png" alt="Zone de relaxation de 8, fonction de décroissance arc tangente." /></p>

<p>[1] Kallberg, 1977. Test of a lateral boundary relaxation scheme in a barotropic model.</p>

<h1 id="test-de-la-condition-aux-limites">Test de la condition aux limites</h1>

<p>Nous avons déjà parlé de modèles à aire limitée, et précisé <a href="2018/09/a-propos-de-la-condition-aux-limites/">comment spécifier la condition limite latérale du domaine</a>. Je vous propose de refaire un test fait par Kallberg afin d’illustrer les effets induits par une spécification rigide des données à la frontière, et l’intérêt d’une zone de relaxation.</p>

<p>Sur un domaine à aire limitée, qui est en fait un domaine ouvert, il faudrait idéalement laisser entrer et sortir les ondes librement. Une telle condition aux limites est assez complexe à mettre en oeuvre, car elle nécessite d’identifier les flux entrants et sortants pour les traiter différemment. C’est pourquoi il est plus simple de fournir les données aux frontières - on appelle cela la sur-spécification. Cela a malheureusement un effet délétère sur la simulation, en introduisant un bruit important qui grandit avec le temps. Cela limite la durée pratique du calcul sur aire limitée.</p>

<h2 id="le-test">Le test</h2>

<p>Le test fait par Kallberg consiste à créer un domaine avec un géopotentiel constant en tout point, et un vent nul. Sur les bords, ces valeurs restent donc imposées à ces valeurs de départ. Au centre, on créé une perturbation de géopotentiel en forme de bosse. On fait la simulation sans zone de relaxation, plus refaite avec. Le pas de temps est de 10s et la grille fait 40x40 cases de résolution 10km. Les résultats sont présentés ci-dessous, tout d’abord sans zone de relaxation.</p>

<p>Simulation de la perturbation de géopotentiel sans zone de relaxation. Chiffres x1000 mètres.</p>

<p>On voit que l’onde se propage vers l’extérieur, avant d’être réfléchie vers l’intérieur du domaine. Elle ne réussit pas vraiment à s’atténuer, même après 4h. Voyons ce qu’il se passe quand on a une zone de relaxation de 6 cases de large.</p>

<p>Même simulation avec la zone de relaxation.</p>

<p>Cette fois, l’onde se propage puis se retrouve amortie et absorbée sans aucune réflexion. L’onde disparaît quasi -complètement au bout d’un peu plus d’une heure de simulation.</p>

<h2 id="conclusion">Conclusion</h2>

<p>On voit cette donc fois l’intérêt d’une bonne formulation de la condition aux limites pour éviter de polluer la simulation avec un bruit inutile. La stabilité du calcul s’en trouve donc améliorée sur des simulations de plus long terme.</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="modèle météo" /><category term="modélisation" /><category term="PIFO" /><category term="Javascript" /><summary type="html"><![CDATA[Dans le tutoriel sur le modèle barotrope, que nous avons implémenté sur une aire limitée, on a discuté de la manière de définir les conditions aux bords du domaine et de coupler avec un modèle global. J’ai expliqué rapidement la technique consistant à créer une zone de transition avec un coefficient alpha décroissant qui permet de faire un rappel  progressif vers les valeurs que l’on souhaite imposer.]]></summary></entry><entry><title type="html">Grille C et premiers résultats</title><link href="https://www.meteo-blois.fr/2018/08/01/partie4/" rel="alternate" type="text/html" title="Grille C et premiers résultats" /><published>2018-08-01T00:00:00+02:00</published><updated>2018-08-01T00:00:00+02:00</updated><id>https://www.meteo-blois.fr/2018/08/01/partie4</id><content type="html" xml:base="https://www.meteo-blois.fr/2018/08/01/partie4/"><![CDATA[<p>Depuis le tutoriel sur le modèle barotrope, beaucoup de code a été écrit, et de nombreux tests ont été effectués. Un gros travail de refactoring a été effectué pour constituer un framework de développement et test pour expérimenter les variantes du modèle et les futures implémentations comme le modèle barocline. Mettons aujourd’hui le focus sur un perfectionnement du modèle barotrope : l’utilisation de la grille C. Voyons un peu de quoi il s’agit, puis nous discuterons des résultats obtenus.</p>

<h2 id="la-grille-c">La grille C</h2>

<p>Le modèle de notre série de tutoriels est implémenté en grille A, c’est la grille la plus simple : toutes les variables sont représentées sur les mêmes points. Mais le calcul sur cette grille présente un inconvénient, en créant des ondes parasites qu’il est indispensable de filtrer pour exploiter les résultats. Elles sont dûes au découplage des points de grille pairs avec les points de grille impairs, dûs à la discrétisation des dérivées. Les micro-erreurs de calcul finissent par se cumuler et causer deux solutions qui divergent, d’où la création d’ondes de longueur 2*dx. La grille C consiste à décaler la position des variables de vent U et V d’une demi-maille par rapport au géopotentiel. Il faut en tenir compte quand on initialise les données, afin d’interpoler correctement ces variables.</p>

<p><img src="/wp-content/uploads/2018/08/grille-a-et-c.png" alt="Grille A et C" title="Grille A et C" /></p>

<p>Disposition des variables sur la grille A et C</p>

<p>Ceci modifie la manière d’effectuer les calculs, puisque les valeurs des variables ne sont plus toutes définies aux points où l’on souhaite évaluer les dérivées. Il faut alors les reconstituer à partir des moyennes des points autour. Bien que cela fasse un léger surcroît de calcul, la méthode présente quelques avantages. Tout d’abord, l’arithmétique discrète correspondante revient à évaluer certains termes avec un ordre de précision plus grand : les différences centrales sont évaluées avec une distance de DX au lieu de 2*DX en grille A. D’autre part, le décalage des variables a pour effet d’éliminer le découplage à l’origine des ondes parasites. Le modèle en grille C n’a donc pas besoin d’être filtré. Enfin, de part les discrétisations employées, le modèle est bien moins sujet à l’aliasing, autre phénomène de création d’ondes parasites qui peut mener à l’instabilité du calcul. L’absence de filtrage compense largement le petit surcroît de calculs nécessaire pour chaque itération. Mais la méthode est plus contraignante sur le pas de temps, qui doit être réduit de moitié, ce qui est facilement compréhensible compte tenu de la réduction de l’intervalle pour les différences discrètes. Le gain en précision du schéma vaut malgré tout la peine, et il reste parfaitement exploitable.</p>

<h2 id="résultats">Résultats</h2>

<p>A des fins de tests, nous partons d’un scénario réel issu des données GFS du 22/06/2018 à 00h, sur un domaine Atlantique nord-Europe correspondant exactement aux cartes que nous allons tracer. La résolution spatiale est de un degré d’arc en latitude comme en longitude, ce qui fait une maille de l’ordre de 100km. La simulation se fera sur 96h avec un pas de temps de 90s. On historise les résultats toutes les 6h. Les tests seront faits avec le modèle barotrope en grille A non filtré, puis filtré, et enfin le modèle barotrope en grille C. Pour la grille A, on utilise le filtre de Schumann. On comparera les résultats obtenus avec les cartes issues du même run du modèle GFS. Place aux images à t=96h :</p>

<p><img src="/wp-content/uploads/2018/08/epp_prmsl_hgt500_96.png" alt="Modele barotrope en grille A non filtré." title="Modele barotrope en grille A non filtré." /></p>

<p>Modèle barotrope en grille A non filtré, t=96h.</p>

<p><img src="/wp-content/uploads/2018/08/epp_prmsl_hgt500_96-1.png" alt="Modele barotrope en grille A filtré." title="Modele barotrope en grille A filtré." /></p>

<p>Modèle barotrope en grille A filtré, t=96h. Oups…</p>

<p><img src="/wp-content/uploads/2018/08/epp_prmsl_hgt500_96-2.png" alt="Modèle barotrope en grille C" title="Modèle barotrope en grille C" /></p>

<p>Modèle barotrope en grille C, t=96h.</p>

<p>Premiers constats qualitatifs :</p>

<ul>
  <li>Le filtre de Schumann est très destructeur sur les structures. En faisant un lissage assez violent à chaque pas de temps, on se retrouve avec une simulation qui n’a plus rien de réaliste et où tout est plat… Il va donc falloir tester un schéma où le filtre est exécuté moins souvent, par exemple avant d’enregistrer l’historique, une fois toutes les 6h.</li>
  <li>Le modèle en grille A sans filtrage se montre assez bruité comme on peut le voir a l’aspect tremblant des isohypses sur la carte.</li>
  <li>Le modèle en grille C n’a pas de problème de bruit, les champs restent bien lisses.</li>
</ul>

<p>Allez on refait le test en grille A avec un filtrage toutes les 6h :</p>

<p><img src="/wp-content/uploads/2018/08/epp_prmsl_hgt500_96-3.png" alt="Modèle barotrope en grille A filtré toutes les 6h" title="Modèle barotrope en grille A filtré toutes les 6h" /></p>

<p>Modèle barotrope en grille A filtré toutes les 6h, t=96h</p>

<p>C’est mieux ! On constate que le bruitage a disparu, mais par rapport à la grille C il semble y avoir un peu de perte au niveau des structures les plus fines. Le centre de la dorsale anticyclonique est plus lissé, de même que le thalweg au sud-est qui est plus arrondi et moins marqué.  Du côté de la solution trouvée, on constate finalement assez peu de différence entre la grille A et la grille C - du moins si l’on n’abuse pas du filtre de Schumann. Quelques ajustements sont vraisemblablement nécessaires pour éviter que celui-ci n’impacte trop la simulation. Ce qui est intéressant maintenant, c’est de comparer à la réalité. Pour cela, il faudrait récupérer les données des réanalyses du NCEP et tracer les mêmes cartes pour faire ressortir les différences. N’ayant pas ces données sous la main, je me contente de comparer les résultats à la solution qu’a calculé GFS pour ce même run. GFS étant un modèle opérationnel parfaitement validé, la solution calculée reste pour moi suffisamment proche de la réalité à cette échéance. Notez bien que le barotrope ne prévoit que le géopotentiel 500hPa, les isobares de pression au niveau de la mer ne sont donc pas comparables.</p>

<p><img src="/wp-content/uploads/2018/08/gfs_prmsl_hgt500_96.png" alt="La solution obtenue par GFS" title="La solution obtenue par GFS" /></p>

<p>La solution obtenue par GFS, t=96h.</p>

<p>On constate quelques différences. La position de la goutte froide au large de la péninsule ibérique n’est pas exactement au même endroit, ainsi que la dépression à l’est de la Scandinavie. En Méditerranée, le modèle ne creuse pas suffisamment la goutte froide. Sur l’Islande et le Groenland, on voit d’importantes différences au niveau du système dépressionnaire. Nous avons toutefois une solution qui ressemble assez bien à la solution GFS, car les valeurs de géopotentiel pour l’anticyclone sont quand même très proches. On garde bien une structure en oméga, et l’on constate bien une progression d’ouest en est du système dépressionnaire nord-atlantique, bien que celle-ci ne soit pas identique avec GFS. Étant en régime de blocage, les différences sont contenues. En effet, il y a fort à parier que les différences auraient été plus importantes en cas de régime zonal davantage perturbé. N’oublions pas que le modèle barotrope est une simplification à l’extrême des équations de l’atmosphère, qui ne tient pas compte de la température, et qui plus est, sans aucun phénomène physique pris en compte. La simulation est donc complètement inertielle : pas de frottement, pas d’apport solaire, pas d’évaporation… GFS, lui, tient compte de tous ces effets qui modifient l’énergie du système. D’autres différences peuvent être expliquées : au niveau des bords. On le voit bien à l’écrasement de la zone de bas géopotentiel sur le Groenland. Notre modèle étant à aire limitée, il y a une zone de transition qui fait un effet de “rappel” (damping) vers un forçage imposé par le modèle GFS. Nous avons ici choisi de prendre les bords constants tout au long de la simulation, ce qui d’une part dévie de la solution GFS, et d’autre part, finit inévitablement par créer une erreur vers l’intérieur du domaine.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Notre test n’est en aucun cas un vrai test d’évaluation de la qualité de simulation. On se contente de voir si les cartes de géopotentiel ressemblent à la réalité. Une vraie évaluation avec calcul de l’écart quadratique moyen serait bien plus scientifique, mais on remettra ça à plus tard. En tout cas, les tests effectués montrent que le modèle fonctionne et donne un résultat physiquement plausible. C’est très encourageant pour la suite du projet ! Côté temps d’exécution, je n’ai pas noté de gros écarts entre la version en grille A et la grille C, chaque pas de temps prends de l’ordre de 1-2ms sur ma machine avec Firefox. On peut quand même noter qu’au final la grille C prends le double de temps de calcul vu la contrainte supplémentaire sur le pas de temps pour assurer la stabilité numérique. Oh j’oubliais… J’ai finalement baptisé ce projet d’expérimentations sur les modèles du nom de code PIFO (Projet Informatique à Formules Ouvertes). Un petit clin d’œil aux acronymes à la française, qui représente un peu l’état d’esprit du projet. On fait ça pour s’amuser, on verra bien le résultat !</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="modèle météo" /><category term="modélisation" /><category term="PIFO" /><category term="Javascript" /><summary type="html"><![CDATA[Depuis le tutoriel sur le modèle barotrope, beaucoup de code a été écrit, et de nombreux tests ont été effectués. Un gros travail de refactoring a été effectué pour constituer un framework de développement et test pour expérimenter les variantes du modèle et les futures implémentations comme le modèle barocline. Mettons aujourd’hui le focus sur un perfectionnement du modèle barotrope : l’utilisation de la grille C. Voyons un peu de quoi il s’agit, puis nous discuterons des résultats obtenus.]]></summary></entry><entry><title type="html">Un modèle météo simplifié en JavaScript – Partie 3 : Finalisation et améliorations</title><link href="https://www.meteo-blois.fr/2018/03/02/partie3/" rel="alternate" type="text/html" title="Un modèle météo simplifié en JavaScript – Partie 3 : Finalisation et améliorations" /><published>2018-03-02T00:00:00+01:00</published><updated>2018-03-02T00:00:00+01:00</updated><id>https://www.meteo-blois.fr/2018/03/02/partie3</id><content type="html" xml:base="https://www.meteo-blois.fr/2018/03/02/partie3/"><![CDATA[<p>Voici le dernier article de cette série concernant l’implémentation du modèle météo barotrope, ou modèle en eau peu profonde, en JavaScript. Il nous restait à aborder quelques problématiques et concepts afin d’arriver à une version pleinement fonctionnelle. Nous allons aujourd’hui finaliser l’application.</p>

<h2 id="filtrage">Filtrage</h2>

<p>Si on lance le modèle tel que programmé dans l’épisode précédent, la simulation fonctionne, mais on s’aperçoit rapidement que les champs deviennent très bruités. Et si on laisse tourner la simulation plus longtemps, on voit apparaître des sortes de vagues de 2 mailles de large, voire des zones où le vent devient localement très fort, et qui provoque un creusement ou une élévation brutale du géopotentiel. C’est un phénomène lié au traitement numérique des équations en grille A qui créé des ondes stationnaires. Ceci, cumulé aux défauts du traitement numérique des équations, peut rendre la simulation instable et créer des infinis si on laisse tourner le modèle suffisamment longtemps. De toute façon ceci rend les champs assez inexploitables.</p>

<p><img src="/wp-content/uploads/2018/03/effet-sans-filtrage.png" alt="Simulation sans filtrage" title="Simulation sans filtrage" /></p>

<p>Apparitions d’ondes et d’instabilités locales au bout de 18h de simulation environ.</p>

<p>Il existe une solution pour éliminer ce problème : il faut filtrer les champs. On remarque que ces ondes “parasites” ont une longueur d’onde de deux fois la taille de notre maille - ce qui est d’ailleurs démontrable mathématiquement. Il nous faut donc les supprimer à l’aide d’un filtre qui élimine correctement cette longueur d’onde sans trop altérer le reste. Nous utiliseront un filtre appelé filtre de Shuman qui est très efficace. Il s’agit d’une moyenne pondérée de 3 points de grille, appliquée en deux temps, horizontalement puis verticalement. Ce filtre est à appliquer après chaque itération de l’intégration sur chaque champ, donc dans les fonctions start() et step(). Le plus simple pour comprendre le fonctionnement est de regarder le code du filtre :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.filtreMoyenneX = function(a, v, res)
{
    for (var y=0;y&lt;this.height;y++)
    {
        var i = y\*this.width;
        res\[i\] = a\[i\];
        for(var x=1;x&lt;this.width-1;x++)
        {
            var i = x+y\*this.width;
            res\[i\] = a\[i\]\*(1-v)+(a\[i+1\]+a\[i-1\])\*v/2;
        }
        i = this.width-1+y\*this.width;
        res\[i\] = a\[i\];
    }
}
    
this.filtreMoyenneY = function(a, v, res)
{
    for (var x=0;x&lt;this.width;x++)
    {
        var i = x+this.width\*(this.height-1);
        res\[x\] = a\[x\];
        res\[i\] = a\[i\];
    }
    for (var y=1;y&lt;this.height-1;y++)
    {
        var i = y\*this.width;
        res\[i\] = a\[i\];
        for(var x=1;x&lt;this.width-1;x++)
        {
            var i = x+y\*this.width;
            res\[i\] = a\[i\]\*(1-v)+(a\[i+this.width\]+a\[i-this.width\])\*v/2;
        }
        i = this.width-1+y\*this.width;
        res\[i\] = a\[i\];
    }
}

    
this.filtre = function (a)
{
    var tmp = \[\];
    this.filtreMoyenneX(a, 0.5, tmp);
    this.filtreMoyenneX(tmp, -0.5, a);
    
    this.filtreMoyenneY(a, 0.5, tmp);
    this.filtreMoyenneY(tmp, 0.5, a);
}
</code></pre></div></div>

<p>Le filtrage a l’inconvénient de nécessiter un peu de calculs supplémentaires, mais cela reste gérable. Au niveau du résultat, on constate que cela lisse un peu les champs sans trop altérer les grandes structures. A la résolution où l’on travaille, on voit rapidement que les dorsales ou thalwegs un peu faibles vont se combler plus rapidement. Mais les problèmes d’instabilités locales sont réglés.</p>

<p><img src="/wp-content/uploads/2018/03/effet-avec-filtrage.png" alt="Simulation avec filtrage" title="Simulation avec filtrage" /></p>

<p>Avec filtrage, le problème est résolu mais les champs se trouvent beaucoup plus lissés.</p>

<h2 id="le-problème-des-conditions-aux-limites">Le problème des conditions aux limites</h2>

<p>Nous travaillons sur une aire limitée. Cela signifie qu’aux bord du domaine, nous ne pouvons pas faire évoluer les champs. On peut se contenter de fixer leurs valeurs, et considérer qu’elles n’évoluent pas au cours de la simulation, mais on limite de fait l’échéance de prévision que l’on peut atteindre. Il est souvent plus intéressant de coupler des modèles qui travaillent à aire limitée avec des modèles globaux, comme on fait pour calculer les modèles WRF ou AROME à partir des données de GFS et ARPEGE respectivement. La technique est très simple. On définit une zone de relaxation autour de l’aire de travail, qui fait un certain nombre de mailles de largeur. Cette zone sert de transition entre les données du modèle global et celles de notre modèle. On positionne dessus un coefficient alpha, qui vaut 1 sur le bord, et qui diminue progressivement pour atteindre zéro au centre. A la fin de chaque étape de calcul, on fait un mixage entre les valeurs calculées et les valeurs imposées à l’aide de ce coefficient, la résultante devenant les valeurs de nos champs. Un bout de code et une illustration valent mieux qu’un long discours.</p>

<p><img src="/wp-content/uploads/2018/03/zone-de-relaxation.png" alt="Couplage du domaine avec un modèle extérieur." title="Couplage du domaine avec un modèle extérieur." /></p>

<p>Couplage du domaine avec un modèle extérieur.</p>

<p>Dans la classe Atmosphere, on prévoit la méthode couple() qui fait ce travail de “mixage” :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.couple = function(x, c)
{
    for (var i=0;i&lt;this.height\*this.width;i++)
    {
        x\[i\] = (1-this.alpha\[i\])\*x\[i\] + this.alpha\[i\]\*c\[i\];
    }
}
</code></pre></div></div>

<p>A la fin de chaque étape de calcul on ajoute les appels nécessaires. On utilise des variables dédiées pour stocker les valeurs imposées (suffixées par “_couplage”). Ces valeurs sont fixées par l’utilisateur de la classe.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>if (this.relaxation&gt;0)
{
    this.couple(this.U\_t, this.U\_couplage);
    this.couple(this.V\_t, this.V\_couplage);
    this.couple(this.phi\_t, this.phi\_couplage);
}
</code></pre></div></div>

<p>Dans la page du modèle, on aura au préalable chargé des valeurs de couplage pour différentes échéances de temps. Je vous passe les détails, ce qui nous intéresse c’est la manière dont nous fixons les valeurs imposées. C’est le rôle de la fonction coupler(), appelée à chaque itération du modèle. On commence par rechercher dans notre liste d’échéances l’intervalle de temps où l’on se trouve. On boucle, en testant le temps depuis le début de la simulation, jusqu’à trouver notre bonheur, notre liste étant triée. Une fois trouvé l’intervalle, on procède à une interpolation linéaire entre les valeurs fixées aux deux temps correspondants. C’est le rôle de la fonction coupler(). Ensuite, on utilise les fonctions setter pour imposer les valeurs calculées au modèle.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function interpoler(a, b, t1, t2, t, res)
{
    var coef = (t-t1)/(t2-t1);
    for (var i=0;i&lt;atmos.width\*atmos.height;i++)
    {
        res\[i\] = (1-coef)\*a\[i\]+coef\*b\[i\];
    }
}

function coupler()
{
    var t;
    var tprec=Number(valids\[0\])\*3600;
    for (var i=1;i&lt;valids.length;i++)
    {
        t = Number(valids\[i\])\*3600;
        if (atmos.time&gt;=tprec &amp;&amp; atmos.time&lt;t)
        {
            interpoler(h500\[i-1\], h500\[i\], tprec, t, atmos.time, h500\_couplage);
            interpoler(u500\[i-1\], u500\[i\], tprec, t, atmos.time, u500\_couplage);
            interpoler(v500\[i-1\], v500\[i\], tprec, t, atmos.time, v500\_couplage);
            atmos.setPhiCouplage(h500\_couplage);
            atmos.setUCouplage(u500\_couplage);
            atmos.setVCouplage(v500\_couplage);
            return;
        }
        tprec = t;
    }
}
</code></pre></div></div>

<p>Dans la classe Atmosphere, j’ai prévu une variable “relaxation” qui sert à paramétrer la largeur de la zone de relaxation en nombre de points de grille. La valeur doit être fixée avant l’appel à init() pour que l’on puisse initialiser les valeurs de alpha en tout point de la grille. Je vous laisse le soin d’aller voir la section de code correspondant dans la démo, n’étant que de la recette de cuisine il n’est pas intéressant de le reproduire ici. Dans la démo, nous utilisons une zone de relaxation de 4.</p>

<h2 id="réalisme-de-la-simulation">Réalisme de la simulation</h2>

<p>Le but du modèle barotrope est de simuler l’évolution du géopotentiel du sommet de l’atmosphère, limite à partir de laquelle on considère la pression comme nulle. Or, le niveau 500hPa ne correspond pas réellement au sommet, puisqu’il y a encore de la pression au-dessus. Si l’on simule en l’état, on obtient des comportements pas vraiment désirables, comme le fait que les ondes de hauts et bas géopotentiels vont se propager d’est en ouest, ce qui n’est pas réaliste. Il faut donc ramener le problème à un équivalent “eau peu profonde” conforme aux hypothèses sous-jacente à la modélisation. Pour cela, l’auteur Jean Coiffier préconise de simuler non pas directement le géopotentiel Phi=gz du 500Hpa, mais Phi=gz - 40000. Cela revient grossièrement à diminuer la couche simulée de 4000 mètres, on suppose que cette valeur a été choisie soigneusement pour assurer le meilleur ajustement possible. Et on comprends dès lors le nom du modèle : on veut simuler une couche fine. La simulation sera faite sur ce géopotentiel “adapté”, et pour afficher le résultat, il faudra bien entendu refaire le calcul inverse. La fonction setter setPhi() de la classe Atmosphere se charge de faire la conversion préalable. Le vent quand à lui reste inchangé, on utilise bien le vent à 500hPa.</p>

<h2 id="les-invariants-du-modèle">Les invariants du modèle</h2>

<p>Les équations d’un système physique doivent toujours conserver un certain nombre de grandeurs physiques. En général, l’énergie en fait partie. C’est le cas pour le modèle atmosphérique, en plus de trois autres grandeurs : le tourbillon total, la masse, et l’enstropie. Dans la classe Atmosphere, ces invariants sont systématiquement calculés après chaque itération du modèle par la fonction calcDiagnostics(), et ils peuvent être ensuite affichés.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.calcDiagnostics = function()
{
    this.total\_masse = 0;
    this.total\_energie = 0;
    this.total\_tourbillon = 0;
    this.total\_enstropie = 0;
    for(var i=0;i&lt;this.width\*this.height;i++)
    {
        var v = ((this.tourbillon\[i\]+this.f\[i\])/this.phi\[i\]);
        this.total\_masse += this.phi\[i\]\*this.dx\*this.dy/(this.m\[i\]\*this.m\[i\]);
        this.total\_energie += this.phi\[i\]\*(this.phi\[i\]/2+this.K\[i\])\*this.dx\*this.dy/(this.m\[i\]\*this.m\[i\]);
        this.total\_tourbillon += this.phi\[i\]\*v\*this.dx\*this.dy/(this.m\[i\]\*this.m\[i\]);            
        this.total\_enstropie += (this.phi\[i\]/2)\*v\*v\*this.dx\*this.dy/(this.m\[i\]\*this.m\[i\]);
    }
    this.total\_masse \*= this.rho/this.g;
    this.total\_energie \*= this.rho/this.g;
    this.total\_tourbillon \*= this.rho/this.g;
    this.total\_enstropie \*= this.rho/this.g;
}
</code></pre></div></div>

<p>En théorie, ces calculs ne doivent pas changer de valeur quel que soit le moment de la simulation. Dans la pratique, le traitement numérique des équations ne permet pas toujours de les conserver exactement. Selon le schéma d’intégration utilisé, la conservation est plus ou moins heureuse pour certains d’entre eux. Plus le schéma et le type de grille utilisés sont sophistiqués, plus on peut garantir leur préservation, qui est en quelque sorte un indicateur de la qualité de simulation. Dans notre cas, notre schéma étant le plus simple, il n’est pas le mieux loti de ce côté. D’autant que le couplage que nous réalisons vient un peu brouiller les pistes. Vous pourrez toujours vous amuser à surveiller ces valeurs - j’ai prévu ce qu’il faut dans l’interface, mais vous constaterez qu’elles ne sont pas constantes à cause de cela. J’ai toutefois vérifié qu’en l’absence de couplage, les valeurs étaient quasi-constantes ce qui prouve que mon modèle fonctionne au niveau attendu.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Nous voici au terme d’un bon morceau de code ! C’est ce que l’on peut faire de plus basique comme modèle atmosphérique de prévision. Notre implémentation et nos choix de traitement numérique sont les plus simples existants. Que faire maintenant ? On peut tout d’abord essayer d’améliorer le traitement numérique, en utilisant d’autres types de grilles, et/ou  d’autres schémas d’intégration plus sophistiqués. Cela pourrait faire l’objet de futurs articles, je ne sais pas encore si je vais me lancer dans ce projet. C’est intéressant pour apprendre, mais cela sort de l’objectif initial. L’étape suivante, c’est de perfectionner la simulation en prenant en compte les couches d’atmosphère et la température. Pour cela, il faut changer de type de modèle : on parle alors de modèle barocline. C’est un projet qui m’occupe depuis un moment déjà, le modèle est programmé mais le fonctionnement n’est pas stable. J’espère trouver le problème et pouvoir vous en parler prochainement.</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="modèle météo" /><category term="modélisation" /><category term="PIFO" /><category term="Javascript" /><summary type="html"><![CDATA[Voici le dernier article de cette série concernant l’implémentation du modèle météo barotrope, ou modèle en eau peu profonde, en JavaScript. Il nous restait à aborder quelques problématiques et concepts afin d’arriver à une version pleinement fonctionnelle. Nous allons aujourd’hui finaliser l’application.]]></summary></entry><entry><title type="html">Un modèle météo simplifié en JavaScript – Partie 2 : Le codage</title><link href="https://www.meteo-blois.fr/2018/03/01/partie2/" rel="alternate" type="text/html" title="Un modèle météo simplifié en JavaScript – Partie 2 : Le codage" /><published>2018-03-01T00:00:00+01:00</published><updated>2018-03-01T00:00:00+01:00</updated><id>https://www.meteo-blois.fr/2018/03/01/partie2</id><content type="html" xml:base="https://www.meteo-blois.fr/2018/03/01/partie2/"><![CDATA[<p>Nous avons vu dans <a href="/2018/02/01/partie1">la précédente partie la théorie du modèle en eau peu profonde</a>, ainsi que les techniques d’intégration. On va maintenant se lancer dans le code JavaScript.</p>

<h2 id="organisation-du-programme">Organisation du programme</h2>

<p>Notre programme sera constitué de deux grandes parties :</p>

<ul>
  <li>La partie interface utilisateur, qui sera la page web où l’utilisateur pourra faire fonctionner le modèle et visualiser les données,</li>
  <li>La partie modèle proprement dite, sous forme d’une librairie JavaScript qui contiendra le code de simulation.</li>
</ul>

<h3 id="linterface-utilisateur">L’interface utilisateur</h3>

<p>On ne va pas chercher à faire quelque chose de super joli, on veut aller à l’essentiel. Le code sera basé sur la librairie jQuery. Je ne vais détailler que les parties intéressantes du code, le reste n’étant que de la pure programmation HTML/JavaScript. Vous aurez tout loisir d’afficher le code source de la démo pour l’étudier. L’interface utilisateur sera constituée des éléments suivants :</p>

<ul>
  <li>Des boutons Reset, Start et Step. Ils permettront respectivement de remettre le modèle à son état initial (t=0), d’exécuter le premier pas de la simulation en appliquant le schéma d’Euler, et d’exécuter les pas suivants avec le schéma en différences centrales. Comme il s’agit uniquement de tester le modèle, on n’a pas prévu de mode “automatique” où l’exécution se déroule sans avoir à cliquer pour chaque étape.</li>
  <li>Un petit message de statut permettant de savoir où l’on en est.</li>
  <li>Un certain nombre de boutons permettant de choisir la variable du modèle affichée.</li>
  <li>La zone de visualisation. Par défaut, un tableau de chiffres correspondant à la grille du modèle sera affiché sont forme de table HTML. Mais on prévoira une représentation colorée pour le vent et le géopotentiel, plus lisible en terme de représentation. On utilisera là encore des tables HTML pour ne pas se lancer dans des représentations plus complexes. Mais utiliser le canvas HTML5 pour ces représentations pourrait être une amélioration intéressante pour plus tard. Le vent sera représenté par des plages de couleur pour l’intensité, et sa direction approximative par des caractères spéciaux HTML.</li>
</ul>

<p><img src="/wp-content/uploads/2018/03/InterfaceModeleEPP.png" alt="Interface du Modèle " title="Interface du Modèle" /></p>

<p>L’interface du Modèle, affichant le champ de vent</p>

<h3 id="le-modèle">Le modèle</h3>

<p>Nous allons implémenter le modèle sous forme d’une classe JavaScript que nous appellerons Atmosphere, dans un fichier js distinct (mb_meteo_epp.js). Voici l’interface publique de la classe, la description est dans les commentaires :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var Atmosphere = function ()
{
    // \*\*\*\* CONSTANTES TECHNIQUES \*\*\*\*
    // Types de projection cartégienne. m=1 constant
    this.PROJ\_CARTESIEN = 0;
    // Type de projection mercator de diamètre terre. m=cos(lat)
    this.PROJ\_MERCATOR = 1;
    
    // \*\*\*\* PARAMETRES DU MODELE \*\*\*\*
    
    // Type de projection à utiliser pour les équations (détermine m)
    this.projection = this.PROJ\_CARTESIEN;
    
    
    // Pas de grille en degré dans la direction des latitudes.
    this.dlat = 10;
    
    // Pas de grille en degré dans la direction des longitudes.
    this.dlon = 10;
    
    // Pas de grille en X. 1° = 111.11km. Recalculé à partir de dlon.
    this.dx = 1111110;
    
    // Pas de grille en Y. 1° = 111.11km. Recalculé à partir de dlat.
    this.dy = 1111110;

    // Largeur de grille du domaine
    this.width=36;    
    
    // Hauteur de grille du domaine
    this.height=36;

    // Latitude du coin haut gauche du domaine.
    this.nlat = 90;
    
    // Latitude du coin bas droite du domaine.
    this.slat = -80;
    
    // Latitude du coin haut gauche du domaine
    this.wlon = 0;
    
    // Longitude du coin bas droite du domaine
    this.elon = 350;
    
    // Pas de temps (attention à la stabilité !)
    this.dt = 3600;
      
    // Largeur de la zone de relaxation pour le couplage.
    this.relaxation = 2;

    // Combien de temps écoulé depuis le début de simulation
    this.time = 0;

    // \*\*\*\* VARIABLES DE LA SIMULATION \*\*\*\*
    
    // Composantes du vent T
    this.U = \[\];    
    this.V = \[\];
    
    // Geopotentiel pression nulle (=gz où p=0). 
    this.phi = \[\];
    
    // Initialise le géopotentiel 500hPa 
    this.setPhi = function(g500) { }
    
    // Initialise la composante U du vent 500hPa 
    this.setU = function(u500) { }
    
    // Initialise la composante V du vent 500hPa
    this.setV = function(v500) { }
    
    // Initialise le modèle avec les variables qui ont été fournies préalablement.
    this.init = function() { }
    
    // Démarre le modèle en exécutant le schéma d'Euler.
    this.start = function() { }
    
    // Avance le modèle d'un pas en utilisant le schéma explicite centré.
    this.step = function() { }

 }
</code></pre></div></div>

<p>Pour utiliser la classe, on doit paramétrer de la manière suivante, ce qui est fait dans la page HTML :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var atmos = new Atmosphere();
...
$(document).ready(function() {
    atmos.projection = atmos.PROJ\_CARTESIEN;
    atmos.width = 144;
    atmos.height = 72;
    atmos.dt = 360; 
    atmos.dlat = 1;
    atmos.dlon = 1;
    atmos.nlat = 80;
    atmos.slat = atmos.nlat-atmos.height\*atmos.dlon;
    atmos.elon = 40;
    atmos.wlon = atmos.elon-atmos.width\*atmos.dlon;
...
}
</code></pre></div></div>

<p>La définition du domaine mérite sans doutes quelques précisions :</p>

<ul>
  <li>La largeur d’un point de grille en degré d’arc (dlat et dlon)</li>
  <li>La largeur et la hauteur en points de grille (width et height)</li>
  <li>Les latitudes extrêmes nord et sud (nlat et slat)</li>
  <li>Les longitudes extrêmes est et ouest (elon et wlon)</li>
  <li>La projection de grille, que l’on choisit cartésienne, mais le programme supporte aussi une projection Mercator. Souvenez-vous, cela définit le facteur d’échelle m dont on a parlé dans la partie théorique. Le cartésien fixe un m constant à 1 en tout point du domaine.</li>
  <li>Les valeurs choisies permettent d’avoir une simulation stable selon le critère CFL. Le pas de temps est de 360 secondes soit 6 minutes, pour la résolution de 1° d’arc que l’on s’est fixée.</li>
</ul>

<p>Il faut ensuite fournir au modèle les données U, V et Phi grâce aux fonctions setXXX correspondantes. Les données attendues sont sous forme de tableau à une dimension. Les valeurs de chaque ligne de grille sont simplement concaténées l’une à la suite de l’autre, les latitudes les plus au nord venant en premier. Si la grille fait 100 de large, alors les données de la première ligne vont de l’indice 0 à l’indice 99, puis les données de la deuxième ligne vont de l’indice 100 à 199 et ainsi de suite. On a choisi de passer par des “setters” pour paramétrer ces données car nous devrons appliquer quelques transformations aux données au passage, afin de s’adapter au référentiel utilisé et pour le traitement correct du géopotentiel. Rien de très compliqué, mais je ne vais pas vous noyer pour le moment dans ces explications, je me réserve cela pour plus tard. Les données étant renseignées, il ne reste plus qu’à appeler init(), puis start(), et enfin step() autant que nécessaire, ce qui est fait par un peu de jQuery sur le code des liens dont le code est ci-dessous. Notez que j’ai cité la totalité du code de ces gestionnaires d’événements, qui font un certain nombre d’autres choses relatives à l’affichage ou le calcul du temps d’exécution de chaque pas de temps à des fins statistiques. Je reviendrais plus tard sur l’appel à la fonction “coupler()” et son rôle, pour le moment considérons que cette fonction ne fait rien de spécial.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
&lt;script&gt;
...
function reset()
{    
    if (status!="ready") return;
    atmos.setPhi(h500\[0\]);
    atmos.setU(u500\[0\]);
    atmos.setV(v500\[0\]);
    atmos.init();
    
    totalTime = 0;
    totalStep = 0;
    printResult();
}

function start()
{
    if (status!="ready") return;
    var firstTimestamp = new Date().getTime(); 
    coupler();
    atmos.start();
    var secondTimestamp = new Date().getTime();
    lastExecTime = secondTimestamp - firstTimestamp; 
    totalStep++;
    totalTime+=lastExecTime;
}

function step()
{
    if (status!="ready") return;
    var firstTimestamp = new Date().getTime(); 
    coupler();
    atmos.step();
    var secondTimestamp = new Date().getTime();
    lastExecTime = secondTimestamp - firstTimestamp;
    totalStep++;
    totalTime+=lastExecTime;
}
&lt;/script&gt;
...
&lt;a href="#" onclick="reset(); return false;"&gt;\[Reset\]&lt;/a&gt; - 
&lt;a href="#" onclick="start(); printResult(); return false;"&gt;\[Start\]&lt;/a&gt; - 
&lt;a href="#" onclick="step(); printResult(); return false;"&gt;\[Step\]&lt;/a&gt; | 
&lt;span id="statistics"&gt;&lt;/span&gt;
...
</code></pre></div></div>

<h2 id="préparation-et-chargement-des-données">Préparation et chargement des données</h2>

<p>Vu le peu d’exigences en terme de champs de données, n’importe quel modèle accessible en open data peut faire l’affaire pour initialiser notre simulation, on pourrait même partir des réanalyses du NCEP. Pour l’implémentation, j’avais le GFS 0.5° sous la main, c’est donc lui qui me servira. A partir des datasets téléchargés, il suffit d’extraire les champs souhaités au format texte à l’aide de l’utilitaire <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/">wgrib2 du NWS</a>. Voici un petit exemple de script Bash permettant d’extraire le vent et le géopotentiel pour nos 24 heures de simulation. Notez que pour initialiser le modèle, seul les champs à t=00 sont requis, mais ici je prends de l’avance pour un peu plus tard, vous verrez pourquoi. On obtient au final un fichier par champ et par échéance.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/sh
for valid in "000" "003" "006" "009" "012" "015" "018" "021" "024"
do
    for hgt in "500"
    do
        wgrib2 gfs.t00z.pgrb2.0p50.f$valid -s | grep HGT:$hgt | wgrib2 -i gfs.t00z.pgrb2.0p50.f$valid -text hgt\_$hgt"\_"$valid.txt
        wgrib2 gfs.t00z.pgrb2.0p50.f$valid -s | grep UGRD:$hgt | wgrib2 -i gfs.t00z.pgrb2.0p50.f$valid -text ugrd\_$hgt"\_"$valid.txt
        wgrib2 gfs.t00z.pgrb2.0p50.f$valid -s | grep VGRD:$hgt | wgrib2 -i gfs.t00z.pgrb2.0p50.f$valid -text vgrd\_$hgt"\_"$valid.txt
    done
done
</code></pre></div></div>

<p>Les fichiers texte sont ensuite chargés en mémoire via la méthode AJAX au chargement de la page, après constitution d’une liste des champs requis. Les tableaux h500, u500 et v500 contiendront une entrées pour les données de chaque échéance.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var h500 = \[\];
var u500 = \[\];
var v500 = \[\];

var valids = \["000", "003", "006", "012", "015", "018", "021", "024"\];
var reslist = \[\];
var status = "loading";
$(document).ready(function() {

....
    for (i=0;i&lt;valids.length;i++) { 
        reslist.push("hgt\_500\_"+valids\[i\]+".txt"); 
        reslist.push("ugrd\_500\_"+valids\[i\]+".txt"); 
        reslist.push("vgrd\_500\_"+valids\[i\]+".txt"); 
    } 
    printLoadingStatus(); 
    $.ajax({ url : "res/run/"+scenario+"/"+reslist\[0\], 
        dataType: "text", 
        success : onFieldDownload }); 
}); 


function onFieldDownload(data) { 
    var f = reslist\[0\].substring(0,1); 
    switch (f) { 
        case "h": h500\[h500.length\]=\[\]; 
            loadField(h500\[h500.length-1\], data); 
            break; 
        case "u": u500\[u500.length\]=\[\]; 
            loadField(u500\[u500.length-1\], data); 
            break; 
        case "v": v500\[v500.length\]=\[\]; 
            loadField(v500\[v500.length-1\], data); 
            break; 
    } 
    reslist.shift(); 
    if (reslist.length&gt;0)
    {
        printLoadingStatus();
        $.ajax({
          url : "res/run/"+scenario+"/"+reslist\[0\],
          dataType: "text",
          success : onFieldDownload
       });
    }
    else
    {
        $(statistics)("Prêt");
        status = "ready";
        reset();
    }
}

function printLoadingStatus()
{
    $(statistics)("Chargement "+reslist\[0\]);
}
</code></pre></div></div>

<p>La fonction loadField() est un peu particulière, et son code est un peu compliqué. En effet, GFS est un modèle global, qui contient plus de données que le domaine que l’on veut utiliser, qui plus est en résolution supérieure. On doit donc prendre une donnée sur deux pour atteindre la résolution de 1°. Pour ne rien simplifier, notre domaine est à cheval sur le méridien de Greenwich, qui correspond aux limites horizontales de la grille de GFS : pour constituer notre grille, on doit aller piocher les données à l’est et à l’ouest du méridien, qui sont à deux endroits différents. Et dernier point, mais là c’est la faute à mes choix techniques, j’ai voulu travailler avec une grille orientée dans le sens d’affichage “informatique”, cad avec les points les plus au nord en haut. Ce qui oblige encore à un parcours inversé dans la grille de GFS. Voici le code et ses calculs d’indices affreux :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function loadField(f, data)
{
    var lines = data.split('\\n');
    var width = 720;
    var height = 361;
    lines.shift();
    
    // Ce qui est à droite de greenwich
    var greenwich = Math.floor(-atmos.wlon/atmos.dlon);
    var ystep = 2\*atmos.dlat;
    var ystart = Math.floor((90-atmos.nlat)\*2);
    var yend = Math.floor((90-atmos.slat)\*2);
    var xstep = 2\*atmos.dlon;
    var xstart = 0;
    var xend = 2\*atmos.elon;
    var i = greenwich;
    for (var y = ystart ; y&lt;yend ; y+=xstep)
    {
        for (var x = xstart ; x&lt;xend ; x+=xstep)
        {
            f\[i\] = Number(lines\[x+(360-y)\*width\]);
            i++;
        }
        i += greenwich;
    }
    
    // Ce qui est à gauche de greenwich
    var xstart = width-Math.floor((-atmos.wlon\*2));
    var xend = 720;
    i = 0;
    for (var y = ystart ; y&lt;yend ; y+=ystep)
    {
        for (var x = xstart ; x&lt;xend ; x+=xstep)
        {
            f\[i\] = Number(lines\[x+(360-y)\*width\]);
            i++;
        }
        i += atmos.width-greenwich;
    }
}
</code></pre></div></div>

<h2 id="le-coeur-du-modèle">Le coeur du modèle</h2>

<p>On va maintenant aborder la partie intéressante : la simulation proprement dite. Si vous avez bien suivi la partie théorique, vous verrez que ça ne présente pas une si grande difficulté.</p>

<h3 id="opérateurs-de-calculs">Opérateurs de calculs</h3>

<p>Commençons par définir quelques opérateurs de calcul dont nous aurons besoin.  Tout d’abord le produit et la somme de deux champs, point à point. Ces deux opérations, qui stockent le résultat dans une variable résultat passée en paramètre, ne présentent pas de grande difficulté :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.product = function(x, y, res)
{
    for(var i=0;i&lt;this.width\*this.height;i++)
    {
        res\[i\] = x\[i\]\*y\[i\];
    }
}

this.sum = function(x, y, res)
{
    for(var i=0;i&lt;this.width\*this.height;i++)
    {
         res\[i\] = x\[i\]+y\[i\];
    }
}
</code></pre></div></div>

<p>Le coeur du modèle repose ensuite sur les calculs de dérivée. Nous aurons besoin de pouvoir calculer des dérivées spatiales selon l’axe x et selon l’axe y. Il s’agit tout simplement des formules que nous avions données dans la partie théorique. Remarquez que ces dérivées ne peuvent être calculées aux frontières du domaine, car sinon les indices seraient en dehors du tableau. Cela signifie que nous ne pourrons pas calculer d’évolution du modèle pour les indices de tableau situés aux limites. Cela posera évidemment des problèmes à mesure que l’on avancera dans la simulation, mais nous verrons comment fixer cela. Voici le code de calcul des dérivées spaciales :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.d\_dx = function(f, res)
{
    for (var y=1;y&lt;this.height-1;y++)
    {
        for(var x=1;x&lt;this.width-1;x++)
        {
            var i = x+y\*this.width;
            res\[i\] = (f\[i+1\]-f\[i-1\])/(2\*this.dx\*this.m\[i\]);
        }
    }
}
    
this.d\_dy = function(f, res)
{
    for (var y=1;y&lt;this.height-1;y++)
    {
        for(var x=1;x&lt;this.width-1;x++)
        {
            var i = x+y\*this.width;
            res\[i\] = (f\[i-this.width\]-f\[i+this.width\])/(2\*this.dy);
        }           
    }
}
</code></pre></div></div>

<h3 id="initialisation">Initialisation</h3>

<p>L’initialisation du modèle sert avant tout à allouer les variables intermédiaires dont nous aurons besoin, et calculer quelques tables de lookup. Javascript ne dispose pas d’instruction permettant d’allouer un tableau, les éléments sont créés au moment de leur première affectation. Pour ne pas avoir de problèmes ou d’erreurs d’exécution, nous devrons initialiser chaque élément de chaque tableau avec une valeur par défaut. Les principales variables à initialiser sont :</p>

<ul>
  <li>On calcule une valeur pour dx et dy en fonction de la résolution en degrés du modèle.</li>
  <li>U_t, V_t, phi_t qui sont les valeurs à T-1 des variables du modèle pour le schéma explicite centré. On les initialise ici aux mêmes valeurs que U, V et phi à t=0, mais c’est plus par convenance que par réelle nécessité - on aurait pu tout aussi bien les mettre à zéro.</li>
  <li>Le paramètre de coriolis f=2Ωsin(lat), qui est une simple table de lookup pour ne pas avoir à recalculer le sinus à chaque fois. Ca fait partie des optimisations faciles.</li>
  <li>Le facteur d’échelle m, qui vaut 1 pour les projections cartésiennes et cos(lat) pour Mercator. On a prévu que m puisse être fourni par l’utilisateur de la classe pour toute autre type de projection ayant une projection cartographique simple.</li>
  <li>On initialise les variables K et tourbillon représentant les termes d’énergie et de tourbillon intervenant dans les équations du modèle. On commence par allouer le tableau, puis on appelle les fonctions permettant de calculer leurs valeurs. Normalement ces termes devraient être calculés au début de chaque itération du modèle. Vu que je souhaite pouvoir débugger les valeurs à chaque étape, il est préférable d’avoir ces valeurs avant de commencer. J’ai avancé leur calcul en fin des fonctions init(), start() et step() pour que la valeur correspondant à l’état actuel du modèle soit disponible à l’affichage immédiatement après le calcul. Au final, ça ne change rien au résultat : c’est juste plus pratique pour moi comme cela.</li>
  <li>On procède également à l’initialisation d’une table de paramètre pour le couplage du modèle. J’en reparlerais ultérieurement.</li>
  <li>Notez l’appel à une fonction de calcul de diagnostics. Ce sont des calculs de vérification de la cohérence du modèle, sur la conservation de certaines valeurs physiques. J’en reparlerais plus tard, ce n’est pas indispensable pour la simulation.</li>
  <li>Le reste des variables initialisées sont des variables temporaires, contenant des produits intermédiaires ou des résultats de calculs utilisés pour certaines opérations.</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.init = function()
{
    var lat = this.nlat\*(Math.PI/180);
    this.dx = 111.1 \* this.dlon \* 1000;
    this.dy = 111.1 \* this.dlat \* 1000;
    this.time = 0;
    for (var y=0;y&lt;this.height;y++)
    {
        for(var x=0;x&lt;this.width;x++)
        {
            var i = x+y\*this.width;
            var h = 0;

            // Paramètre de coriolis et facteur d'échelle en fonction de la latitude
            this.f\[i\] = 2 \* this.omega \* Math.sin(lat);
            switch (this.projection)
            {
                case this.PROJ\_CARTESIEN:
                    this.m\[i\] = 1;
                    break;
                case this.PROJ\_MERCATOR:
                    this.m\[i\] = Math.cos(lat);
                    break;
                default:
                    //supposé fourni par l'appelant
                    //this.m\[i\] = 1;
            }

            // Initialisation du couplage
            if (y==0 || y==this.height-1 || x==0 || x==this.width-1)
            {
                this.alpha\[i\] = 1.0;
            }
            else if (y&lt;1+this.relaxation||y&gt;=this.height-this.relaxation-1
                    ||x&lt;1+this.relaxation||x&gt;=this.width-this.relaxation-1)
            {
                var xd = 0;
                var yd = 0;

                if (x&lt;1+this.relaxation) xd = this.relaxation-x+1;
                else if (x&gt;=this.width-this.relaxation-1) 
                    xd = x-this.width+this.relaxation+2;
                if (y&lt;1+this.relaxation) yd = this.relaxation-y+1;
                else if (y&gt;=this.height-this.relaxation-1) 
                    yd = y-this.height+this.relaxation+2;

                if (xd&lt;yd) xd = yd;
                //else if (xd&lt;yd) xd = yd;

                this.alpha\[i\] = (xd/(this.relaxation+1));
            }
            else 
            {
                this.alpha\[i\] = 0.0;
            }

            // Creation des tableaux
            this.K\[i\] = 0;
            this.tourbillon\[i\] = 0;                
            this.U\_t\[i\] = this.U\[i\];
            this.V\_t\[i\] = this.V\[i\];
            this.phi\_t\[i\] = this.phi\[i\];
            this.dU\_dx\[i\] = 0;
            this.dV\_dy\[i\] = 0;
            this.phi\_U\[i\] = 0;
            this.phi\_V\[i\] = 0;
            this.phi\_K\[i\] = 0;
            this.dx\_phi\_K\[i\] = 0;
            this.dy\_phi\_K\[i\] = 0;
            this.dx\_phi\_U\[i\] = 0;
            this.dy\_phi\_V\[i\] = 0;
        }

        lat -= this.dlat\*(Math.PI/180);
    }

    this.calcEnergy();
    this.calcTourbillon();
    this.calcDiagnostics();        
}
</code></pre></div></div>

<h3 id="calcul-de-lénergie-et-du-tourbillon">Calcul de l’énergie et du tourbillon</h3>

<p>Le calcul de ces termes ne présente pas de difficulté particulière, il suffit d’appliquer les formules que nous avons données en chaque point de grille, en utilisant les opérateurs que nous avons définis précédemment.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.calcEnergy = function()
{
    for(var i=0;i&lt;this.width\*this.height;i++)
    {
        this.K\[i\] = this.m\[i\]\*this.m\[i\]\*(this.U\[i\]\*this.U\[i\]+this.V\[i\]\*this.V\[i\])/2;
    }
}

this.calcTourbillon = function()
{
    this.d\_dy(this.U, this.dU\_dy);
    this.d\_dx(this.V, this.dV\_dx);
    for(var i=0;i&lt;this.width\*this.height;i++)
    {
        this.tourbillon\[i\] = this.m\[i\]\*this.m\[i\]\*(this.dV\_dx\[i\]-this.dU\_dy\[i\]);
    }
}
</code></pre></div></div>

<h3 id="le-schéma-deuler">Le schéma d’Euler</h3>

<p>Le schéma d’Euler, qui sert uniquement au premier pas de temps, n’est pas particulièrement compliqué à implémenter. Il se trouve dans la fonction start(). On commence par calculer des variables intermédiaires correspondant aux dérivées, produits et sommes de champs dont nous aurons besoin pour les calculs. Puis nous calculons trois termes A, B, C correspondant aux dérivées temporelles du vent et du géopotentiel, en suivant les formules données par les équations du modèle. Il suffit ensuite d’appliquer la formule de calcul du schéma pour obtenir les nouvelles valeurs de U, V et phi. Le reste consiste à échanger la valeur actuelle avec la nouvelle valeur,  pour le schéma explicite centré. Et on calcule les nouvelles valeurs de l’énergie, du tourbillon et des diagnostics.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.start = function()
{              
    // Formules intermédiaires et dérivées 
    this.product(this.U, this.phi, this.phi\_U);
    this.d\_dx(this.phi\_U, this.dx\_phi\_U);
    this.product(this.V, this.phi, this.phi\_V);
    this.d\_dy(this.phi\_V, this.dy\_phi\_V);

    this.sum(this.K, this.phi, this.phi\_K);
    this.d\_dx(this.phi\_K, this.dx\_phi\_K);
    this.d\_dy(this.phi\_K, this.dy\_phi\_K);

    // Schema d'Euler pour le premier pas de temps
    for (var y=1;y&lt;this.height-1;y++)
    {
        for(var x=1;x&lt;this.width-1;x++)
        {
            var i = x+y\*this.width;
            var A = (this.tourbillon\[i\] + this.f\[i\])\*this.V\[i\]-this.dx\_phi\_K\[i\];
            var B = -(this.tourbillon\[i\] + this.f\[i\])\*this.U\[i\]-this.dy\_phi\_K\[i\];
            var C = -this.m\[i\]\*this.m\[i\]\*(this.dx\_phi\_U\[i\]+this.dy\_phi\_V\[i\]);

            this.U\_t\[i\] = this.U\[i\] + this.dt\*A;
            this.V\_t\[i\] = this.V\[i\] + this.dt\*B;
            this.phi\_t\[i\] = this.phi\[i\] + this.dt\*C;
        }
    }

...

    var tmp = this.U\_t; this.U\_t = this.U; this.U = tmp;
    tmp = this.V\_t; this.V\_t = this.V; this.V = tmp;
    tmp = this.phi\_t; this.phi\_t = this.phi; this.phi = tmp;

    this.calcEnergy();
    this.calcTourbillon();
    this.calcDiagnostics();

    this.time += this.dt;
}
</code></pre></div></div>

<h3 id="le-schéma-explicite-centré">Le schéma explicite centré</h3>

<p>L’avance par le schéma saute-mouton n’est pas plus compliquée que le schéma d’Euler, en fait le code est tellement similaire que seule change la formule de calcul. Pour ne pas surcharger cet article, je ne répéterais donc pas les parties identiques. En fait, j’aurais même pu faire une économie d’écriture au niveau du programme en factorisant du code, mais quand j’ai développé le modèle ce n’étais pas ma priorité, et maintenant j’avoue que j’ai la flemme de le faire #honte. Le code est dans la fonction step() :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.step = function()
{
    // Formules intermédiaires et dérivées 
...
    // Schema différences centrales
    for (var y=1;y&lt;this.height-1;y++)
    {
        for(var x=1;x&lt;this.width-1;x++)
        {
            var i = x+y\*this.width;
            var A = (this.tourbillon\[i\] + this.f\[i\])\*this.V\[i\]-this.dx\_phi\_K\[i\]; 
            var B = -(this.tourbillon\[i\] + this.f\[i\])\*this.U\[i\]-this.dy\_phi\_K\[i\];
            var C = -this.m\[i\]\*this.m\[i\]\*(this.dx\_phi\_U\[i\]+this.dy\_phi\_V\[i\]);

            this.U\_t\[i\] = this.U\_t\[i\] + 2\*this.dt\*A;
            this.V\_t\[i\] = this.V\_t\[i\] + 2\*this.dt\*B;
            this.phi\_t\[i\] = this.phi\_t\[i\] + 2\*this.dt\*C;
        }
    }

...
}
</code></pre></div></div>

<h2 id="cest-tout-pour-aujourdhui">C’est tout pour aujourd’hui</h2>

<p>On a fini de passer en revue l’essentiel du code du modèle. A ce stade, on peut déjà faire une simulation. Vous avez vu qu’il reste encore des choses que j’ai omises ici, et qui font partie des techniques de modélisation. Je ne pensais pas faire de troisième partie, mais comme cet article est finalement horriblement long, cela est devenu nécessaire pour aborder ces quelques points. Mais au fait, vous lisez ceci ? Vous avez survécu ! Bravo ! Avouez que j’ai été sympa aussi, je vous ai épargné le récit des longues séances de debug, de mise au point, d’incompréhensions et d’arrachages de cheveux en tous genres quand rien ne marchait. <a href="/2018/03/02/partie3">Vers la partie 3 : démo en ligne et améliorations.</a></p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="modèle météo" /><category term="modélisation" /><category term="PIFO" /><category term="Javascript" /><summary type="html"><![CDATA[Nous avons vu dans la précédente partie la théorie du modèle en eau peu profonde, ainsi que les techniques d’intégration. On va maintenant se lancer dans le code JavaScript.]]></summary></entry><entry><title type="html">Un modèle météo simplifié en JavaScript - Partie 1 : La Théorie</title><link href="https://www.meteo-blois.fr/2018/02/01/partie1/" rel="alternate" type="text/html" title="Un modèle météo simplifié en JavaScript - Partie 1 : La Théorie" /><published>2018-02-01T00:00:00+01:00</published><updated>2018-02-01T00:00:00+01:00</updated><id>https://www.meteo-blois.fr/2018/02/01/partie1</id><content type="html" xml:base="https://www.meteo-blois.fr/2018/02/01/partie1/"><![CDATA[<p>Je vous propose aujourd’hui de relever un challenge de programmation très intéressant ! Il s’agit ni plus ni moins que de coder un modèle météo. Le but n’est pas de révolutionner la science, mais plutôt de réaliser le modèle météo de prévision le plus simple possible. L’objectif initial du projet était de faire un moteur physiquement réaliste mais léger pour un jeu basé sur la météo. On veut donc se contenter de quelque chose de très basique : résolution grossière, physique basique qui va à l’essentiel : nuages, pluie, rayonnement solaire.  Il faut que ce soit très léger en calculs, pour pouvoir tourner en temps réel. Et le tout doit être programmé en JavaScript, parce que c’est bien plus rapide pour proto-typer et tester sans avoir besoin d’outils de développement et d’une tonne de librairies. Armé de mes plus précieux bouquins de météo, je me suis attelé au challenge. Je vous propose de relater mes avancées au fil de l’eau sur ce blog, en espérant que ça vous intéressera. Je ne sait pas où ça nous mènera, on va y aller étape par étape et on verra bien si on arrive au bout ou pas ! Le but est avant tout d’apprendre.</p>

<h2 id="la-stratégie">La stratégie</h2>

<p>Il n’est clairement pas envisageable de se lancer bille en tête dans le codage. Des modèles, il en existe de beaucoup de sortes : barocline, barotrope, en grille A, B, C ou D, à différences centrales, spectral… Il faut donc faire un choix dans tout cela. Sans surprise, on va commencer notre quête par le niveau 1 - voire même le tuto d’initiation, ce n’est pas la peine de se noyer directement en affrontant le boss de fin ;). Gardons toujours à l’esprit l’objectif initial : avoir un modèle simple à implémenter et pas trop lourd en calculs. En d’autres termes, on cherche moins la précision du résultat que la vitesse et la simplicité de calcul.</p>

<p>Notre premier choix se porte donc sans surprise sur le modèle le plus basique que j’ai pu trouver. Il porte le doux nom de modèle barotrope, ou modèle en eau peu profonde. On va commencer par une première partie un peu théorique où l’on va décortiquer le principe de fonctionnement et d’intégration, et puis on va aborder le codage proprement dit dans une seconde partie.</p>

<h2 id="le-modèle-en-eau-peu-profonde">Le modèle en eau peu profonde</h2>

<p>Ce modèle permet seulement de prévoir le géopotentiel à 500hPa (environ 5500 mètres d’altitude), représentatif de l’atmosphère moyenne. Il part de l’hypothèse simplificatrice que l’atmosphère est une couche mince et homogène, qui s’écoule autour de la terre, un peu comme un cours d’eau - d’où son nom. Pour le faire fonctionner, on doit seulement connaître le vent et l’altitude du niveau du sommet de l’atmosphère, celui-ci agissant comme la surface de la “rivière” qui ondule et se déforme au gré du courant. Comme il n’y a pas de notion de température, de vitesse verticale ni de frottements, c’est comme considérer que l’évolution de l’atmosphère est uniquement inertielle. L’approximation est raisonnable pour une prévision à 24 heures. Au-delà, ce n’est plus suffisamment réaliste. Mais ce n’est pas grave en regard de nos objectifs : commençons par implémenter le modèle en eau peu profonde, pour apprendre les techniques numériques et se faire un peu la main.</p>

<p><img src="/wp-content/uploads/2018/02/modele-barotrope.png" alt="Principe du modèle barotrope" title="Principe du modèle barotrope" /></p>

<p>Principe du modèle barotrope</p>

<p>Commençons par jeter un oeil aux équations du modèle :</p>

<p><img src="/wp-content/uploads/2018/02/barotrope-1.png" alt="Equations du modèle barotrope" /></p>

<p>Equations du modèle barotrope</p>

<p>Celles-ci sont écrites directement sous forme de dérivées, c’est-à-dire qu’elles expriment pour chaque unité de temps t de combien varient les variables du modèle en fonction de l’état actuel du système. Voyons ce que nous avons :</p>

<ul>
  <li>Le vecteur V est la première variable du modèle, qui représente le vent. Il a pour composantes U et V, respectivement le vent zonal et longitudinal. C’est le vent global de l’atmosphère, nous initialiserons notre modèle avec le vent à l’altitude 500hPa supposé représentatif de l’atmosphère moyenne.</li>
  <li>La lettre grecque Φ se prononce “Phi” et représente le géopotentiel du sommet de l’atmosphère, la variable que nous souhaitons prévoir. Le géopotentiel représente la quantité gz, g étant la constante gravitationnelle (9.81m par seconde) et z étant l’atitude en mètre. Φs est le géopotentiel de la surface inférieure. Notez qu’on parle ici de sommet de l’atmosphère… alors que le 500hPa que l’on souhaite prévoir n’est pas le sommet ! On verra quand on codera comment on peut faire pour que ça marche.</li>
  <li>La variable f représente le facteur de coriolis, la déviation du vent par la rotation de la terre. La formule est f=2Ω*sin(lat), lat étant la latitude en degré et oméga la vitesse angulaire de rotation de la terre. La force est maximale aux pôles et minimale à l’équateur.</li>
  <li>La variable ξ (prononcer “xi”) représente le tourbillon et sa formule vaut ξ=m²(du/dx-du/dy). La notion de tourbillon est un peu complexe à expliquer, disons juste que c’est un terme qui intervient dans la rotation des masses d’air. Nb : u et v représentent les composantes du vecteur V et x et y les axes du vent, et la lettre d l’opérateur de dérivée.</li>
  <li>Au passage, le terme m représente le facteur d’échelle. Il permet de tenir compte d’une éventuelle projection cartographique, mais pour simplifier nous prendrons ce terme constant à 1.</li>
  <li>Le vecteur k est le vecteur unitaire représentant la verticale, cad l’axe z pointant donc vers le haut. Cf illustration plus bas.</li>
  <li>Enfin la lettre k non vectorielle (à ne pas confondre avec le vecteur unitaire) représente l’énergie. On la définit par la formule k=m²/2 * (u²+v²).</li>
</ul>

<p>Tous les opérateurs de gradient, divergence et de produit vectoriel peuvent paraître barbares… Je ne souhaite pas alourdir cet article en expliquant à quoi ils servent. Développons et écrivons ces équations dans une forme un peu plus “informatisable”. Au final tout se résume à de bonnes vieilles dérivées comme on a appris à l’école, selon un axe x ou y :</p>

<ul>
  <li>du = (xi + f) * v - dérivée_x(k + Phi)</li>
  <li>dv = -(xi + f) * u + dérivée_y(k + Phi)</li>
  <li>dPhi = -m² * (dérivee_x(Phi * u) + dérivée_y(Phi * v)</li>
</ul>

<h2 id="lintégration-du-modèle">L’intégration du modèle</h2>

<p>Réaliser la simulation n’est alors plus qu’un problème d’itération. L’algorithme est le suivant :</p>

<ol>
  <li>Initialiser les variables u, v et Phi avec des données réelles.</li>
  <li>Pour chaque pas de temps:
    <ol>
      <li>Calculer les variables xi et k selon les formules (f sera initialisée une fois pour toutes à l’initialisation du modèle)</li>
      <li>Calculer les termes du, dy et dPhi selon les équations</li>
      <li>Calculer les nouvelles valeurs de u, v et Phi selon la formule d’Euler et le schéma explicite centré</li>
    </ol>
  </li>
</ol>

<p>Il se pose maintenant plusieurs questions auxquelles nous allons devoir répondre :</p>

<ul>
  <li>La représentation des variables, décrites par les équations à l’échelle du continuum, sous forme informatisable</li>
  <li>Comment on calcule une dérivée spatiale</li>
  <li>Comment calculer l’évolution temporelle selon les schémas que nous avons mentionné.</li>
  <li>Les problématiques du traitement numérique</li>
</ul>

<h3 id="la-discrétisation-des-variables">La discrétisation des variables</h3>

<p>Les variables du modèle ont deux dimensions - on appelle cela un champ. Comme on ne peut pas informatiquement représenter les données de façon continue, on va procéder comme pour tout signal numérisé : on discrétise, ce qui est l’équivalent d’un échantillonnage pour le son par exemple. On va définir une grille à deux dimensions, et en chaque point de grille espacés de dx et dy nous aurons les valeurs de nos variables. C’est tout simplement un tableau. Dans notre cas, toutes les variables sont définies aux mêmes points de grille, on dit qu’il s’agit d’une grille de type A. Il existe des dispositions plus évoluées qui permettent de façon astucieuse d’augmenter la précision des calculs. Mais c’est hors du cadre de cet article, on aura l’occasion d’y revenir.</p>

<p><img src="/wp-content/uploads/2018/02/grille_1_degre_referentiel-1.png" alt="Grille et référentiel utilisés dans les articles" title="Grille et référentiel utilisés dans les articles" /></p>

<p>Grille et référentiel utilisés dans les articles. La grille fait 1 degré d’arc. On représente également les composantes du vent V, et la taille de grille dx et dy. Les variables du modèle sont positionnées aux intersections des traits de grille.</p>

<h3 id="comment-calculer-une-dérivée-spatiale">Comment calculer une dérivée spatiale</h3>

<p>Ce n’est pas un problème très compliqué, on se contentera de donner la formule suivante, qui calcule la dérivée d’une variable A au point X selon l’axe x :</p>

<p><code class="language-plaintext highlighter-rouge">dA(x)/dx = 1/(2*dx) * ( A(x+dx) - A(x-dx) )</code></p>

<p>Il suffit donc de prendre les valeurs aux points de grille à droite et à gauche, et d’en faire la différence. Je vous laisse le soin d’adapter la formule pour l’axe y ;).</p>

<p>Note pour les matheux : ce calcul est le développement de Taylor du premier ordre de la dérivée.</p>

<h3 id="les-schémas-davance-temporelle">Les schémas d’avance temporelle</h3>

<p>Pour calculer les nouvelles valeurs à T+dt de nos variables, le schéma d’avance temporelle le plus simple est le schéma d’Euler :</p>

<p><code class="language-plaintext highlighter-rouge">A(t+dt) = A(t) + dA(t) * dt</code></p>

<p>Il a le mérite de permettre l’avance dans le temps en ne connaissant que les valeurs des variables à l’instant T. Mais ce schéma est d’une précision insuffisante, on dit qu’il est instable.</p>

<p>Pour avoir une intégration temporelle stable, il existe bien d’autres schémas, certains étant plus complexes que d’autres à mettre en oeuvre. Fidèles à notre objectif de simplification, nous prendrons le schéma d’avance explicite centré. En voici la formule :</p>

<p><code class="language-plaintext highlighter-rouge">A(t+dt) = A(t-dt) + dA(t)*2*dt</code></p>

<p>De part le fait qu’il calcule la valeur en t+dt à partir de la valeur en t-dt, sans tenir compte de la valeur en t, on l’appelle aussi schéma en saute-mouton. Plus précis et stable, ce schéma a l’inconvénient de nécessiter de connaître la valeur précédente des variables. Il n’est donc pas utilisable au démarrage de l’intégration. Pour solutionner le problème, on procède de la manière suivante :</p>

<ul>
  <li>Pour chaque variable, on garde trace variables en t et t-dt.</li>
  <li>Pour le premier pas de temps, initialiser les variables “t-dt” avec les mêmes valeurs que les variables d’initialisation, cad en t=0. Utiliser le schéma d’Euler pour calculer le premier pas en t=dt.</li>
  <li>Pour les pas suivants. Calculer leur valeur en t selon le schéma explicite centré, connaissant t-dt. Puis on échange la valeur courante des variables qui deviennent les valeurs “t-dt”. Et ainsi de suite.</li>
</ul>

<h3 id="problématiques-de-lintégration-numérique">Problématiques de l’intégration numérique</h3>

<p>L’intégration numérique ne fonctionne que sous certaines conditions. On ne peut pas prendre n’importe quelle taille de grille dx, dy ou de pas de temps dt. Il a été démontré que pour que le modèle soit stable, il faut que la condition suivante soit réalisée, dite condition CFL du nom des météorologues qui l’ont démontrée :</p>

<p><code class="language-plaintext highlighter-rouge">U*dt/dx &lt; 1</code></p>

<p>Pour faire simple, U représente la vitesse maximale de propagation que l’on souhaite représenter dans le modèle, tous types d’onde compris. Afin d’avoir une modélisation correcte, on fixe U=300m par seconde.</p>

<p>Pour notre projet, on souhaite travailler à une résolution horizontale d’un degré d’arc, soit environ 111km pour dx. Selon la formule, notre pas de temps ne devra pas dépasser 370 secondes soit un peu plus de 6 minutes - qu’on arrondira volontiers à 360 secondes.</p>

<h2 id="limplémentation-du-modèle">L’implémentation du modèle</h2>

<p>On a maintenant tous les éléments théoriques nécessaires pour se lancer dans l’implémentation en JavaScript. Mais cet article est déjà assez long comme cela, je vous donne rendez-vous pour <a href="/2018/03/01/partie2">la partie 2</a> : on abordera le codage et on présentera une démo en ligne du modèle.</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="modèle météo" /><category term="modélisation" /><category term="PIFO" /><category term="Javascript" /><summary type="html"><![CDATA[Je vous propose aujourd’hui de relever un challenge de programmation très intéressant ! Il s’agit ni plus ni moins que de coder un modèle météo. Le but n’est pas de révolutionner la science, mais plutôt de réaliser le modèle météo de prévision le plus simple possible. L’objectif initial du projet était de faire un moteur physiquement réaliste mais léger pour un jeu basé sur la météo. On veut donc se contenter de quelque chose de très basique : résolution grossière, physique basique qui va à l’essentiel : nuages, pluie, rayonnement solaire.  Il faut que ce soit très léger en calculs, pour pouvoir tourner en temps réel. Et le tout doit être programmé en JavaScript, parce que c’est bien plus rapide pour proto-typer et tester sans avoir besoin d’outils de développement et d’une tonne de librairies. Armé de mes plus précieux bouquins de météo, je me suis attelé au challenge. Je vous propose de relater mes avancées au fil de l’eau sur ce blog, en espérant que ça vous intéressera. Je ne sait pas où ça nous mènera, on va y aller étape par étape et on verra bien si on arrive au bout ou pas ! Le but est avant tout d’apprendre.]]></summary></entry><entry><title type="html">Le projet PIFO</title><link href="https://www.meteo-blois.fr/pifo/le-projet-pifo/" rel="alternate" type="text/html" title="Le projet PIFO" /><published>2018-01-31T00:00:00+01:00</published><updated>2018-01-31T00:00:00+01:00</updated><id>https://www.meteo-blois.fr/pifo/le-projet-pifo</id><content type="html" xml:base="https://www.meteo-blois.fr/pifo/le-projet-pifo/"><![CDATA[<h2 id="description-du-projet">Description du projet</h2>

<p>Le projet PIFO est un framework de modélisation météo écrit initialement en JavaScript. Plus simplement : c’est un modèle météo dont l’objectif est avant tout éducatif. Il s’agit d’implémenter les techniques de calcul utilisées dans les modèles de prévision.</p>

<p>L’acronyme PIFO signifie Projet Informatique à Formules Ouvertes. Il reflète la structure modulaire et évolutive du projet, l’absence d’objectif opérationnel, et la genèse du projet. Il se veut un petit clin d’oeil humoristique aux sigles à la française, tout en étant un projet dont le noyau scientifique reste solide.</p>

<h2 id="le-modèle-opérationnel">Le modèle opérationnel</h2>

<p>Caractéristiques :</p>

<ul>
  <li>4 runs par jour</li>
  <li>Prévisions à 48h</li>
  <li>Modèle hydrostatique à aire limitée, en grille C et coordonnée sigma</li>
  <li>Schéma d’intégration de type explicite centré avec filtrage temporel</li>
  <li>Résolution horizontale de 1° (environ 100km)</li>
  <li>Grille de 111x72 de type C en projection Mercator positionnée de l’Atlantique Nord à l’Europe de l’Est</li>
  <li>8 couches d’atmosphère en coordonnées sigma.</li>
  <li>Initialisation et conditions aux limites données par GFS</li>
  <li>Gestion du relief</li>
  <li>Paramétrisations physiques :
    <ul>
      <li>Rayonnement : non implémenté</li>
      <li>Couche limite, turbulence : non implémenté</li>
      <li>Schéma de précipitations de grande échelle : de type Kessler</li>
      <li>Schéma de convection : non implémenté.</li>
    </ul>
  </li>
  <li>Temps de calcul : environ 10 minutes.</li>
</ul>

<p>Détail des champs prévus :</p>

<ul>
  <li>Champs 3D :
    <ul>
      <li>Vent U, V</li>
      <li>Vitesse verticale généralisée W</li>
      <li>Température</li>
      <li>Géopotentiel</li>
      <li>Tourbillon relatif et absolu</li>
      <li>Humidité spécifique</li>
    </ul>
  </li>
  <li>Champs 2D :
    <ul>
      <li>Pression de surface</li>
      <li>Accumulation des précipitations</li>
    </ul>
  </li>
</ul>

<h2 id="historique-du-projet">Historique du projet</h2>

<p>Au départ, tout est parti d’une idée de faire un mini-jeu jouable sur navigateur, basé sur une simulation météo basique. Idée qui est née à la suite de l’étude du live de Jean Coiffier, “Les bases de la prévision numérique du temps”. La quantité de calculs et le nombre de problématiques d’ordre numérique se sont avérés trop importants pour l’objectif initial, mais le projet a été poursuivi malgré tout.</p>

<p>Le langage Javascript s’est imposé d’une part pour la contrainte navigateur, et d’autre part pour des raisons de simplicité de prototypage. Le projet a débuté pendant l’été 2017 par le modèle barotrope. Il a donné lieu à une série d’articles didactiques en février 2018 sur le site Météo Blois, qui en propose la démonstration en ligne.</p>

<p>Le projet s’est ensuite étoffé avec l’implémentation d’un modèle barocline de type hydrostatique. Des outils annexes ont été ajoutés par la suite pour gérer notamment l’initialisation du modèle et l’historisation des résultats. Un frontal Node.JS a été implémenté à l’été 2018, permettant de le faire tourner de manière automatisée.</p>

<p>Depuis le 28/10/2018, PIFO est passé en production opérationnelle. Il reflète l’état de l’art du projet, et a été volontairement limité en résolution par les capacités de calcul du serveur.</p>

<p>Parallèlement, le schéma de précipitations est progressivement ajouté. D’abord sans gestion de la glace, puis avec la séparation pluie/neige.</p>

<p>Au cours de l’hiver 2018-2019, un important travail autour du framework a été réalisé. Il s’agissait de modulariser le code et faire abstraction du type de coeur dynamique utilisé. Il est maintenant possible de construire un modèle à partir de briques de base (coeur dynamique, type d’intégration temporelle, paramétrisations physiques, filtres…). Chaque élément pouvant ensuite avoir ses propres paramètres.</p>

<p>A cette modularisation s’ajoute un gros travail sur la gestion des modes de fonctionnement (initialisation, run…) et des processus de préparation et traitement des données en entrée et en sortie. Un système de gestion de workflow piloté par fichier de configuration a été ajouté.</p>

<p>Parallèlement, et depuis mars-avril 2019, la priorité est d’améliorer la gestion du bruit dans le modèle, pour améliorer sa stabilité lors de longues simulations et permettre de prévoir au-delà de 48h. Des implémentations et tests systématiques des différentes techniques de filtrage sont réalisés.</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="modélisation" /><category term="météo" /><category term="modélisation" /><category term="PIFO" /><category term="Javascript" /><summary type="html"><![CDATA[Description du projet]]></summary></entry><entry><title type="html">MB Weather Maps : les outils de génération de carte Météo Blois sous licence GPL</title><link href="https://www.meteo-blois.fr/2017/12/16/mb-weather-maps-sous-licence-gpl/" rel="alternate" type="text/html" title="MB Weather Maps : les outils de génération de carte Météo Blois sous licence GPL" /><published>2017-12-16T12:44:00+01:00</published><updated>2017-12-16T12:44:00+01:00</updated><id>https://www.meteo-blois.fr/2017/12/16/mb-weather-maps-sous-licence-gpl</id><content type="html" xml:base="https://www.meteo-blois.fr/2017/12/16/mb-weather-maps-sous-licence-gpl/"><![CDATA[<p>Depuis 2012, Météo Blois illustre ses articles et ses posts sur Twitter avec des cartes et diagrammes météo produits à partir de données de modèles en open data. Pour cela, des outils ont été développés en interne. C’est avec grand plaisir que je vous annonce aujourd’hui la création et la mise à disposition du projet MB Weather Map issu de ces travaux.</p>

<h4 id="le-projet-mb-weather-maps-cest-quoi-pour-qui-pourquoi-">Le projet MB Weather Maps, c’est quoi, pour qui, pourquoi ?</h4>

<p>MB Weather Maps (pour Météo Blois Weather Maps) est un ensemble de scripts dont la fonction est de récupérer les données météo gratuites auprès des centres météo, faire calculer le modèle WRF sur la France et produire des cartes et diagrammes sous forme de fichiers images.</p>

<p>Il est destiné principalement aux utilisateurs qui veulent monter un site météo ou les organisations qui ont besoin d’exploiter des données météo. Une très bonne connaissance des systèmes Unix/Linux est vivement recommandée pour installer les pré-requis et mettre en oeuvre cette application.</p>

<p>Météo Blois a toujours été dans l’esprit de partage des informations et des connaissances sur Internet, et pro-logiciel libre. Il était donc dommage de garder tout cela pour soi. C’est pourquoi j’ai décidé de packager les scripts et les distribuer sous licence libre <a href="https://www.gnu.org/licenses/quick-guide-gplv3.fr.html">GPL version 3</a>.</p>

<p>Pour télécharger les scripts et avoir plus d’informations techniques, je vous invite à vous rendre sur la page du projet, qui est hébergée sur un repository Bitbucket.</p>

<p><strong>La page du projet MB Weather Maps</strong> : <a href="https://bitbucket.org/nicolas_gasnier/mbweathermaps">https://bitbucket.org/nicolas_gasnier/mbweathermaps</a></p>

<p>Pour télécharger, allez dans la page “Downloads” du projet et choisissez l’option “Download repository”.</p>

<h4 id="fonctionnalités-mb-weather-maps">Fonctionnalités MB Weather Maps</h4>

<p>MB Weather Maps permet de produire des cartes pour les modèles suivants :</p>

<ul>
  <li>GFS : Cartes France et Europe, émagrammes, coupes et météogrammes  3 et 7 jours</li>
  <li>WRF : en résolution 0.05° sur la France</li>
  <li>ECMWF : cartes France et Europe</li>
  <li>CFS (en daily) : cartes France et Europe</li>
  <li>ARPEGE WMO (basse résolution et champs limités) : cartes France et Europe</li>
</ul>

<p><a href="/wp-content/uploads/2017/12/cartes2Bmeteo.png"><img src="/wp-content/uploads/2017/12/cartes2Bmeteo.png" alt="Exemples de cartes et diagrammes proposés par MB Weather Maps" title="Exemples de cartes et diagrammes proposés par MB Weather Maps" /></a></p>

<p>Exemples de cartes et diagrammes proposés par MB Weather Maps</p>

<p>Un support très basique et expérimental existe pour les modèles suivants fournis par Météo France :</p>

<ul>
  <li>ARPEGE</li>
  <li>AROME</li>
</ul>

<p>Le logiciel se base sur le langage de script NCL pour générer les cartes, et l’automatisation est réalisée à partir de scripts bash.</p>

<h4 id="obtenir-de-laide">Obtenir de l’aide</h4>

<p>En plus de la documentation sur la page du projet, vous pourrez trouver beaucoup d’aide sur <a href="/tutoriels/">ce blog dans la partie tutoriels</a>. Nous avons écrit une large partie consacrée à la mise en oeuvre du modèle WRF, et une introductions au langage de scripting NCL utilisé pour la génération des produits. Le système de commentaires de cet article peut être utilisé pour obtenir un support de type forum. Pour contacter directement l’auteur, les informations sont indiquées sur la page Bitbucket du projet.</p>

<h4 id="contribuer-au-projet">Contribuer au projet</h4>

<p>Vous êtes invités si vous en avez la possibilité à améliorer l’outil et contribuer vos modifications au projet. Toutes les informations pour participer sont indiquées dans le readme de la page du projet.</p>

<p>J’espère que ce projet vous sera utile, et que vous ferez de beaux sites !</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="mb weather maps" /><category term="gpl" /><category term="cartes météo" /><category term="open source" /><summary type="html"><![CDATA[Depuis 2012, Météo Blois illustre ses articles et ses posts sur Twitter avec des cartes et diagrammes météo produits à partir de données de modèles en open data. Pour cela, des outils ont été développés en interne. C’est avec grand plaisir que je vous annonce aujourd’hui la création et la mise à disposition du projet MB Weather Map issu de ces travaux.]]></summary></entry><entry><title type="html">Exploiter les données météo gratuites d’internet</title><link href="https://www.meteo-blois.fr/2015/04/19/exploiter-les-donnees-meteo-gratuites-dinternet/" rel="alternate" type="text/html" title="Exploiter les données météo gratuites d’internet" /><published>2015-04-19T12:32:00+02:00</published><updated>2015-04-19T12:32:00+02:00</updated><id>https://www.meteo-blois.fr/2015/04/19/exploiter-les-donnees-meteo-gratuites-dinternet</id><content type="html" xml:base="https://www.meteo-blois.fr/2015/04/19/exploiter-les-donnees-meteo-gratuites-dinternet/"><![CDATA[<p>Depuis 1995, l’OMM (Organisation Météorologique Mondiale) a adopté la Résolution 40, un accord qui traite de l’échange international des données météorologiques. Elle statue notamment sur l’échange libre et gratuit entre les centres météo des pays membres, mais surtout, et c’est ce qui nous intéresse, définit un certain nombres de données d’utilité publique qui doivent être accessibles à tous de manière gratuite.</p>

<p>Il est donc possible d’obtenir auprès des centres météo des différents pays toutes sortes de données (observations, prévisions) librement. On trouvera toujours dans chaque pays signataire le minimum requis par la Résolution 40, et souvent bien plus. Les américains sont probablement les plus généreux car c’est auprès du NWS (le « Météo France » américain) que l’on pourra obtenir le plus de données (NDLA : c’était vrai au moment de la rédaction de cet article, mais cela a beaucoup changé depuis, avec la libération de nombreuses données et notamment des modèles ARPEGE et ALADIN par Météo France).</p>

<p>Cet article a pour objectif de faire un tour d’horizon des données météorologiques que l’on peut obtenir sur Internet, comment les exploiter et les principaux sites qui les diffusent sous forme brute, ou sous forme de produits dérivés comme des cartes de prévision ou des graphiques. Cet article n’a pas pour but d’être exhaustif, mais de présenter les principales sources utiles pour la France.</p>

<h3 id="données-dobservation">Données d’observation</h3>

<p>Les stations météo, qu’elles soient automatiques ou manuelles, alimentent les centres météo en données d’observations. Elles sont nombreuses, situées au sol, sur des bateaux, des balises en mer ou sur des avions instrumentés. Toutes ne fournissent pas le même panel de mesures. Certaines d’entre-elles font partie de ce que l’on appelle le réseau synoptique, un réseau mondial de stations fournissant des mesures complètes en simultané aux heures dites synoptiques (toutes les 3 heures). En France, il en existe au moins une par département.</p>

<h4 id="obtenir-les-données-sous-forme-de-messages-texte">Obtenir les données sous forme de messages texte</h4>

<p>De nombreuses stations météo sont situées dans des aéroports ou aérodromes. Elles émettent régulièrement, le plus souvent toutes les heures, un court message texte décrivant l’état du ciel et les relevés au sol. Ces messages normalisés appelés METAR (METeorological Aerodrome Report) servent prioritairement à l’aéronautisme, mais sont également exploitables comme source de relevés.</p>

<p>Ils sont transmis mondialement, et archivés par différents organismes. Ainsi, connaissant le code ICAO de l’aérodrome (4 caractères), on peut les obtenir auprès de différents sites internet comme celui de la NOAA, où des services FTP permettent d’obtenir les messages au format décodé ou non décodé :</p>

<p><a href="http://www.nws.noaa.gov/tg/datahelp.php">http://www.nws.noaa.gov/tg/datahelp.php</a></p>

<p>Exemple de message METAR pour l’aéroport de Tours St Symphorien (code LFOT) :</p>

<p>LFOT 200830Z AUTO 12004KT 070V180 9999 NSC 11/05 Q1003</p>

<p>Le décodage de fait de la façon suivante :</p>

<ul>
  <li>LFOT : code OACI de la station</li>
  <li>200830Z : observation le 20 du mois à 08h30 UTC</li>
  <li>12004KT : vent 120° par rapport au nord (sud-ouest), 4 nœuds (KT) soit 7.4 km/h.</li>
  <li>070V180 : la direction du vent varie entre 70° et 180°</li>
  <li>9999 : visibilité supérieure à 10km</li>
  <li>NSC : pas de nuages significatifs</li>
  <li>11/05 : température de 11°C, point de rosée 5°C</li>
  <li>Q1003 : pression de 1003 hPa</li>
</ul>

<p>Les METAR peuvent comporter des informations de tendances. D’autres messages comme le TAF (Terminal Aerodrome Forecast) permettent d’avoir une prévision sur la station pour les heures à venir. Enfin, des messages comme le SYNOP (Surface Synoptic Observation) permettent d’avoir une information plus complète aux heures synoptiques. Ils circulent sur le système mondial de télécommunication de l’OMM permettant l’échange entre les centres météo.
Les messages SYNOP sont disponibles dans le cadre de la Résolution 40 sur le site des données publiques de Météo France, ainsi que la documentation permettant de les décoder :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=90&amp;id_rubrique=32">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=90&amp;id_rubrique=32 </a></p>

<h4 id="consulter-les-données-dobservation">Consulter les données d’observation</h4>

<p>Les messages bruts vus ci-dessus sont difficilement exploitables en tant que tel, sans une application quelconque pour les présenter. Heureusement, nombreux sont les sites internet amateurs à constituer une base de données en collectant les messages des stations, et en complétant par de nombreuses stations amateurs. Ils produisent ainsi en quasi temps-réel des cartes d’observations et des graphiques par station. Bien souvent, les utilisateurs ont également la possibilité de reporter leurs observations in situ, et d’illustrer leurs propos par des photographies. Il est ainsi possible d’avoir une vision actualisée du temps qu’il fait partout en France. A cela s’ajoute bien souvent la possibilité de consulter les archives des observations. Voici les principaux sites qui proposent ce genre de services :</p>

<ul>
  <li>Le site Meteociel : <a href="http://www.meteociel.fr/">http://www.meteociel.fr</a></li>
  <li>Le site Infoclimat : <a href="http://www.infoclimat.fr/">http://www.infoclimat.fr</a></li>
  <li>Le site Meteo 60 : <a href="http://www.meteo60.fr/">http://www.meteo60.fr </a></li>
</ul>

<p><a href="/wp-content/uploads/2015/04/022BMeteociel2Btableaux2Bhoraires.png"><img src="/wp-content/uploads/2015/04/022BMeteociel2Btableaux2Bhoraires.png" alt="Exemple de diagrammes d'observations du site Meteociel" title="Exemple de diagrammes d'observations du site Meteociel" /></a></p>

<p>Exemple de diagrammes d’observations du site Meteociel</p>

<h4 id="les-radiosondages">Les radiosondages</h4>

<p>Certaines stations météo effectuent deux fois par jour des lâchers de ballons instrumentés afin de mesurer les paramètres de l’atmosphère à différentes altitudes : température, humidité, pression et vent. Ces radiosondages sont ensuite représentés sur un graphique appelé émagramme, aussi appelé skew-t chez les anglo-saxons. Ils sont très utiles pour prévoir la nébulosité, ainsi que l’instabilité de l’atmosphère. On peut obtenir les graphiques depuis le site des données publiques de Météo France.</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=97&amp;id_rubrique=33">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=97&amp;id_rubrique=33</a></p>

<p><a href="/wp-content/uploads/2015/04/032BExemple2Bd27C3A9magramme.png"><img src="/wp-content/uploads/2015/04/032BExemple2BdC3A9magramme.png" alt="Exemple d'émagramme du site Meteo France" title="Exemple d'émagramme du site Meteo France" /></a></p>

<p>Exemple d’émagramme du site Meteo France</p>

<p>En France métropolitaine, des radiosondages sont disponibles pour les villes de Trappes , Brest, Ajaccio , Nîmes et Bordeaux. Les départements d’outre-mer disposent également de radiosondages : Dumont D’Urville (Terre Adélie), Iles Kerguelen, Rochambeau (Guyane), Hiva-Oa (Polynésie Française), Faa’a (Tahiti), Rapa (Polynésie Française), Nouméa (Nouvelle Calédonie).</p>

<p>Depuis juillet 2015, les données brutes des radiosondages (messages TEMP) sont accessibles via des webservices en libre accès ETALAB :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=96&amp;id_rubrique=33">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=96&amp;id_rubrique=33</a></p>

<h4 id="données-historiques-et-climatiques">Données historiques et climatiques</h4>

<p>On peut avoir besoin à des fins d’analyse ou de statistiques d’obtenir des données d’observations historiques. Cela peut être le cas lorsque l’on a besoin de calculer des moyennes sur plusieurs années afin d’établir des normales saisonnières. De telles données peuvent être obtenues auprès des centres météo, mais souvent après le paiement d’une redevance assez élevée. Les américains nous permettent quand à eux d’accéder à ces données climatiques gratuitement pour un très grand nombre de stations du monde entier.</p>

<p>Le Climate Data Center, qui dépend de la NOAA (National Oceanographic and Atmospheric Agency) propose en effet le service CDO (Climate Data Online), donnant accès à ses archives :</p>

<p><a href="http://www.ncdc.noaa.gov/cdo-web/">http://www.ncdc.noaa.gov/cdo-web/</a></p>

<p>Depuis cette page, il faut utiliser l’outil « Mapping tool », puis l’onglet « Time related maps ». L’utilisateur se voit alors proposer le choix entre des données horaires ou agrégées par année, mois, semaine, ou jour. L’outil permet ensuite de sélectionner des stations sur une carte pour en obtenir les données.</p>

<p><a href="/wp-content/uploads/2015/04/112Boutil2Bselection2Bncdc.png"><img src="/wp-content/uploads/2015/04/112Boutil2Bselection2Bncdc.png" alt="Sélection des stations" title="Sélection des stations" /></a></p>

<p>Sélection des stations</p>

<p>Une fois les stations sélectionnées, l’utilisateur dispose d’un formulaire permettant de choisir la période d’observations qu’il veut extraire, ainsi que le format qu’il souhaite : complet ou simplifié. Ensuite, le système demande une adresse E-Mail, puis le système débutera l’extraction. Quand la génération des fichiers est terminée, ce qui peut prendre plusieurs heures suivant la quantité de données demandées et la charge du système, des liens permettant de télécharger les données sont envoyés à l’adresse indiquée. Les fichiers sont au format texte, on pourra alors rentrer les données dans un tableur ou une base de données pour les exploiter.</p>

<p><a href="/wp-content/uploads/2015/04/122Brecuperation2Bdonnees2Bcdcd.png"><img src="/wp-content/uploads/2015/04/122Brecuperation2Bdonnees2Bcdcd.png" alt="Formulaire d'obtention des données" title="Formulaire d'obtention des données" /></a></p>

<p>Formulaire d’obtention des données</p>

<h3 id="limagerie">L’imagerie</h3>

<h4 id="images-satellite">Images satellite</h4>

<p>L’observation satellite est prépondérante en météorologie. Elle permet de voir les masses nuageuses,  d’anticiper leurs développements et trajectoires, et de vérifier le calage des modèles. Internet regorge de sites proposant de l’imagerie satellite en temps réel sur différents canaux avec mise à jour toutes les heures ou tous les quart d’heure, avec animation sur les dernières heures.</p>

<p>Il existe plusieurs types de satellite. Les satellites géostationnaires d’une part, qui tournent en même temps que la terre et restent à la verticale du même point, scrutent toujours la même région du globe et produisent des images à intervalle régulier ce qui permet une surveillance continue. Les images d’Europe nous parviennent des satellites Meteosat 8 et 9. Il y a en tout 6 satellites géostationnaires en fonction, gérés par différents pays.</p>

<p><a href="/wp-content/uploads/2015/04/042Bexemple2Bsat24.png"><img src="/wp-content/uploads/2015/04/042Bexemple2Bsat24.png" alt="Image satellite visible du site Sat24" title="Image satellite visible du site Sat24" /></a></p>

<p>Image satellite visible du site Sat24</p>

<p>D’autre part, nous disposons de satellites défilants , dont l’orbite passe par les pôles et qui sont synchronisés avec le déplacement apparent du soleil (héliosynchrones). Ils font le tour de la terre en 2 heures seulement. Ces satellites ont l’avantage de pouvoir cartographier l’ensemble du globe, en particulier les régions inaccessibles aux observations, mais pas plus de deux fois par jour.</p>

<p><a href="/wp-content/uploads/2015/04/062Bmodis.png"><img src="/wp-content/uploads/2015/04/062Bmodis.png" alt="Image du système MODIS" title="Image du système MODIS" /></a></p>

<p>Image du système MODIS</p>

<p>Qu’ils soient géostationnaires ou héliosynchrones, ils embarquent une multitude d’instruments permettant de produire de l’imagerie dans différents canaux. Les principaux canaux qui seront restitués au grand public sont :</p>

<ul>
  <li>Le visible : permet une image souvent de haute résolution des masses nuageuses, mais seulement la journée.</li>
  <li>L’infrarouge : il mesure la température du sommet des nuages. Plus c’est clair, plus c’est froid, et donc plus sont élevés les nuages. Ces images sont disponibles le jour et la nuit.</li>
  <li>La vapeur d’eau : il s’agit d’un canal particulier dans l’infrarouge qui permet de visualiser la densité de vapeur d’eau dans l’atmosphère. Il est très utile pour suivre les anomalies de tropopause lors des tempêtes.</li>
</ul>

<p>Les données de Meteosat sont reprises par de nombreux sites. Le site <a href="http://www.sat24.com/">http://www.sat24.com</a> permet d’avoir des images de haute résolution sur la France, l’Europe et d’autres régions dans les canaux visible et infrarouge, avec une mise à jour tous les quart d’heure.</p>

<p>Le site de l’EUMETSAT (<a href="http://www.eumetsat.int/">http://www.eumetsat.int/</a>), l’organisme qui gère les satellites européens, permet d’avoir accès à plus de régions sur le globe, et d’avoir en plus le canal vapeur d’eau dans le cadre des données essentielles. On y accède par la rubrique « Images &gt; Real time images », puis en sélectionnant « Meteosat 0 degree ». La résolution est en revanche moins élevée, et la mise à jour se fait toutes les heures. Un zoom plus élaboré en composition colorée est disponible dans la rubrique « RGB Composites &gt; Eview », qui est repris par certains sites internet pour créer des cartes personnalisées.</p>

<p>Le site Meteo Spatiale permet également d’obtenir de très belles images en composition colorée sur l’Europe, avec un intervalle de 15 minutes, mais avec environ deux heures de décalage :</p>

<p><a href="http://www.meteo-spatiale.fr/src/animation_europe_en_direct.php">http://www.meteo-spatiale.fr/src/animation_europe_en_direct.php</a></p>

<p>On retrouve également une animation avec intervalle d’une heure dans les différents canaux sur le site de Meteo France :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=109&amp;id_rubrique=28">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=109&amp;id_rubrique=28</a></p>

<p>Les images des satellites à défilement sont les plus belles que l’on puisse obtenir. Le site de la NASA les propose en résolution allant de 2 km à 250 m. Elles sont au nombre de deux par jour.</p>

<p><a href="https://earthdata.nasa.gov/data/near-real-time-data/rapid-response/modis-subsets">https://earthdata.nasa.gov/data/near-real-time-data/rapid-response/modis-subsets</a></p>

<p>Les images satellite ont également leur page dédiée sur les sites amateurs dont nous avons déjà parlé (Méteociel, Infoclimat, Meteo 60).</p>

<h4 id="images-radar">Images radar</h4>

<p>Les radars météorologiques utilisent la réflexion d’ondes électromagnétiques sur les différents météores (gouttes de pluie, neige, grêle…) pour repérer les précipitations. Un radar a généralement une portée de l’ordre de 200km. Afin de couvrir tout un territoire, plusieurs radars sont nécessaires afin de constituer une mosaïque. Les radars les plus courants sont ceux qui balayent horizontalement l’atmosphère, permettant une création de carte en deux dimensions. D’autres permettent de sonder l’atmosphère en trois dimensions, et certains utilisent l’effet doppler pour estimer la direction, la force et le cisaillement des vents. Ces derniers sont souvent disposés sur des camions mobiles destinés à l’étude des tornades aux Etats-Unis. Ils sont devenus un outil indispensable pour le réseau d’alerte aux populations, et, accessoirement, aux chasseurs de tornades, au travers de services payants. Les radars américains sont consultables sur le site <a href="http://radar.weather.gov/">http://radar.weather.gov/</a>.</p>

<p>En France, le site Meteo France propose gratuitement des images radar pour les trois dernières heures, avec un intervalle de 15 minutes. De plus, des services payants permettent d’avoir une image plus précise et une mise à jour toutes les cinq minutes. Les images sont disponibles sur cette page :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=98&amp;id_rubrique=34">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=98&amp;id_rubrique=34 </a></p>

<p><a href="/wp-content/uploads/2015/04/radar2Bmeteo2Bfrance.png"><img src="/wp-content/uploads/2015/04/radar2Bmeteo2Bfrance.png" alt="Mosaïque radar Meteo France" title="Mosaïque radar Meteo France" /></a></p>

<p>Mosaïque radar Meteo France</p>

<p>Beaucoup d’autres sites rivalisent pour fournir des images radar :</p>
<ul>
  <li>MeteoX (<a href="http://www.meteox.fr/">http://www.meteox.fr</a>) pour une vue plus large sur l’Europe</li>
  <li>Meteo 60 (<a href="http://www.meteo60.fr/radars_index.php">http://www.meteo60.fr/radars_index.php</a>) a été le seul pendant longtemps à proposer des zooms haute résolution sur les régions, repris sur de nombreux sites.</li>
  <li>Infoclimat (<a href="http://www.infoclimat.fr/cartes-meteo-temps-reel-images-satellites-infrarouge-visible-haute-resolution.html?i=radar">http://www.infoclimat.fr/cartes-meteo-temps-reel-images-satellites-infrarouge-visible-haute-resolution.html?i=radar</a>) propose depuis peu la consultation et la vue temps réel haute résolution avec un intervalle de 5 minutes. Un site dédié avec zoom type google maps reprend également les observations (<a href="http://www.meteo-temps-reel.fr/">http://www.meteo-temps-reel.fr/</a>).</li>
</ul>

<h4 id="détection-de-la-foudre">Détection de la foudre</h4>

<p>Les impacts de foudre émettent un rayonnement électromagnétique qu’il est possible de capter : un simple poste de radio grandes ondes réglé en dehors d’une station permet de détecter des clics. C’est cette propriété qui est exploitée par les systèmes de détection. On utilise un réseau d’antennes directionnelles, c’est-à-dire permettant de localiser l’angle de provenance de l’onde, pour enregistrer les signaux de foudre et les centraliser dans un système informatique. Celui-ci va ensuite, par triangulation, calculer l’emplacement de l’impact.</p>

<p>En France, le réseau Meteorage a cette fonction. Il est possible d’accéder aux cartes de localisation en temps réel, moyennant une redevance, soit en passant par le site de Meteo France, soit directement sur le site de la société (<a href="http://www.meteorage.fr/">http://www.meteorage.fr/</a>). Il existe aussi d’autres réseaux, dans d’autres pays, qui coopèrent pour former le réseau Euclid dont les cartes sont reprises sur de nombreux sites (<a href="http://www.euclid.org/">http://www.euclid.org/</a>).</p>

<p>Enfin, un projet amateur existe : le réseau Blitzortung (<a href="http://www.blitzortung.org/">http://www.blitzortung.org</a>). Il s’agit de proposer à qui le souhaite de fabriquer ses propres détecteurs pour participer au réseau et d’améliorer les programmes de triangulation. Un réseau parfaitement opérationnel sur l’Europe existe, géré par des passionnés et des associations. Le réseau s’étend progressivement sur le monde entier. Des cartes de visualisation temps réel sont proposées par de nombreux sites dont voici les principaux :</p>

<ul>
  <li>Infoclimat <a href="http://www.infoclimat.fr/cartes-meteo-temps-reel-prevision-foudre.html">http://www.infoclimat.fr/cartes-meteo-temps-reel-prevision-foudre.html</a></li>
  <li>Meteociel <a href="http://www.meteociel.fr/observations-meteo/foudre.php">http://www.meteociel.fr/observations-meteo/foudre.php</a></li>
  <li>Meteo 60 <a href="http://www.meteo60.fr/foudre_impacts.php">http://www.meteo60.fr/foudre_impacts.php</a></li>
</ul>

<p><a href="/wp-content/uploads/2015/04/latest2h-1.gif"><img src="/wp-content/uploads/2015/04/latest2h-1.gif" alt="Exemple de carte impact du réseau Blitzortung, proposée par Météociel" title="Exemple de carte impact du réseau Blitzortung, proposée par Météociel" /></a></p>

<p>Exemple de carte impact du réseau Blitzortung, proposée par Météociel</p>

<h3 id="les-modèles-de-prévision">Les modèles de prévision</h3>

<p>L’une des principales activités des centres météo est d’élaborer des prévisions. Pour ce faire, ils disposent d’une grande puissance de calcul pour élaborer des simulations de l’évolution du temps qu’il fait. Les résultats de ces simulations, très techniques, ne sont généralement pas disponibles au grand public car il faut payer une redevance très importante, et ils nécessitent une certaine expertise pour les exploiter. Toutefois, dans le cadre de la résolution 40, certaines de ces données sont rendues disponibles sur Internet.</p>

<p>Les météorologues partent du principe que connaissant l’état de l’atmosphère à un moment donné, et les lois de la physique, on peut déterminer l’état futur de l’atmosphère par le calcul. Ils ont mis au point des programmes informatiques destinés à élaborer des prévisions météo. Ces programmes sont appelés des modèles, et ils nécessitent énormément de moyens pour être mis en œuvre, car il faut centraliser beaucoup de données et disposer d’une grande puissance de calcul : Météo France, par exemple, a mis en service un nouveau calculateur en 2014 dont la capacité équivaut à environ 100 000 ordinateurs de bureau.</p>

<p>La plupart des modèles ont quatre sorties par jour, aux heures synoptiques (0h, 6h, 12h et 18h UTC), mais toutes ne sont pas disponibles pour le public. Certains modèles dit globaux, en cela qu’ils simulent le temps sur l’intégralité du globe terrestre, servent à initialiser d’autres modèles plus fins à aire limitée, pour affiner la prévision de certains phénomènes sur une région d’intérêt, généralement le pays dont dépend le centre météo qui le produit.</p>

<h4 id="les-principaux-modèles">Les principaux modèles</h4>

<p>Chaque centre météo a mis au point son propre modèle du temps. Chacun a des caractéristiques propres, comme le type de grille utilisé, la résolution, le type d’équations dynamiques et les paramétrisations physiques utilisées. Ils diffèrent également par leur processus d’assimilation des données, c’est-à-dire les sources de données utilisées et la méthode de calcul de l’analyse (l’état initial de l’atmosphère déterminé depuis les mesures). Faisons un petit tour d’horizon non exhaustif de différents modèles utilisés de part le monde.</p>

<p><strong>ECMWF/CEP</strong></p>

<p>Ce modèle porte le nom de son organisation (European Center for Medium-range Weather Forecasts), aussi appelé CEP en France (Centre Européen de Prévision), qui est basée en Angleterre.  Le programme en lui-même s’appelle IFS et est issu d’une collaboration d’une trentaine de pays, que ce soit pour de la recherche et une utilisation opérationnelle. C’est un des modèles utilisés à Météo France. Il utilise une représentation spectrale des données qui équivaut à une grille de 16km environ  et 137 niveaux verticaux. Il propose deux prévisions globales par jour, qui vont jusqu’à 10 jours. Il propose également une variante ensembliste permettant d’évaluer la fiabilité du scénario simulé.</p>

<p>Dans le cadre de la collaboration mondiale, il est possible de télécharger les données essentielles des sorties des runs de ces modèles au format GRIB via la page suivante :</p>

<p><a href="http://www.ecmwf.int/en/forecasts/datasets/wmo-essential">http://www.ecmwf.int/en/forecasts/datasets/wmo-essential </a></p>

<p>Les champs proposés gratuitement se limitent à la pression au niveau de la mer, le géopotentiel 500hPa, la température et le vent à 850hPa.</p>

<p><strong>ARPEGE</strong></p>

<p>C’est le modèle global opérationnel de Météo France, dont le sigle signifie Action de Recherche Petite Echelle Grande Echelle. Utilisant des éléments de IFS, il a la particularité d’utiliser une grille de résolution variable, centrée sur la France, ayant une résolution d’environ 10km sur la France et 60km à l’opposé sur 70 niveaux verticaux. A l’instar d’ECMWF, il utilise également une représentation spectrale des données. Les sorties de ce modèles sont plus fréquentes, quatre fois par jour, avec des échéances allant jusqu’à 4 jours.</p>

<p>Quelques cartes succintes issues du modèle ARPEGE sont consultables sur le site des données essentielles de Météo France.</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=134&amp;id_rubrique=42">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=134&amp;id_rubrique=42 </a></p>

<p>Pour les développeurs, un web service permet également de récupérer les données essentielles OMM en résolution 2.5° :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=201&amp;id_rubrique=42">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=201&amp;id_rubrique=42</a></p>

<p>Mais depuis le mois de juillet 2015, les données du modèle ARPEGE sont disponibles en résolution 0.1° pour des échéances de 3 heures en 3 heures jusqu’à H+96h en licence libre ETALAB :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=130&amp;id_rubrique=51">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=130&amp;id_rubrique=51</a></p>

<p><strong>AROME</strong></p>

<p>C’est le modèle opérationnel haute résolution à aire limitée de Météo France. Il est initialisé à partir des runs d’ARPEGE et intègre également d’autres données d’observation comme les lames d’eau radar. Il permet une prévision à maille fine sur la France métropolitaine notamment. Depuis le mois de juillet 2015, Météo France propose les données en libre accès ETALAB en résolution 0.025° sur 36h :</p>

<p><a href="https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=131&amp;id_rubrique=51">https://donneespubliques.meteofrance.fr/?fond=produit&amp;id_produit=131&amp;id_rubrique=51</a></p>

<p><strong>GFS</strong></p>

<p>Le Global Forecast System est américain, et produit par le NWS (National Weather Service). Sa résolution est de 0,25 degrés d’arc (soit environ 30km) et il utilise 64 niveaux verticaux, bien que seulement 26 soient disponibles en sortie sur Internet. Il produit quatre runs par jour, avec un intervalle de 3h jusqu’à 8 jours, puis il produit des prévisions de 0,5 degrés d’arc à 16 jours. Le grand intérêt de ce modèle est d’être disponible dans le domaine public grâce à la loi américaine : il est donc le plus utilisé par les météorologues amateurs de part le monde.</p>

<p>Les données du modèle GFS sont accessibles au format GRIB via la page suivante, où il est possible d’obtenir des grilles dans plusieurs résolutions (0,25°, 0,5° et 1°)  :</p>

<p><a href="http://www.nco.ncep.noaa.gov/pmb/products/gfs/">http://www.nco.ncep.noaa.gov/pmb/products/gfs/</a></p>

<p>Toutes les données sont disponibles sur 26 niveaux, ainsi que des niveaux de sol, les températures de surface et un certain nombre de variables diagnostiques. De quoi produire toutes sortes de cartes, et de calculer d’autres variables diagnostiques.</p>

<p>Il existe une variante ensembliste de GFS. Il s’agit de refaire la même prévision mais en perturbant les données initiales, de manière à voir comment le résultat final varie en fonction des incertitudes sur les mesures. On peut ainsi établir des écarts-type et des moyennes pour vérifier la validité et la fiabilité de la prévision dans le temps. Cet ensemble s’appelle GEFS, et les données GRIB sont accessibles à l’adresse suivante :</p>

<p><a href="http://www.nco.ncep.noaa.gov/pmb/products/gens/">http://www.nco.ncep.noaa.gov/pmb/products/gens/</a></p>

<p><strong>WRF</strong></p>

<p>Le Weather Research Forecast est un programme de recherche issu d’une collaboration internationale, dont le code source est ouvert. C’est un modèle à aire limitée, et hautement paramétrable. Il est très souvent utilisé par les sociétés de météorologie en combinaison avec GFS, dont les sorties servent à l’initialiser, pour produire des prévisions à maille fine sur une région d’intérêt. Bien qu’exploité par de nombreux centres météo, à commencer par les américains, il n’y a pas de données brutes disponibles pour ce modèle pour la France ou l’Europe. Vous retrouverez donc ce modèle sous forme de cartes sur les sites météo.</p>

<p>En revanche, si vous avez les connaissances techniques requises, il est possible de l’exploiter vous-même. Pour cela, il suffit de télécharger le code source pour le compiler et l’installer sur votre système. L’adresse de téléchargement est la suivante :</p>

<p><a href="http://www2.mmm.ucar.edu/wrf/users/">http://www2.mmm.ucar.edu/wrf/users/</a></p>

<p>Ce programme est prévu pour les systèmes UNIX et Linux, et nécessite de bonnes connaissances techniques pour le mettre en œuvre. L’utilisateur pourra se contenter des cartes proposées par différents sites internet (voir ci-après). Le lecteur intéressé pourra parcourir la série de tutoriaux suivante :</p>

<p><a href="/2013/08/14/mise-en-oeuvre-wrf-partie-1/">/2013/08/14/mise-en-oeuvre-wrf-partie-1/</a></p>

<p><strong>CFS</strong></p>

<p>Le Climate Forecast System est également un modèle américain, mais qui n’est pas destiné à des prévisions opérationnelles. Son rôle est de faire des prévisions saisonnières, jusqu’à 9 mois. Il a la particularité de coupler un modèle océanique et un modèle de glace polaire à un modèle atmosphérique afin de tenir compte de tous les effets qui influencent le climat. Quatre fois par jour, il produit une prévision globale à 2,5 degrés de résolution, avec une sortie toutes les 6 heures. Les prévisions forment trois ensembles basés chacun sur une des trois dernières décades d’observations. Ces ensembles de 10 jours sont ensuite moyennés sur des périodes d’un mois pour obtenir trois tendances par rapport aux moyennes saisonnières, celles-ci pouvant être comparées pour valider la stabilité du modèle dans le temps. Les données de ce modèle sont disponibles sur Internet, et peuvent être téléchargées au format GRIB depuis le site suivant :</p>

<p><a href="http://www.nco.ncep.noaa.gov/pmb/products/cfs/">http://www.nco.ncep.noaa.gov/pmb/products/cfs/</a></p>

<p>Des cartes de synthèse sont de plus proposées sur le site suivant :</p>

<p><a href="http://www.cpc.ncep.noaa.gov/products/people/wwang/cfsv2fcst/">http://www.cpc.ncep.noaa.gov/products/people/wwang/cfsv2fcst/</a></p>

<p><strong>Exploiter les données GRIB</strong></p>

<p>Pour exploiter les données brutes des modèles, il faut des outils pour représenter les données. Voici quelques uns d’entre eux, gratuits ou open source, que le lecteur pourra utiliser pour créer ses propres cartes ou graphiques.</p>

<p><strong>ZyGrib</strong></p>

<p>Cet outil disponible à la fois pour Windows et Linux offre une interface simple et pratique pour afficher des données au format GRIB. Il permet de plus de récupérer directement les données de différents modèles, dont GFS, et les représenter sur une carte interactive que l’on peut déplacer et sur laquelle il est possible de zoomer. L’outil zyGrib peut être téléchargé à l’adresse <a href="http://www.zygrib.org/">http://www.zygrib.org</a>.</p>

<p><a href="/wp-content/uploads/2015/04/182Bzygrib.png"><img src="/wp-content/uploads/2015/04/182Bzygrib.png" alt="Le logiciel ZyGrib" title="Le logiciel ZyGrib" /></a></p>

<p>Le logiciel ZyGrib</p>

<p><strong>GrADS</strong></p>

<p>GrADS est également un outil interactif destiné à la visualisation des données GRIB, mais il est davantage destiné à la représentation scientifique. Il est destiné aux systèmes de type UNIX/Linux. Son utilisation est un peu plus technique, puisque tout se fait à l’aide de commandes à taper, mais en gardant malgré tout une relative simplicité grâce à un langage très concis, permettant de créer des scripts automatiques. Il permet un grand nombre de modes de représentation : vecteurs, contours, coupes verticales, sondages, courbes temporelles… L’outil peut être téléchargé depuis l’adresse <a href="http://www.iges.org/grads/">http://www.iges.org/grads/</a>.</p>

<p><a href="/wp-content/uploads/2015/04/192Bgrads.png"><img src="/wp-content/uploads/2015/04/192Bgrads.png" alt="Le logiciel GrADS" title="Le logiciel GrADS" /></a></p>

<p>Le logiciel GrADS</p>

<p><strong> NCL</strong></p>

<p>Aussi appelé NCAR Command Language, c’est un langage de scripting doté d’une très grande variété de fonctions de visualisation, avec le support de nombreux formats de fichiers dont GRIB et NetCDF. Son utilisation requiert quelques connaissances en programmation, car il s’agit d’écrire des programmes produisant des diagrammes et des cartes, qui peuvent être de très grande qualité. Disponible uniquement sur système UNIX/Linux, il peut être téléchargé gratuitement moyennant une inscription sur le site via l’adresse <a href="http://www.ncl.ucar.edu/">http://www.ncl.ucar.edu</a>.</p>

<p><a href="/wp-content/uploads/2015/04/202Bmeteogramme2Bde2Bmeteo2Bblois.png"><img src="/wp-content/uploads/2015/04/202Bmeteogramme2Bde2Bmeteo2Bblois.png" alt="Exemple de météogramme réalisé avec NCL" title="Exemple de météogramme réalisé avec NCL" /></a></p>

<p>Exemple de météogramme réalisé avec NCL</p>

<p><strong>METVIEW</strong></p>

<p>L’organisme ECMWF a rendu un certain nombre de ces outils disponibles sous forme de logiciel libre. On notera notamment le logiciel Magics++ qui est un outil similaire à NCL permettant la génération de diagrammes et de cartes scientifiques. L’ECMWF propose également le logiciel METVIEW qui permet la consultation et l’affichage des données météo sous toutes leurs formes. Les outils sont disponibles à l’adresse suivante :</p>

<p><a href="http://www.ecmwf.int/en/forecasts/software-and-tools/software">http://www.ecmwf.int/en/forecasts/software-and-tools/software** **</a>.</p>

<h4 id="obtenir-des-cartes-météo">Obtenir des cartes météo</h4>

<p>Nul besoin d’être un informaticien pour se servir des modèles disponibles. De nombreux sites internet produisent des cartes à partir des données essentielles de nombreux modèles internationaux, dont GFS, ECMWF et CFS. Ils font souvent tourner leur propre version du modèle WRF.</p>

<p>Le modèle GFS est fort logiquement le mieux servi. On peut le retrouver sur le site allemand <a href="http://www2.wetter3.de/">http://www2.wetter3.de/</a>,  qui propose des cartes d’Europe et des coupes verticales. On y retrouve aussi quelques cartes fax issues d’autres modèles.</p>

<p>Le site de l’association <a href="http://www.infoclimat.fr/">http://www.infoclimat.fr/</a> propose également des cartes issues du modèle GFS, mais aussi des modèles UKMO, ECMWF, NAVGEM, GEM, ainsi que les versions ensemblistes de GFS. Il fait tourner son propre modèle WRF sur la France.</p>

<p><a href="/wp-content/uploads/2015/04/cartes2Bmeteo.png"><img src="/wp-content/uploads/2015/04/cartes2Bmeteo.png" alt="Exemples de cartes et diagrammes de prévision" title="Exemples de cartes et diagrammes de prévision" /></a></p>

<p>Exemples de cartes et diagrammes de prévision</p>

<p>Le site <a href="http://www.meteociel.fr/">http://www.meteociel.fr</a> s’est forgé une solide réputation en proposant le panel le plus complet de modèles sur la France, l’Europe, et depuis peu, tout l’hémisphère nord. Il est le seul à proposer les modèles japonais, russes et allemands par exemple. En plus des cartes, il propose des coupes verticales et des radiosondages en tout point de la carte. Il propose pas moins d’une quinzaine de modèles, et fait tourner son propre modèle WRF sur la France et de nombreux pays européens. Il  propose d’ailleurs depuis peu une résolution inédite de 2km sur la France.</p>

<p>Le site spécialisé Météo 60 propose également des cartes du modèle GFS et propose son modèle WRF: <a href="http://www.meteo60.fr/">http://www.meteo60.fr</a>. Le site associatif <a href="http://www.infoclimat.fr/">http://www.infoclimat.fr</a> est également l’un des mieux lotis en terme de cartographie de modèles.</p>

<p>Enfin, l’observatoire français des tornades et orages violents Keraunos propose des cartes GFS ainsi que son propre modèle WRF, avec une spécialisation pour les champs utilisés dans la prévision des orages : <a href="http://www.keraunos.org/">http://www.keraunos.org</a>. L’accès à certains champs est toutefois réservé à ses membres.</p>

<h3 id="conclusion">Conclusion</h3>

<p>Nous avons fait un tour d’horizon des principales sources de données météo pour la France. Jusqu’à il y a peu, les données étaient relativement fermées, mais de nouvelles directives gouvernementales forcent Météo France à ouvrir leurs modèles. Les passionnés de météo que nous sommes ne peuvent que saluer cet état de fait. D’autres produits pourraient être rendus accessibles dans le futur, nous ne manquerons pas de surveiller cela.</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="météo" /><category term="ressources" /><category term="données météo" /><category term="open data" /><category term="résolution 40" /><category term="nws" /><summary type="html"><![CDATA[Depuis 1995, l’OMM (Organisation Météorologique Mondiale) a adopté la Résolution 40, un accord qui traite de l’échange international des données météorologiques. Elle statue notamment sur l’échange libre et gratuit entre les centres météo des pays membres, mais surtout, et c’est ce qui nous intéresse, définit un certain nombres de données d’utilité publique qui doivent être accessibles à tous de manière gratuite.]]></summary></entry><entry><title type="html">Mise en oeuvre des modèles météo WRF-ARW et WRF-NMM - Partie 9 - Aller plus loin</title><link href="https://www.meteo-blois.fr/2014/07/30/mise-en-oeuvre-wrf-partie-9/" rel="alternate" type="text/html" title="Mise en oeuvre des modèles météo WRF-ARW et WRF-NMM - Partie 9 - Aller plus loin" /><published>2014-07-30T11:12:00+02:00</published><updated>2014-07-30T11:12:00+02:00</updated><id>https://www.meteo-blois.fr/2014/07/30/mise-en-oeuvre-wrf-partie-9</id><content type="html" xml:base="https://www.meteo-blois.fr/2014/07/30/mise-en-oeuvre-wrf-partie-9/"><![CDATA[<p>Nous avons fait un long parcours jusqu’ici pour mettre en oeuvre le modèle WRF, que ce soit en version ARW ou NMM. Jusqu’à maintenant, nous n’avons fait qu’utiliser le modèle “tel quel”, sans chercher à comprendre davantage son fonctionnement, comment l’optimiser, et améliorer la qualité de la simulation. Cet ultime article, <a href="/2013/11/12/mise-en-oeuvre-wrf-partie-8/">comme promis précédemment</a>, sera une discussion permettant de donner les pistes nécessaires à une mise en exploitation plus sérieuse du modèle.</p>

<h3 id="les-paramétrisations-physiques">Les paramétrisations physiques</h3>

<p>Nous allons dans un premier temps rechercher comment on peut obtenir la simulation la plus réaliste possible. Pour cela, il faut bien comprendre comment fonctionne un modèle météo, et avoir un aperçu des phénomènes qu’il faut prendre en compte.</p>

<p>Un modèle découpe l’atmosphère en une grille tridimensionnelle plus ou moins fine, et considère que chaque point de grille est un volume d’air dont les propriétés (température, pression, vent…) sont homogènes. L’atmosphère est en quelque sorte discrétisée, et la connaissance que l’on en a, qui provient des observations ou d’un autre modèle comme c’est le cas dans nos articles, est reportée dans cette grille de façon physiquement cohérente. On appelle cette grille initiale une analyse.</p>

<p>Le modèle va calculer l’évolution de cette analyse en appliquant les équations de la dynamique des fluides. Sans rentrer dans les termes barbares des équations, celles-ci décrivent :</p>

<ul>
  <li>le bilan des forces physiques : pesanteur, pression,… et leur effet sur l’accélération de l’air et donc la création du vent</li>
  <li>la prise en compte de la force de coriolis, déviation du vent dûe à la rotation de la terre</li>
  <li>la conservation de la masse : au cours du mouvement, aucune quantité de matière ne se rajoute ou disparait.</li>
  <li>le transport d’eau, que ce soit en vapeur, liquide ou solide.</li>
  <li>la conservation du tourbillon, c’est-à-dire la rotation des volumes d’air sur eux-même (dûe entre autres à la rotation de la terre).</li>
</ul>

<p>En résolvant ces équations à chaque pas de temps, on en déduit les mouvements de l’atmosphère et donc son évolution. Mais cette description ne prend pas en compte tous les phénomènes. En effet, la taille de maille est généralement trop importante pour résoudre des phénomènes d’échelle aérologique ou de micro-échelle, comme les cumulus de beau temps ou la turbulence. D’autres phénomènes sont trop complexes pour être intégrés directement dans les équations dynamiques. On utilise des modèles simplifiés pour chaque phénomène physique, afin de calculer les effets moyens sur la maille en tenant compte de façon plus ou moins réaliste des boucles de rétroaction (rayonnement vs couverture nuageuse…). Voici une liste non exhaustive des principaux phénomènes physiques paramétrisés :</p>

<ul>
  <li>apports de chaleur par le rayonnement du soleil, et à l’inverse la perte nocturne par rayonnement infrarouge.</li>
  <li>la condensation de la vapeur d’eau, ou d’une manière plus générale la formation des nuages. Cela génère des précipitation, et libère une grande quantité de chaleur latente qu’il faut prendre en compte dans les calculs. Il existe également une boucle de rétroaction avec le rayonnement solaire.</li>
  <li>l’influence de la surface et de son type (urbain, forêt, champs…), qui freine le vent, réchauffe l’atmosphère par la base, et génère des turbulences (couche limite atmosphérique, couche limite de surface)</li>
  <li>le sol et les océans sont également pris en compte. On calcule les échanges de chaleur, en prenant en compte plusieurs couches de sol et d’océan, et on modélise également de manière simplifiée l’hydrologie pour prendre en compte la saturation des sols et l’écoulement des eaux de pluie, car cela modifie l’interaction sol/atmosphère (évapotranspiration, etc…).</li>
  <li>l’influence du relief qui bloque ou dévie les vents, provoque d’importants forçages verticaux</li>
</ul>

<p>Dans WRF, il est possible de choisir entre plusieurs modèles pour différents paramètres physiques. Nous n’avons fait jusqu’ici qu’utiliser les modèles standard, qui fonctionnent certes très bien, mais qui ne donnent pas forcément le résultat escompté dans certaines situations. C’est le cas par exemple du modèle de cumulus. Notre fichier namelist.input comportait la ligne suivante :</p>

<p>cu_physics = 2,</p>

<p>Cela signifie que l’on utilise le modèle Betts Miller Janjic, un modèle qui ne traite pas explicitement les courants ascendants/descendants. En simulant dans des situations orageuses, on comprend assez vite que ce modèle rend compte assez mal des phénomènes convectifs. La part convective des précipitations produites est peu importante, et en-dessous de la réalité. Il faut donc trouver un modèle plus élaboré.</p>

<p>Il existe une dizaine de schémas de cumulus dans WRF, mais ils ne fonctionnent pas forcément avec tous les coeurs. J’en ai testé trois qui fonctionnent avec NMM :</p>

<ul>
  <li>2 : Bretts Milles Janjic, qui vient par défaut. Il ne gère qu’un seul type de particule de nuages.</li>
  <li>14 : New SAS (Simplified Arakawa Schubert). Il gère la glace de nuage ainsi que les courants descendants.</li>
  <li>1 : Kain-Fritsch. Il gère la glace, la pluie et la neige, les courants descendants et ascendants.</li>
</ul>

<p>Le type 2 donne un résultat assez peu réaliste en présence de convection profonde. Le type 14 donne un bien meilleur résultat, mais il apparaît beaucoup trop lissé, les cellules semblent isolées les unes des autres. Ce schéma semble ne pas gérer forcément bien la convection peu profonde. Le meilleur résultat selon moi est obtenu avec le type 1, d’une part parce qu’il est plus complet, et d’autre part parce qu’il simule de façon satisfaisante les différents niveaux de convection.</p>

<p>On voit donc l’influence que peut avoir le choix d’une paramétrisation physique sur la qualité de simulation. Sans faire de test chiffré, je n’ai pas vu de différence de temps de calcul significative avec ces différents modèles. Le choix peut donc se porter sur le réalisme de la simulation.</p>

<p>Je ne vais pas faire de discussion longue sur tous les types de schéma des autres phénomènes physiques, je laisse le lecteur expérimenter sur le sujet en utilisant les documentations du modèle.</p>

<h3 id="augmenter-la-résolution-ou-réduire-les-temps-de-calcul">Augmenter la résolution ou réduire les temps de calcul</h3>

<p>Il est tentant pour augmenter la qualité de simulation d’augmenter la résolution du domaine. Avec WRF, il est possible de descendre sous les 5 km, mais il faut savoir que tout doublement de la taille horizontale de grille se traduit par une augmentation du temps de calcul par 4. De même, un doublement du nombre de niveaux verticaux entrainera un doublement du temps de calcul. En réalité, c’est même pire que cela : le pas de temps devra être réduit de moitié pour avoir un modèle numériquement stable, ce qui augmente encore d’un facteur 2 le nombre de calculs à effectuer.</p>

<p>Si l’on prend une grille de 5km, sur 30 niveaux, sur la France, soit une résolution de 256x256x30, il faut à un Intel core i7 3770k environ 1h30 pour calculer 48h de simulation. Un doublement de la résolution horizontale nécessiterais de traiter 4 fois plus de points de maille, et de le faire pour 2 fois plus de pas de temps en raison de la condition de stabilité. Le temps de calcul serait donc multiplié par 8 !</p>

<p>On comprend alors très vite qu’armé d’un simple PC, même puissant, il va devenir compliqué de faire ce genre de simulations dans un temps raisonnable. Pour augmenter la puissance de calcul, il n’y a pas 36 solutions : il faut plus de processeurs. Quand vous vous appelez Météo France, vous disposez d’un monstre équipé de milliers de processeurs capable de vous faire cela avant même que vous n’ayez eu le temps de vous servir un café. Mais tout le monde n’a pas le budget d’un centre de calcul… Une autre solution est de mettre en cluster plusieurs PC et de les faire calculer en parallèle.</p>

<p>Cela nécessite bien entendu un investissement matériel qui peut être conséquent, mais avec des processeurs plus grand public on peut arriver à de très bon résultats sans trop exploser le budget. Dans ce tutorial, on est quasiment prêt pour la mise en cluster. En effet, si vous avez compilé WRF avec l’option MPI, vous avez quasiment tout ce qu’il vous faut. Pour mettre en cluster, l’idée est donc la suivante :</p>

<ul>
  <li>Acheter et assembler plusieurs machines identiques, les mettre en réseau gigabit et prendre un bon abonnement chez EDF</li>
  <li>Installer linux sur chacune des machines en respectant les pré-requis pour WRF,</li>
  <li>installer NFS sur chaque machine. Partager votre dossier météo sur la machine maître pour toutes les autres.</li>
  <li>Mettre en place la communication inter-machines (SSH, fichier host…)</li>
  <li>Compiler WRF sur la machine maître (si vous avez suivi ce tutorial, c’est déjà fait), dans le dossier partagé sur NFS</li>
  <li>Installer MPICH et configurer le fichier machine</li>
  <li>Lancer WRF depuis la machine maître avec la commande MPI qui va bien…</li>
</ul>

<p>Tout ceci ne représente que les grandes lignes, et n’a pas été testé par l’auteur de cet article (qui n’a pas de datacenter chez lui). Une procédure plus détaillée pour Ubuntu est accessible dans <a href="https://help.ubuntu.com/community/MpichCluster">la documentation officielle de la distribution</a>, pour les lecteurs qui seraient tentés d’essayer.</p>

<h3 id="se-concentrer-sur-les-régions-dintérêt">Se concentrer sur les régions d’intérêt</h3>

<p>Pour des raisons de budget, il n’est pas toujours envisageable de monter un cluster de machines chez soi. Pour limiter la puissance de calcul nécessaire, on peut limiter la simulation à des domaines d’intérêt plus petits. Mais un domaine trop petit ne donne pas forcément de bonnes simulations, en raison de la vitesse de propagation de certains phénomènes. Un vent de 100km/h traverserait en 2h un domaine de 200km, ce qui peut poser des problèmes de précision aux limites car par exemple avec GFS on ne dispose que d’un fichier toutes les 3 heures.</p>

<p>On partirais plutôt dans l’optique de baisser la résolution sur notre domaine (la france entière) : une diminution par 3 divise en gros notre temps de calcul par 9. Dans notre cas, on passe de 0.05 degrés à 0.15 degrés, ce qui est grosso-modo trois fois mieux que GFS 0.5 degrés. Notre grille passe de 256x256 à 84x84, et  au lieu de 1H30 de calcul on passe à 10-15 minutes. On utilise cette solution rapide pour initialiser ensuite un domaine plus petit mais avec une résolution 3 fois plus fine, centré sur notre région d’intérêt. On prend une grille de 0.05 dgrés, faisant seulement 128x128 ce qui divise malgré tout le temps de calcul initial par 4 soit environ 25 minutes. Votre temps de calcul pour l’ensemble serait ramené à environ 40-45 minutes.</p>

<p>WRF permet de faire cela très facilement, il suffit pour cela de le recompiler avec l’option nesting. Reprenez pour cela <a href="/2013/11/04/mise-en-oeuvre-wrf-partie-7/">la procédure de la partie 7</a> de ce tutorial, mais déclarez une nouvelle variable d’environnement WRF_NMM_NEST=1 avant de compiler. Ensuite, il faut déclarer les différents domaines dans les fichiers namelist.wps et namelist.input. Inspirez-vous du fichier d’origine fourni avec les sources, qui utilise cette fonctionnalité. A la sortie, WRF produira autant de fichiers que de domaines existants. Il faudra en tenir compte dans le script Unipost et dans les scripts de génération de cartes.</p>

<p><a href="/wp-content/uploads/2014/07/wrf_nesting-1.png"><img src="/wp-content/uploads/2014/07/wrf_nesting.png" alt="Exemple de nesting 0.15° et 0.05°C sur le champ de précipitations." title="Exemple de nesting 0.15° et 0.05°C sur le champ de précipitations." /></a></p>

<p>Exemple de nesting 0.15° (à gauche) et 0.05°C (à droite) sur le champ de précipitations.</p>

<p>Voici les portions importantes du fichier namelist.wps permettant de faire cela :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&amp;share
wrf_core = 'NMM',
max_dom = 2,

&amp;geogrid
parent_id         =   1,    1
parent_grid_ratio =   1,    3
i_parent_start    =   1,    10
j_parent_start    =   1,    26
e_we              =  42,     64
e_sn              =  84,    128
geog_data_res     = '5m', '2m'
dx = 0.15,
dy = 0.15,
</code></pre></div></div>
<p>Les variables à modifier sont :</p>

<ul>
  <li>max_dom : indique le nombre de domaines</li>
  <li>parent_id : permet lier hiérarchiquement les domaines entre eux.</li>
  <li>i_parent_start, j_parent_start : indices de lignes et de colonnes permettant de positionner la grille “détaillée” dans la grille “large”.</li>
  <li>e_we, e_sn, geog_data_res : des paramètres connus qu’il faut définir pour chaque grille</li>
  <li>dx, dy : la résolution de la grille la plus large.</li>
</ul>

<p>Et pareil pour le fichier namelist.input :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&amp;time_control
start_year                          = 2014,   2014
start_month                         = 06,     06,
start_day                           = 30,     30,
start_hour                          = 12,     12,
start_minute                        = 00,      00,
start_second                        = 00,       00,
end_year                            = 2014,     2014,
end_month                           = 07,        07,
end_day                             = 02,        02,
end_hour                            = 12,        12,
end_minute                          = 00,        00,
end_second                          = 00,        00,

...
history_interval                    = 60,        60,
frames_per_outfile                  = 1000,      1000,
...
&amp;domains
e_we                                = 42,        64,
e_sn                                = 84,        128,
e_vert                              = 30,        30,
...
dx                                  = 0.15,    0.05,
dy                                  = 0.15,    0.05,
grid_id                             = 1,        2,
parent_id                           = 0,        1,
i_parent_start                      = 1,        10,
j_parent_start                      = 1,       26,
parent_grid_ratio                   = 1,        3,
parent_time_step_ratio              = 1,        3,
...
&amp;physics
mp_physics                          = 5,        5,
ra_lw_physics                       = 99,        99,
ra_sw_physics                       = 99,        99,
radt                      = 15,  5,
nrads                               = 105,     105,
nradl                               = 105,     105,
co2tf                               = 1,
sf_sfclay_physics                   = 2,        2,
sf_surface_physics                  = 2,        2,
bl_pbl_physics                      = 2,        2,
nphs                                = 6,
cu_physics                          = 1,        1,
ncnvc                               = 6,
tprec                               = 3,         3,
theat                               = 6,         6,
tclod                               = 6,         6,
trdsw                               = 6,         6,
trdlw                               = 6,         6,
tsrfc                               = 6,         6,
pcpflg                              = .false., .false.,
...
&amp;bdy_control
spec_bdy_width                      = 1,
spec_zone                           = 1,
relax_zone                          = 4,
specified                           = .true.,     .false,
nested                              = .false., .true.,
/
...
</code></pre></div></div>

<p>Sans rentrer dans tous les détails, on définit pour chaque grille les différents paramètres de taille de grille et de paramétrisations physiques. En principe, celles-ci sont identiques pour chaque domaine. Mais si vous descendez sous la barre des 3km sur un domaine, il peut être judicieux de se passer des modèles de cumulus car le modèle NMM simule alors explicitement la convection. Le domaine correspondant pourra avoir le cu_physics à 0.</p>

<p>L’économie de temps de calcul est substantielle, puisque je met deux fois moins de temps pour avoir une simulation sur ma région d’intérêt, sans perdre du réalisme de la simulation. Dans certains cas, j’ai même constaté une meilleure précision qu’avec un modèle qui part directement de GFS sur toute la France. En effet, le “nest” se trouve initialisé avec des données aux limites affinées par rapport au GFS d’origine, les forçages par exemple se trouvent mieux rendus.</p>

<h3 id="automatisation">Automatisation</h3>

<p>Nous avons vu jusqu’à maintenant comment mettre en oeuvre le modèle, mais nous n’avons pas parlé d’automatisation. Comment récupérer les données de GFS, lancer le modèle et créer les cartes ? Depuis décembre 2017 nous vous proposons nos scripts sous licence GPL. Pour plus de détails, c’est dans cet article bonus : <a href="/2017/12/16/mb-weather-maps-sous-licence-gpl/">MB Weather Maps, les outils de création de cartes de Météo Blois</a>.</p>

<h3 id="conclusion">Conclusion</h3>

<p>Nous arrivons au terme de cette serie de tutoriaux sur le modèle WRF. Il y aurait certainement encore beaucoup de choses à dire, ce qui fera peut-être l’objet d’articles complémentaires futurs au gré de mes expérimentations. En espérant que cette série vous aura intéressé, que vous aurez trouvé les informations techniques utiles. Et surtout que vous prendrez plaisir autant que moi à expérimenter vous aussi vos propres simulations avec WRF.</p>]]></content><author><name>Nicolas Gasnier</name></author><category term="modèle météo" /><category term="wrf" /><category term="modèle météo" /><category term="compilation" /><category term="linux" /><category term="modélisation" /><summary type="html"><![CDATA[Nous avons fait un long parcours jusqu’ici pour mettre en oeuvre le modèle WRF, que ce soit en version ARW ou NMM. Jusqu’à maintenant, nous n’avons fait qu’utiliser le modèle “tel quel”, sans chercher à comprendre davantage son fonctionnement, comment l’optimiser, et améliorer la qualité de la simulation. Cet ultime article, comme promis précédemment, sera une discussion permettant de donner les pistes nécessaires à une mise en exploitation plus sérieuse du modèle.]]></summary></entry></feed>