Commit 5b9c4cea authored by Matej Forman's avatar Matej Forman Committed by mattijs
Browse files

ENH: rigidbodyDynamics: prescribed rotation + testcase

See:
src/rigidBodyDynamics/restraints/prescribedRotation
tutorials/multiphase/overInterDyMFoam/boatAndPropeller
parent 5848b0af
......@@ -32,6 +32,7 @@ restraints/linearSpring/linearSpring.C
restraints/linearDamper/linearDamper.C
restraints/linearAxialAngularSpring/linearAxialAngularSpring.C
restraints/sphericalAngularDamper/sphericalAngularDamper.C
restraints/prescribedRotation/prescribedRotation.C
rigidBodyModel/rigidBodyModel.C
rigidBodyModel/forwardDynamics.C
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "prescribedRotation.H"
#include "rigidBodyModel.H"
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace RBD
{
namespace restraints
{
defineTypeNameAndDebug(prescribedRotation, 0);
addToRunTimeSelectionTable
(
restraint,
prescribedRotation,
dictionary
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::RBD::restraints::prescribedRotation::prescribedRotation
(
const word& name,
const dictionary& dict,
const rigidBodyModel& model
)
:
restraint(name, dict, model),
omegaSet_(model_.time(), "omega")
{
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::RBD::restraints::prescribedRotation::~prescribedRotation()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::RBD::restraints::prescribedRotation::restrain
(
scalarField& tau,
Field<spatialVector>& fx
) const
{
vector refDir = rotationTensor(vector(1, 0, 0), axis_) & vector(0, 1, 0);
vector oldDir = refQ_ & refDir;
vector newDir = model_.X0(bodyID_).E() & refDir;
if (mag(oldDir & axis_) > 0.95 || mag(newDir & axis_) > 0.95)
{
// Directions close to the axis, changing reference
refDir = rotationTensor(vector(1, 0, 0), axis_) & vector(0, 0, 1);
oldDir = refQ_ & refDir;
newDir = model_.X0(bodyID_).E() & refDir;
}
// Removing axis component from oldDir and newDir and normalising
oldDir -= (axis_ & oldDir)*axis_;
oldDir /= (mag(oldDir) + VSMALL);
newDir -= (axis_ & newDir)*axis_;
newDir /= (mag(newDir) + VSMALL);
scalar theta = mag(acos(min(oldDir & newDir, 1.0)));
// Temporary axis with sign information
vector a = (oldDir ^ newDir);
// Ensure a is in direction of axis
a = (a & axis_)*axis_;
scalar magA = mag(a);
if (magA > VSMALL)
{
a /= magA;
}
else
{
a = Zero;
}
// Adding rotation to a given body
vector omega = model_.v(model_.master(bodyID_)).w();
scalar Inertia = mag(model_.I(model_.master(bodyID_)).Ic());
// from the definition of the angular momentum:
// moment = Inertia*ddt(omega)
// with time step 1:
// moment = Inertia*(omega_wanted - omega)
vector moment
(
(Inertia * (omegaSet_.value(model_.time().value()) - omega) & a) * a
);
if (model_.debug)
{
Info<< " angle " << theta*sign(a & axis_) << endl
<< " moment " << moment << endl
<< " oldDir " << oldDir << endl
<< " newDir " << newDir << endl
<< " refDir " << refDir
<< endl;
}
// Accumulate the force for the restrained body
fx[bodyIndex_] += spatialVector(moment, Zero);
}
bool Foam::RBD::restraints::prescribedRotation::read
(
const dictionary& dict
)
{
restraint::read(dict);
refQ_ = coeffs_.lookupOrDefault<tensor>("referenceOrientation", I);
if (mag(mag(refQ_) - sqrt(3.0)) > 1e-9)
{
FatalErrorInFunction
<< "referenceOrientation " << refQ_ << " is not a rotation tensor. "
<< "mag(referenceOrientation) - sqrt(3) = "
<< mag(refQ_) - sqrt(3.0) << nl
<< exit(FatalError);
}
axis_ = coeffs_.lookup("axis");
scalar magAxis(mag(axis_));
if (magAxis > VSMALL)
{
axis_ /= magAxis;
}
else
{
FatalErrorInFunction
<< "axis has zero length"
<< abort(FatalError);
}
// Read the actual entry
omegaSet_.reset(coeffs_);
return true;
}
void Foam::RBD::restraints::prescribedRotation::write
(
Ostream& os
) const
{
restraint::write(os);
os.writeEntry("referenceOrientation", refQ_);
os.writeEntry("axis", axis_);
omegaSet_.writeData(os);
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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 <http://www.gnu.org/licenses/>.
Class
Foam::RBD::restraints::prescribedRotation
Group
grpRigidBodyDynamicsRestraints
Description
Restraint setting angular velocity of the rigid body.
Developed from the linear axial angular spring restraint.
Adds a rotation along given axis to the body.
Used for a combination of 6DOF bodies where one is driven by 6DOF and
the other attached to it using specified rotation
in the local reference frame.
Usage
\table
Property | Description | Required | Default value
referenceOrientation | Orientation | no | I
axis | Rotation axis (in reference) | yes |
omega | Angular velocity (rad/s) | yes |
\endtable
SourceFiles
prescribedRotation.C
\*---------------------------------------------------------------------------*/
#ifndef prescribedRotation_H
#define prescribedRotation_H
#include "rigidBodyRestraint.H"
#include "TimeFunction1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace RBD
{
namespace restraints
{
/*---------------------------------------------------------------------------*\
Class prescribedRotation Declaration
\*---------------------------------------------------------------------------*/
class prescribedRotation
:
public restraint
{
// Private data
//- Reference orientation where there is no moment
tensor refQ_;
//- Global unit axis around which the motion is sprung
vector axis_;
//- Rotational velocity [rad/sec]
TimeFunction1<vector> omegaSet_;
public:
//- Runtime type information
TypeName("prescribedRotation");
// Constructors
//- Construct from components
prescribedRotation
(
const word& name,
const dictionary& dict,
const rigidBodyModel& model
);
//- Construct and return a clone
virtual autoPtr<restraint> clone() const
{
return autoPtr<restraint>
(
new prescribedRotation(*this)
);
}
//- Destructor
virtual ~prescribedRotation();
// Member Functions
//- Accumulate the retraint internal joint forces into the tau field and
// external forces into the fx field
virtual void restrain
(
scalarField& tau,
Field<spatialVector>& fx
) const;
//- Update properties from given dictionary
virtual bool read(const dictionary& dict);
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace RBD
} // End namespace RBD
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
......@@ -163,16 +163,22 @@ Foam::label Foam::RBD::rigidBodyModel::join_
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
Foam::RBD::rigidBodyModel::rigidBodyModel()
Foam::RBD::rigidBodyModel::rigidBodyModel(const Time& time)
:
time_(time),
g_(Zero)
{
initializeRootBody();
}
Foam::RBD::rigidBodyModel::rigidBodyModel(const dictionary& dict)
Foam::RBD::rigidBodyModel::rigidBodyModel
(
const Time& time,
const dictionary& dict
)
:
time_(time),
g_(Zero)
{
initializeRootBody();
......
......@@ -58,6 +58,10 @@ SourceFiles
namespace Foam
{
// Forward declaration of friend functions and operators
class Time;
namespace RBD
{
......@@ -93,6 +97,9 @@ class rigidBodyModel
protected:
//- Reference to time database
const Time& time_;
// Protected data representing the model structure
//- List of the bodies.
......@@ -211,10 +218,10 @@ public:
// Constructors
//- Null-constructor which adds the single root-body at the origin
rigidBodyModel();
rigidBodyModel(const Time& time);
//- Construct from dictionary
rigidBodyModel(const dictionary& dict);
rigidBodyModel(const Time& time, const dictionary& dict);
//- Destructor
......@@ -223,6 +230,9 @@ public:
// Member Functions
//- Return the time
inline const Time& time() const;
//- Return the number of bodies in the model (bodies().size())
inline label nBodies() const;
......
......@@ -25,6 +25,12 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::Time& Foam::RBD::rigidBodyModel::time() const
{
return time_;
}
inline Foam::label Foam::RBD::rigidBodyModel::nBodies() const
{
return bodies_.size();
......
......@@ -42,9 +42,9 @@ void Foam::RBD::rigidBodyMotion::initialize()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::RBD::rigidBodyMotion::rigidBodyMotion()
Foam::RBD::rigidBodyMotion::rigidBodyMotion(const Time& time)
:
rigidBodyModel(),
rigidBodyModel(time),
motionState_(*this),
motionState0_(*this),
aRelax_(1.0),
......@@ -55,10 +55,11 @@ Foam::RBD::rigidBodyMotion::rigidBodyMotion()
Foam::RBD::rigidBodyMotion::rigidBodyMotion
(
const Time& time,
const dictionary& dict
)
:
rigidBodyModel(dict),
rigidBodyModel(time, dict),
motionState_(*this, dict),
motionState0_(motionState_),
X00_(X0_.size()),
......@@ -78,11 +79,12 @@ Foam::RBD::rigidBodyMotion::rigidBodyMotion
Foam::RBD::rigidBodyMotion::rigidBodyMotion
(
const Time& time,
const dictionary& dict,
const dictionary& stateDict
)
:
rigidBodyModel(dict),
rigidBodyModel(time, dict),
motionState_(*this, stateDict),
motionState0_(motionState_),
X00_(X0_.size()),
......
......@@ -55,6 +55,10 @@ SourceFiles
namespace Foam
{
// Forward declarations
class Time;
namespace RBD
{
......@@ -112,17 +116,19 @@ public:
// Constructors
//- Construct null
rigidBodyMotion();
rigidBodyMotion(const Time& time);
//- Construct from dictionary
rigidBodyMotion
(
const Time& time,
const dictionary& dict
);
//- Construct from constant and state dictionaries
rigidBodyMotion
(
const Time& time,
const dictionary& dict,
const dictionary& stateDict
);
......
......@@ -90,6 +90,7 @@ Foam::rigidBodyMeshMotion::rigidBodyMeshMotion
displacementMotionSolver(mesh, dict, typeName),
model_
(
mesh.time(),
coeffDict(),
IOobject
(
......
......@@ -73,6 +73,7 @@ Foam::rigidBodyMeshMotionSolver::rigidBodyMeshMotionSolver
motionSolver(mesh, dict, typeName),
model_
(
mesh.time(),
coeffDict(),
IOobject
(
......
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus-overset |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
defaultFaces
{
//type slip;
type uniformFixedValue;
uniformValue (0 0 0);
}
"(hullWall|propellerWall|rudderWall)"
{
type movingWallVelocity;
value uniform (0 0 0);
}
atmosphere
{
type pressureInletOutletVelocity;
value uniform (0 0 0);
}
//
// right1
// {
// type zeroGradient; //calculated;
// value $internalField;
// }
"overset.*"
{
type overset;
value uniform (0 0 0);
}
}
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1612+ |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";