mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
This is a more convenient way of maintaining the state or multiple states (for higher-order integration), storing, retrieving and passing between processors.
263 lines
6.6 KiB
C
263 lines
6.6 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / 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 "rigidBodyModel.H"
|
|
#include "rigidBodyModelState.H"
|
|
#include "rigidBodyRestraint.H"
|
|
|
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
|
|
void Foam::RBD::rigidBodyModel::applyRestraints(Field<spatialVector>& fx) const
|
|
{
|
|
if (restraints_.empty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
forAll(restraints_, ri)
|
|
{
|
|
DebugInfo << "Restraint " << restraints_[ri].name();
|
|
|
|
// Accumulate the restraint forces
|
|
fx[master(restraints_[ri].bodyID())] += restraints_[ri].restrain();
|
|
}
|
|
}
|
|
|
|
|
|
void Foam::RBD::rigidBodyModel::forwardDynamics
|
|
(
|
|
rigidBodyModelState& state,
|
|
const scalarField& tau,
|
|
const Field<spatialVector>& fx
|
|
) const
|
|
{
|
|
const scalarField& q = state.q();
|
|
const scalarField& w = state.w();
|
|
const scalarField& qDot = state.qDot();
|
|
scalarField& qDdot = state.qDdot();
|
|
|
|
DebugInFunction
|
|
<< "q = " << q << nl
|
|
<< "qDot = " << qDot << nl
|
|
<< "tau = " << tau << endl;
|
|
|
|
// Joint state returned by jcalc
|
|
joint::XSvc J;
|
|
|
|
v_[0] = Zero;
|
|
|
|
for (label i=1; i<nBodies(); i++)
|
|
{
|
|
const joint& jnt = joints()[i];
|
|
jnt.jcalc(J, q, w, qDot);
|
|
|
|
S_[i] = J.S;
|
|
S1_[i] = J.S1;
|
|
|
|
Xlambda_[i] = J.X & XT_[i];
|
|
|
|
const label lambdai = lambda_[i];
|
|
|
|
if (lambdai != 0)
|
|
{
|
|
X0_[i] = Xlambda_[i] & X0_[lambdai];
|
|
}
|
|
else
|
|
{
|
|
X0_[i] = Xlambda_[i];
|
|
}
|
|
|
|
v_[i] = (Xlambda_[i] & v_[lambdai]) + J.v;
|
|
c_[i] = J.c + (v_[i] ^ J.v);
|
|
IA_[i] = I(i);
|
|
pA_[i] = v_[i] ^* (I(i) & v_[i]);
|
|
|
|
if (fx.size())
|
|
{
|
|
pA_[i] -= *X0_[i] & fx[i];
|
|
}
|
|
}
|
|
|
|
for (label i=nBodies()-1; i>0; i--)
|
|
{
|
|
const joint& jnt = joints()[i];
|
|
const label qi = jnt.qIndex();
|
|
|
|
if (jnt.nDoF() == 1)
|
|
{
|
|
U1_[i] = IA_[i] & S1_[i];
|
|
Dinv_[i].xx() = 1/(S1_[i] && U1_[i]);
|
|
u_[i].x() = tau[qi] - (S1_[i] && pA_[i]);
|
|
|
|
const label lambdai = lambda_[i];
|
|
|
|
if (lambdai != 0)
|
|
{
|
|
const spatialTensor Ia
|
|
(
|
|
IA_[i] - (U1_[i]*(Dinv_[i].xx()*U1_[i]))
|
|
);
|
|
|
|
const spatialVector pa
|
|
(
|
|
pA_[i] + (Ia & c_[i]) + U1_[i]*(Dinv_[i].xx()*u_[i].x())
|
|
);
|
|
|
|
IA_[lambdai] +=
|
|
spatialTensor(Xlambda_[i].T())
|
|
& Ia
|
|
& spatialTensor(Xlambda_[i]);
|
|
|
|
pA_[lambdai] += Xlambda_[i].T() & pa;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
U_[i] = IA_[i] & S_[i];
|
|
Dinv_[i] = (S_[i].T() & U_[i]).inv();
|
|
|
|
u_[i] = tau.block<vector>(qi) - (S_[i].T() & pA_[i]);
|
|
|
|
const label lambdai = lambda_[i];
|
|
|
|
if (lambdai != 0)
|
|
{
|
|
spatialTensor Ia
|
|
(
|
|
IA_[i]
|
|
- (U_[i] & Dinv_[i] & U_[i].T())
|
|
);
|
|
|
|
spatialVector pa
|
|
(
|
|
pA_[i]
|
|
+ (Ia & c_[i])
|
|
+ (U_[i] & Dinv_[i] & u_[i])
|
|
);
|
|
|
|
IA_[lambdai] +=
|
|
spatialTensor(Xlambda_[i].T())
|
|
& Ia
|
|
& spatialTensor(Xlambda_[i]);
|
|
|
|
pA_[lambdai] += Xlambda_[i].T() & pa;
|
|
}
|
|
}
|
|
}
|
|
|
|
a_[0] = spatialVector(Zero, -g_);
|
|
|
|
for (label i=1; i<nBodies(); i++)
|
|
{
|
|
const joint& jnt = joints()[i];
|
|
const label qi = jnt.qIndex();
|
|
|
|
a_[i] = (Xlambda_[i] & a_[lambda_[i]]) + c_[i];
|
|
|
|
if (jnt.nDoF() == 1)
|
|
{
|
|
qDdot[qi] = Dinv_[i].xx()*(u_[i].x() - (U1_[i] && a_[i]));
|
|
a_[i] += S1_[i]*qDdot[qi];
|
|
}
|
|
else
|
|
{
|
|
vector qDdoti(Dinv_[i] & (u_[i] - (U_[i].T() & a_[i])));
|
|
|
|
// Need to add mutable "block<vector>" to Field
|
|
qDdot[qi] = qDdoti.x();
|
|
qDdot[qi+1] = qDdoti.y();
|
|
qDdot[qi+2] = qDdoti.z();
|
|
|
|
a_[i] += (S_[i] & qDdoti);
|
|
}
|
|
}
|
|
|
|
DebugInfo
|
|
<< "qDdot = " << qDdot << nl
|
|
<< "a = " << a_ << endl;
|
|
}
|
|
|
|
|
|
void Foam::RBD::rigidBodyModel::forwardDynamicsCorrection
|
|
(
|
|
const rigidBodyModelState& state
|
|
) const
|
|
{
|
|
DebugInFunction << endl;
|
|
|
|
const scalarField& q = state.q();
|
|
const scalarField& w = state.w();
|
|
const scalarField& qDot = state.qDot();
|
|
const scalarField& qDdot = state.qDdot();
|
|
|
|
// Joint state returned by jcalc
|
|
joint::XSvc J;
|
|
|
|
v_[0] = Zero;
|
|
a_[0] = spatialVector(Zero, -g_);
|
|
|
|
for (label i=1; i<nBodies(); i++)
|
|
{
|
|
const joint& jnt = joints()[i];
|
|
const label qi = jnt.qIndex();
|
|
|
|
jnt.jcalc(J, q, w, qDot);
|
|
|
|
S_[i] = J.S;
|
|
S1_[i] = J.S1;
|
|
|
|
Xlambda_[i] = J.X & XT_[i];
|
|
|
|
const label lambdai = lambda_[i];
|
|
|
|
if (lambdai != 0)
|
|
{
|
|
X0_[i] = Xlambda_[i] & X0_[lambdai];
|
|
}
|
|
else
|
|
{
|
|
X0_[i] = Xlambda_[i];
|
|
}
|
|
|
|
v_[i] = (Xlambda_[i] & v_[lambdai]) + J.v;
|
|
c_[i] = J.c + (v_[i] ^ J.v);
|
|
a_[i] = (Xlambda_[i] & a_[lambdai]) + c_[i];
|
|
|
|
if (jnt.nDoF() == 1)
|
|
{
|
|
a_[i] += S1_[i]*qDdot[qi];
|
|
}
|
|
else
|
|
{
|
|
a_[i] += S_[i] & qDdot.block<vector>(qi);
|
|
}
|
|
}
|
|
|
|
DebugInfo<< "a = " << a_ << endl;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|