Mouvement du batteur¶
Description de la situation
On se propose ici de simuler le mouvement d’un batteur piston, de façon similaire à la génération de houle par le batteur du canal à houle.
Pour reproduire le mouvement d’un batteur, nous utiliserons les fonctionnalités de maillage dynamique d’OpenFOAM.
L’ensemble des opérations à effectuer se trouve dans le fichier Allrun.case:
#!/bin/bash
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions #Charger les scripts OpenFOAM
# Lancer le maillage
Allmesh
# Lancer le calcul. L'option -s lance setFields
Allrun -s &
# Attendre 2 secondes avant de lancer le monitoring
sleep 2
# Suivre la progression du calcul et lancer la commande
# ls lorsque le calcul est terminé
AllpostProcess lireSondes.py resample.py spectre.py
Maillage
Pour la géométrie de la simulation, nous utiliserons un canal rectangulaire,
qui se génère aisément à partir de l’outil blockMesh. Le fichier de configuration
se trouve dans system/blockMeshDict.
//Dimensions du canal
xmin 0.0;
xmax 26.0;
xsep 4.0; //zone de séparation pour le premier bloc
ymin 0.0;
ymax 1.0;
zmin 0.0;
zmax 2.5;
xLen #calc "$xmax - $xmin";
zLen #calc "$zmax - $zmin";
//Nombre de points dans la direction z (verticale)
nz 50.0; //Doit être un double!
//Taux de croissance du pas dx
xgrad 0.5;
//Nombre de points dans le direction x du maillage constant
nx #calc "($xmax - $xsep)/($zmax - $zmin) * $nz";
//Pas de discrétisation dans la direction x
dx #calc "($xmax - $xsep) / $nx";
//Nombre de points dans la partie non constante
nxGauche #calc "log( $xgrad ) / log( ($xsep - $dx / $xgrad) / ($xsep - $dx) ) + 1.0";
//Ne pas oublier de reconvertir en int
Ng #calc "std::floor($nxGauche)";
Nz #calc "std::floor($nz)";
Nx #calc "std::floor($nx)";
vertices
(
($xmin $ymin $zmin) //0
($xsep $ymin $zmin) //1
($xsep $ymin $zmax) //2
($xmin $ymin $zmax) //3
($xmin $ymax $zmin) //4
($xsep $ymax $zmin) //5
($xsep $ymax $zmax) //6
($xmin $ymax $zmax) //7
($xmax $ymin $zmin) //8
($xmax $ymin $zmax) //9
($xmax $ymax $zmax) //10
($xmax $ymax $zmin) //11
);
blocks
(
hex (0 1 5 4 3 2 6 7) ( $Ng 1 $Nz) simpleGrading ($xgrad 1 1)
hex (1 8 11 5 2 9 10 6) ( $Nx 1 $Nz) simpleGrading ( 1 1 1)
);
edges
(
);
boundary
(
bottom1
{
type wall;
faces
(
(0 1 5 4)
);
}
bottom2
{
type wall;
faces
(
(1 8 11 5)
);
}
front
{
type empty;
faces
(
(0 1 2 3)
(1 8 9 2)
);
}
back
{
type empty;
faces
(
(4 5 6 7)
(5 11 10 6)
);
}
leftwall
{
type patch;
faces
(
(0 4 7 3)
);
}
rightwall
{
type patch;
faces
(
(8 11 10 9)
);
}
top
{
type wall;
faces
(
(3 2 6 7)
(2 9 10 6)
);
}
);
Le maillage sera découpé en deux parties: une première partie où le maillage ne sera pas uniforme, pour absorber les déformations du maillage dynamique, et une autre partie où le maillage sera uniforme.
La gestion du maillage s’effectue avec les lignes suivantes, issues de system/blockMeshDict
blocks
(
hex (0 1 5 4 3 2 6 7) ( $Ng 1 $Nz) simpleGrading ($xgrad 1 1)
hex (1 8 11 5 2 9 10 6) ( $Nx 1 $Nz) simpleGrading ( 1 1 1)
);
Le premier block s’étend de \(x=0\) m à \(x=4\) m où le de croissance de
la dimension \(x\) est de \(0.5\), qui s’indique avec la variable ($xgrad 1 1).
Le deuxième block s’étend de \(x=4\) m à \(x=30\) m et est uniforme, car nos taux
de croissance sont tous à (1 1 1).
Après avoir lancé la commande blockMesh, vous pouvez visualiser le maillage avec ParaView.
Une capture d’écran est donnée ci-dessous.
Génération de houle
Le mouvement du batteur va être généré à partir du fichier de commande
mouvementBatteur.dat:
(
(0.0 (0.0 0 0))
(0.0050000310568651205 (2.1000000000000002e-05 0 0))
(0.010000062113730241 (4.29e-05 0 0))
...
(804.9749999689432 (-1.91e-05 0 0))
(804.98 (-2.51e-12 0 0))
);
Chaque ligne du fichier est du type (t (x y z)), où t correspond au
temps, et (x y z) sont les coordonnées du déplacement du batteur.
Le mouvement du batteur est horizontal, donc toutes les coordonnéees
y et z sont nulles.
Pour indiquer à OpenFOAM que l’on souhaite utiliser le maillage dynamique,
nous allons spéficier quelques paramètres dans le fichier constant/dynamicMeshDict
dynamicFvMesh dynamicMotionSolverFvMesh;
motionSolverLibs (fvMotionSolvers);
solver displacementLaplacian;
displacementLaplacianCoeffs
{
diffusivity inverseDistance (leftwall);
}
La première ligne indique le type de maillage dynamique souhaité. Ici,
nous choisissons dynamicMotionSolverFvMesh qui est à utiliser
pour des mouvements de maillage. Il en existe plusieurs,
comme dynamicRefineFvMesh, qui permet de raffiner le maillage automatiquement
selon plusieurs critères. Pour plus d’informations sur les types de maillages
dynamiques, consultez la documentation.
La deuxième ligne permet d’inclure la librairie de maillage dynamique. La troisième ligne indique le type de solveur à utiliser pour la propagation du déplacement du maillage. Le maillage sera comprimé/dilaté, et ce déplacement va être propagé dans le reste du maillage. Cette propagation est résolue avec différents solveurs. La documentation d’OpenFOAM sur les maillages dynamiques étant très incomplète, vous pourrez voir le détail des solveurs disponibles en allant dans les fichiers source directement. `
La dernière partie donne des précisions sur la zone du maillage à déplacer,
en l’occurence le patch leftwall qui correspond à notre batteur.
Les autres paramètres indiquent la méthode de calcul de diffusivité,
c’est-à-dire la propagation du déplacement de la zone mobile dans le
reste du maillage. La méthode que nous utilisons ici est inverseDistance,
mais vous pouvez aussi utiliser les modèles suivants:
(directional exponential file inverseDistance inverseFaceDistance
inversePointDistance inverseVolume motionDirectional quadratic
uniform)
Pour indiquer au batteur le mouvement qu’il doit effectuer, nous allons
configurer le fichier 0.orig/pointDisplacement:
dimensions [0 1 0 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
leftwall
{
type uniformFixedValue;
uniformValue tableFile;
file "mouvementBatteur.dat";
outOfBounds clamp;
}
"(back|front)"
{
type empty;
}
rightwall
{
type fixedValue;
value uniform (0 0 0);
}
"(bottom1|bottom2|top)"
{
type zeroGradient;
}
}
Ce fichier permet d’indiquer le comportement de chaque limite du maillage.
En premier, nous indiquons à la limite leftwall de suivre les
mouvements donnés dans mouvementBatteur.dat en spécifiant une condition
limite du type uniformFixedValue et tableFile.
La face verticale droite doît être fixe, ce que l’on précise bien avec la
condition fixedValue. Enfin, on ajoute une condition zeroGradient
sur les limites hautes et basses, qui indique qu’on autorise le déplacement
Enfin, il faut ajouter une condition de movingWallVelocity dans le fichier
0.orig/U pour indiquer à OpenFOAM que l’on est en présence d’un corps
en déplacement, et qu’il faut prendre en compte le mouvement relatif de
cet objet.
leftwall
{
type movingWallVelocity;
value uniform (0 0 0);
}
Les autres conditions limites sont celles utilisées classiquement, avec absorption de la houle sur la face de sortie.
Sondes et mesure de hauteur de houle
Des sondes sont configurées dans le fichier system/controlDict.
Si vous souhaitez changer leur position/nom, éditez directement les
variables définies à cet effet (sonde1/x1, etc).
// Indiquer ici les sondes et leurs coordonnées (position x en m)
sonde1 S1-5.0;
x1 5.0;
sonde2 S2-10.0;
x2 10.0;
sonde3 S3-17.0;
x3 17.0;
sonde4 S4-24.0;
x4 24.0;
sonde5 inlet;
x5 0.0;
// Coordonnées des points de mesure
ystart 0.0;
yend 0.0;
zstart 0.0;
zend 2.0;
N 201; // Nombre de points
functions
{
line
{
type sets;
libs ("libsampling.so");
enabled true; // Mettre à false pour désactiver les sondes
// Contrôle d'écriture :
// - timeStep : pas de temps
// - adjustable : temps (si pas de temps adaptatif)
// - runTime : temps (si pas de temps constant)
writeControl timeStep;
writeInterval 2;
fixedLocations false;
interpolationScheme cellPoint;
setFormat raw;
sets
(
$sonde1
{
type uniform;
axis distance;
start ( $x1 $ystart $zstart );
end ( $x1 $yend $zend );
nPoints $N;
}
$sonde2
{
type uniform;
axis distance;
start ( $x2 $ystart $zstart );
end ( $x2 $yend $zend );
nPoints $N;
}
$sonde3
{
type uniform;
axis distance;
start ( $x3 $ystart $zstart );
end ( $x3 $yend $zend );
nPoints $N;
}
$sonde4
{
type uniform;
axis distance;
start ( $x4 $ystart $zstart );
end ( $x4 $yend $zend );
nPoints $N;
}
$sonde5
{
type uniform;
axis distance;
start ( $x5 $ystart $zstart );
end ( $x5 $yend $zend );
nPoints $N;
}
);
fields (
alpha.water
);
}
}
solveur
Pour lancer le calcul, copiez le dossier 0.orig, lancez setFields pour
initialiser la hauteur d’eau à 1.38 m et lancez le calcul avec la commande
interFoam. Vous pouvez aussi directement effectuer ces trois opérations avec
la commande Allrun -s &.
Le calcul est lancé avec un maxCo de 0.5, sur 20 secondes,
en sauvegardant les données toutes les 0.1 secondes. Libre à
vous de modifier la durée de la simulation ainsi que la durée de sauvegarde.
Post-traitement
Pour effectuer le traitement des mesures de sondes, vous pouvez lancer la commande:
$ AllpostProcess lireSondes.py resample.py spectre.py
La commande AllpostProcess vous permet de lancer une série de scripts
lorsque la simulation sera terminée. Ici, nous lancerons d’abord le programme
de lecture de mesures de sondes pour extraire le signal de houle avec lireSondes.py,
puis le programme de rééchantillonnage de ce signal avec resample.py
car nos mesures ne sont pas effectuées à un pas de temps régulier. Enfin,
spectre.py va reconstruire le spectre du signal de chaque sonde,
en les comparant au spectre de JONSWAP théorique utilisé pour générer
le signal du batteur. Les paramètres du spectre théorique sont donnés dans
le fichier jonswapDict.
Les signaux de houle sont disponibles dans les fichiers line_probes.csv
et RESAMPLED_line_probes.csv (ce dernier étant le signal rééchantillonné).