Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
Example n°4

From this example, options or singletons will no longer be an issue. Here, the focus will be on optimization, in case this service is used more seriously than for simple debugging.

The result will therefore change slightly:

Results_Example4 Iteration 1 Iteration 2 Iteration 3 Somme
Nb de Fissions 36 0 85 121
Nb de Collisions 29 84 21 134

Initial entry point

Let's look at the start-init entry point:

SimpleTableOutputExample4Module.cc

void SimpleTableOutputExample4Module::
initModule()
{
srand(1234);
options()->stOutput()->init();
// Pour cet exemple, on va définir le nom des colonnes dès l'init.
// En effet, ajouter des colonnes au fur et à mesure prend du temps
// puisque le tableau est réalloué à chaque fois (dans l'implem actuelle).
// (après, si les perfs de cette partie ne sont pas une priorité, c'est
// pas impératif de faire ça, tout dépend de l'utilisation faite du service).
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 les deux 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 Collisions"});
m_pos_fis = options()->stOutput()->rowPosition("Nb de Fissions");
m_pos_col = options()->stOutput()->rowPosition("Nb de Collisions");
options()->stOutput()->print();
}

In this example, we will create the rows and columns in the init instead of doing it gradually.

Additionally, we will retrieve the row positions.

Indeed, internally, the value array is simply represented by an object of the RealUniqueArray2 class, a 2D array. At the algorithmic level, this array is represented by a 1D array, with each row placed side by side in memory. Creating a row is therefore easy (if there is space) because you just need to enlarge the 1D array. But adding a column is noticeably more complex and time-consuming because you are forced to shift the values of N-1 rows. And the more values there are in the array, the longer it will take.

To avoid all this, we can create the rows and columns from the start. Afterward, it will be enough to add the values where necessary.

To go even further, we save the positions of the two rows in class attributes. This allows us to avoid performing a search for the String in the internal row name array StringUniqueArray. But this is dispensable given that the fewer rows there are, the less costly this search is, and the more rows there are, the more complicated position management becomes. For this part, it's up to you.

Loop entry point

Let's look at the compute-loop entry point:

SimpleTableOutputExample4Module.cc

void SimpleTableOutputExample4Module::
loopModule()
{
Integer nb_fissions = rand()%99;
Integer nb_collisions = rand()%99;
// On ajoute deux valeurs à nos deux lignes.
options()->stOutput()->addElementInRow(m_pos_fis, nb_fissions);
options()->stOutput()->addElementInRow(m_pos_col, nb_collisions);
options()->stOutput()->print();
if (m_global_iteration() == NB_ITER)
subDomain()->timeLoopMng()->stopComputeLoop(true);
}

Here, we can see that the ISimpleTableOutput::addElementInRow() method is used differently. Indeed, this method is overloaded to allow the use of the row position instead of its name, which avoids a String search. Furthermore, this method returns a boolean that indicates whether the value could be added or not, in case the position is incorrect. (To simplify the example, I do not check the returned value).

Exit entry point

Finally, let's look at the exit entry point:

SimpleTableOutputExample4Module.cc

void SimpleTableOutputExample4Module::
endModule()
{
// On peut faire la somme des valeurs des lignes si on souhaite.
// Dans le cas où il y a des cases vides, elle sont initialisé à 0.
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();
}

To vary things a bit and show how to use the values entered into the array, we calculated the sum of the two rows and put these results into a new column, Somme.

Note
We do not use an ArrayView in the service because it is impossible to create a view on a column given that the column values are discontinuous.

This sum example shows that this service is not just a file writing service but can also store values to exploit later.