diff --git a/changelog-entries/947.md b/changelog-entries/947.md new file mode 100644 index 000000000..f6413e2e4 --- /dev/null +++ b/changelog-entries/947.md @@ -0,0 +1 @@ +- Added a new tutorial perpendicular-flap-3d, with OpenFOAM and OpenRadioss (OpenCourant) [#947](https://github.com/precice/tutorials/pull/947) \ No newline at end of file diff --git a/perpendicular-flap-3d/README.md b/perpendicular-flap-3d/README.md new file mode 100644 index 000000000..7f65fc1ff --- /dev/null +++ b/perpendicular-flap-3d/README.md @@ -0,0 +1,85 @@ +--- +title: Perpendicular flap 3D +permalink: tutorials-perpendicular-flap-3d.html +aliases: + - /tutorials-perpendicular-flap-3d.html +keywords: fluid-structure interaction, FSI, OpenFOAM, OpenRadioss, OpenCourant +summary: This tutorial describes how to run a 3D fluid-structure interaction using OpenFOAM and OpenRadioss. +--- + +{% note %} +Get the [case files of this tutorial](https://github.com/precice/tutorials/tree/develop/perpendicular-flap-3d), as continuously rendered here, or see the [latest released version](https://github.com/precice/tutorials/tree/master/perpendicular-flap-3d) (if there is already one). Read how in the [tutorials introduction](https://precice.org/tutorials.html). +{% endnote %} + +## Setup + +This tutorial is derived from the "Pulsating flow over flexible flap" test case discussed in the [OpenFOAM-preCICE paper](https://doi.org/10.51560/ofj.v3.88) (comparing to a [benchmark from the literature](https://doi.org/10.1002/nme.6072)), +and it was originally designed to validate OpenRadioss as a solid participant in fluid-structure interaction. +In contrast to the discussed case, this is using an explicit coupling scheme with a smaller coupling time window / solver time step. + +Overall, this tutorial consists of a 3D flow channel with an elastic flap perpendicular to the flow, anchored from the bottom. The inlet velocity oscillates over time, and the flap deforms in all dimensions. + +## Configuration + +preCICE configuration (image generated using the [precice-config-visualizer](https://precice.org/tooling-config-visualization.html)): + +![preCICE configuration visualization](images/tutorials-perpendicular-flap-3d-precice-config.png) + +## Available solvers + +Fluid participant: + +* OpenFOAM (pimpleFoam). For more information, have a look at the [OpenFOAM adapter documentation](https://precice.org/adapter-openfoam-overview.html). This tutorial needs the OpenFOAM adapter v1.4.0 or later. + +Solid participant: + +* OpenRadioss. While [OpenRadioss is no longer maintained](https://en.wikipedia.org/wiki/Radioss), the community fork [OpenCourant](https://opencourant.org/) is actively maintained and works with this tutorial. OpenCourant needs to [be built with preCICE enabled](https://github.com/OpenCourant/OpenCourant/tree/main/engine/source/coupling). +In addition to the `starter` and `engine`, you will need to build the [`anim_to_vtk` tool](https://github.com/OpenCourant/Tools/tree/main/output_converters/anim_to_vtk). + +## Mesh Configuration + +The test case implemented within this repository implements what the [OpenFOAM-preCICE paper](https://doi.org/10.51560/ofj.v3.88) refers to as `coarse` mesh: +The OpenRadioss `Solid` domain is discretized with 48 `HEX20` solid elements, arranged with a 2 x 4 x 6 cell resolution along the three spatial directions. + +## Running the simulation + +Open two separate terminals and start the desired fluid and solid participant by calling the respective run script `run.sh` located in the participant directory. For example: + +```sh +# Terminal 1 +cd fluid-openfoam -parallel +./run.sh + +# Terminal 2 +cd solid-openradioss +./run.sh +``` + +The scripts rely on tools found in `../tools/`. + +OpenFOAM can be executed in parallel using `run.sh -parallel`. +The default setting uses 8 MPI ranks, but you can increase the number of subdomains in `system/decomposeParDict`. +Since this case takes a long time to complete, you probably want to run the fluid case in parallel. + +## Post-processing + +OpenCourant (same as OpenRadioss) writes `.anim` files, which can be converted to VTK using the [`anim_to_vtk` tool](https://github.com/OpenCourant/Tools/tree/main/output_converters/anim_to_vtk) tool. This tool can be called (commented out by default) at the end of `solid-openradioss/run.sh` using the alias `toVTK`, defined in `tools/setup-openradioss.sh`. + +OpenFOAM results can directly be loaded in ParaView ([visualization details](https://precice.org/tutorials/visualization/)). + +At `t=2.5 s`, the flap should deform as follows: + +![Surface plot of velocity](./images/tutorials-perpendicular-flap-3d-surface.png) + +Two watchpoints are defined: one in the center of the flap, and one on its left tip. These can be visualized using the provided gnuplot script: + +```shell +./plot-displacement.sh solid-openradioss +``` + +Expected results for the two watchpoints (left and center of the flap): + +![Left watchpoint plot](./images/tutorials-perpendicular-flap-3d-watchpoint-left.png) +![Central watchpoint plot](./images/tutorials-perpendicular-flap-3d-watchpoint-center.png) + +Detailed results can be found in the [`openradioss-cases` repository](https://github.com/elisa-santoro/openradioss-cases) and in the [Master's thesis of Elisa Santoro](https://webthesis.biblio.polito.it/id/eprint/40822). diff --git a/perpendicular-flap-3d/clean-tutorial.sh b/perpendicular-flap-3d/clean-tutorial.sh new file mode 120000 index 000000000..4713f5092 --- /dev/null +++ b/perpendicular-flap-3d/clean-tutorial.sh @@ -0,0 +1 @@ +../tools/clean-tutorial-base.sh \ No newline at end of file diff --git a/perpendicular-flap-3d/fluid-openfoam/0/U b/perpendicular-flap-3d/fluid-openfoam/0/U new file mode 100644 index 000000000..663efc9f2 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/0/U @@ -0,0 +1,82 @@ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + inlet + { + type codedFixedValue; + value uniform (0 0 0); + name timeVaryingParabolic; + + code + #{ + const vectorField& Cf = patch().Cf(); // face centres + const vectorField& n = patch().nf(); // face normals (unit normals) + vectorField& field = *this; + + const scalar pi = constant::mathematical::pi; + const scalar t = this->db().time().value(); + + forAll(Cf, faceI) + { + const scalar y = Cf[faceI].y(); + const scalar z = Cf[faceI].z(); + + // Equivalent of: + // para = -2*((2500/81)*y*(y-0.6)*(z+0.6)*(z-0.6))*normal(); + + const scalar poly = + -2.0 * (2500.0/81.0) + * y * (y - 0.6) + * (z + 0.6) + * (z - 0.6); + + vector para = poly * n[faceI]; + + if (t < 10.0) + { + scalar ramp = 0.5 * (1.0 - cos(pi * t)); + field[faceI] = ramp * para; + } + else + { + field[faceI] = vector::zero; + } + } + #}; + } + + outlet + { + type zeroGradient; + } + flap + { + type movingWallVelocity; + value uniform (0 0 0); + } + upperWall + { + type noSlip; + } + lowerWall + { + type noSlip; + } + frontAndBack + { + type noSlip; + } +} diff --git a/perpendicular-flap-3d/fluid-openfoam/0/p b/perpendicular-flap-3d/fluid-openfoam/0/p new file mode 100644 index 000000000..b8e9a0fdd --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/0/p @@ -0,0 +1,46 @@ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + inlet + { + type zeroGradient; + } + + outlet + { + type fixedValue; + value uniform 0; + } + + flap + { + type zeroGradient; + } + + upperWall + { + type zeroGradient; + } + + lowerWall + { + type zeroGradient; + } + + frontAndBack + { + type zeroGradient; + } +} diff --git a/perpendicular-flap-3d/fluid-openfoam/0/phi b/perpendicular-flap-3d/fluid-openfoam/0/phi new file mode 100644 index 000000000..084a57543 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/0/phi @@ -0,0 +1,46 @@ +FoamFile +{ + version 2.0; + format ascii; + class surfaceScalarField; + location "0"; + object phi; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 3 -1 0 0 0 0]; + +internalField uniform 0; +boundaryField +{ + inlet + { + type calculated; + value $internalField; + } + outlet + { + type calculated; + value $internalField; + } + flap + { + type calculated; + value uniform 0; + } + upperWall + { + type calculated; + value uniform 0; + } + lowerWall + { + type calculated; + value uniform 0; + } + frontAndBack + { + type calculated; + value uniform 0; + } +} diff --git a/perpendicular-flap-3d/fluid-openfoam/0/pointDisplacement b/perpendicular-flap-3d/fluid-openfoam/0/pointDisplacement new file mode 100644 index 000000000..4c35cb06a --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/0/pointDisplacement @@ -0,0 +1,50 @@ +FoamFile +{ + version 2.0; + format ascii; + class pointVectorField; + object pointDisplacement; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 0 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + inlet + { + type fixedValue; + value uniform (0 0 0); + } + + outlet + { + type fixedValue; + value uniform (0 0 0); + } + + flap + { + type fixedValue; + value $internalField; + } + + upperWall + { + type slip; + } + + lowerWall + { + type fixedValue; + value uniform (0 0 0); + } + + frontAndBack + { + type fixedValue; + value uniform (0 0 0); + } +} diff --git a/perpendicular-flap-3d/fluid-openfoam/clean.sh b/perpendicular-flap-3d/fluid-openfoam/clean.sh new file mode 100755 index 000000000..b64fc5101 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/clean.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +set -e -u + +. ../../tools/cleaning-tools.sh + +clean_openfoam . diff --git a/perpendicular-flap-3d/fluid-openfoam/constant/dynamicMeshDict b/perpendicular-flap-3d/fluid-openfoam/constant/dynamicMeshDict new file mode 100644 index 000000000..d323bc059 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/constant/dynamicMeshDict @@ -0,0 +1,22 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object dynamicMeshDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dynamicFvMesh dynamicMotionSolverFvMesh; + +motionSolverLibs ("libfvMotionSolvers.so"); + +solver displacementLaplacian; + +displacementLaplacianCoeffs { + + diffusivity quadratic inverseDistance (flap); + +} \ No newline at end of file diff --git a/perpendicular-flap-3d/fluid-openfoam/constant/transportProperties b/perpendicular-flap-3d/fluid-openfoam/constant/transportProperties new file mode 100644 index 000000000..e2dfbd972 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/constant/transportProperties @@ -0,0 +1,13 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object transportProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +transportModel Newtonian; + +nu nu [ 0 2 -1 0 0 0 0 ] 0.01; diff --git a/perpendicular-flap-3d/fluid-openfoam/constant/turbulenceProperties b/perpendicular-flap-3d/fluid-openfoam/constant/turbulenceProperties new file mode 100644 index 000000000..7df19cc34 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/constant/turbulenceProperties @@ -0,0 +1,11 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; diff --git a/perpendicular-flap-3d/fluid-openfoam/run.sh b/perpendicular-flap-3d/fluid-openfoam/run.sh new file mode 100755 index 000000000..8f55fbfa5 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e -u + +. ../../tools/log.sh +exec > >(tee --append "$LOGFILE") 2>&1 + +blockMesh + +../../tools/run-openfoam.sh "$@" +. ../../tools/openfoam-remove-empty-dirs.sh && openfoam_remove_empty_dirs + +close_log diff --git a/perpendicular-flap-3d/fluid-openfoam/system/blockMeshDict b/perpendicular-flap-3d/fluid-openfoam/system/blockMeshDict new file mode 100644 index 000000000..641c43843 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/system/blockMeshDict @@ -0,0 +1,290 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +x0 0.; +x1 0.5; +x2 0.57; +x3 1.8; + +y0 0.; +y1 0.35; +y2 0.6; + +z0 -0.6; +z1 -0.3; +z2 0.3; +z3 0.6; + +vertices +( +// Left z-layer + ($x0 $y0 $z0 ) // 0 + ($x1 $y0 $z0 ) // 1 + ($x2 $y0 $z0 ) // 2 + ($x3 $y0 $z0 ) // 3 + ($x0 $y1 $z0 ) // 4 + ($x1 $y1 $z0 ) // 5 + ($x2 $y1 $z0 ) // 6 + ($x3 $y1 $z0 ) // 7 + ($x0 $y2 $z0 ) // 8 + ($x1 $y2 $z0 ) // 9 + ($x2 $y2 $z0 ) // 10 + ($x3 $y2 $z0 ) // 11 + +// Beginning flap + ($x0 $y0 $z1 ) // 12 + ($x1 $y0 $z1 ) // 13 + ($x2 $y0 $z1 ) // 14 + ($x3 $y0 $z1 ) // 15 + ($x0 $y1 $z1 ) // 16 + ($x1 $y1 $z1 ) // 17 + ($x2 $y1 $z1 ) // 18 + ($x3 $y1 $z1 ) // 19 + ($x0 $y2 $z1 ) // 20 + ($x1 $y2 $z1 ) // 21 + ($x2 $y2 $z1 ) // 22 + ($x3 $y2 $z1 ) // 23 + +// End flap + ($x0 $y0 $z2 ) // 24 + ($x1 $y0 $z2 ) // 25 + ($x2 $y0 $z2 ) // 26 + ($x3 $y0 $z2 ) // 27 + ($x0 $y1 $z2 ) // 28 + ($x1 $y1 $z2 ) // 29 + ($x2 $y1 $z2 ) // 30 + ($x3 $y1 $z2 ) // 31 + ($x0 $y2 $z2 ) // 32 + ($x1 $y2 $z2 ) // 33 + ($x2 $y2 $z2 ) // 34 + ($x3 $y2 $z2 ) // 35 + +// End domain + ($x0 $y0 $z3 ) // 36 + ($x1 $y0 $z3 ) // 37 + ($x2 $y0 $z3 ) // 38 + ($x3 $y0 $z3 ) // 39 + ($x0 $y1 $z3 ) // 40 + ($x1 $y1 $z3 ) // 41 + ($x2 $y1 $z3 ) // 42 + ($x3 $y1 $z3 ) // 43 + ($x0 $y2 $z3 ) // 44 + ($x1 $y2 $z3 ) // 45 + ($x2 $y2 $z3 ) // 46 + ($x3 $y2 $z3 ) // 47 + + +); + +// x direction +h1 8; +h2 2; +h3 20; + +// x grading +hx1 0.7; +hx3 2; + +// y direction +v1 8; +v2 7; + +// y grading +vy1 1; +vy2 1; + +// z direction +w1 8; +w2 15; +w3 8; + + +blocks +( +// Left z-layer + + // Bottom y layer + hex ( 0 1 5 4 12 13 17 16 ) + ($h1 $v1 $w1 ) + simpleGrading ($hx1 $vy1 1) + + hex ( 1 2 6 5 13 14 18 17 ) + ($h2 $v1 $w1) + simpleGrading (1 $vy1 1) + + hex ( 2 3 7 6 14 15 19 18 ) + ($h3 $v1 $w1) + simpleGrading ($hx3 $vy1 1) + + // top y layer + hex ( 4 5 9 8 16 17 21 20 ) + ($h1 $v2 $w1) + simpleGrading ($hx1 $vy2 1) + + hex ( 5 6 10 9 17 18 22 21 ) + ($h2 $v2 $w1) + simpleGrading (1 $vy2 1) + + hex ( 6 7 11 10 18 19 23 22 ) + ($h3 $v2 $w1) + simpleGrading ($hx3 $vy2 1) + +// Middle z-layer + + // Bottom y layer + hex ( 12 13 17 16 24 25 29 28 ) + ($h1 $v1 $w2 ) + simpleGrading ($hx1 $vy1 1) + + hex ( 14 15 19 18 26 27 31 30 ) + ($h3 $v1 $w2) + simpleGrading ($hx3 $vy1 1) + + // top y layer + hex ( 16 17 21 20 28 29 33 32 ) + ($h1 $v2 $w2) + simpleGrading ($hx1 $vy2 1) + + hex ( 17 18 22 21 29 30 34 33 ) + ($h2 $v2 $w2) + simpleGrading (1 $vy2 1) + + hex ( 18 19 23 22 30 31 35 34 ) + ($h3 $v2 $w2) + simpleGrading ($hx3 $vy2 1) + +// End z-layer + + // Bottom y layer + hex ( 24 25 29 28 36 37 41 40 ) + ($h1 $v1 $w3 ) + simpleGrading ($hx1 $vy1 1) + + hex ( 25 26 30 29 37 38 42 41 ) + ($h2 $v1 $w3) + simpleGrading (1 $vy1 1) + + hex ( 26 27 31 30 38 39 43 42 ) + ($h3 $v1 $w3) + simpleGrading ($hx3 $vy1 1) + + // top y layer + hex ( 28 29 33 32 40 41 45 44 ) + ($h1 $v2 $w3) + simpleGrading ($hx1 $vy2 1) + + hex ( 29 30 34 33 41 42 46 45 ) + ($h2 $v2 $w3) + simpleGrading (1 $vy2 1) + + hex ( 30 31 35 34 42 43 47 46 ) + ($h3 $v2 $w3) + simpleGrading ($hx3 $vy2 1) +); + +edges +( +); + +boundary +( + inlet + { + type patch; + faces + ( + ( 0 4 16 12 ) + ( 4 8 20 16 ) + ( 12 16 28 24 ) + ( 16 20 32 28 ) + ( 24 28 40 36 ) + ( 28 32 44 40 ) + ); + } + outlet + { + type patch; + faces + ( + ( 3 7 19 15 ) + ( 7 11 23 19 ) + ( 15 19 31 27 ) + ( 19 23 35 31 ) + ( 27 31 43 39 ) + ( 31 35 47 43 ) + ); + } + flap + { + type wall; + faces + ( + ( 13 17 29 25 ) + ( 17 18 30 29 ) + ( 18 14 26 30 ) + ( 13 17 18 14 ) + ( 25 29 30 26 ) + ); + } + upperWall + { + type wall; + faces + ( + ( 8 9 21 20 ) + ( 9 10 22 21 ) + ( 10 11 23 22 ) + + ( 20 21 33 32 ) + ( 21 22 34 33 ) + ( 22 23 35 34 ) + + ( 32 33 45 44 ) + ( 33 34 46 45 ) + ( 34 35 47 46 ) + ); + } + lowerWall + { + type wall; + faces + ( + ( 0 1 13 12 ) + ( 1 2 14 13 ) + ( 2 3 15 14 ) + + ( 12 13 25 24 ) + ( 14 15 27 26 ) + + ( 24 25 37 36 ) + ( 25 26 38 37 ) + ( 26 27 39 38 ) + ); + } + frontAndBack + { + type wall; + faces + ( + ( 0 1 5 4 ) + ( 1 5 6 2 ) + ( 2 3 7 6 ) + ( 4 5 9 8 ) + ( 5 6 10 9 ) + ( 6 7 11 10 ) + + ( 36 37 41 40 ) + ( 37 41 42 38 ) + ( 38 39 43 42 ) + ( 40 41 45 44 ) + ( 41 42 46 45 ) + ( 42 43 47 46 ) + ); + } +); diff --git a/perpendicular-flap-3d/fluid-openfoam/system/controlDict b/perpendicular-flap-3d/fluid-openfoam/system/controlDict new file mode 100644 index 000000000..07327ada2 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/system/controlDict @@ -0,0 +1,46 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application pimpleFoam; // OpenFOAM v1806, OpenFOAM 6, or newer + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 30.0; + +deltaT 0.001; + +writeControl runTime; + +writeInterval 0.5; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 15; + +writeCompression off; + +timeFormat general; + +timePrecision 8; + +functions +{ + preCICE_Adapter + { + type preciceAdapterFunctionObject; + libs ("libpreciceAdapterFunctionObject.so"); + } +} diff --git a/perpendicular-flap-3d/fluid-openfoam/system/decomposeParDict b/perpendicular-flap-3d/fluid-openfoam/system/decomposeParDict new file mode 100644 index 000000000..655bb7238 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/system/decomposeParDict @@ -0,0 +1,22 @@ +FoamFile { + version 2.0; + class dictionary; + object decomposeParDict; + format ascii; +} + +// This domain can be decomposed more. +// If you have the CPU resources, try, for example: +// numberOfSubdomains 48 +// n (4 4 3); +numberOfSubdomains 8; + +// The adapter is independent of the decomposition method, more advanced methods are known to work as well +method simple; + +simpleCoeffs +{ + n (4 2 1); + delta 0.001; +} + diff --git a/perpendicular-flap-3d/fluid-openfoam/system/fvSchemes b/perpendicular-flap-3d/fluid-openfoam/system/fvSchemes new file mode 100644 index 000000000..7d6e65da7 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/system/fvSchemes @@ -0,0 +1,40 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ + default Gauss linear; + div(phi,U) Gauss limitedLinearV 1; +} + +interpolationSchemes +{ + default linear; +} + +laplacianSchemes +{ + default Gauss linear corrected; +} + +snGradSchemes +{ + default corrected; +} diff --git a/perpendicular-flap-3d/fluid-openfoam/system/fvSolution b/perpendicular-flap-3d/fluid-openfoam/system/fvSolution new file mode 100644 index 000000000..c4a88f688 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/system/fvSolution @@ -0,0 +1,134 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + + p + { + solver GAMG; + smoother GaussSeidel; + nPreSweeps 0; + nPostSweeps 2; + nVcycles 2; + cacheAgglomeration true; + nCellsInCoarsestLevel 50; + agglomerator faceAreaPair; + mergeLevels 1; + tolerance 1e-08; + relTol 0; + minIter 1; + } + + U + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-08; + relTol 0; + minIter 1; + } + + pcorr + { + solver GAMG; + smoother GaussSeidel; + nPreSweeps 0; + nPostSweeps 2; + nVcycles 2; + cacheAgglomeration true; + nCellsInCoarsestLevel 50; + agglomerator faceAreaPair; + mergeLevels 1; + tolerance 1e-6; + relTol 0.01; + minIter 1; + } + + pFinal + { + solver GAMG; + smoother GaussSeidel; + nPreSweeps 0; + nPostSweeps 2; + nVcycles 2; + cacheAgglomeration true; + nCellsInCoarsestLevel 50; + agglomerator faceAreaPair; + mergeLevels 1; + tolerance 1e-7; + relTol 0.01; + minIter 1; + } + + UFinal + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-6; + relTol 0.1; + minIter 1; + } + + pcorrFinal + { + solver GAMG; + smoother GaussSeidel; + nPreSweeps 0; + nPostSweeps 2; + nVcycles 2; + cacheAgglomeration true; + nCellsInCoarsestLevel 50; + agglomerator faceAreaPair; + mergeLevels 1; + tolerance 1e-6; + relTol 0.01; + minIter 1; + } + + cellDisplacement + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-06; + relTol 0.0001; + minIter 2; + } + cellDisplacementFinal + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-06; + relTol 0; + minIter 2; + } +} + +PIMPLE +{ + consistent yes; + nNonOrthogonalCorrectors 3; + nOuterCorrectors 5; + nCorrectors 3; + momentumPredictor yes; + correctPhi yes; +} + +relaxationFactors +{ + fields + { + p 1; +} + equations + { + U 1; + } +} diff --git a/perpendicular-flap-3d/fluid-openfoam/system/preciceDict b/perpendicular-flap-3d/fluid-openfoam/system/preciceDict new file mode 100644 index 000000000..16227f309 --- /dev/null +++ b/perpendicular-flap-3d/fluid-openfoam/system/preciceDict @@ -0,0 +1,39 @@ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object preciceDict; +} + +preciceConfig "../precice-config.xml"; + +participant Fluid; + +modules (FSI); + +interfaces +{ + Interface + { + mesh Fluid-Mesh; + patches (flap); + locations faceCenters; + + readData + ( + DISPLACEMENTS + ); + + writeData + ( + FORCES + ); + }; +} + +FSI +{ + rho rho [1 -3 0 0 0 0 0] 1; +} \ No newline at end of file diff --git a/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-precice-config.png b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-precice-config.png new file mode 100644 index 000000000..38581d06c Binary files /dev/null and b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-precice-config.png differ diff --git a/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-surface.png b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-surface.png new file mode 100644 index 000000000..71fd7bc37 Binary files /dev/null and b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-surface.png differ diff --git a/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-watchpoint-center.png b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-watchpoint-center.png new file mode 100644 index 000000000..b77af3fcb Binary files /dev/null and b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-watchpoint-center.png differ diff --git a/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-watchpoint-left.png b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-watchpoint-left.png new file mode 100644 index 000000000..436d736c0 Binary files /dev/null and b/perpendicular-flap-3d/images/tutorials-perpendicular-flap-3d-watchpoint-left.png differ diff --git a/perpendicular-flap-3d/metadata.yaml b/perpendicular-flap-3d/metadata.yaml new file mode 100644 index 000000000..ce8ac4dda --- /dev/null +++ b/perpendicular-flap-3d/metadata.yaml @@ -0,0 +1,21 @@ +name: Perpendicular flap 3D +path: perpendicular-flap-3d +url: https://precice.org/tutorials-perpendicular-flap-3d.html + +participants: + - Fluid + - Solid + +cases: + fluid-openfoam: + participant: Fluid + directory: ./fluid-openfoam + run: ./run.sh + component: openfoam-adapter + + solid-openradioss: + participant: Solid + directory: ./solid-openradioss + run: ./run.sh + component: openradioss-adapter + \ No newline at end of file diff --git a/perpendicular-flap-3d/plot-displacement.sh b/perpendicular-flap-3d/plot-displacement.sh new file mode 100755 index 000000000..1ddaae3b1 --- /dev/null +++ b/perpendicular-flap-3d/plot-displacement.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env sh + +if [ "${1:-}" = "" ]; then + echo "No target directory specified. Please specify the directory of the solid participant containing the watchpoint, e.g. ./plot-displacement.sh solid-openradioss." + exit 1 +fi + +FILE_CENTER="$1/precice-Solid-watchpoint-Center-Front-Tip.log" + +if [ ! -f "$FILE_CENTER" ]; then + echo "Unable to locate the watchpoint file ${FILE_CENTER}. Make sure the specified directory matches the solid participant you used for the calculations." + exit 1 +fi + +gnuplot -p << EOF + set grid + set title 'x-displacement of the central flap tip' + set xlabel 'time [s]' + set ylabel 'x-displacement [m]' + plot "$1/precice-Solid-watchpoint-Center-Front-Tip.log" using 1:5 with lines title "$1" +EOF + +FILE_LEFT="$1/precice-Solid-watchpoint-Left-Back-Tip.log" + +if [ ! -f "$FILE_LEFT" ]; then + echo "Unable to locate the watchpoint file ${FILE_LEFT}. Make sure the specified directory matches the solid participant you used for the calculations." + exit 1 +fi + +gnuplot -p << EOF + set grid + set title 'x-displacement of the left flap tip' + set xlabel 'time [s]' + set ylabel 'x-displacement [m]' + plot "$1/precice-Solid-watchpoint-Left-Back-Tip.log" using 1:5 with lines title "$1" +EOF \ No newline at end of file diff --git a/perpendicular-flap-3d/precice-config.xml b/perpendicular-flap-3d/precice-config.xml new file mode 100644 index 000000000..67daaad20 --- /dev/null +++ b/perpendicular-flap-3d/precice-config.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/perpendicular-flap-3d/reference-results/fluid-openfoam_solid-openradioss.tar.gz b/perpendicular-flap-3d/reference-results/fluid-openfoam_solid-openradioss.tar.gz new file mode 100644 index 000000000..b5dd77108 --- /dev/null +++ b/perpendicular-flap-3d/reference-results/fluid-openfoam_solid-openradioss.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8d4412f028fbbd48029411cb23009d4633c600fcda21eabf87af7ed7cede322 +size 364574 diff --git a/perpendicular-flap-3d/solid-openradioss/.gitignore b/perpendicular-flap-3d/solid-openradioss/.gitignore new file mode 100644 index 000000000..7100269cb --- /dev/null +++ b/perpendicular-flap-3d/solid-openradioss/.gitignore @@ -0,0 +1,4 @@ +solid-openradioss*.out +solid-openradiossA* +solid-openradiossT* +solid-openradioss*.rst \ No newline at end of file diff --git a/perpendicular-flap-3d/solid-openradioss/clean.sh b/perpendicular-flap-3d/solid-openradioss/clean.sh new file mode 100755 index 000000000..8e178b944 --- /dev/null +++ b/perpendicular-flap-3d/solid-openradioss/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -e -u + +. ../../tools/cleaning-tools.sh + +clean_openradioss . +rm -fv solid-openradiossA* solid-openradiossT* \ No newline at end of file diff --git a/perpendicular-flap-3d/solid-openradioss/run.sh b/perpendicular-flap-3d/solid-openradioss/run.sh new file mode 100755 index 000000000..2bad9723f --- /dev/null +++ b/perpendicular-flap-3d/solid-openradioss/run.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e -u +shopt -s expand_aliases + +. ../../tools/log.sh +exec > >(tee --append "$LOGFILE") 2>&1 + +. ../../tools/setup-openradioss.sh + +radioss_starter -i solid-openradioss_0000.rad + +radioss_engine -i solid-openradioss_0001.rad + +# Depends on https://github.com/OpenCourant/Tools/tree/main/output_converters/anim_to_vtk +# toVTK solid-openradioss + +close_log diff --git a/perpendicular-flap-3d/solid-openradioss/solid-openradioss.cpl b/perpendicular-flap-3d/solid-openradioss/solid-openradioss.cpl new file mode 100644 index 000000000..be08f1607 --- /dev/null +++ b/perpendicular-flap-3d/solid-openradioss/solid-openradioss.cpl @@ -0,0 +1,6 @@ +/PRECICE/PARTICIPANT_NAME/Solid +/PRECICE/CONFIG_FILE/../precice-config.xml +/PRECICE/MESH_NAME/Solid-Mesh +/PRECICE/READ/FORCES +/PRECICE/WRITE/DISPLACEMENTS +/PRECICE/GRNOD/2 \ No newline at end of file diff --git a/perpendicular-flap-3d/solid-openradioss/solid-openradioss_0000.rad b/perpendicular-flap-3d/solid-openradioss/solid-openradioss_0000.rad new file mode 100644 index 000000000..6206aee30 --- /dev/null +++ b/perpendicular-flap-3d/solid-openradioss/solid-openradioss_0000.rad @@ -0,0 +1,608 @@ +#RADIOSS STARTER +##======================================================================================== +## +## Radioss Input Deck Generated by HyperMesh Version : 2026.0.0.27 +## Generated using HyperMesh-Radioss Template Version : 2026.0.0.27-290296 +## Date: 02-18-2026 Time: 15:55:26 +## +##======================================================================================== +## +## +/BEGIN +#Runname +pulsatingFlap +# Invers Irun + 2024 0 +# Input_mass_unit Input_length_unit Input_time_unit + kg m s +# Work_mass_unit Work_length_unit Work_time_unit + kg m s +## +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/NODE +# node_ID Xc Yc Zc + 723 0.57 0.0 -0.3 + 724 0.57 0.0875 -0.3 + 725 0.57 0.175 -0.3 + 726 0.57 0.2625 -0.3 + 727 0.57 0.35 -0.3 + 728 0.57 0.35 -0.2 + 729 0.57 0.35 -0.1 + 730 0.57 0.35 0.0 + 731 0.57 0.35 0.1 + 732 0.57 0.35 0.2 + 733 0.57 0.35 0.3 + 734 0.57 0.2625 0.3 + 735 0.57 0.175 0.3 + 736 0.57 0.0875 0.3 + 737 0.57 0.0 0.3 + 738 0.57 0.0 0.2 + 739 0.57 0.0 0.1 + 740 0.57 0.0 0.0 + 741 0.57 0.0 -0.1 + 742 0.57 0.0 -0.2 + 743 0.57 0.2625 0.0 + 744 0.57 0.175 0.0 + 745 0.57 0.0875 0.0 + 746 0.57 0.175 -0.1 + 747 0.57 0.175 -0.2 + 748 0.57 0.2625 -0.1 + 749 0.57 0.2625 -0.2 + 750 0.57 0.0875 -0.1 + 751 0.57 0.0875 -0.2 + 752 0.57 0.175 0.2 + 753 0.57 0.175 0.1 + 754 0.57 0.2625 0.2 + 755 0.57 0.2625 0.1 + 756 0.57 0.0875 0.2 + 757 0.57 0.0875 0.1 + 758 0.535 0.175 -0.3 + 759 0.535 0.175 -0.2 + 760 0.535 0.2625 -0.2 + 761 0.535 0.2625 -0.3 + 762 0.5 0.175 -0.3 + 763 0.5 0.175 -0.2 + 764 0.5 0.2625 -0.2 + 765 0.5 0.2625 -0.3 + 766 0.535 0.2625 -0.1 + 767 0.535 0.2625-1.3972643976463E-17 + 768 0.535 0.35 0.0 + 769 0.535 0.35 -0.1 + 770 0.5 0.2625 -0.1 + 771 0.5 0.26254.92605861874315E-19 + 772 0.5 0.35 0.0 + 773 0.5 0.35 -0.1 + 774 0.535 0.0875 -0.2 + 775 0.535 0.0875 -0.1 + 776 0.535 0.175 -0.1 + 777 0.5 0.0875 -0.2 + 778 0.5 0.0875 -0.1 + 779 0.5 0.175 -0.1 + 780 0.535 0.0 0.2 + 781 0.535 0.0 0.3 + 782 0.535 0.0875 0.3 + 783 0.535 0.0875 0.2 + 784 0.5 0.0 0.2 + 785 0.5 0.0 0.3 + 786 0.5 0.0875 0.3 + 787 0.5 0.0875 0.2 + 788 0.535 0.175 0.2 + 789 0.535 0.175 0.3 + 790 0.535 0.2625 0.3 + 791 0.535 0.2625 0.2 + 792 0.5 0.175 0.2 + 793 0.5 0.175 0.3 + 794 0.5 0.2625 0.3 + 795 0.5 0.2625 0.2 + 796 0.535 0.35 -0.2 + 797 0.535 0.35 -0.3 + 798 0.5 0.35 -0.2 + 799 0.5 0.35 -0.3 + 800 0.535 0.0875-3.1957535076908E-18 + 801 0.535 0.175-9.1564782721976E-18 + 802 0.5 0.08752.23739686447266E-36 + 803 0.5 0.1757.46704475903674E-20 + 804 0.535 0.175 0.1 + 805 0.535 0.2625 0.1 + 806 0.5 0.175 0.1 + 807 0.5 0.2625 0.1 + 808 0.535 0.0875 0.1 + 809 0.5 0.0875 0.1 + 810 0.535 0.0875 -0.3 + 811 0.5 0.0875 -0.3 + 812 0.535 0.0 -0.2 + 813 0.535 0.0 -0.1 + 814 0.5 0.0 -0.2 + 815 0.5 0.0 -0.1 + 816 0.535 0.35 0.1 + 817 0.5 0.35 0.1 + 818 0.535 0.0 0.1 + 819 0.5 0.0 0.1 + 820 0.535 0.35 0.3 + 821 0.535 0.35 0.2 + 822 0.5 0.35 0.3 + 823 0.5 0.35 0.2 + 824 0.535 0.0 0.0 + 825 0.5 0.0 0.0 + 826 0.535 0.0 -0.3 + 827 0.5 0.0 -0.3 + 828 0.57 0.04375 -0.3 + 829 0.57 0.0 -0.25 + 831 0.5525 0.0 -0.3 + 832 0.57 0.13125 -0.3 + 834 0.57 0.0875 -0.25 + 835 0.5525 0.0875 -0.3 + 836 0.57 0.21875 -0.3 + 837 0.57 0.175 -0.25 + 839 0.5525 0.175 -0.3 + 841 0.57 0.30625 -0.3 + 843 0.57 0.2625 -0.25 + 845 0.5525 0.2625 -0.3 + 847 0.57 0.35 -0.25 + 849 0.5525 0.35 -0.3 + 850 0.57 0.35 -0.15 + 851 0.57 0.30625 -0.2 + 852 0.5525 0.35 -0.2 + 853 0.57 0.35 -0.05 + 854 0.57 0.30625 -0.1 + 855 0.5525 0.35 -0.1 + 856 0.57 0.35 0.05 + 857 0.57 0.30625 0.0 + 859 0.5525 0.35 0.0 + 861 0.57 0.35 0.15 + 863 0.57 0.30625 0.1 + 865 0.5525 0.35 0.1 + 867 0.57 0.35 0.25 + 868 0.57 0.30625 0.2 + 870 0.5525 0.35 0.2 + 871 0.57 0.30625 0.3 + 872 0.5525 0.35 0.3 + 873 0.57 0.21875 0.3 + 874 0.57 0.2625 0.25 + 875 0.5525 0.2625 0.3 + 876 0.57 0.13125 0.3 + 877 0.57 0.175 0.25 + 879 0.5525 0.175 0.3 + 880 0.57 0.04375 0.3 + 882 0.57 0.0875 0.25 + 883 0.5525 0.0875 0.3 + 884 0.57 0.0 0.25 + 885 0.5525 0.0 0.3 + 886 0.57 0.0 0.15 + 887 0.57 0.04375 0.2 + 889 0.5525 0.0 0.2 + 891 0.57 0.0 0.05 + 893 0.57 0.04375 0.1 + 895 0.5525 0.0 0.1 + 897 0.57 0.0 -0.05 + 898 0.57 0.04375 0.0 + 901 0.5525 0.0 0.0 + 902 0.57 0.0 -0.15 + 904 0.57 0.04375 -0.1 + 906 0.5525 0.0 -0.1 + 908 0.57 0.04375 -0.2 + 909 0.5525 0.0 -0.2 + 910 0.57 0.21875 0.0 + 911 0.57 0.2625 -0.05 + 912 0.57 0.2625 0.05 + 913 0.5525 0.2625-6.9863219882313E-18 + 914 0.57 0.13125 0.0 + 915 0.57 0.175 -0.05 + 917 0.57 0.175 0.05 + 919 0.5525 0.175-4.5782391360988E-18 + 921 0.57 0.0875 -0.05 + 923 0.57 0.0875 0.05 + 924 0.5525 0.0875-1.5978767538454E-18 + 925 0.57 0.175 -0.15 + 926 0.57 0.21875 -0.1 + 928 0.57 0.13125 -0.1 + 930 0.5525 0.175 -0.1 + 932 0.57 0.21875 -0.2 + 934 0.57 0.13125 -0.2 + 935 0.5525 0.175 -0.2 + 936 0.57 0.2625 -0.15 + 937 0.5525 0.2625 -0.1 + 938 0.5525 0.2625 -0.2 + 939 0.57 0.0875 -0.15 + 940 0.5525 0.0875 -0.1 + 941 0.5525 0.0875 -0.2 + 942 0.57 0.175 0.15 + 943 0.57 0.21875 0.2 + 945 0.57 0.13125 0.2 + 947 0.5525 0.175 0.2 + 949 0.57 0.21875 0.1 + 951 0.57 0.13125 0.1 + 952 0.5525 0.175 0.1 + 953 0.57 0.2625 0.15 + 954 0.5525 0.2625 0.2 + 955 0.5525 0.2625 0.1 + 956 0.57 0.0875 0.15 + 957 0.5525 0.0875 0.2 + 958 0.5525 0.0875 0.1 + 959 0.535 0.175 -0.25 + 960 0.535 0.21875 -0.3 + 961 0.5175 0.175 -0.3 + 963 0.535 0.13125 -0.3 + 965 0.535 0.21875 -0.2 + 966 0.5175 0.175 -0.2 + 967 0.535 0.13125 -0.2 + 968 0.535 0.175 -0.15 + 969 0.535 0.2625 -0.25 + 970 0.5175 0.2625 -0.2 + 971 0.535 0.2625 -0.15 + 972 0.535 0.30625 -0.2 + 974 0.5175 0.2625 -0.3 + 975 0.535 0.30625 -0.3 + 977 0.5 0.175 -0.25 + 978 0.5 0.21875 -0.3 + 980 0.5 0.13125 -0.3 + 981 0.5 0.21875 -0.2 + 982 0.5 0.13125 -0.2 + 983 0.5 0.175 -0.15 + 984 0.5 0.2625 -0.25 + 985 0.5 0.2625 -0.15 + 986 0.5 0.30625 -0.2 + 990 0.5 0.30625 -0.3 + 991 0.535 0.2625 -0.05 + 992 0.535 0.30625 -0.1 + 993 0.5175 0.2625 -0.1 + 994 0.535 0.21875 -0.1 + 995 0.535 0.30625-6.9863219882313E-18 + 996 0.5175 0.2625-6.7400190572942E-18 + 997 0.535 0.21875-1.1564561124330E-17 + 998 0.535 0.2625 0.05 + 999 0.535 0.35 -0.05 + 1000 0.5175 0.35 0.0 + 1002 0.535 0.35 0.05 + 1005 0.5175 0.35 -0.1 + 1006 0.535 0.35 -0.15 + 1008 0.5 0.2625 -0.05 + 1009 0.5 0.30625 -0.1 + 1010 0.5 0.21875 -0.1 + 1012 0.5 0.306252.46302930937158E-19 + 1014 0.5 0.218752.83638154732341E-19 + 1015 0.5 0.2625 0.05 + 1017 0.5 0.35 -0.05 + 1020 0.5 0.35 0.05 + 1022 0.5 0.35 -0.15 + 1023 0.535 0.0875 -0.15 + 1024 0.5175 0.0875 -0.2 + 1025 0.535 0.0875 -0.25 + 1026 0.535 0.04375 -0.2 + 1027 0.535 0.13125 -0.1 + 1028 0.5175 0.0875 -0.1 + 1029 0.535 0.0875 -0.05 + 1030 0.535 0.04375 -0.1 + 1031 0.5175 0.175 -0.1 + 1032 0.535 0.175 -0.05 + 1033 0.5 0.0875 -0.15 + 1034 0.5 0.0875 -0.25 + 1035 0.5 0.04375 -0.2 + 1038 0.5 0.13125 -0.1 + 1039 0.5 0.0875 -0.05 + 1042 0.5 0.04375 -0.1 + 1045 0.5 0.175 -0.05 + 1046 0.535 0.0 0.25 + 1047 0.535 0.04375 0.2 + 1048 0.5175 0.0 0.2 + 1050 0.535 0.0 0.15 + 1052 0.535 0.04375 0.3 + 1054 0.5175 0.0 0.3 + 1056 0.535 0.0875 0.25 + 1058 0.5175 0.0875 0.3 + 1059 0.535 0.13125 0.3 + 1061 0.5175 0.0875 0.2 + 1062 0.535 0.13125 0.2 + 1063 0.535 0.0875 0.15 + 1064 0.5 0.0 0.25 + 1065 0.5 0.04375 0.2 + 1067 0.5 0.0 0.15 + 1068 0.5 0.04375 0.3 + 1069 0.5 0.0875 0.25 + 1071 0.5 0.13125 0.3 + 1072 0.5 0.13125 0.2 + 1073 0.5 0.0875 0.15 + 1074 0.535 0.175 0.25 + 1075 0.535 0.21875 0.2 + 1076 0.5175 0.175 0.2 + 1077 0.535 0.175 0.15 + 1078 0.535 0.21875 0.3 + 1079 0.5175 0.175 0.3 + 1081 0.535 0.2625 0.25 + 1083 0.5175 0.2625 0.3 + 1084 0.535 0.30625 0.3 + 1086 0.5175 0.2625 0.2 + 1087 0.535 0.2625 0.15 + 1088 0.535 0.30625 0.2 + 1089 0.5 0.175 0.25 + 1090 0.5 0.21875 0.2 + 1091 0.5 0.175 0.15 + 1093 0.5 0.21875 0.3 + 1094 0.5 0.2625 0.25 + 1096 0.5 0.30625 0.3 + 1099 0.5 0.2625 0.15 + 1101 0.5 0.30625 0.2 + 1102 0.535 0.35 -0.25 + 1103 0.5175 0.35 -0.2 + 1106 0.5175 0.35 -0.3 + 1107 0.5 0.35 -0.25 + 1108 0.535 0.13125-6.1761158899442E-18 + 1109 0.5175 0.0875-1.5978767538454E-18 + 1110 0.535 0.0875 0.05 + 1111 0.535 0.04375-1.5978767538454E-18 + 1112 0.5175 0.175-4.5409039123036E-18 + 1113 0.535 0.175 0.05 + 1114 0.5 0.131253.73352237951837E-20 + 1115 0.5 0.0875 0.05 + 1117 0.5 0.043751.11869843223633E-36 + 1118 0.5 0.175 0.05 + 1119 0.535 0.21875 0.1 + 1120 0.5175 0.175 0.1 + 1121 0.535 0.13125 0.1 + 1122 0.5175 0.2625 0.1 + 1123 0.535 0.30625 0.1 + 1124 0.5 0.21875 0.1 + 1125 0.5 0.13125 0.1 + 1126 0.5 0.30625 0.1 + 1127 0.5175 0.0875 0.1 + 1128 0.535 0.04375 0.1 + 1129 0.5 0.04375 0.1 + 1130 0.5175 0.0875 -0.3 + 1131 0.535 0.04375 -0.3 + 1135 0.5 0.04375 -0.3 + 1136 0.535 0.0 -0.15 + 1137 0.5175 0.0 -0.2 + 1139 0.535 0.0 -0.25 + 1142 0.5175 0.0 -0.1 + 1143 0.535 0.0 -0.05 + 1145 0.5 0.0 -0.15 + 1147 0.5 0.0 -0.25 + 1149 0.5 0.0 -0.05 + 1150 0.5175 0.35 0.1 + 1151 0.535 0.35 0.15 + 1154 0.5 0.35 0.15 + 1155 0.5175 0.0 0.1 + 1156 0.535 0.0 0.05 + 1159 0.5 0.0 0.05 + 1160 0.535 0.35 0.25 + 1161 0.5175 0.35 0.3 + 1164 0.5175 0.35 0.2 + 1165 0.5 0.35 0.25 + 1166 0.5175 0.0 0.0 + 1167 0.5175 0.0 -0.3 +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/BRIC20/1 +# bric_ID node_ID1 node_ID2 node_ID3 node_ID4 node_ID5 node_ID6 node_ID7 node_ID8 +# node_ID9 node_ID10 node_ID11 node_ID12 node_ID13 node_ID14 node_ID15 node_ID16 +#node_ID17 node_ID18 node_ID19 node_ID20 + 25 725 747 749 726 758 759 760 761 + 837 932 843 836 839 935 938 845 + 959 965 969 960 + 26 758 759 760 761 762 763 764 765 + 959 965 969 960 961 966 970 974 + 977 981 984 978 + 27 748 743 730 729 766 767 768 769 + 911 857 853 854 937 913 859 855 + 991 995 999 992 + 28 766 767 768 769 770 771 772 773 + 991 995 999 992 993 996 1000 1005 + 1008 1012 1017 1009 + 29 751 750 746 747 774 775 776 759 + 939 928 925 934 941 940 930 935 + 1023 1027 968 967 + 30 774 775 776 759 777 778 779 763 + 1023 1027 968 967 1024 1028 1031 966 + 1033 1038 983 982 + 31 738 737 736 756 780 781 782 783 + 884 880 882 887 889 885 883 957 + 1046 1052 1056 1047 + 32 780 781 782 783 784 785 786 787 + 1046 1052 1056 1047 1048 1054 1058 1061 + 1064 1068 1069 1065 + 33 752 735 734 754 788 789 790 791 + 877 873 874 943 947 879 875 954 + 1074 1078 1081 1075 + 34 788 789 790 791 792 793 794 795 + 1074 1078 1081 1075 1076 1079 1083 1086 + 1089 1093 1094 1090 + 35 726 749 728 727 761 760 796 797 + 843 851 847 841 845 938 852 849 + 969 972 1102 975 + 36 761 760 796 797 765 764 798 799 + 969 972 1102 975 974 970 1103 1106 + 984 986 1107 990 + 37 750 745 744 746 775 800 801 776 + 921 914 915 928 940 924 919 930 + 1029 1108 1032 1027 + 38 775 800 801 776 778 802 803 779 + 1029 1108 1032 1027 1028 1109 1112 1031 + 1039 1114 1045 1038 + 39 744 753 755 743 801 804 805 767 + 917 949 912 910 919 952 955 913 + 1113 1119 998 997 + 40 801 804 805 767 803 806 807 771 + 1113 1119 998 997 1112 1120 1122 996 + 1118 1124 1015 1014 + 41 753 752 754 755 804 788 791 805 + 942 943 953 949 952 947 954 955 + 1077 1075 1087 1119 + 42 804 788 791 805 806 792 795 807 + 1077 1075 1087 1119 1120 1076 1086 1122 + 1091 1090 1099 1124 + 43 757 756 752 753 808 783 788 804 + 956 945 942 951 958 957 947 952 + 1063 1062 1077 1121 + 44 808 783 788 804 809 787 792 806 + 1063 1062 1077 1121 1127 1061 1076 1120 + 1073 1072 1091 1125 + 45 724 751 747 725 810 774 759 758 + 834 934 837 832 835 941 935 839 + 1025 967 959 963 + 46 810 774 759 758 811 777 763 762 + 1025 967 959 963 1130 1024 966 961 + 1034 982 977 980 + 47 742 741 750 751 812 813 775 774 + 902 904 939 908 909 906 940 941 + 1136 1030 1023 1026 + 48 812 813 775 774 814 815 778 777 + 1136 1030 1023 1026 1137 1142 1028 1024 + 1145 1042 1033 1035 + 49 746 744 743 748 776 801 767 766 + 915 910 911 926 930 919 913 937 + 1032 997 991 994 + 50 776 801 767 766 779 803 771 770 + 1032 997 991 994 1031 1112 996 993 + 1045 1014 1008 1010 + 51 756 736 735 752 783 782 789 788 + 882 876 877 945 957 883 879 947 + 1056 1059 1074 1062 + 52 783 782 789 788 787 786 793 792 + 1056 1059 1074 1062 1061 1058 1079 1076 + 1069 1071 1089 1072 + 53 743 755 731 730 767 805 816 768 + 912 863 856 857 913 955 865 859 + 998 1123 1002 995 + 54 767 805 816 768 771 807 817 772 + 998 1123 1002 995 996 1122 1150 1000 + 1015 1126 1020 1012 + 55 739 738 756 757 818 780 783 808 + 886 887 956 893 895 889 957 958 + 1050 1047 1063 1128 + 56 818 780 783 808 819 784 787 809 + 1050 1047 1063 1128 1155 1048 1061 1127 + 1067 1065 1073 1129 + 57 754 734 733 732 791 790 820 821 + 874 871 867 868 954 875 872 870 + 1081 1084 1160 1088 + 58 791 790 820 821 795 794 822 823 + 1081 1084 1160 1088 1086 1083 1161 1164 + 1094 1096 1165 1101 + 59 745 757 753 744 800 808 804 801 + 923 951 917 914 924 958 952 919 + 1110 1121 1113 1108 + 60 800 808 804 801 802 809 806 803 + 1110 1121 1113 1108 1109 1127 1120 1112 + 1115 1125 1118 1114 + 61 741 740 745 750 813 824 800 775 + 897 898 921 904 906 901 924 940 + 1143 1111 1029 1030 + 62 813 824 800 775 815 825 802 778 + 1143 1111 1029 1030 1142 1166 1109 1028 + 1149 1117 1039 1042 + 63 747 746 748 749 759 776 766 760 + 925 926 936 932 935 930 937 938 + 968 994 971 965 + 64 759 776 766 760 763 779 770 764 + 968 994 971 965 966 1031 993 970 + 983 1010 985 981 + 65 740 739 757 745 824 818 808 800 + 891 893 923 898 901 895 958 924 + 1156 1128 1110 1111 + 66 824 818 808 800 825 819 809 802 + 1156 1128 1110 1111 1166 1155 1127 1109 + 1159 1129 1115 1117 + 67 749 748 729 728 760 766 769 796 + 936 854 850 851 938 937 855 852 + 971 992 1006 972 + 68 760 766 769 796 764 770 773 798 + 971 992 1006 972 970 993 1005 1103 + 985 1009 1022 986 + 69 755 754 732 731 805 791 821 816 + 953 868 861 863 955 954 870 865 + 1087 1088 1151 1123 + 70 805 791 821 816 807 795 823 817 + 1087 1088 1151 1123 1122 1086 1164 1150 + 1099 1101 1154 1126 + 71 723 742 751 724 826 812 774 810 + 829 908 834 828 831 909 941 835 + 1139 1026 1025 1131 + 72 826 812 774 810 827 814 777 811 + 1139 1026 1025 1131 1167 1137 1024 1130 + 1147 1035 1034 1135 +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +#- 1. PART: +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/PART/1 +#part_title +flapPart +# prop_ID mat_ID Thick + 1 1 +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +#- 2. MATERIAL DEFINITION: +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/MAT/OGDEN/1 +flapMaterial +# RHO_I + 250 +# Nu sigma_cut funIDbulk Fscale_bulk M I_form + 0.4 0 0 0 0 1 +# Mu_1 Mu_2 Mu_3 Mu_4 Mu_5 + 178.5714 0 +# Mu_6 Mu_7 Mu_8 Mu_9 Mu_10 + +# alpha_1 alpha_2 alpha_3 alpha_4 alpha_5 + 2 0 +# alpha_6 alpha_7 alpha_8 alpha_9 alpha_10 + +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +#- 3. PROPERTIES DEFINITION: +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/PROP/SOLID/1 +flapProperty +# Isolid Ismstr Iale Icpre Itetra10 Inpts Itetra4 Iframe Dn + 16 0 0 0 0 0 0 0 0.0 +# qa qb h Lambda Mu + 0.0 0.0 0.0 0.0 0.0 +# deltaT_min Vdef_min Vdef_max ASP_max COL_min + 0.0 0.0 0.0 0.0 0.0 +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +#- 4. BOUNDARY CONDITIONS: +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/BCS/1 +fixedWallZ0 +# Tra rot skew_ID grnod_ID + 111 000 0 1 +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/GRNOD/NODE/1 +#title +fixedEnd +# item_ID1 item_ID2 item_ID3 item_ID4 item_ID5 item_ID6 item_ID7 item_ID8 item_ID9 item_ID10 + 723 737 738 739 740 741 742 780 781 784 + 785 812 813 814 815 818 819 824 825 826 + 827 829 831 884 885 886 889 891 895 897 + 901 902 906 909 1046 1048 1050 1054 1064 1067 + 1136 1137 1139 1142 1143 1145 1147 1149 1155 1156 + 1159 1166 1167 +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +#- 5. INTERFACES: +#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----| +/GRNOD/NODE/2 +#title +interface +# item_ID1 item_ID2 item_ID3 item_ID4 item_ID5 item_ID6 item_ID7 item_ID8 item_ID9 item_ID10 + 723 724 725 726 727 728 729 730 731 732 + 733 734 735 736 737 738 739 740 741 742 + 743 744 745 746 747 748 749 750 751 752 + 753 754 755 756 757 762 763 764 765 768 + 769 770 771 772 773 777 778 779 784 785 + 786 787 792 793 794 795 796 797 798 799 + 802 803 806 807 809 811 814 815 816 817 + 819 820 821 822 823 825 827 828 829 832 + 834 836 837 841 843 847 849 850 851 852 + 853 854 855 856 857 859 861 863 865 867 + 868 870 871 872 873 874 876 877 880 882 + 884 886 887 891 893 897 898 902 904 908 + 910 911 912 914 915 917 921 923 925 926 + 928 932 934 936 939 942 943 945 949 951 + 953 956 977 978 980 981 982 983 984 985 + 986 990 999 1000 1002 1005 1006 1008 1009 1010 + 1012 1014 1015 1017 1020 1022 1033 1034 1035 1038 + 1039 1042 1045 1064 1065 1067 1068 1069 1071 1072 + 1073 1089 1090 1091 1093 1094 1096 1099 1101 1102 + 1103 1106 1107 1114 1115 1117 1118 1124 1125 1126 + 1129 1135 1145 1147 1149 1150 1151 1154 1159 1160 + 1161 1164 1165 +##-------------------------------------------------------------------------------------------------- +## End Of Radioss Block Deck +##-------------------------------------------------------------------------------------------------- +/END \ No newline at end of file diff --git a/perpendicular-flap-3d/solid-openradioss/solid-openradioss_0001.rad b/perpendicular-flap-3d/solid-openradioss/solid-openradioss_0001.rad new file mode 100644 index 000000000..56c53c779 --- /dev/null +++ b/perpendicular-flap-3d/solid-openradioss/solid-openradioss_0001.rad @@ -0,0 +1,31 @@ +/RUN/pulsatingFlap/1/ +30.0 +/VERS/2024 + +/ANIM/DT +0.0 0.5 +/ANIM/VECT/VEL +/ANIM/VECT/DISP +/ANIM/VECT/CONT +/ANIM/VECT/FINT +/ANIM/VECT/FEXT +/ANIM/VECT/FOPT +/ANIM/ELEM/EPSP +/ANIM/ELEM/ENER +#/ANIM/NODA/DT +#/ANIM/NODA/DMAS +#/ANIM/TENS/STRESS/MEMB +#/ANIM/TENS/STRAIN/UPPER +/ANIM/MASS +# +/TFILE/0 +0.005 +# +/PRINT/-100 +# +# +/DT +0.9 0.001 +# +/DTIX +0.001 0.001 \ No newline at end of file diff --git a/tests/component-templates/openradioss-adapter.yaml b/tests/component-templates/openradioss-adapter.yaml new file mode 100644 index 000000000..045b03c7d --- /dev/null +++ b/tests/component-templates/openradioss-adapter.yaml @@ -0,0 +1,16 @@ +build: + context: {{ dockerfile_context }} + args: + {% for key, value in build_arguments.items() %} + - {{key}}={{value}} + {% endfor %} + target: openradioss_adapter +depends_on: + prepare: + condition: service_completed_successfully +volumes: + - {{ run_directory }}:/runs +command: > + /bin/bash -c "id && + cd '/runs/{{ tutorial_folder }}/{{ case_folder }}' && + {{ run }} | tee system-tests_{{ case_folder }}.log 2>&1" diff --git a/tests/components.yaml b/tests/components.yaml index 9f171c597..f57873135 100644 --- a/tests/components.yaml +++ b/tests/components.yaml @@ -377,6 +377,27 @@ openfoam-adapter: OPENFOAM_ADAPTER_PR: default: "" +openradioss-adapter: + template: component-templates/openradioss-adapter.yaml + build_arguments: + PLATFORM: + default: "ubuntu_2404" + PRECICE_REF: + repository: https://github.com/precice/precice + default: "develop" + PRECICE_PR: + default: "" + PRECICE_PRESET: + default: "production-audit" + TUTORIALS_REF: + repository: https://github.com/precice/tutorials + default: "develop" + TUTORIALS_PR: + default: "" + OPENCOURANT_REF: + repository: https://github.com/OpenCourant/OpenCourant + default: "latest-20261011" + python-bindings: template: component-templates/python-bindings.yaml build_arguments: diff --git a/tests/dockerfiles/ubuntu_2404/Dockerfile b/tests/dockerfiles/ubuntu_2404/Dockerfile index 29e4c6831..6c0e8851f 100644 --- a/tests/dockerfiles/ubuntu_2404/Dockerfile +++ b/tests/dockerfiles/ubuntu_2404/Dockerfile @@ -438,6 +438,29 @@ RUN git clone https://github.com/precice/openfoam-adapter.git &&\ ### end of openfoam_adapter stage ### +FROM precice AS openradioss_adapter +ARG OPENCOURANT_REF + +USER precice +WORKDIR /home/precice +RUN git clone https://github.com/OpenCourant/OpenCourant.git && \ + cd OpenCourant && \ + git checkout ${OPENCOURANT_REF} && \ + cd starter && \ + ./build_script.sh -arch=linux64_gf -nt $(nproc) +RUN cd OpenCourant/engine && \ + ./build_script.sh -arch=linux64_gf -mpi=ompi -mpi-include=/usr/lib/x86_64-linux-gnu/openmpi/include -preCICE -nt $(nproc) + +ENV OPENRADIOSS_PATH="/home/precice/OpenCourant" +ENV RAD_CFG_PATH="$OPENRADIOSS_PATH/hm_cfg_files" +ENV RAD_H3D_PATH="$OPENRADIOSS_PATH/extlib/h3d/lib/linux64" +ENV LD_LIBRARY_PATH="$OPENRADIOSS_PATH/extlib/hm_reader/linux64/:$OPENRADIOSS_PATH/extlib/h3d/lib/linux64/:$LD_LIBRARY_PATH" +ENV PATH="$OPENRADIOSS_PATH/starter/cbuild_starter_linux64_gf:$OPENRADIOSS_PATH/engine/cbuild_engine_linux64_gf_ompi_precice/:$PATH" +RUN echo "alias radioss_starter=starter_linux64_gf" >> ~/.bashrc +RUN echo "alias radioss_engine=engine_linux64_gf_ompi_precice" >> ~/.bashrc +### end of openradioss_adapter + + FROM python_bindings AS su2_adapter ARG SU2_VERSION ARG SU2_ADAPTER_PR diff --git a/tests/reference_versions.yaml b/tests/reference_versions.yaml index 73d3665a3..e77b79b2a 100644 --- a/tests/reference_versions.yaml +++ b/tests/reference_versions.yaml @@ -25,6 +25,7 @@ GISMO_ADAPTER_REF: "71658c7" # main, Oct 1, 2026, compatible with v26.09.0 FMI_RUNNER_REF: "v0.2.1" JULIA_BINDINGS_REF: "v3.4.0" MICRO_MANAGER_REF: "v0.12.0" +OPENCOURANT_REF: "latest-20261011" OPENFOAM_ADAPTER_REF: "v1.4.0" PRECICE_REF: "v3.4.1" PYTHON_BINDINGS_REF: "v3.4.0" diff --git a/tests/tests.yaml b/tests/tests.yaml index a39616bd1..2502d599c 100644 --- a/tests/tests.yaml +++ b/tests/tests.yaml @@ -661,6 +661,17 @@ test_suites: max_time: 0.1 reference_result: ./perpendicular-flap-stress/reference-results/fluid-openfoam_solid-gismo.tar.gz + perpendicular-flap-3d_fluid-openfoam_solid-openradioss: + tutorials: + - &perpendicular-flap-3d_fluid-openfoam_solid-openradioss + path: perpendicular-flap-3d + case_combination: + - fluid-openfoam + - solid-openradioss + max_time: 0.02 + skip_compare: true + reference_result: ./perpendicular-flap-3d/reference-results/fluid-openfoam_solid-openradioss.tar.gz + quickstart_fluid-openfoam_solid-cpp: tutorials: - &quickstart_fluid-openfoam_solid-cpp @@ -972,6 +983,10 @@ test_suites: tutorials: - *perpendicular-flap-stress_fluid-openfoam_solid-gismo + perpendicular-flap-3d: + tutorials: + - *perpendicular-flap-3d_fluid-openfoam_solid-openradioss + quickstart: tutorials: - *quickstart_fluid-openfoam_solid-cpp @@ -1128,6 +1143,7 @@ test_suites: - *perpendicular-flap_fluid-openfoam_solid-openfoam - *perpendicular-flap_fluid-su2_solid-fenics - *perpendicular-flap-stress_fluid-openfoam_solid-gismo + - *perpendicular-flap-3d_fluid-openfoam_solid-openradioss - *quickstart_fluid-openfoam_solid-cpp - *resonant-circuit_capacitor-python_coil-python - *turek-hron-fsi3_fluid-openfoam_solid-dealii @@ -1314,6 +1330,8 @@ test_suites: - *perpendicular-flap_fluid-openfoam_solid-fenics - *perpendicular-flap_fluid-openfoam_solid-openfoam - *perpendicular-flap_fluid-openfoam_solid-solids4foam + - *perpendicular-flap-stress_fluid-openfoam_solid-gismo + - *perpendicular-flap-3d_fluid-openfoam_solid-openradioss - *turek-hron-fsi3_fluid-openfoam_solid-dealii - *quickstart_fluid-openfoam_solid-cpp - *volume-coupled-flow_fluid-openfoam_source-nutils @@ -1323,6 +1341,10 @@ test_suites: - *partitioned-heat-conduction-mixedbc_left-openfoam_right-openfoam - *partitioned-heat-conduction-robin_left-openfoam_right-openfoam + openradioss-adapter: + tutorials: + - *perpendicular-flap-3d_fluid-openfoam_solid-openradioss + julia-bindings: tutorials: - *resonant-circuit_capacitor-julia_coil-julia diff --git a/tools/cleaning-tools.sh b/tools/cleaning-tools.sh index eaa4758fd..64aaff4b4 100644 --- a/tools/cleaning-tools.sh +++ b/tools/cleaning-tools.sh @@ -157,6 +157,17 @@ clean_openfoam() { ) } +clean_openradioss() { + ( + set -e -u + cd "$1" + echo "- Cleaning up OpenRadioss case in $(pwd)" + rm -fv ./*.out ./*.rst ./*.vtk + clean_precice_logs . + clean_case_logs . + ) +} + clean_su2() { ( set -e -u diff --git a/tools/setup-openradioss.sh b/tools/setup-openradioss.sh new file mode 100644 index 000000000..adbe995b6 --- /dev/null +++ b/tools/setup-openradioss.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Script that prepares an environment with aliases used in the OpenRadioss preCICE tutorials. +# This script was originally prepared for OpenRadioss, but also works with OpenCourant (as of November 2026). + +# Set OPENRADIOSS_PATH in your ~/.bashrc, or edit the next line +# export OPENRADIOSS_PATH="/home/user/OpenRadioss" + +# As recommended by the installation guide +export RAD_CFG_PATH=$OPENRADIOSS_PATH/hm_cfg_files +export LD_LIBRARY_PATH="$OPENRADIOSS_PATH/extlib/hm_reader/linux64/:$OPENRADIOSS_PATH/extlib/h3d/lib/linux64/:$LD_LIBRARY_PATH" +export OMP_STACKSIZE=400m + +export PATH="$OPENRADIOSS_PATH/starter/cbuild_starter_linux64_gf:$OPENRADIOSS_PATH/engine/cbuild_engine_linux64_gf_ompi_precice/:$PATH" +alias radioss_starter='starter_linux64_gf' +alias radioss_engine='engine_linux64_gf_ompi_precice' + +# These tools are not included in the basic installation. +# For OpenCourant, find them in https://github.com/OpenCourant/Tools/tree/main/output_converters +alias radiossVTK='$OPENRADIOSS_PATH/exec/anim_to_vtk_linux64_gf' +alias radiossCSV='$OPENRADIOSS_PATH/exec/th_to_csv_linux64_gf' + +# Run `toVTK modelA` to convert all animation files modelAA* to VTK format +toVTK() { + + if [ $# -lt 1 ]; then + echo "ERROR - Usage: toVTK ROOTNAME" + fi + + Rootname="$1" + + for file in "${Rootname}"A*; do + # skip if no matching files + [ -e "$file" ] || { echo "ERROR: No files matching ${Rootname}A*"; } + + animation_number="${file#"${Rootname}A"}" + + radiossVTK "$file" > "${Rootname}_${animation_number}.vtk" + + echo "Converted ${Rootname}A${animation_number} → ${Rootname}_${animation_number}.vtk" + done +} + +# Run `toCSV modelA` to convert all animation files modelAT* to CSV format +toCSV() { + + if [ $# -lt 1 ]; then + echo "ERROR - Usage: toVTK ROOTNAME" + fi + + Rootname="$1" + + for file in "${Rootname}"T*; do + # skip if no matching files + [ -e "$file" ] || { echo "ERROR: No files matching ${Rootname}T*"; } + + history_number="${file#"${Rootname}T"}" + + radiossCSV "$file" > "${Rootname}_${history_number}.csv" + + echo "Converted ${Rootname}T${history_number} → ${Rootname}_${history_number}.csv" + done +} \ No newline at end of file