/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
Application
polynomial-motion
Description
Polynomial representations of position/angle for fluid-structure
interface check.
Generates position and rotation angle of each node.
Note
The values may or may not correspond to experimental values.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "Fstream.H"
#include "polynomialFunction.H"
#include "unitConversion.H"
#include "foamVtkSeriesWriter.H"
#include "lumpedPointTools.H"
#include "lumpedPointState.H"
#include "lumpedPointIOMovement.H"
#include
using namespace Foam;
//- Position/angle generator based on polynomials
class position_generator
{
// Private Data
typedef FixedList xyzPoly;
List points_;
List angles_;
// Private Member Functions
//- Calculate position/rotation at given time
lumpedPointState calc(scalar currTime) const
{
// Limit the time
currTime = min(currTime, maxTime);
const auto polyToValue =
[=](const xyzPoly& p) -> vector
{
return vector
(
p[0].value(currTime),
p[1].value(currTime),
p[2].value(currTime)
);
};
pointField pts(points_.size());
std::transform
(
points_.cbegin(), points_.cend(), pts.begin(), polyToValue
);
vectorField ang(angles_.size());
std::transform
(
angles_.cbegin(), angles_.cend(), ang.begin(), polyToValue
);
return lumpedPointState{pts, ang};
}
public:
// Control Parameters
// Upper time limit on polynomials
scalar maxTime = GREAT;
// Constructors
//- Default construct
position_generator() = default;
//- Read construct from dictionary
position_generator(const dictionary& dict)
{
dict.readIfPresent("maxTime", maxTime);
dict.readEntry("points", points_);
dict.readEntry("angles", angles_);
if (angles_.size() != points_.size())
{
Info<< "Resized angles to match number of points" << nl;
angles_.resize(points_.size(), xyzPoly(polynomialFunction()));
}
}
// Member Functions
//- Calculate position/rotation at given time
lumpedPointState state(const scalar currTime) const
{
return calc(currTime);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Polynomial representations of position/angle for fluid-structure"
" interface check."
" Generates position and rotation angle of each node."
);
argList::noBanner();
argList::noParallel();
// Time control
argList::addOption
(
"time",
"value",
"The time to use"
);
argList::addOption
(
"deltaT",
"value",
"The time increment for multiple time loops"
);
argList::addOption
(
"nTimes",
"value",
"The number of time loops"
);
// Query, output
argList::addBoolOption
(
"query",
"Report values only and exit"
);
argList::addOption
(
"output",
"file",
"write to file, with header"
);
argList::addOption
(
"scale",
"factor",
"Scaling factor for movement (default: 1)"
);
argList::addOption
(
"visual-length",
"len",
"Visualization length for planes (visualized as triangles)"
);
// Run controls
argList::addBoolOption
(
"dry-run",
"Test movement without a mesh"
);
argList::addBoolOption
(
"removeLock",
"Remove lock-file on termination of slave"
);
argList::addBoolOption
(
"slave",
"Invoke as a slave responder for testing"
);
argList::addArgument
(
"file",
"Points/angles as triples of polynomials.\n"
"Dictionary format"
);
#include "setRootCase.H"
// The position/angle generator
position_generator gen;
{
// Input polynomials file
IFstream is(args[1]);
dictionary dict(is);
gen = position_generator(dict);
}
// Control parameters
const bool dryrun = args.found("dry-run");
const bool slave = args.found("slave");
const bool removeLock = args.found("removeLock");
const bool optQuery = args.found("query");
const fileName outputFile(args.getOrDefault("output", ""));
const scalar relax = args.getOrDefault("scale", 1);
args.readIfPresent("visual-length", lumpedPointState::visLength);
// Time parameters
scalar currTime = args.getOrDefault("time", 0);
const scalar deltaT = args.getOrDefault("deltaT", 0.001);
const label nTimes = args.getOrDefault