Case geometry and mesh
This case consists of a thick elastic plate attached to the bottom surface of a rectangular channel (see the figure above). Due to symmetry, only half of the spatial domain is considered. An incompressible viscous fluid with a density of 1000 kg/m3 and kinematic viscosity of 0.001 m2/s enters the channel from the left-hand side with a parabolic velocity profile.
This case can be analysed in two forms:
The fluid is described by incompressible Newtonian isothermal laminar flow, where the Navier-Stokes governing equations take the form:
\[\nabla \cdot \boldsymbol{v} = 0\] \[\frac{\partial \boldsymbol{v}}{\partial t} + \nabla \cdot (\boldsymbol{v} \boldsymbol{v}) = \nu \nabla^2 \boldsymbol{v} - \frac{1}{\rho} \nabla \textcolor{red}{p} + \boldsymbol{f_b}\]For the solid, we assume finite strains (though a small strain assumption would be OK in the the original form of the case) with the material behaviour described by the neo-Hookean hyperelastic law:
\[\rho \frac{\partial^2 \boldsymbol{u}}{\partial t^2} = \nabla \cdot \boldsymbol{\sigma} + \rho \boldsymbol{g}\] \[\boldsymbol{\sigma} = \frac{1}{J} \left[ \frac{K}{2} (J^2 - 1) \mathbf{I} + \mu J^{-\frac{2}{3}} \mathrm{dev} \left[ \mathbf{F} \cdot \mathbf{F}^T \right] \right]\] \[\mathbf{F} = \mathbf{I} + (\nabla_0 \boldsymbol{u})^T \qquad J = \det [\mathbf{F}]\]Kinematic and dynamic conditions hold at the interface between the fluid and solid regions. The kinematic conditions state that the velocity and displacement must be continuous across the interface:
\[\boldsymbol{v}_{\mathrm{fluid}}^{[i]} = \boldsymbol{v}_{\mathrm{solid}}^{[i]} \qquad \boldsymbol{u}_{\mathrm{fluid}}^{[i]} = \boldsymbol{u}_{\mathrm{solid}}^{[i]}\]The dynamic conditions follow from linear momentum conservation and state that the forces are in equilibrium:
\[\boldsymbol{n}^{[i]} \cdot \boldsymbol{\sigma}_{\mathrm{fluid}}^{[i]} = \boldsymbol{n}^{[i]} \cdot \boldsymbol{\sigma}_{\mathrm{solid}}^{[i]}\]A partitioned approach is adopted for enforcing these interface conditions where the fluid and solid regions are solved separately. A strongly-coupled Dirichlet-Neumann coupling algorithm is used:
for all time-steps
do
solve fluid domain
pass fluid interface forces to the solid interface
solve solid domain
pass solid interface velocities to the fluid
interface using under-relaxation
update the fluid mesh
while not converged
end
The incoming flow imparts pressure and viscous forces on the plate, causing it to bend. Following some initial transient effects, the flow and beam reach a steady-state. In the modified form of the case, with an increased peak inlet velocity of 0.3 m/s and reduced Young's modulus of 10 kPa, displacement of point A is pexected to be (0.01463, 0.005, −0.000447) m at steady state. Further details of the case can be found in Ž. Tuković, A. Karač, P. Cardiff, H. Jasak, A. Ivanković (2018) OpenFOAM Finite Volume Solver for Fluid-Solid Interaction; in particular, see Fig. 28 therein. The figure below shows the displacement field in the beam, the fluid velocity streamlines, and the fluid pressure on the channel ground, wall and outlet.
Expected results
The tutorial case can be run using the included Allrun
script, i.e. > ./Allrun
. In this case, the Allrun
script is
#!/bin/bash
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
# Source solids4Foam scripts
source solids4FoamScripts.sh
# Check case version is correct
solids4Foam::convertCaseFormat .
# Create meshes
solids4Foam::runApplication -s solid blockMesh -region solid
solids4Foam::runApplication -s fluid blockMesh -region fluid
# Run solver
if [[ "$1" == "parallel" ]]; then
# Run parallel
solids4Foam::runApplication -s fluid decomposePar -region fluid
solids4Foam::runApplication -s solid decomposePar -region solid
solids4Foam::runParallel solids4Foam
solids4Foam::runApplication -s fluid reconstructPar -region fluid
solids4Foam::runApplication -s solid reconstructPar -region solid
else
# Run serial
solids4Foam::runApplication solids4Foam
fi
# Create plots
if command -v gnuplot &> /dev/null
then
echo "Generating deflection.pdf using gnuplot"
gnuplot deflection.gnuplot &> /dev/null
echo "Generating force.pdf using gnuplot"
gnuplot force.gnuplot &> /dev/null
else
echo "Please install gnuplot if you would like to generate the plots"
fi
where the solids4Foam::convertCaseFormat .
script makes minor changes to the case to make it compatible with your version of OpenFOAM/foam-extend. As can be seen, if the argument "parallel" is passed to the Allrun
script (i.e. > ./Allrun parallel
) it will run the case in parallel. After the solver has finished, force.pdf
and deflection.pdf
plots are generated if the gnuplot
program is installed.
Remember that a tutorial case can be cleaned and reset using the includedAllrun
script, i.e. > ./Allclean
.
In the ParaView, both the solid and fluid regions are loaded by default. The Extract Block filter in ParaView can be used to extract the solid region, and a second instance of the Extract Block filter for the fluid region. In that way, the fluid region can be coloured by a fluid field (e.g. p
or U
) and the solid region by a solid field (e.g. D
or sigmaEq
). As an alternative to using the Extract Block filter, two instances of the case can be opened (File -> Open -> case.foam), where one opens the "fluid/internalMesh" and the other opens the "solid/internalMesh".
Displacement of the beam, pressure on the fluid walls, and streamlines coloured by velocity
If you would like to learn more about the case, please continue; if not, how about you check out another tutorial.
The case follows the typical multi-region (e.g. as used by chtMultiRegionSimpleFoam
) case structure:
beamInCrossFlow
├── 0
│ ├── fluid
│ │ └── ...
│ └── solid
│ │ └── ...
├── Allclean
├── Allrun
├── constant
│ ├── fluid
│ │ └── ...
│ ├── fsiProperties
│ ├── physicsProperties
│ └── solid
│ └── ...
└── system
├── fluid
│ └── ...
└── solid
└── ...
where fluid
and solid' sub-directories are present in the
0,
constantand
system` directories.
As in all solids4foam cases, the constant/physicsProperties
dictionary must be present, where, in this case, a fluid-solid interaction analysis is specified:
type fluidSolidInteraction;
As a fluid-solid interaction, a constant/fsiProperties
dictionary must also be present, where, in this case, the Aitken's accelerated coupling algorithm is specified:
fluidSolidInterface Aitken;
AitkenCoeffs
{
// ...
}
Coupling algorithm parameters are given here, e.g. solid interface patch(es), fluid interface patch(es), maximum number of FSI correctors, FSI tolerance, etc.
During a partitioned fluid-solid interaction analysis, the solids4Foam
solver will perform multiple outer FSI iterations per time-step, where both the fluid and solid and solved within each FSI iteration. Several types of information will be printed to the log, including
U
and p
residuals and iteractionsFor example:
Time = 0.1, iteration: 15
Current fsi under-relaxation factor (Aitken): 0.980175
Maximal accumulated displacement of interface points: 8.51423e-07
Evolving fluid model: icoFluid
Courant Number mean: 0.00184822 max: 0.0346019 velocity magnitude: 0.00487047
time step continuity errors : sum local = 9.26048e-10, global = -2.65049e-11,
cumulative = -2.74836e-09
time step continuity errors : sum local = 2.0302e-10, global = -1.72198e-11,
cumulative = -2.76558e-09
time step continuity errors : sum local = 1.11805e-10, global = 6.68802e-12,
cumulative = -2.7589e-09
Setting traction on solid patch
Total force (fluid) = (-0.147015 0.378642 -0.38067)
Total force (solid) = (0.146715 -0.378943 0.380941)
Evolving solid solver
Solving the updated Lagrangian form of the momentum equation for DD
Corr, res, relRes, matRes, iters
Both residuals have converged
2, 5.23068e-07, 7.10068e-07, 0, 2
Current fsi relative residual norm: 5.70921e-07
Alternative fsi residual: 5.70555e-07
When I view the fluid and solid in ParaView, there is a gap between the fluid and solid interface: the solid domain does not align with the fluid domain
Solution 1: some of the solidModels use a non-moving mesh formulation so, bydefault, some solids may not move at all when shown in ParaView. To show thesolid domain deformation/motion in ParaView, select the solid case and use the“Warp By Vector” filter with the displacement (D
or pointD
) field. If thereis still a gap between the fluid and solid, see Solution 2 below.
Solution 2: if the FSI loop does not converge then the FSI interfaceconstraints (see below) may not be strictly enforced; examine the “fsi residual”in the log file and check if the maximum number of FSI iterations is beingreached. If the FSI method is not converging to the required tolerance, thenincreases the maximum number of FSI correctors and/or decrease the initialrelaxation factor (in fsiProperties). In addition, you can try a different FSIcoupling procedure. If the FSI loop is converging but there is still a gapbetween the fluid and solid, see the next points on the following slide.
Solution 3: if the FSI loop is converging but there is still a gap betweenthe fluid and solid, then try increase the FSI solution tolerance (infsiProperties
); you may also need to increase the maximum number of FSIcorrectors to achieve a tighter tolerance. If this still does not help, seeSolution 4 below.
Solution 4: try create a conformal fluid-to-solid interface i.e. make thefluid interface patch mesh exactly the same as the solid interface patch mesh.
Solution 5: if the FSI method is still struggling to converge, try make theproblem “easier” by setting the solid to be temporarily stiffer and denser (inmechanicalProperties) by e.g. multiple orders of magnitude. If the problem workswith the artificially stiff/dense solid, then slowly decrease the solidproperties towards the real ones until you find the point at which the FSImethods breaks; then try decreasing the starting FSI relaxation factor and/ormaximum number of FSI correctors and/or FSI coupling algorithm to determine thecritical/optimal algorithm variables.
The solid model is not converging
Solution 1: try use a lower under-relaxation factor in the solid fvSolutionrelaxationFactors sub-dict; use a value of 0.1-1.0 for the D
or DD
fieldsand/or 0.9-1.0 for the D
or DD
equations.
Solution 2: try a different (more robust) solid model e.g. linear geometrysolid models, such as linGeomTotalDispSolid
andcoupledUnsLinGeomLinearElasticSolid
, tend to converge better than thenon-linear geometry models.
Perform independent analyses on the solid and fluid domains separately, beforeenabling FSI coupling, to ensure all fluid and solid properties, meshes, schemes,etc. are reasonable.
If you are having convergence issues, try prepare a more simple - butrepresentative - version of your case and make sure that works: it may provideunderstanding of critical settings.
If you are having convergence issues, try use a conformal mesh at the fluid-to-solid interface.
Tip: if you are having convergence issues, try a different (more robust)fluid model and/or a different (more robust) solid model; the pUCoupledFoamfluidModel tends to converge well and the linear geometry solid models (e.g.linGeomTotalDispSolid
or coupledUnsLinGeomLinearElasticSolid
) tend toconverge better than the non-linear geometry models
fluidSolidInterface
For the cylinderInChannel
test case, we have selected a "fluidSolidInterface" analysis in the physicsProperties
dictionary: this means a fluidSolidInterface
class will be selected; then, we specify the actual fluidSolidInterface
class to be the AitkenCouplingInterface
class.
The code for the AitkenCouplingInterface
class is located at:
solids4foam/src/solids4FoamModels/fluidSolidInterfaces/AitkenCouplingInterface/AitkenCouplingInterface.C
Let us examine the code, in particular, the "evolve" function of this class, to see how the FSI procedure is implemented.
bool AitkenCouplingInterface::evolve()
{
initializeFields();
updateInterpolator();
scalar residualNorm = 0;
if (predictSolid_)
{
updateForce();
solid().evolve();
residualNorm = updateResidual();
}
do
{
outerCorr()++;
// Transfer the displacement from the solid to the fluid
updateDisplacement();
// Move the fluid mesh
moveFluidMesh();
// Solve fluid
fluid().evolve();
// Transfer the force from the fluid to the solid
updateForce();
// Solve solid
solid().evolve();
// Calculate the FSI residual
residualNorm = updateResidual();
}
while (residualNorm > outerCorrTolerance() && outerCorr() < nOuterCorr());
solid().updateTotalFields();
return 0;
}