Skip to content

Commit 826b6cd

Browse files
gertjanvanzwietenuekermanMakisH
authored
Add Nutils participants for turek-hron-fsi3 (#648)
* Add Nutils participants for turek-hron-fsi3 * Add python requirements * Change Nutils cases from FSI2 to FSI3 * Remove dummy mock from solid.py * Adjust README and plotting script * Update turek-hron-fsi3/README.md Co-authored-by: Gerasimos Chourdakis <gerasimos.chourdakis@ipvs.uni-stuttgart.de> * Restructure time loop This patch conforms the code to the standard control flow order of requires_writing_checkpoint, requires_reading_checkpoint and is_time_window_complete. * Prepare for dynamic timesteps This patch removes the Dynamic.set_timestep method, which is not a good fit in a situation where time steps may vary. Instead the add_and_plot method is rewritten to use dimensional times rather than a fixed-length deque, and the newmark_defo and newmark_velo methods receive a timestep argument to replace the attribute. The latter will be further modified in a subsequent commit to allow for truly dynamic time steps. * Rename t->traction to make place for time variable * Update precice timestep at every iteration * Acknowledgements --------- Co-authored-by: Benjamin Uekermann <benjamin.uekermann@ipvs.uni-stuttgart.de> Co-authored-by: Benjamin Uekermann <benjamin.uekermann@gmail.com> Co-authored-by: Gerasimos Chourdakis <gerasimos.chourdakis@ipvs.uni-stuttgart.de>
1 parent 55f776a commit 826b6cd

12 files changed

Lines changed: 786 additions & 15 deletions

File tree

turek-hron-fsi3/README.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
title: Turek Hron FSI3
33
permalink: tutorials-turek-hron-fsi3.html
4-
keywords: OpenFOAM, deal.II, verification
5-
summary: The Turek-Hron FSI cases are well-established numerical benchmarks and, therefore, well suited for verification of preCICE itself and the used adapters. In this tutorial, we focus on the FSI3 case, which presents the most challenging case in terms of added mass. Please note that the meshes of this case are significantly finer than for other tutorials. Running the simulation might take a few hours. We do not recommend to run this tutorials as your first preCICE tutorial.
4+
keywords: OpenFOAM, deal.II, Nutils, verification
5+
summary: The Turek-Hron FSI cases are well-established numerical benchmarks and, therefore, well suited for verification of preCICE itself and the used adapters. In this tutorial, we focus on the FSI3 case, which presents the most challenging case in terms of added mass. Please note that the meshes of this case are significantly finer than for other tutorials. Running the simulation might take a few hours. We do not recommend to run this tutorials as your first preCICE tutorial.
66
---
77

88
{% note %}
@@ -28,14 +28,16 @@ preCICE configuration (image generated using the [precice-config-visualizer](htt
2828
Fluid participant:
2929

3030
* OpenFOAM (pimpleFoam). In case you are using a very old OpenFOAM version, you will need to adjust the solver to `pimpleDyMFoam` in the `Fluid/system/controlDict` file. For more information, have a look at the [OpenFOAM adapter documentation](https://precice.org/adapter-openfoam-overview.html).
31+
* Nutils. For more information, have a look at the [Nutils adapter documentation](https://precice.org/adapter-nutils.html). This Nutils solver requires at least Nutils v9.0. This case takes significantly longer to run than the OpenFOAM case, see [related issue](https://github.com/precice/tutorials/issues/506).
3132

3233
Solid participant:
3334

3435
* deal.II. For more information, have a look at the [deal.II adapter documentation](https://precice.org/adapter-dealii-overview.html). This tutorial requires the nonlinear solid solver. Please copy the nonlinear solver executable to the `solid-dealii` folder or make it discoverable at runtime and update the `solid-dealii/run.sh` script.
36+
* Nutils. For more information, have a look at the [Nutils adapter documentation](https://precice.org/adapter-nutils.html). This Nutils solver requires at least Nutils v9.0.
3537

3638
## Running the Simulation
3739

38-
Open two separate terminals and start each participant by calling the respective run script.
40+
Open two separate terminals and start each participant by calling the respective run script. For example:
3941

4042
```bash
4143
cd fluid-openfoam
@@ -57,13 +59,16 @@ In the first few timesteps, many coupling iterations are required for convergenc
5759

5860
## Post-processing
5961

60-
You can visualize the results of the coupled simulation using e.g. ParaView. Fluid results are in the OpenFOAM format and you may load the `fluid-openfoam.foam` file. Solid results are in VTK format.
62+
You can visualize the results of the coupled simulation using e.g. ParaView. OpenFOAM uses an OpenFOAM-specific format, and you can directly load the (empty) file `fluid-openfoam.foam` in Paraview or convert the results to VTK with `foamToVTK`. deal.II writes VTK files. Both Nutils solvers currently do not write VTK files (but use their own in-situ visualization), but this can be easily added similarly to the [perpendicular flap solvers](https://github.com/precice/tutorials/blob/98a78fe2dc2f6c5d84b2b30d35d00352782236f8/perpendicular-flap/fluid-nutils/fluid.py#L227).
6163

62-
If you want to visualize both domains with ParaView, keep in mind that the deal.II solver writes results every few timesteps, while the OpenFOAM solver writes in reference to simulated time. For this reason, make sure that you use compatible write intervals. You may also need to convert the OpenFOAM results to VTK (with the command `foamToVTK`).
64+
If you want to visualize both domains with ParaView, keep in mind that the different solvers may write results with different output frequencies, which you might want to [synchronize](https://precice.org/tutorials-visualization.html#synchronizing-results).
6365

64-
There is an [known issue](https://github.com/precice/openfoam-adapter/issues/26) that leads to additional "empty" result directories when running with some OpenFOAM versions, leading to inconveniences during post-processing. At the end of `run.sh`, we call `openfoam_remove_empty_dirs` (provided by `tools/openfoam-remove-empty-dirs`) to delete the additional files before importing the results in ParaView.
66+
There is a [known issue](https://github.com/precice/openfoam-adapter/issues/26) that leads to additional "empty" result directories when running with some OpenFOAM versions, leading to inconveniences during post-processing. At the end of `run.sh`, we call `openfoam_remove_empty_dirs` (provided by `tools/openfoam-remove-empty-dirs`) to delete the additional files before importing the results in ParaView.
6567

66-
Moreover, as we defined a watchpoint at the flap tip (see `precice-config.xml`), we can plot it with gnuplot using the script `plot-displacement.sh`. The resulting graph shows the vertical (y) displacement of the tip of the flap.
68+
Moreover, as we defined a watchpoint at the flap tip (see `precice-config.xml`), we can plot it with gnuplot using the script `plot-displacement.sh`, which expects the directory of the selected solid participant as a command line argument. For example:
69+
70+
```shell
71+
plot-displacement.sh solid-dealii
6772

6873
![FSI3 watchpoint](images/tutorials-turek-hron-fsi3-tip-plot.png)
6974

@@ -84,14 +89,10 @@ mv blockMeshDict blockMeshDict_original
8489
mv blockMeshDict_refined blockMeshDict
8590
```
8691

87-
For the double-refined mesh, it is wisely to use local basis functions in the RBF data mapping method instead of global ones. You can use:
88-
89-
```xml
90-
<mapping:rbf-compact-tps-c2 direction="read" from="Fluid-Mesh-Centers" to="Solid-Mesh"
91-
support-radius="0.011" constraint="consistent" />
92-
```
92+
## Acknowledgements
9393

94-
You can find more information on RBF data mapping in the [documentation](https://precice.org/configuration-mapping.html#radial-basis-function-mapping).
94+
Thanks to the Technical University of Eindhoven for funding the development of
95+
the Nutils participants for this tutorial.
9596

9697
## References
9798

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env sh
2+
set -e -u
3+
4+
. ../../tools/cleaning-tools.sh
5+
6+
clean_nutils .
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Geometry file for the turek.py example.
2+
//
3+
// This is a generalized description of the setup defined by Turek and Hron,
4+
// which requires the following lenghts to be supplied externally, using the
5+
// numbers argument of mesh.gmsh or the -setnumber switch when invoking the
6+
// gmsh application directly:
7+
//
8+
// - channel_length: length of the fluid domain
9+
// - channel_height: height of the fluid domain
10+
// - x_center: horizontal position of the cylinder measured from the left edge
11+
// - y_center: vertical position of the cylinder measured from the bottom edge
12+
// - cylinder_radius: radius of the cylinder
13+
// - structure_length: length of the elastic structure measured from the cylinder wall
14+
// - structure_thickness: thickness of the elastic structure
15+
// - min_elemsize: mesh element size at the solid/fluid interface
16+
// - max_elemsize: mesh element size at the channel wall and far field
17+
//
18+
// The parameterization matches largely that of Table 1 of Turek and Hron 2006,
19+
// with the main difference that reference points A and B cannot be
20+
// independently placed but are always located at the tip of the elastic
21+
// structure and the leading edge of the cylinder, respectively.
22+
23+
SetFactory("OpenCASCADE");
24+
25+
Rectangle(1) = {0, 0, 0, channel_length, channel_height};
26+
Rectangle(2) = {x_center, y_center - structure_thickness/2, 0, cylinder_radius + structure_length, structure_thickness, 0};
27+
Disk(3) = {x_center, y_center, 0, cylinder_radius};
28+
BooleanDifference(4) = { Surface{2}; }{ Surface{3}; };
29+
BooleanDifference(5) = { Surface{1}; }{ Surface{2,3}; };
30+
A = newp; Point(A) = {x_center + cylinder_radius + structure_length, y_center, 0};
31+
B = newp; Point(B) = {x_center - cylinder_radius, y_center, 0};
32+
33+
// At this point surface 3 (cylinder), 4 (solid domain) and 5 (fluid domain) are
34+
// non-overlapping. Gmsh promises that the boolean fragments operation with
35+
// deletion will reuse the surface IDs for the new objects.
36+
37+
_() = BooleanFragments{ Surface{3,4,5}; Point{A,B}; Delete; }{};
38+
39+
// Fragments deduplicates boundary segments, which means that we can now
40+
// perform boolean operations on the index sets.
41+
42+
bnd_cylinder() = Abs(Boundary{ Surface{3}; });
43+
bnd_structure() = Abs(Boundary{ Surface{4}; });
44+
tmp = bnd_structure();
45+
bnd_structure -= bnd_cylinder();
46+
bnd_cylinder -= tmp();
47+
bnd_fluid() = Abs(Boundary{ Surface{5}; });
48+
bnd_fluid -= bnd_structure();
49+
bnd_fluid -= bnd_cylinder();
50+
51+
// After subtracting the inner boundaries, only the four boundary segments of
52+
// rectangle 1 remain in bnd_fluid, and we are going to assume that they are
53+
// ordered bottom, right, top, left.
54+
55+
Physical Surface("fluid") = {5};
56+
Physical Line("inlet") = {bnd_fluid(3)};
57+
Physical Line("outlet") = {bnd_fluid(1)};
58+
Physical Line("wall") = {bnd_fluid(0), bnd_fluid(2)};
59+
Physical Line("cylinder") = {bnd_cylinder()};
60+
Physical Line("structure") = {bnd_structure()};
61+
Physical Point("A") = {A};
62+
Physical Point("B") = {B};
63+
64+
// The element size is set to be uniformly min_elemsize inside the elastic
65+
// structure, and grow linearly to max_elemsize in the fluid domain over a
66+
// distance of half the channel height.
67+
68+
Mesh.MeshSizeFromPoints = 0;
69+
Mesh.MeshSizeFromCurvature = 0;
70+
Mesh.MeshSizeExtendFromBoundary = 0;
71+
Field[1] = Distance;
72+
Field[1].SurfacesList = {3,4};
73+
Field[2] = Threshold;
74+
Field[2].InField = 1;
75+
Field[2].DistMin = 0;
76+
Field[2].DistMax = channel_height/2;
77+
Field[2].SizeMin = min_elemsize;
78+
Field[2].SizeMax = max_elemsize;
79+
Background Field = 2;

0 commit comments

Comments
 (0)