From 8b9240293076bcb13b1f329f28afa6b2951ea66c Mon Sep 17 00:00:00 2001
From: Henry Weller <http://cfd.direct>
Date: Mon, 11 Apr 2016 15:14:18 +0100
Subject: [PATCH] rigidBodyDynamics/restraints: Added linearAxialAngularSpring,
 linear axial angular spring restraint

Included for backward-compatibility with the 6-DoF solver but in the
future will be re-implemented as a joint rather than body restraint and
accumulated in tau (internal forces) rather than fx (external forces).
---
 src/rigidBodyDynamics/Make/files              |   1 +
 .../linearAxialAngularSpring.C                | 199 ++++++++++++++++++
 .../linearAxialAngularSpring.H                | 125 +++++++++++
 3 files changed, 325 insertions(+)
 create mode 100644 src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.C
 create mode 100644 src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.H

diff --git a/src/rigidBodyDynamics/Make/files b/src/rigidBodyDynamics/Make/files
index bdd244ae8a..b07f5e8c81 100644
--- a/src/rigidBodyDynamics/Make/files
+++ b/src/rigidBodyDynamics/Make/files
@@ -29,6 +29,7 @@ restraints/restraint/rigidBodyRestraint.C
 restraints/restraint/rigidBodyRestraintNew.C
 restraints/linearSpring/linearSpring.C
 restraints/linearDamper/linearDamper.C
+restraints/linearAxialAngularSpring/linearAxialAngularSpring.C
 
 rigidBodyModel/rigidBodyModel.C
 rigidBodyModel/forwardDynamics.C
diff --git a/src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.C b/src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.C
new file mode 100644
index 0000000000..795c9021b7
--- /dev/null
+++ b/src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.C
@@ -0,0 +1,199 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     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 "linearAxialAngularSpring.H"
+#include "rigidBodyModel.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace RBD
+{
+namespace restraints
+{
+    defineTypeNameAndDebug(linearAxialAngularSpring, 0);
+
+    addToRunTimeSelectionTable
+    (
+        restraint,
+        linearAxialAngularSpring,
+        dictionary
+    );
+}
+}
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::RBD::restraints::linearAxialAngularSpring::
+linearAxialAngularSpring
+(
+    const word& name,
+    const dictionary& dict,
+    const rigidBodyModel& model
+)
+:
+    restraint(name, dict, model)
+{
+    read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::RBD::restraints::linearAxialAngularSpring::
+~linearAxialAngularSpring()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+Foam::spatialVector
+Foam::RBD::restraints::linearAxialAngularSpring::restrain() 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;
+    }
+
+    // Damping of along axis angular velocity only
+    vector moment
+    (
+        -(
+            stiffness_*theta
+          + damping_*(model_.v(model_.master(bodyID_)).w() & a)
+         )*a
+    );
+
+    if (model_.debug)
+    {
+        Info<< " angle " << theta*sign(a & axis_)
+            << " moment " << moment
+            << endl;
+    }
+
+    return spatialVector(moment, Zero);
+}
+
+
+bool Foam::RBD::restraints::linearAxialAngularSpring::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);
+    }
+
+    coeffs_.lookup("stiffness") >> stiffness_;
+    coeffs_.lookup("damping") >> damping_;
+
+    return true;
+}
+
+
+void Foam::RBD::restraints::linearAxialAngularSpring::write
+(
+    Ostream& os
+) const
+{
+    restraint::write(os);
+
+    os.writeKeyword("referenceOrientation")
+        << refQ_ << token::END_STATEMENT << nl;
+
+    os.writeKeyword("axis")
+        << axis_ << token::END_STATEMENT << nl;
+
+    os.writeKeyword("stiffness")
+        << stiffness_ << token::END_STATEMENT << nl;
+
+    os.writeKeyword("damping")
+        << damping_ << token::END_STATEMENT << nl;
+}
+
+
+// ************************************************************************* //
diff --git a/src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.H b/src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.H
new file mode 100644
index 0000000000..412e21976a
--- /dev/null
+++ b/src/rigidBodyDynamics/restraints/linearAxialAngularSpring/linearAxialAngularSpring.H
@@ -0,0 +1,125 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     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::linearAxialAngularSpring
+
+Description
+    Linear axial angular spring restraint.
+
+SourceFiles
+    linearAxialAngularSpring.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef linearAxialAngularSpring_H
+#define linearAxialAngularSpring_H
+
+#include "rigidBodyRestraint.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace RBD
+{
+namespace restraints
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class linearAxialAngularSpring Declaration
+\*---------------------------------------------------------------------------*/
+
+class linearAxialAngularSpring
+:
+    public restraint
+{
+    // Private data
+
+        //- Reference orientation where there is no moment
+        tensor refQ_;
+
+        //- Global unit axis around which the motion is sprung
+        vector axis_;
+
+        //- Spring stiffness coefficient (Nm/rad)
+        scalar stiffness_;
+
+        //- Damping coefficient (Nms/rad)
+        scalar damping_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("linearAxialAngularSpring");
+
+
+    // Constructors
+
+        //- Construct from components
+        linearAxialAngularSpring
+        (
+            const word& name,
+            const dictionary& dict,
+            const rigidBodyModel& model
+        );
+
+        //- Construct and return a clone
+        virtual autoPtr<restraint> clone() const
+        {
+            return autoPtr<restraint>
+            (
+                new linearAxialAngularSpring(*this)
+            );
+        }
+
+
+    //- Destructor
+    virtual ~linearAxialAngularSpring();
+
+
+    // Member Functions
+
+        //- Return the external force applied to the body by this restraint
+        virtual spatialVector restrain() 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
+
+// ************************************************************************* //
-- 
GitLab