\section{Les variables d'état et les entrées/sorties de la physique}
\label{sc:iophy}

Le champ d'ozone est contenu dans la variable \verb+wo+. La variable
\verb+wo+ est utilisée dans la procédure \verb+physiq+ et déclarée
dans le module \verb+phys_state_var_mod+. Au premier passage dans
\verb+physiq+, la procédure \verb+phys_state_var_init+ est appelée,
qui alloue \verb+wo+. Puis, si le modèle n'est pas couplé à INCA,
\verb+wo+ n'est modifié que par \verb+ozonecm+ ou bien lecture d'un
fichier. Cf. figure (\ref{fig:wo}).
\begin{figure}[htbp]
  \centering
  \includegraphics{\local/wo}
  \caption{Flot de la variable \texttt{wo}, contenant le champ
    d'ozone. Un rectangle peut correspondre à une procédure, une
    module ou un fichier. La couleur verte est associée aux modules,
    la couleur noire aux procédures, la couleur rouge aux fichiers.
    Une procédure est représentée par l'empilement de deux rectangles
    : le rectangle supérieur est l'interface de la procédure, le
    rectangle inférieur contient les données locales.  Une variable de
    module est en vert au niveau du module. Une variable de module
    utilisée ou définie dans une procédure, et donc visible dans cette
    procédure par utilisation (\Eng{use association}) ou descente
    (\Eng{host association}) est récrite au niveau de cette procédure
    en bleu. Les variables autres que les variables de module sont
    aussi en bleu. Si la procédure est une fonction alors, dans
    l'interface, le nom de la fonction est repris pour désigner son
    résultat. Une ligne bleue désigne une lecture ou une écriture dans
    un fichier ou une affectation. Une ligne verte désigne une
    association par utilisation ou descente. Une flèche à l'une ou
    l'autre extrémité d'une ligne indique le sens du transfert de la
    donnée (le transfert peut dans certains cas se faire dans les deux
    sens).}
  \label{fig:wo}
\end{figure}

\subsection{Lecture d'un fichier contenant le champ d'ozone}

Nous partons d'un fichier NetCDF contenant le champ d'ozone en
fonction de la latitude, de la pression et du mois de l'année. Le
maillage en latitude et pression peut être quelconque. Le champ
d'ozone est remaillé pour LMDZ, en latitude et en temps, dans
\verb+ce0l+. Le remaillage en temps est une
interpolation linéaire produisant des valeurs pour chaque 360\ieme
d'année à partir des valeurs mensuelles. Le remaillage vertical est
fait une fois par 360\ieme d'année dans \verb+gcm+. Nous négligeons
donc l'effet sur le remaillage de la variation temporelle de pression
à la surface pendant un 360\ieme d'année. Cf. figure (\ref{fig:regrid_o3}).
\begin{figure}[htbp]
  \centering
  \includegraphics{\local/regrid_o3}
  \caption{Remaillage du champ d'ozone pour LMDZ. Remaillage par
    moyenne en latitude et pression. Remaillage par interpolation
    linéaire en temps. Les valeurs mensuelles, en noir, sont interprétées comme
    les valeurs aux milieux des mois. En vert, le remaillage
    latitude-pression à un jour intermédiaire. Le remaillage en
    latitude est le même à toutes les dates. Le remaillage en pression
    change chaque jour.}
  \label{fig:regrid_o3}
\end{figure}

Le fichier lu par \verb+ce0l+ doit s'appeler
\verb+climoz.nc+. \verb+ce0l+ crée un nouveau fichier
NetCDF : \verb+climoz_LMDZ.nc+.

Justification d'un choix de programmation. Pour l'interpolation en
temps dans \verb+ce0l+, nous avons choisi de permettre un fichier
d'entrée contenant 12 ou 14 mois.  Cf. sur le site de LMDZ : Accueil
$\to$ Documentation $\to$ Guides $\to$ LMDZ pas à pas $\to$
Utilisation comme boîte noire $\to$
\href{http://lmdz.lmd.jussieu.fr/documentation/guides/short-guide/utilisation-comme-boite-noire-1/le-champ-dozone}{Le
  champ d'ozone}. Une autre possibilité aurait été de ne permettre que
12 mois dans \verb+climoz.nc+ et de lire trois fichiers
\verb+climoz.nc+ dans \verb+ce0l+ : une année entière d'un fichier, le
mois de décembre seulement d'un autre fichier et le mois de janvier
seulement du dernier fichier. Ce serait simplifier un peu la
préparation des fichiers \verb+climoz.nc+ et compliquer un peu la
programmation dans \verb+ce0l+. Ce serait aussi alourdir un peu
l'utilisation de \verb+ce0l+ : il lui faudrait systématiquement trois
fichiers de climatologie en entrée, dont deux seraient éventuellement
des liens symboliques vers le troisième.


Le programme \verb+gcm+ lit \verb+climoz_LMDZ.nc+, qui doit contenir
la fraction molaire d'ozone en fonction de la latitude, de la pression
et de la date. Le maillage en latitude doit déjà être celui du
programme \verb+gcm+. La date est représentée par un indice compris
entre 1 et 360, indépendamment du calendrier utilisé dans \verb+gcm+.
Lorsque le programme utilise un calendrier à 360 jours, l'indice
correspond au jour de l'année. Pour un autre calendrier, l'indice
correspond à une période d'un trois-cent-soixantième d'année,
différente d'un jour.

\`A chaque passage dans la procédure \verb+physiq+, en fonction de la
date courante, nous décidons de quel état de l'ozone nous avons
besoin, c'est-à-dire de quelle valeur de l'indice temporel comprise
entre 1 et 360. Cette valeur souhaitée de l'indice est dans la
variable \verb+ro3i+ de \verb+physiq+. Le nom \verb+ro3i+ signifie :
``\Eng{required ozone index}''. \verb+ro3i+ est donc recalculé à
chaque passage dans \verb+physiq+. (Cette variable n'a pas à être
rémanente.) Une autre variable de \verb+physiq+, \verb+co3i+, contient
l'indice temporel du champ d'ozone déjà contenu dans la variable
\verb+wo+. Le nom \verb+co3i+ signifie : ``\Eng{current ozone
  index}''. \verb+co3i+ est initialisé à 0 à la compilation et cette
valeur nulle est reconnue comme signifiant que \verb+wo+ n'a pas
encore été défini.

Calcul de \verb+ro3i+. Notons ici $L$ la durée de l'année courante et
$t$ la durée écoulée depuis le début de l'année. ($t$ est la durée
exacte, a priori pas un nombre entier de jours.) Cf. figure
(\ref{fig:read_oz}).
\begin{figure}[htbp]
  \centering
  \includegraphics{\local/read_oz}
  \caption{Indice temporel de l'ozone en fonction de la durée écoulée
    depuis le début de l'année.}
  \label{fig:read_oz}
\end{figure}
Nous avons :
\begin{displaymath}
  \mathtt{ro3i} = E\left(\frac{t}{L / 360}\right) + 1
\end{displaymath}
($E$ est la partie entière.) En principe $t < L$ donc $\mathtt{ro3i}
\le 360$. Dans \verb+physiq+, nous ajoutons un test pour le cas où $t
/ L \times 360$ donnerait une valeur supérieure ou égale à 360, par
erreur d'arrondi. Dans \verb+physiq+, $t$ est donné par :
\begin{verbatim}
days_elapsed + jh_cur - jh_1jan
\end{verbatim}
et $L$ est donné par \verb+ioget_year_len(year_cur)+. Ces deux
expressions sont en jours.

Comme la variable \verb+jh_cur+ dans \verb+physiq+ a le statut OpenMP
de variable privée, nous privatisons aussi \verb+co3i+ (et \verb+ro3i+).

Le programme \verb+gcm+ ne lit pas une fois pour toutes les 360 états
temporels du champ d'ozone, il lit chaque état au moment où il en a
besoin, donc tous les 360\ieme d'année.
