Loïc Gouarin
Journée de rentrée du CMAP - 2019
Prenons un domaine $\Omega \in [0, 1] \times [0, 1]$.
Pour un niveau $l$ donné, une cellule $C^l_{i,j}$ est donnée par $[2^{-l}i,2^{-l}(i+1)] \times [2^{-l}j,2^{-l}(j+1)]$ pour $i, j=0, \cdots, 2^j-1$.Calcul de la valeur prédite $\hat{u}_{i, j}^l$
moyenne
opérateur local à la cellule avec un stencil
Contrainte
$$ \mathbf{P}_{l+1\rightarrow l}\circ \mathbf{P}_{l\rightarrow l+1} = \mathit{Id} $$Navier-Stokes incompressible avec
transport d'un scalaire
$l_{max}=2^9$, $\epsilon=5\cdot 10^{-3}$, taux de compression autour
de 90%
Peut réduire considérablement les temps de calcul
Contrôle fin de l'erreur
S'adapte bien aux méthodes volumes finis
Le maillage change
tout le temps.
(insertion et suppression
de cellules)
Une recherche fréquente des parents et des générations précédentes
Le parcours en profondeur peut être important
Crée le lien entre la méthode numérique,
l'algorithme
et la machine
Essayer de réconcilier les accès mémoire et la phase de calcul
Exploiter les architectures cibles au maximum
Faciliter l'abstraction
level: 0
y: 0
x: [0, 4[
y: 1
x: [0, 1[, [3, 4[
y: 2
x: [0, 1[, [3, 4[
y: 3
x: [0, 4[
level: 1
y: 2
x: [2, 6[
y: 3
x: [2, 6[
y: 4
x: [2, 6[
y: 5
x: [2, 6[
level: 0
x: [0, 4[ , [0, 1[ , [3, 4[ ,
[0, 1[ , [3, 4[ , [0, 4[
y: [0, 4[
offset: [0, 1, 3, 5, 6]
level: 1
x: [2, 6[ , [2, 6[ , [2, 6[ ,
[2, 6[
y: [2, 6[@0
offset: [0, 1, 2, 3, 4]
level: 0
x: [0, 4[@0, [0, 1[@4, [3, 4[@2,
[0, 1[@6, [3, 4[@4, [0, 4[@8
y: [0, 4[@0
offset: [0, 1, 3, 5, 6]
level: 1
x: [2, 6[@10, [2, 6[@14, [2, 6[@18,
[2, 6[@22
y: [2, 6[@0
offset: [0, 1, 2, 3, 4]
Intersection
Union
Différence
Projection
Translation
...
Algorithme récursif sur les dimensions
Composable à l'infini
Toujours travailler sur des espaces comparables
Attention à l'opérateur différence en multi D
Information compacte du maillage
Meilleure localité dans la direction x et par niveau
Facile à découper et à paralléliser
Recherche par direction
Moins de tests conditionnels !
Code | Mémoire (MB) | Speedup |
Code maison (Z-curve) | 365 | 1 |
p4est | 160 | 2.7 |
Intervalles | 16 | 19.2 |
auto expr = intersection(mesh[all_cells][level],
mesh[proj_cells][level - 1])
.on(level - 1);
expr.apply_op(projection(field));
class projection_op: ...
{
public:
template< class T >
void operator()(Dim<1>, T &field) const
{
field(level, i) =
.5 * (field(level + 1, 2 * i) + field(level + 1, 2 * i + 1));
}
template< class T >
void operator()(Dim<2>, T &field) const
{
field(level, i, j) = .25 * (field(level + 1, 2 * i, 2 * j) +
field(level + 1, 2 * i, 2 * j + 1) +
field(level + 1, 2 * i + 1, 2 * j) +
field(level + 1, 2 * i + 1, 2 * j + 1));
}
...
};
template
class upwind_op : ...
{
public:
// 1D
template< class T >
auto left_flux(Dim<1>, double a, const T &u) const
{
return ((a < 0) ? a : 0) / dx * (u(level, i + 1) - u(level, i));
}
template< class T >
auto right_flux(Dim<1>, double a, const T &u) const
{
return ((a > 0) ? a : 0) / dx * (u(level, i) - u(level, i - 1));
}
...
};
u = u - dt * upwind(a, u);
u = u - dt * upwind(a, u);