164 | | * L'inclusion d'un pointeur de tableau réel en tant que nouvelle composante du type dérivé "tr" permet d'obtenir des raccourcis documentés vers les traceurs (utile notamment pour l'eau) tout en les laissant rangés comme avant (pas de pénalité numérique). A discuter. |
165 | | * Ces objets "tr" incluent, de manière plus ordonnée, donc pratique il me semble, les différents indices gérant les différentes générations. À rediscuter avec Camille, notamment pour savoir comment ranger la partie "initialisation" (les valeurs par défaut - coefficients de fractionnement par exemple - utiles pour les isotopes et leur initialisation, seraient assez à leur place dans les fichiers tracer_*.def sous forme de clefs). |
| 164 | |
| 165 | * Il n'est pas nécessaire de substituer aux principaux tableaux (**qx** et **tr_seri** notamment) des types dérivés **tr** étendus par ajout d'une composante tableau: on peut conserver le tableau lui-même inchangé, tout en disposant du descripteur associé (de type **tr**), accessible par indice (numéro de traceur dans **qx** ou **tr_seri**) ou par nom de traceur (utilisation de **idxTracer()**). |
| 166 | Ces descripteurs présentent l'avantage de regrouper en une seule variable vectorielle les informations utiles pour tous les traceurs. |
| 167 | |
| 168 | * De nombreuses variables possèdent un pendant isotopique (souvent repéré par un **x** additionnel dans le préfixe) ; les opérations s'appliquant à ces variables comme à leurs descendantes forçent pour l'instant la création explicite de ces descendantes ainsi que la duplication des lignes de code correspondant aux opérations en question. |
| 169 | L'utilisation d'un pointeur semble toute indiquée. Par exemple, pour **q_seri** étendue à ses isotopes, pour l'exemple donné plus haut, il faudrait pouvoir écrire: |
| 170 | {{{ |
| 171 | q_seri => qx(:,:,[1,(k,k=10:21)]) |
| 172 | }}} |
| 173 | Cette extension de la fonction **aliasTracer()** est hélas illicite en fortran: un pointeur ne peut être associé à des sections non contigües d'un tableau. |
| 174 | Abandonner le classement des traceurs dans **qx** par génération croissante pourrait résoudre le problème, mais rendrait l'organisation bien moins claire (resterait aussi à savoir comment ranger les traceurs de tagging). |
| 175 | Il semble préférable de se contenter de définir **q_seri** (et les autres variables analogues) sous la forme d'un objet de type dérivé muni d'une composante contenant le vecteur d'indices des traceurs de **qx** requis. Les opérations répétées sur la variable principale et ses variables isotopiques le sont par simple bouclage sur ce vecteur d'indices. |
| 176 | On définit donc le type dérivé suivant: |
| 177 | {{{ |
| 178 | TYPE tr2 |
| 179 | REAL, ALLOCATABLE :: v(:,:,:) |
| 180 | INTEGER ALLOCATABLE :: iq(:) |
| 181 | END TYPE tr2 |
| 182 | }}} |
| 183 | Dans le cas de **q_seri**: |
| 184 | {{{ |
| 185 | TYPE(tr2) :: q_seri |
| 186 | q_seri = defVar('H2O-g') |
| 187 | }}} |
| 188 | La fonction **defVar** encapsule les opérations nécessaires: |
| 189 | {{{ |
| 190 | TYPE(tr2) FUNCTION defVar(name) RESULT(out) |
| 191 | CHARACTER(LEN=*), INTENT(IN) :: name |
| 192 | INTEGER :: ix, n |
| 193 | ix = idxTracer(name) |
| 194 | out%iq = [ix, tracers(ix)%ichild(:)] |
| 195 | out%v = [ ( qx(:,:,out%iq(k)), k=1, SIZE(out(:), DIM=1) ) ] |
| 196 | END FUNCTION defVar |
| 197 | }}} |
| 198 | On peut envisager d'ajouter un second argument à defVar: la génération maximale (2 dans l'exemple ci-dessus). |
| 199 | La boucle typique pour une opération agissant sur une grandeur de génération 1 et ses dérivés isotopiques prend alors la forme (exemple pour **q_seri**): |
| 200 | {{{ |
| 201 | DO k=1,SIZE(t_seri%iq, DIM=1) |
| 202 | Opérations sur t_seri%v(:,:,t_seri%iq(k)) |
| 203 | END DO |
| 204 | }}} |
| 205 | Si l'objectif est d'agir directement sur des composantes de **qx**, sans création d'une variable spécifique **t_seri%v(:,:,:)**, il suffit de remplacer **t_seri%v(:,:,t_seri%iq(k))** par **qx(:,:,iq(k))**, où **iq(:)** est le vecteur d'undices non encapsulé dans un type dérivé. |
| 206 | |
| 207 | * Ajout de caractéristiques des isotopes dans le fichier **tracer_*.def** directement, en tant que clefs supplémentaires, accessibles grâce à la routine **getKey()**. |
| 208 | Notamment, **tnat** et **alpha_ideal** me semblent ici plus à leur place qu'en dur dans le code. |
| 209 | L'exemple donné plus haut devient: |
| 210 | |
| 211 | {{{ |
| 212 | &version=1.0 |
| 213 | &default |
| 214 | # Note: currently, the 2 recognized types are "tracer" and "tag" |
| 215 | parent=air hadv=10 vadv=10 phases=g type=tracer |
| 216 | &lmdz |
| 217 | blue,red parent=H[2]HO,H2O type=tag # Tagging tracer of gen 1&2 tracers |
| 218 | H2O phases=g hadv=14 vadv=14 # Water vapour |
| 219 | water parent=H2O tnat=1.0 alpha=1.0 # [1]H[1]H[16]O ~ H2O total |
| 220 | H2[18]O parent=H2O tnat=2.00052e-3 alpha=1.006 # [1]H[1]H[18]O |
| 221 | H[2]HO parent=H2O tnat=1.5576e-4 alpha=1.01 # [1]H[2]H[16]O |
| 222 | H[3]HO parent=H2O tnat=0. alpha=1.0 # [1]H[3]H[16]O |
| 223 | yellow parent=H[3]HO type=tag # Tagging tracer for single isotope |
| 224 | H2O phases=ls # H2O in liquid and solid phases |
| 225 | }}} |
| 226 | |
| 227 | Deux remarques: |
| 228 | |
| 229 | 1) On perd l'avantage de la factorisation en fonction des parents à cause de ces paramètres ; on pourrait le garder avec cette convention: |
| 230 | {{{ |
| 231 | water,H2[18]O,H[2]HO,H[3]HO parent=H2O tnat=1.0,2.00052e-3,1.5576e-4,0. alpha=1.0,1.006,1.01,1.0 |
| 232 | }}} |
| 233 | mais ça n'est pas très lisible. Tant que le nombre d'isotopes n'est pas excessif, l'inconvénient de cette perte me semble mineur. |
| 234 | |
| 235 | 2) Un fichier **tracer_*.def** ne contenant pas nécessairement tous les isotopes utilisables, et ne constitue pas une base de données complète pour des paramètres tels que **tnat** et **alpha_ideal**. |
| 236 | On peut pallier à ce défaut par exemple: |
| 237 | - en créant une base de données séparée sous la forme de sections supplémentaires ; exemple: |
| 238 | {{{ |
| 239 | &tnat |
| 240 | water,1.0 H2[17]O,4.E-5 H2[18]O,2.00052e-3 H[2]HO,1.5576e-4 H[3]HO,0. |
| 241 | &alpha |
| 242 | water,1.0 H2[17]O,1.003 H2[18]O,1.006 H[2]HO,1.01 H[3]HO,1.0 |
| 243 | }}} |
| 244 | Ça me semble relativement peu lisible... |
| 245 | - en ajoutant une clef "activate" pour indiquer lorsqu'un traceur/isotope est ou n'est pas activé: |
| 246 | {{{ |
| 247 | &version=1.0 |
| 248 | &default |
| 249 | type_trac=lmdz parent=air hadv=10 vadv=10 phases=g type=tracer activate=y |
| 250 | &lmdz |
| 251 | H2O phases=g hadv=14 vadv=14 # vapour water |
| 252 | H2O phases=l # liquid water |
| 253 | water parent=H2O tnat=1.0 alpha=1.0 # [1]H[1]H[16]O ~ H2O total |
| 254 | H2[17]O parent=H2O tnat=4.E-5 alpha=1.003 activate=n # [1]H[1]H[17]O |
| 255 | H2[18]O parent=H2O tnat=2.00052e-3 alpha=1.006 # [1]H[1]H[18]O |
| 256 | H[2]HO parent=H2O tnat=1.5576e-4 alpha=1.01 # [1]H[2]H[16]O |
| 257 | H[3]HO parent=H2O tnat=0. alpha=1.0 # [1]H[3]H[16]O |
| 258 | }}} |
| 259 | Ça me semble un peu lourd, et on ne sait pas au premier coup d'œil ce qui est vraiment utilisé dans le modèle. |
| 260 | La solution initiale (pas de base de données complète dans tout fichier **tracer_*.def** concernant des paramètres supplémentaires du type **tnat** ou **alpha_ideal**) semble donc préférable. |
| 261 | À discuter. |