2.1. Matrices Creuses#
Le but maintenant est d’implémenter la méthode des éléments finis P1 en 2D, autrement dit, à un maillage donné, de calculer :
Les matrices de masse 2D (union de triangles) et 1D (union de segments)
Les matrices de rigité (union de triangles) et 1D (union de segments)
Appliquer les conditions de Dirichlet éventuelles
Approcher des intégrales par des quadratures adaptées
La matrice du système finale sera stockée sous le format COOrdinate. L’algorithme d’assemblage se prête particulièrement bien au stockage COO puisque la redondance des coefficients est autorisée par Scipy. Autrement dit, les fonctions calculant les matrices de masse et de rigidité retourneront des triplets de type [I, J, Valeur]
où I
est l’indice ligne, J
l’indice colonne et Valeur
le coefficient (potentiellement partiel).
Avant de résoudre le système, la matrice sera transformée au format Compressed Storage Raw (CSR).
2.1.1. Matrice COO#
2.1.1.1. Rappels#
Le format COO (COOrdinates) propose de ne stocker que les coefficients non nuls d’une matrice A
sous la forme de 2 listes d’entiers row
et col
et une liste de réels val
, toutes trois de même taille, telles que
A[row[i], col[i]] = val[i]
Les trois listes peuvent aussi être combinées en une seule liste data
de triplets de type [int, int, double]
et telle que :
data[i] = [row[i], col[i], val[i]]
Le format COO est assez permissif :
Redondance : si deux triplets possèdent les mêmes indices ligne et colonne alors le coefficient de la matrice, associé à ces indices ligne et colonne, sera obtenu en sommant les valeurs de ces triplets.
Pas d’ordre : aucune nécessité d’ordonner les triplets selon les lignes ou les colonnes
Par exemple, les deux jeux de listes ci-dessous décrivent la même maitrce, la seule différence est que le coefficient en (2,2) est scindé en deux et le premier et le dernier triplet ont été permutés :
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
---|---|---|---|---|---|---|---|
|
0 |
0 |
1 |
2 |
3 |
3 |
3 |
|
0 |
3 |
1 |
2 |
0 |
1 |
3 |
|
1.1 |
2 |
1 |
2.3 |
0.5 |
2 |
2 |
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
---|---|---|---|---|---|---|---|---|
|
3 |
0 |
1 |
2 |
2 |
3 |
3 |
0 |
|
3 |
3 |
1 |
2 |
2 |
0 |
1 |
0 |
|
2 |
2 |
1 |
1.3 |
1 |
0.5 |
2 |
1.1 |
2.1.1.2. Scipy#
Pour construire une matrice COO dans Scipy à partir d’un jeu de données data
, ce dernier doit être de type ([], ([],[]))
: un Tuple
contenant une List
(val
) ainsi qu’un Tuple
contenant deux List
(row
et col
) (list vs. tuple ?) :
data = (val, (row, col))
Une matrice COO se construit alors ainsi
A = coo_matrix(data) # si data dans le format ci-dessus
A = coo_matrix((val, (row, col))) # si row, col et val sont séparées
Une matrice COO peut être visualisée en se transformant en array
avec la méthode toarray() :
print(A.toarray())
2.1.1.3. Triplets#
Nous proposons de construire notre future matrice par concaténation de triplets de type (I, J, valeur). une classe Triplets
qui encapsule cette structure de données. Nous lui adjoignons une méthode append
permettant d’ajouter un triplet au bout des autres :
Triplets t; print(t.data) # ([], ([], []))
t.append(0, 1 ,2.); print(t.data) # ([2.], ([0], [1]))
t.append(3, 4 ,5.2); print(t.data) # ([2., 5.2], ([0, 3], [1, 4]))
La classe ressemble alors à cela:
def class Triplet:
def __init__():
self.data = ([], ([], []))
def __str__():
return str(self.data)
def append(self, I, J, val):
# Ajoute le triplet [I, J, val] dans self.data
# ...
Construisez la classe Triplet
et implémentez la méthode append
. N’oubliez pas de tester votre classe.
Testez votre classe Triplet
en construisant la matrice suivante (au format COO évidemment) :
2.1.2. Format CSR#
Une fois la matrice au format COO construite, nous la transformerons au format CSR par la méthode tocsr() :
A = coo_matrix((val, (row, col))).tocsr()