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]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 :

i

0

1

2

3

4

5

6

row[i]

0

0

1

2

3

3

3

col[i]

0

3

1

2

0

1

3

val[i]

1.1

2

1

2.3

0.5

2

2

i

0

1

2

3

4

5

6

7

row[i]

3

0

1

2

2

3

3

0

col[i]

3

3

1

2

2

0

1

0

val[i]

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

Remark 2.15

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#

classDiagram class Triplets{ +(float[ ], (int[ ], int[ ])) data __init__(self) append(self, i, j, val) }

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
    # ...

Exercise 2.1

Construisez la classe Triplet et implémentez la méthode append. N’oubliez pas de tester votre classe.

Exercise 2.2

Testez votre classe Triplet en construisant la matrice suivante (au format COO évidemment) :

\[\begin{split}A = \begin{pmatrix} 1.1 & 0 & 0 & 2 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 2.3 & 0 \\ 0.5 & 2 & 0 & 2 \end{pmatrix}\end{split}\]

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()