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);
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
EnvCell c = *ienvcell;
mat_pressure[c] = mat_temperature[ienvcell];
}
Boucles sur les matériaux
CellGroup test_mat_group;
IMeshMaterial* mat = env1->materials()[0];
MatCellVector mat_vector(test_mat_group,mat);
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
MatCell c = *imatcell;
mat_pressure[c] = mat_temperature[imatcell];
}
Boucles génériques sur les composants
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
ComponentCell c = *iccell;
mat_pressure[c] = mat_temperature[iccell];
}
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 :
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;
auto in_volume = viewIn(mat_volume);
auto in_temperature = viewIn(mat_temperature);
auto out_pressure = viewOut(mat_pressure);
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. */