Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Boucles sur les entités des matériaux et des milieux

Cette page décrit la gestion des boucles sur les entités des matériaux et des milieux.

Dans le reste de cette page, on utilise le terme générique composant pour décrire un matériau ou un milieu.

Les entités d'un composant peuvent se répartir en deux parties : les entités pures et les entités impures. Par définition, les entités qui ne sont pas pures sont impures. La notion de pure varie suivant le type du composant :

  • pour un milieu, une entité est pure s'il n'y a qu'un milieu dans cette entité.
  • pour un matériau, une entité est pure s'il n'y a qu'un seul matériau ET qu'un seul milieu.

Au niveau du rangement mémoire pour une variable donnée, accéder à une entité pure revient à accéder à la valeur globale de cette variable.

Généralisation des boucles

Depuis la version 2.7.0 de Arcane, La macro générique ENUMERATE_COMPONENTITEM() permet d'itérer sur les entités d'un composant de manière globale ou par partie (pure/impure). Elle peut remplacer les macros ENUMERATE_COMPONENTCELL(), ENUMERATE_MATCELL() et ENUMERATE_ENVCELL().

Les valeurs suivantes sont disponibles pour l'itération :

ENUMERATE_COMPONENTITEM(MatCell,icell,container) avec container de type IMeshMaterial* ou MatCellVector.

Il est possible d'itérer uniquement sur la partie pure ou impure d'un composant.

Note
Actuellement, l'ordre de parcours des boucles par partie pure ou impure n'est pas défini et pourra évoluer par la suite. Cela signifie que s'il y a des dépendances entre les itérations de la boucle le résultat peut varier d'une exécution à l'autre.

Les exemples suivants montrent les différentes variantes de la macro ENUMERATE_COMPONENTITEM()

Boucles sur les milieux

CellGroup test_env_group;
IMeshEnvironment* env = env1;
EnvCellVector env_vector(test_env_group,env);
// Boucle sur les mailles du milieu \a env
ENUMERATE_COMPONENTITEM(EnvCell,ienvcell,env){
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
// Boucle sur les mailles du milieu \a env_vector
ENUMERATE_COMPONENTITEM(EnvCell,ienvcell,env_vector){
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
// Boucle sur les mailles pures du milieu \a env
ENUMERATE_COMPONENTITEM(EnvPartCell,ienvcell,env->pureEnvItems()){
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
// Boucle sur les mailles pures du milieu \a env
ENUMERATE_COMPONENTITEM(EnvPartCell,ienvcell,env,eMatPart::Pure){
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
// Boucle sur les mailles impures du milieu \a env
ENUMERATE_COMPONENTITEM(EnvPartCell,ienvcell,env->impureEnvItems()){
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
// Boucle sur les mailles impures du milieu \a env
ENUMERATE_COMPONENTITEM(EnvPartCell,ienvcell,env,eMatPart::Impure){
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
#define ENUMERATE_COMPONENTITEM(enumerator_class_name, iname,...)
Macro générique pour itérer sur les entités d'un matériau ou d'un milieu.

Boucles sur les matériaux

CellGroup test_mat_group;
IMeshMaterial* mat = env1->materials()[0];
MatCellVector mat_vector(test_mat_group,mat);
// Boucle sur les mailles du matériau \a mat
ENUMERATE_COMPONENTITEM(MatCell,imatcell,mat){
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
// Boucle sur les mailles du matériau \a mat_vector
ENUMERATE_COMPONENTITEM(MatCell,imatcell,mat_vector){
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
// Boucle sur les mailles pures du matériau \a mat
ENUMERATE_COMPONENTITEM(MatPartCell,imatcell,mat->pureMatItems()){
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
// Boucle sur les mailles pures du matériau \a mat
ENUMERATE_COMPONENTITEM(MatPartCell,imatcell,mat,eMatPart::Pure){
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
// Boucle sur les mailles impures du matériau \a mat
ENUMERATE_COMPONENTITEM(MatPartCell,imatcell,mat->impureMatItems()){
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
// Boucle sur les mailles impures du matériau \a mat
ENUMERATE_COMPONENTITEM(MatPartCell,imatcell,mat,eMatPart::Impure){
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}

Boucles génériques sur les composants

// Boucle générique sur les mailles du matériau \a mat
ENUMERATE_COMPONENTITEM(ComponentCell,iccell,mat){
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
// Boucle générique sur les mailles du matériau \a mat_vector
ENUMERATE_COMPONENTITEM(ComponentCell,iccell,mat_vector){
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
// Boucle générique sur les mailles pures du matériau \a mat
ENUMERATE_COMPONENTITEM(ComponentPartCell,iccell,mat->pureItems()){
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
// Boucle générique sur les mailles pures du matériau \a mat
ENUMERATE_COMPONENTITEM(ComponentPartCell,iccell,mat,eMatPart::Pure){
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
// Boucle générique sur les mailles impures du matériau \a mat
ENUMERATE_COMPONENTITEM(ComponentPartCell,iccell,mat->impureItems()){
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
// Boucle générique sur les mailles impures du matériau \a mat
ENUMERATE_COMPONENTITEM(ComponentPartCell,iccell,mat,eMatPart::Impure){
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}

Boucles vectorielles sur les composants

Note
Dans la version actuelle de Arcane (2.7.0), les boucles vectorielles ne sont supportées que sur les milieux (mais pas encore sur les matériaux).

Pour pouvoir utiliser la vectorisation sur les composants, il faut inclure le fichier suivant :

using namespace Arcane::Materials;
Active toujours les traces dans les parties Arcane concernant les matériaux.

Il est nécessaire d'utiliser le mécanisme des lambda du C++11 pour itérer sur les composants via des itérateurs vectoriels. Cela se fait via la macro suivante :

};
#define ENUMERATE_COMPONENTITEM_LAMBDA(iter_type, iter, container)
Macro pour itérer sur les entités d'un composant via une fonction lambda du C++11.
Avertissement
Il ne faut surtout pas oublier le point virgule ';' final. Pour plus d'informations, se reporter à la documentation de cette macro.
Note
Ce mécanisme est expérimental et pourra évoluer par la suite.

Par exemple, avec les déclarations suivantes des variables :

MaterialVariableCellReal mat_pressure(VariableBuildInfo(mesh,"Pressure"));
MaterialVariableCellReal mat_volume(VariableBuildInfo(mesh,"Volume"));
MaterialVariableCellReal mat_temperature(VariableBuildInfo(mesh,"Temperature"));

Il est possible d'utiliser les boucles vectorielles comme suit :

Real nr = 1.0;
// Température et volume en lecture seule
auto in_volume = viewIn(mat_volume);
auto in_temperature = viewIn(mat_temperature);
// Pression en écriture
auto out_pressure = viewOut(mat_pressure);
ENUMERATE_COMPONENTITEM_LAMBDA(EnvPartSimdCell,scell,env){
out_pressure[scell] = nr * in_temperature[scell] / in_volume[scell];
};
Avertissement
Pour des raisons de performance, l'ordre des itérations peut être quelconque. Il est donc indispensable qu'il n'y ait pas de relations entre les itérations. En particulier, si des opérations non associatives telles que des sommes sur des réels sont utilisées, alors le résultat peut varier entre deux exécutions.
Note
L'implémentation actuelle comporte plusieurs limitations :
  • Il n'est pas encore possible d'utiliser ces énumérateurs avec les boucles concurrentes (voir page Parallélisation des boucles sur les matériaux et milieux).
  • Pour le SIMD, il faut obligatoirement utiliser les vues.
  • Pour l'instant les vues ne sont disponibles que pour les variables scalaires. */