Added stabilisation for constraints
Note: necessary for arbitrary DAE systems
This commit is contained in:
parent
6b422ec286
commit
8bdb557b93
8 changed files with 173 additions and 24 deletions
|
@ -536,35 +536,52 @@ void Foam::geometricSixDOF::update(const scalar delta)
|
||||||
{
|
{
|
||||||
// Translation
|
// Translation
|
||||||
|
|
||||||
// Update displacement
|
// Get displacement
|
||||||
const vector Xold = Xrel_.value();
|
const vector Xold = Xrel_.value();
|
||||||
|
|
||||||
vector& Xval = Xrel_.value();
|
vector& Xval = Xrel_.value();
|
||||||
|
|
||||||
Xval.x() = coeffs_[0];
|
Xval.x() = coeffs_[0];
|
||||||
Xval.y() = coeffs_[1];
|
Xval.y() = coeffs_[1];
|
||||||
Xval.z() = coeffs_[2];
|
Xval.z() = coeffs_[2];
|
||||||
|
|
||||||
// Update velocity
|
// Get velocity
|
||||||
Uaverage_.value() = (Xval - Xold)/delta;
|
|
||||||
|
|
||||||
vector& Uval = U_.value();
|
vector& Uval = U_.value();
|
||||||
|
|
||||||
Uval.x() = coeffs_[3];
|
Uval.x() = coeffs_[3];
|
||||||
Uval.y() = coeffs_[4];
|
Uval.y() = coeffs_[4];
|
||||||
Uval.z() = coeffs_[5];
|
Uval.z() = coeffs_[5];
|
||||||
|
|
||||||
|
// Stabilise translational constraints if necessary
|
||||||
|
forAll(translationalConstraints(), tcI)
|
||||||
|
{
|
||||||
|
// Note: get end time for this ODE step from mesh, assuming that the top
|
||||||
|
// level solves this ode from [t - deltaT, t], yielding solution at
|
||||||
|
// t. Done this way to preserve the interface of ODE class.
|
||||||
|
// VV, 10/Mar/2017.
|
||||||
|
const scalar t = dict().time().value();
|
||||||
|
|
||||||
|
translationalConstraints()[tcI].stabilise(t, Xval, Uval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update (possibly constrained) displacement
|
||||||
|
coeffs_[0] = Xval.x();
|
||||||
|
coeffs_[1] = Xval.y();
|
||||||
|
coeffs_[2] = Xval.z();
|
||||||
|
|
||||||
|
// Update (possibly constrained) velocity
|
||||||
coeffs_[3] = Uval.x();
|
coeffs_[3] = Uval.x();
|
||||||
coeffs_[4] = Uval.y();
|
coeffs_[4] = Uval.y();
|
||||||
coeffs_[5] = Uval.z();
|
coeffs_[5] = Uval.z();
|
||||||
|
|
||||||
|
// Update average velocity
|
||||||
|
Uaverage_.value() = (Xval - Xold)/delta;
|
||||||
|
|
||||||
|
|
||||||
// Rotation
|
// Rotation
|
||||||
|
|
||||||
// Update omega
|
// Get angular velocity
|
||||||
const vector omegaOld = omega_.value();
|
const vector omegaOld = omega_.value();
|
||||||
|
|
||||||
vector& omegaVal = omega_.value();
|
vector& omegaVal = omega_.value();
|
||||||
|
|
||||||
omegaVal.x() = coeffs_[6];
|
omegaVal.x() = coeffs_[6];
|
||||||
omegaVal.y() = coeffs_[7];
|
omegaVal.y() = coeffs_[7];
|
||||||
omegaVal.z() = coeffs_[8];
|
omegaVal.z() = coeffs_[8];
|
||||||
|
@ -575,11 +592,29 @@ void Foam::geometricSixDOF::update(const scalar delta)
|
||||||
// Update rotational tensor
|
// Update rotational tensor
|
||||||
rotation_ = (rotation_ & rotIncrement_);
|
rotation_ = (rotation_ & rotIncrement_);
|
||||||
|
|
||||||
|
// Stabilise rotational constraints if necessary
|
||||||
|
forAll(rotationalConstraints(), rcI)
|
||||||
|
{
|
||||||
|
// Note: get end time for this ODE step from mesh, assuming that the top
|
||||||
|
// level solves this ode from [t - deltaT, t], yielding solution at
|
||||||
|
// t. Done this way to preserve the interface of ODE class.
|
||||||
|
// VV, 10/Mar/2017.
|
||||||
|
const scalar t = dict().time().value();
|
||||||
|
|
||||||
|
rotationalConstraints()[rcI].stabilise(t, omegaVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update (possibly constrained) omega
|
||||||
|
coeffs_[6] = omegaVal.x();
|
||||||
|
coeffs_[7] = omegaVal.y();
|
||||||
|
coeffs_[8] = omegaVal.z();
|
||||||
|
|
||||||
// Reset increment vector in coefficients for the next step
|
// Reset increment vector in coefficients for the next step
|
||||||
coeffs_[9] = 0;
|
coeffs_[9] = 0;
|
||||||
coeffs_[10] = 0;
|
coeffs_[10] = 0;
|
||||||
coeffs_[11] = 0;
|
coeffs_[11] = 0;
|
||||||
|
|
||||||
|
// Update average omega
|
||||||
omegaAverage_.value() = 0.5*(omegaVal + omegaOld);
|
omegaAverage_.value() = 0.5*(omegaVal + omegaOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,40 +447,54 @@ void Foam::quaternionSixDOF::update(const scalar delta)
|
||||||
{
|
{
|
||||||
// Translation
|
// Translation
|
||||||
|
|
||||||
// Update displacement
|
// Get displacement
|
||||||
vector Xold = Xrel_.value();
|
const vector Xold = Xrel_.value();
|
||||||
|
|
||||||
vector& Xval = Xrel_.value();
|
vector& Xval = Xrel_.value();
|
||||||
|
|
||||||
Xval.x() = coeffs_[0];
|
Xval.x() = coeffs_[0];
|
||||||
Xval.y() = coeffs_[1];
|
Xval.y() = coeffs_[1];
|
||||||
Xval.z() = coeffs_[2];
|
Xval.z() = coeffs_[2];
|
||||||
|
|
||||||
// Update velocity
|
// Get velocity
|
||||||
Uaverage_.value() = (Xval - Xold)/delta;
|
|
||||||
|
|
||||||
vector& Uval = U_.value();
|
vector& Uval = U_.value();
|
||||||
|
|
||||||
Uval.x() = coeffs_[3];
|
Uval.x() = coeffs_[3];
|
||||||
Uval.y() = coeffs_[4];
|
Uval.y() = coeffs_[4];
|
||||||
Uval.z() = coeffs_[5];
|
Uval.z() = coeffs_[5];
|
||||||
|
|
||||||
|
// Stabilise translational constraints if necessary
|
||||||
|
forAll(translationalConstraints(), tcI)
|
||||||
|
{
|
||||||
|
// Note: get end time for this ODE step from mesh, assuming that the top
|
||||||
|
// level solves this ode from [t - deltaT, t], yielding solution at
|
||||||
|
// t. Done this way to preserve the interface of ODE class.
|
||||||
|
// VV, 10/Mar/2017.
|
||||||
|
const scalar t = dict().time().value();
|
||||||
|
|
||||||
|
translationalConstraints()[tcI].stabilise(t, Xval, Uval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update (possibly constrained) displacement
|
||||||
|
coeffs_[0] = Xval.x();
|
||||||
|
coeffs_[1] = Xval.y();
|
||||||
|
coeffs_[2] = Xval.z();
|
||||||
|
|
||||||
|
// Update (possibly constrained) velocity
|
||||||
coeffs_[3] = Uval.x();
|
coeffs_[3] = Uval.x();
|
||||||
coeffs_[4] = Uval.y();
|
coeffs_[4] = Uval.y();
|
||||||
coeffs_[5] = Uval.z();
|
coeffs_[5] = Uval.z();
|
||||||
|
|
||||||
|
// Update average velocity
|
||||||
|
Uaverage_.value() = (Xval - Xold)/delta;
|
||||||
|
|
||||||
|
|
||||||
// Rotation
|
// Rotation
|
||||||
|
|
||||||
// Update omega
|
// Get angular velocity
|
||||||
vector& omegaVal = omega_.value();
|
vector& omegaVal = omega_.value();
|
||||||
|
|
||||||
omegaVal.x() = coeffs_[6];
|
omegaVal.x() = coeffs_[6];
|
||||||
omegaVal.y() = coeffs_[7];
|
omegaVal.y() = coeffs_[7];
|
||||||
omegaVal.z() = coeffs_[8];
|
omegaVal.z() = coeffs_[8];
|
||||||
|
|
||||||
coeffs_[6] = omegaVal.x();
|
|
||||||
coeffs_[7] = omegaVal.y();
|
|
||||||
coeffs_[8] = omegaVal.z();
|
|
||||||
|
|
||||||
rotation_.updateRotation
|
rotation_.updateRotation
|
||||||
(
|
(
|
||||||
|
@ -493,6 +507,24 @@ void Foam::quaternionSixDOF::update(const scalar delta)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Stabilise rotational constraints if necessary
|
||||||
|
forAll(rotationalConstraints(), rcI)
|
||||||
|
{
|
||||||
|
// Note: get end time for this ODE step from mesh, assuming that the top
|
||||||
|
// level solves this ode from [t - deltaT, t], yielding solution at
|
||||||
|
// t. Done this way to preserve the interface of ODE class.
|
||||||
|
// VV, 10/Mar/2017.
|
||||||
|
const scalar t = dict().time().value();
|
||||||
|
|
||||||
|
rotationalConstraints()[rcI].stabilise(t, omegaVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update (possibly constrained) omega
|
||||||
|
coeffs_[6] = omegaVal.x();
|
||||||
|
coeffs_[7] = omegaVal.y();
|
||||||
|
coeffs_[8] = omegaVal.z();
|
||||||
|
|
||||||
|
// Update average omega
|
||||||
omegaAverage_.value() = rotation_.omegaAverage(delta);
|
omegaAverage_.value() = rotation_.omegaAverage(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,16 @@ public:
|
||||||
const vector&
|
const vector&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Stabilise the constraint
|
||||||
|
virtual void stabilise
|
||||||
|
(
|
||||||
|
const scalar,
|
||||||
|
vector&
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Does nothing: no need to stabilise this constraint
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// I-O Functions
|
// I-O Functions
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,12 @@ Description
|
||||||
2. sourceContribution() - corresponding to a(t), to be inserted into right
|
2. sourceContribution() - corresponding to a(t), to be inserted into right
|
||||||
hand side vector.
|
hand side vector.
|
||||||
|
|
||||||
Note: constraints are usually used alongside appropriate initial
|
Notes:
|
||||||
conditions (rotational rate in a given direction).
|
1. Constraints are usually used alongside appropriate initial
|
||||||
|
conditions (rotational rate in a given direction),
|
||||||
|
2. According to DAE theory, a stabilisation on orientation/angular velocity
|
||||||
|
is necessary based on "differentiation index" used to obtain the final
|
||||||
|
form of the constraint.
|
||||||
|
|
||||||
Author
|
Author
|
||||||
Viktor Pandza, FSB Zagreb. All rights reserved.
|
Viktor Pandza, FSB Zagreb. All rights reserved.
|
||||||
|
@ -167,6 +171,14 @@ public:
|
||||||
const vector& omega
|
const vector& omega
|
||||||
) const = 0;
|
) const = 0;
|
||||||
|
|
||||||
|
//- Stabilise the constraint (necessary for constraints with
|
||||||
|
// differentiation index higher than zero)
|
||||||
|
virtual void stabilise
|
||||||
|
(
|
||||||
|
const scalar t,
|
||||||
|
vector& omega
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
|
||||||
// I-O Functions and Operators
|
// I-O Functions and Operators
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,16 @@ public:
|
||||||
const vector&
|
const vector&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Stabilise the constraint
|
||||||
|
virtual void stabilise
|
||||||
|
(
|
||||||
|
const scalar,
|
||||||
|
vector&,
|
||||||
|
vector&
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Does nothing: no need to stabilise this constraint
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// I-O Functions
|
// I-O Functions
|
||||||
|
|
|
@ -117,6 +117,32 @@ Foam::scalar Foam::periodicOscillation::sourceContribution
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::periodicOscillation::stabilise
|
||||||
|
(
|
||||||
|
const scalar t,
|
||||||
|
vector& x,
|
||||||
|
vector& u
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Set the displacement according to periodic oscillation
|
||||||
|
|
||||||
|
// First subtract calculated displacement...
|
||||||
|
x -= (x & dir_)*dir_;
|
||||||
|
|
||||||
|
// ... then add the correct displacement
|
||||||
|
x += dir_*sin(omega_*t + phi_);
|
||||||
|
|
||||||
|
|
||||||
|
// Set the velocity according to periodic oscillation
|
||||||
|
|
||||||
|
// First subract calculated velocity...
|
||||||
|
u -= (u & dir_)*dir_;
|
||||||
|
|
||||||
|
// ... then add the correct velocity
|
||||||
|
u += dir_*cos(omega_*t + phi_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::periodicOscillation::write(Ostream& os) const
|
void Foam::periodicOscillation::write(Ostream& os) const
|
||||||
{
|
{
|
||||||
os.writeKeyword("type") << tab << type()
|
os.writeKeyword("type") << tab << type()
|
||||||
|
|
|
@ -32,6 +32,10 @@ Description
|
||||||
where a is the amplitude of oscillation, omega radial frequency and phi is
|
where a is the amplitude of oscillation, omega radial frequency and phi is
|
||||||
the phase shift.
|
the phase shift.
|
||||||
|
|
||||||
|
Note: since this constraint is basically algebraic (dependent on
|
||||||
|
displacement), the differentiation index is two so the stabilisation on
|
||||||
|
displacement and velocity is necessary.
|
||||||
|
|
||||||
Author
|
Author
|
||||||
Viktor Pandza, FSB Zagreb. All rights reserved.
|
Viktor Pandza, FSB Zagreb. All rights reserved.
|
||||||
Vuko Vukcevic, FSB Zagreb. All rights reserved.
|
Vuko Vukcevic, FSB Zagreb. All rights reserved.
|
||||||
|
@ -124,6 +128,13 @@ public:
|
||||||
const vector&
|
const vector&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Stabilise the constraint
|
||||||
|
virtual void stabilise
|
||||||
|
(
|
||||||
|
const scalar t,
|
||||||
|
vector& x,
|
||||||
|
vector& u
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
// I-O Functions
|
// I-O Functions
|
||||||
|
|
|
@ -41,8 +41,12 @@ Description
|
||||||
2. sourceContribution() - corresponding to a(t), to be inserted into right
|
2. sourceContribution() - corresponding to a(t), to be inserted into right
|
||||||
hand side vector.
|
hand side vector.
|
||||||
|
|
||||||
Note: constraints are usually used alongside appropriate initial
|
Notes:
|
||||||
conditions (velocity in a given direction).
|
1. Constraints are usually used alongside appropriate initial
|
||||||
|
conditions (velocity in a given direction),
|
||||||
|
2. According to DAE theory, a stabilisation on displacement/velocity is
|
||||||
|
necessary based on "differentiation index" used to obtain the final form
|
||||||
|
of the constraint.
|
||||||
|
|
||||||
Author
|
Author
|
||||||
Viktor Pandza, FSB Zagreb. All rights reserved.
|
Viktor Pandza, FSB Zagreb. All rights reserved.
|
||||||
|
@ -169,6 +173,15 @@ public:
|
||||||
const vector& u
|
const vector& u
|
||||||
) const = 0;
|
) const = 0;
|
||||||
|
|
||||||
|
//- Stabilise the constraint (necessary for constraints with
|
||||||
|
// differentiation index higher than zero)
|
||||||
|
virtual void stabilise
|
||||||
|
(
|
||||||
|
const scalar t,
|
||||||
|
vector& x,
|
||||||
|
vector& u
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
|
||||||
// I-O Functions and Operators
|
// I-O Functions and Operators
|
||||||
|
|
||||||
|
|
Reference in a new issue