Documentation de Prise en Main pour Développeurs : Module foampilot
1. Introduction
Le module foampilot est conçu pour simplifier et automatiser la création, la configuration, l'exécution et le post-traitement des cas de simulation basés sur OpenFOAM. Il offre une interface orientée objet en Python pour gérer les fichiers de configuration complexes d'OpenFOAM, permettant aux développeurs de se concentrer sur la physique et la géométrie du problème plutôt que sur la syntaxe des dictionnaires.
Cette documentation a pour but de fournir une vue d'ensemble détaillée de la structure du code pour faciliter la compréhension et la contribution au projet.
2. Concepts Clés et Architecture
L'architecture de foampilot est étroitement calquée sur la structure d'un cas OpenFOAM standard, qui est divisé en trois répertoires principaux : constant, system, et le répertoire du temps initial (0).
La Classe Centrale : Solver
La classe Solver (foampilot.solver.Solver) est l'orchestrateur central du module. Elle encapsule l'ensemble du cas de simulation et fournit des points d'accès aux configurations des répertoires constant et system, ainsi qu'à la gestion des conditions aux limites.
Lors de l'initialisation, une instance de Solver crée automatiquement les objets nécessaires pour gérer les fichiers de configuration :
solver.constant: Une instance deConstantDirectorypour gérer les fichiers du répertoireconstant.solver.system: Une instance deSystemDirectorypour gérer les fichiers du répertoiresystem.solver.boundary: Une instance deBoundarypour gérer les conditions aux limites.
3. Structure Détaillée du Code
Le cœur de la logique de foampilot se trouve dans le répertoire foampilot/foampilot/src/foampilot. Ce répertoire est organisé en sous-modules logiques, chacun responsable d'un aspect spécifique de la gestion des cas OpenFOAM.
| Répertoire Source | Description | Classes Clés (Exemples) |
|---|---|---|
base |
Classes de base et utilitaires pour la manipulation des fichiers OpenFOAM. | Meshing, OpenFOAMFile |
solver |
Contient la classe principale Solver et la logique d'exécution de la simulation. |
Solver, BaseSolver |
constant |
Gestion des fichiers de configuration dans le répertoire constant. |
ConstantDirectory, transportPropertiesFile, turbulencePropertiesFile |
system |
Gestion des fichiers de configuration dans le répertoire system. |
SystemDirectory, controlDictFile, fvSchemesFile, fvSolutionFile |
boundaries |
Définition et application des conditions aux limites. | Boundary, boundaries_conditions_config |
mesh |
Outils de maillage, y compris l'intégration avec classy_blocks et snappyHexMesh. |
BlockMeshFile, Meshing, gmsh_mesher |
utilities |
Fonctions et classes utilitaires non spécifiques à OpenFOAM (unités, propriétés des fluides, etc.). | Quantity, FluidMechanics, manageunits |
postprocess |
Classes pour l'analyse des résultats, la visualisation (via pyvista) et l'extraction de données. |
FoamPostProcessing, ResidualsPost |
4. Mécanismes Internes pour les Développeurs
Pour une contribution efficace, il est crucial de comprendre comment foampilot traduit les objets Python en fichiers OpenFOAM et gère la complexité des configurations.
4.1. Le Mécanisme d'Écriture des Fichiers (OpenFOAMFile)
Le cœur de la sérialisation des données réside dans la classe de base OpenFOAMFile (foampilot/foampilot/src/foampilot/base/openFOAMFile.py).
- Héritage et Attributs : Chaque fichier de configuration OpenFOAM (comme
transportPropertiesFileoucontrolDictFile) hérite deOpenFOAMFile. Les paramètres de configuration sont stockés dans l'attributself.attributesde l'instance. - Accès Dynamique : La surcharge des méthodes magiques
__getattr__et__setattr__permet d'accéder et de modifier les paramètres directement comme des attributs de l'objet (ex:solver.constant.transportProperties.nu = ...), même si ces paramètres sont stockés dans le dictionnaireself.attributes. - Sérialisation (
write_file) : La méthodewrite_fileparcourt récursivement le dictionnaireself.attributeset utilise la méthode interne_format_valuepour convertir les types de données Python (booléens, nombres, tuples, et surtoutQuantity) en la syntaxe spécifique d'OpenFOAM (ex:true/false, listes entre parenthèses).
4.2. Gestion des Unités et des Dimensions (Quantity)
La classe Quantity (foampilot/foampilot/src/foampilot/utilities/manageunits.py) est un wrapper autour de la librairie pint et est essentielle pour assurer la cohérence physique.
- Rôle : Elle stocke une valeur numérique avec son unité physique (ex:
Quantity(10, "m/s")). - Conversion Automatique : Lors de l'écriture dans un fichier OpenFOAM, la méthode
_format_valuedeOpenFOAMFilevérifie si la valeur est une instance deQuantity. Si c'est le cas, elle utilise la méthodeget_in(target_unit)pour convertir la valeur dans l'unité attendue par OpenFOAM (définie dansOpenFOAMFile.DEFAULT_UNITS), garantissant que toutes les valeurs écrites sont dans le système d'unités de base d'OpenFOAM. - Dimensions OpenFOAM : La méthode
to_openfoam_dimensions()utilise les capacités depintpour dériver le vecteur de dimensions OpenFOAM (M, L, T, Θ, N, J, A) à partir de l'unité, ce qui est crucial pour la génération des en-têtes de fichiers de champs (ex:U,p).
4.3. Orchestration du Solveur et des Champs (Solver et CaseFieldsManager)
La classe Solver délègue la gestion des champs à la classe CaseFieldsManager (foampilot/foampilot/src/foampilot/base/cases_variables.py).
- Sélection du Solveur : La classe
Solver(foampilot/foampilot/src/foampilot/solver/solver.py) utilise des propriétés booléennes (ex:self.compressible,self.with_gravity,self.is_vof) pour déterminer le type de simulation. La méthode interne_update_solver()sélectionne le solveur OpenFOAM approprié (ex:incompressibleFluid,compressibleVoF) et met à jour l'instance deBaseSolver. - Gestion des Champs :
CaseFieldsManagerutilise ces mêmes propriétés pour générer dynamiquement la liste des champs physiques nécessaires (ex:U,p,k,epsilon,T).- Si
self.with_gravityest vrai, le champ de pression devientp_rgh. - Si un modèle de turbulence est défini, les champs associés (
k,epsilon,omega,nut) sont ajoutés. - Cette liste de champs est ensuite utilisée par la classe
Boundarypour initialiser les conditions aux limites pour tous les champs requis.
- Si
4.4. Gestion Avancée des Conditions aux Limites (Boundary)
La classe Boundary (foampilot/foampilot/src/foampilot/boundaries/boundaries_dict.py) est responsable de la traduction des conditions physiques en configurations OpenFOAM.
- Configuration Centralisée : Elle utilise un dictionnaire de configuration (
BOUNDARY_CONDITIONS_CONFIG) qui mappe les types de conditions physiques (ex:"velocityInlet") aux configurations OpenFOAM requises pour chaque champ (U, p, k, etc.), en fonction du modèle de turbulence sélectionné. - Application par Wildcard : La méthode
apply_condition_with_wildcard(pattern, condition_type, **kwargs)permet d'appliquer une condition à tous les patchs dont le nom correspond à une expression régulière (pattern). - Résolution des Conditions : Pour chaque champ, la méthode
_resolve_field_configdétermine la configuration OpenFOAM finale. Par exemple, pour une condition de paroi (wall), elle choisit entrenoSlipouslipen fonction des arguments fournis, et applique les fonctions de paroi (wallFunction) appropriées pour les champs de turbulence (k, epsilon, etc.) en utilisant le dictionnaireWALL_FUNCTIONS. - Génération des Fichiers : La méthode
write_boundary_conditions()itère sur tous les champs gérés parCaseFieldsManageret utiliseOpenFOAMFile.write_boundary_filepour générer les fichiers de conditions aux limites dans le répertoire0/.
5. Flux de Travail du Développeur (Basé sur run_exemple2.py)
L'exemple d'utilisation illustre le flux de travail typique pour un développeur utilisant foampilot :
| Étape | Description | Classes et Méthodes Clés |
|---|---|---|
| 1. Initialisation | Définir le répertoire de travail et initialiser le solveur. | Solver(path), FluidMechanics |
| 2. Configuration Physique | Déterminer les propriétés du fluide et les appliquer aux fichiers de configuration. | FluidMechanics.get_fluid_properties(), solver.constant.transportProperties.nu = ... |
| 3. Maillage | Définir la géométrie et le maillage (souvent via l'intégration classy_blocks) et générer le blockMeshDict. |
classy_blocks.Cylinder, cb.Mesh(), Meshing(path, mesher="blockMesh") |
| 4. Conditions aux Limites | Initialiser et appliquer les conditions aux limites aux patchs définis par le maillage. | solver.boundary.initialize_boundary(), solver.boundary.apply_condition_with_wildcard() |
| 5. Écriture des Fichiers | Générer tous les fichiers de configuration OpenFOAM sur le disque. | solver.system.write(), solver.constant.write(), solver.boundary.write_boundary_conditions() |
| 6. Exécution | Lancer la simulation OpenFOAM. | solver.run_simulation() |
| 7. Post-traitement | Analyser les résultats, générer des visualisations et des rapports. | FoamPostProcessing, ResidualsPost, latex_pdf.LatexDocument |
Ce flux de travail met en évidence la manière dont les différents modules de foampilot s'articulent pour fournir une abstraction complète du processus de simulation OpenFOAM. Pour contribuer, un développeur doit comprendre comment les classes de chaque module interagissent avec l'objet central Solver et comment elles traduisent les commandes Python en syntaxe de dictionnaire OpenFOAM.