Arcane  v3.14.11.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Exemple n°5

Dans cet exemple, on va montrer un exemple d'utilisation de lecture/ remplissage du tableau via la position d'un pointeur.

En effet, jusque-là, on a rempli nos tableaux de valeurs avec les noms de lignes/colonnes, en mettant les valeurs les une à côté des autres.
Il se trouve qu'en interne, lorsqu'un élément est ajouté ou modifié, il y a un pointeur qui se met à jour et qui pointe vers le dernier élément manipulé.

Remarques
Pointeur dans le sens "pointeur vers une position du tableau 2D", pas dans le sens "pointeur `C` vers une zone mémoire".

On va donc pouvoir utiliser ce pointeur pour modifier des valeurs autour de la dernière valeur manipulée.

Results_Example5 Iteration 1 Iteration 2 Iteration 3 Somme
Nb de Fissions 36 0 85 121
Nb de Fissions (div par 2) 18 0 42.5 60.5
Nb de Collisions 29 84 21 134
Nb de Collisions (div par 2) 14.5 42 10.5 67

Point d'entrée initial

Voyons le point d'entrée start-init :

SimpleTableOutputExample5Module.cc

void SimpleTableOutputExample5Module::
initModule()
{
srand(1234);
options()->stOutput()->init();
StringUniqueArray columns_name(NB_ITER);
for(Integer i = 0; i < NB_ITER; i++){
columns_name[i] = "Iteration " + String::fromNumber(i+1);
}
options()->stOutput()->addColumns(columns_name);
// On ajoute aussi quatre lignes.
// Toujours dans un soucis d'optimisation, on peut créer les lignes et récupérer
// leur position pour la suite, ainsi, on évite deux recherches de String dans un
// tableau de String à chaque itération.
options()->stOutput()->addRows(StringUniqueArray{
"Nb de Fissions",
"Nb de Fissions (div par 2)",
"Nb de Collisions",
"Nb de Collisions (div par 2)"});
pos_fis = options()->stOutput()->rowPosition("Nb de Fissions");
pos_col = options()->stOutput()->rowPosition("Nb de Collisions");
options()->stOutput()->print();
}

Ici, rien de bien original, mis à part les deux lignes en plus : (div par 2). Ces deux lignes vont contenir le nombre de fissions/collisions d'une itération divisé par 2.

Point d'entrée loop

Voyons le point d'entrée compute-loop :

SimpleTableOutputExample5Module.cc

void SimpleTableOutputExample5Module::
loopModule()
{
Integer nb_fissions = rand()%99;
Integer nb_collisions = rand()%99;
// Ici, on utilise editElementDown() pour ajouter un élement sous l'élement dernièrement
// modifié.
options()->stOutput()->addElementInRow(pos_fis, nb_fissions);
options()->stOutput()->editElementDown(nb_fissions/2.);
options()->stOutput()->addElementInRow(pos_col, nb_collisions);
options()->stOutput()->editElementDown(nb_collisions/2.);
options()->stOutput()->print();
if (m_global_iteration() == NB_ITER)
subDomain()->timeLoopMng()->stopComputeLoop(true);
}

Une nouvelle méthode fait son apparition : ISimpleTableOutput::editElementDown().
Cette méthode permet de modifier la "case" sous la "case" que l'on vient de modifier.
Prenons les deux lignes dédiées à la fission. La première ligne ajoute une valeur sur la ligne Nb de Fissions.
En interne, un pointeur est modifié et pointe désormais sur la valeur que l'on vient d'ajouter.
La seconde ligne appelle la nouvelle méthode. Cette méthode va prendre le pointeur, va rechercher la "case" en dessous et va remplacer sa valeur par nb_fissions/2. Par défaut, le pointeur sera alors mis à jour et pointera vers cette "case" manipulée. Donc si on voulait ajouter, par exemple, nb_fissions*2 juste en dessous, on pourrai refaire un appel à la méthode ISimpleTableOutput::editElementDown() juste après.

Dans le cas où il y aurai une modification de nb_fissions entre les deux lignes (sans toucher au tableau) :

options()->csvOutput()->addElementInRow(pos_fis, nb_fissions);
nb_fissions += 456;
options()->csvOutput()->editElementDown(nb_fissions/2.); // Pas la bonne valeur !!!

On pourrai faire ça :

options()->csvOutput()->addElementInRow(pos_fis, nb_fissions);
nb_fissions += 456;
options()->csvOutput()->editElementDown(element()/2.); // C'est correct !!!

ISimpleTableOutput::element() est une méthode qui permet de récupérer la valeur de la "case" pointé par le pointeur. Ça peut être pratique dans ce cas là par exemple (on est d'accord que si on n'utilise pas le pointeur et les méthodes associées, c'est une méthode qui ne sert à rien).

Note
Il n'y a pas que la méthode ISimpleTableOutput::editElementDown(), il existe des méthodes équivalentes pour les quatre directions :
ISimpleTableOutput::editElementUp()
ISimpleTableOutput::editElementLeft()
ISimpleTableOutput::editElementRight()
Idem pour ISimpleTableOutput::element().

Point d'entrée exit

Enfin, voyons le point d'entrée exit :

SimpleTableOutputExample5Module.cc

void SimpleTableOutputExample5Module::
endModule()
{
for(Integer pos = 0; pos < options()->stOutput()->numberOfRows(); pos++) {
RealUniqueArray row = options()->stOutput()->row(pos);
Real sum = 0.;
for(Real elem : row) {
sum += elem;
}
options()->stOutput()->addElementInColumn("Somme", sum);
}
options()->stOutput()->print();
options()->stOutput()->writeFile();
}

Ce point d'entrée est identique à celui de l'exemple précédent.