Architecture
Lecture d'un maillage
Dans la première partie de ce projet, nous crééons de multiples classes dans le but de charger un maillage (Mesh
) en mémoire.
Structure du code
Ce projet est composé de plusieurs fichiers contenant le code source :
include
contient les fichiers d'en-tête.hpp
.src
contient les fichiers sources.cpp
.tests
contient les fichiers de tests permettant de tester et reproduire les résultats attendus par l'énoncé.input
contient les fichiers des divers maillages (4elt, M0, M1, M2, perforated).
Dans le but de tester nos résultats, des fonctions définies dans include/tests.hpp
permettent :
- de vérifier l'égalité de deux
double
sous une certaine tolérance :bool check_double_equal(double a, double b, double tol)
- de vérifier que 2
doubles
sont différents sous une certaine tolérance :bool check_double_not_equal(double a, double b, double tol)
PhysicalName
La classe PhysicalName
contient les marqueurs physiques des éléments du maillage.
Des opérateurs d'entrée et de sortie sont définis pour pouvoir lire et écrire un PhysicalName
depuis un fichier.
Node
La classe Node
représente un noeud du maillage.
Des opérateurs d'entrée et de sortie sont définis pour pouvoir lire et écrire un Node
depuis un fichier.
Element
La classe Element
représente un élément du maillage (triangle ou segment).
Des opérateurs d'entrée et de sortie sont définis pour pouvoir lire et écrire un Element
depuis un fichier.
De multiples opérations nécéssitent de différencier les éléments par type (triangle ou segment). Ainsi, une méthode int Element::type() const
permet de retourner le type de l'élément.
Mesh
La classe Mesh
représente un maillage.
Un ensemble de méthodes ont été implémentées dans le but d'accéder aux attributs de la classe Mesh
.
La lecture d'un maillage est effectuée lors de la création d'une classe Mesh
. Ainsi, le chemin d'accès au fichier est passé en paramètre du constructeur.
Les attributs M_nb_edges
et M_edges
représentent respectivement le nombre de segments (éléments du bord) et les identifiants des noeuds de ces segments. Ces attributs sont calculés lors de la lecture du maillage. Pour cela, nous parcourons tous les éléments du maillage et nous ajoutons les identifiants des noeuds des segments dans l'ensemble M_edges
.
L'attribut M_egdes
est un std::set
qui permet de stocker les identifiants des noeuds des segments sans doublons.
Calcul de l'aire d'un maillage
La méthode double Mesh::area()
permet de calculer l'aire d'un maillage en sommant les aires des triangles du maillage. Il est donc nécéssaire de filter les éléments par type en vérifiant que e.type() == 2
.
Une méthode permettant de calculer l'aire d'un triangle est également implémentée double Element::area(Node **nodes) const
. Cette méthode est utilisée dans la méthode Mesh::area()
.
Accès aux noeuds
La méthode Element::area
prend en argument un pointeur vers le tableau des noeuds du maillage Node **nodes
. En effet, chaque Element
contient les identifiants de ses noeuds. Pour accéder aux coordonnées des noeuds, il faut donc passer en argument le tableau des noeuds du maillage, ce tableau étant connu uniquement dans la classe Mesh
.
Calcul du périmètre d'un maillage
La méthode double Mesh::perimeter()
permet de calculer le périmètre d'un maillage en sommant les longueurs des segments du maillage. Il est donc nécéssaire de filter les éléments par type en vérifiant que e.type() == 1
.
La formule permettant de calculer la longueur d'un segment est la suivante :
Tests
Pour tester le bon fonctionnement de notre code, l'éxécutable ./part_1
permet de tester les résultats attendus par l'énoncé.
Celui-ci calcule l'aire et le périmètre des maillages 4elt
et perforated
dont le résultat est affiché dans la console.
Les fonctions tests définies précédemment permettent de vérifier que les résultats calculés sont corrects.
std::cout << std::boolalpha << check_double_equal(mesh_4elt.area(), 1.0, 1e-4) << std::endl;
std::cout << std::boolalpha << check_double_equal(mesh_4elt.perimeter(), 4.0, 1e-4) << std::endl;
std::cout << std::boolalpha << check_double_equal(mesh_perforated.area(), 0.837725, 1e-4) << std::endl;
std::cout << std::boolalpha << check_double_equal(mesh_perforated.perimeter(), 11.5086, 1e-4) << std::endl;