Avant de pouvoir coder une opération, il faut bien comprendre comment s'écrit une boucle sur une liste d'entités de maillage telles que les mailles ou les noeuds. En effet, pratiquement toutes les opérations que l'on effectue se font sur un ensemble d'entités et donc comportent une boucle sur une liste d'entités. Par exemple, calculer la masse des mailles consiste à boucler sur l'ensemble des mailles et pour chacune d'elle effectuer le produit de son volume par sa densité. Conventionnellement, cela peut s'écrire de la manière suivante :
La boucle for comprend trois parties séparées par un point-virgule. La première est l'initialisation, la seconde est le test de sortie de boucle et la troisième est l'opération effectuée entre deux itérations.
L'écriture précédente a plusieurs inconvénients :
m_velocity
[i] avec i
étant un numéro de maille et m_velocity
une variable aux noeuds ;En considérant qu'on parcourt toujours la liste des entités dans le même ordre, il est possible de modéliser le comportement précédent par quatre opérations :
Le mécanisme est alors général et indépendant du type du conteneur : l'ensemble des entités pourrait être implémenté sous forme de tableau ou de liste sans changer ce formalisme. Dans l'architecture, le compteur ci-dessus est appelé un itérateur et itérer sur l'ensemble des éléments se fait en fournissant un itérateur de début et de fin, autrement appelé un énumérateur
Dans Arcane, cet énumérateur dérive de la classe de base ItemEnumerator et possède les méthodes suivantes:
Afin d'ajouter un niveau d'abstraction supplémentaire et de permettre d'instrumenter le code, Arcane fournit une fonction sous forme de macro pour chaque type d'énumérateur. Il n'est donc pas nécessaire d'utiliser les méthodes de ItemEnumerator. Cette fonction possède le prototype suivant :
avec:
Lorsqu'on se trouve dans un module (dont la classe de base est BasicModule) ou un service (dont la classe de base est BasicService), Arcane fournit des méthodes pour accéder au groupe contenant toute les entités d'un genre d'entité donné. Par exemple la méthode BasicModule::allCells() permet de récupérer le groupe de toutes les mailles. Ainsi, pour itérer sur toutes les mailles, avec i le nom de l'itérateur, on peut faire comme cela :
La boucle de calcul de la masse décrite précédemment devient alors :
Le type d'un énumérateur dépend du genre de l'élément de maillage : un énumérateur sur un groupe de noeuds n'est pas du même type qu'un énumérateur sur un groupe de mailles et ils sont donc incompatibles. Par exemple, si la vitesse est une variable aux noeuds, l'exemple suivant provoque une erreur de compilation :
De même, il est impossible d'écrire :
car BasicModule::allNodes() est un groupe de noeud et i un énumérateur sur un groupe de mailles.
Notons que l'opérateur '*' de l'énumérateur permet d'accéder à l'élément courant :
Il est possible d'utiliser l'entité elle-même pour récupérer la valeur d'une variable mais, pour des raisons de performances, il faut privilégier l'accès par l'itérateur :