feat(field-support): added field support system, mid migration
currently the barotope and the pressure force operator are migrated to the new support system
This commit is contained in:
@@ -27,8 +27,7 @@ export namespace mean_field::physics {
|
||||
);
|
||||
}
|
||||
|
||||
if (!std::isfinite(polytropic_constant) ||
|
||||
polytropic_constant <= 0.0) {
|
||||
if (!std::isfinite(polytropic_constant) || polytropic_constant <= 0.0) {
|
||||
throw std::invalid_argument(
|
||||
std::format(
|
||||
"The polytropic constant must be finite and positive. "
|
||||
@@ -57,8 +56,7 @@ export namespace mean_field::physics {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return m_polytropic_constant *
|
||||
std::pow(density, 1.0 + 1.0 / m_polytropic_index);
|
||||
return m_polytropic_constant * std::pow(density, 1.0 + 1.0 / m_polytropic_index);
|
||||
}
|
||||
|
||||
[[nodiscard]] double enthalpy_from_density(const double density) const {
|
||||
@@ -67,12 +65,10 @@ export namespace mean_field::physics {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return m_enthalpy_scale *
|
||||
std::pow(density, 1.0 / m_polytropic_index);
|
||||
return m_enthalpy_scale * std::pow(density, 1.0 / m_polytropic_index);
|
||||
}
|
||||
|
||||
[[nodiscard]] double
|
||||
density_from_enthalpy(const double enthalpy) const {
|
||||
[[nodiscard]] double density_from_enthalpy(const double enthalpy) const {
|
||||
validate_finite(enthalpy, "enthalpy");
|
||||
|
||||
if (enthalpy <= 0.0) {
|
||||
@@ -82,20 +78,17 @@ export namespace mean_field::physics {
|
||||
return std::pow(enthalpy / m_enthalpy_scale, m_polytropic_index);
|
||||
}
|
||||
|
||||
[[nodiscard]] double
|
||||
pressure_from_enthalpy(const double enthalpy) const {
|
||||
[[nodiscard]] double pressure_from_enthalpy(const double enthalpy) const {
|
||||
validate_finite(enthalpy, "enthalpy");
|
||||
|
||||
if (enthalpy <= 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return density_from_enthalpy(enthalpy) * enthalpy /
|
||||
(m_polytropic_index + 1.0);
|
||||
return density_from_enthalpy(enthalpy) * enthalpy / (m_polytropic_index + 1.0);
|
||||
}
|
||||
|
||||
[[nodiscard]] double
|
||||
density_derivative_from_enthalpy(const double enthalpy) const {
|
||||
[[nodiscard]] double density_derivative_from_enthalpy(const double enthalpy) const {
|
||||
validate_finite(enthalpy, "enthalpy");
|
||||
if (enthalpy < 0.0) {
|
||||
return 0.0;
|
||||
@@ -106,13 +99,10 @@ export namespace mean_field::physics {
|
||||
}
|
||||
|
||||
return m_polytropic_index / m_enthalpy_scale *
|
||||
std::pow(
|
||||
enthalpy / m_enthalpy_scale, m_polytropic_index - 1.0
|
||||
);
|
||||
std::pow(enthalpy / m_enthalpy_scale, m_polytropic_index - 1.0);
|
||||
}
|
||||
|
||||
[[nodiscard]] double
|
||||
pressure_derivative_from_enthalpy(const double enthalpy) const {
|
||||
[[nodiscard]] double pressure_derivative_from_enthalpy(const double enthalpy) const {
|
||||
validate_finite(enthalpy, "enthalpy");
|
||||
|
||||
if (enthalpy <= 0.0) {
|
||||
@@ -122,8 +112,7 @@ export namespace mean_field::physics {
|
||||
return density_from_enthalpy(enthalpy);
|
||||
}
|
||||
|
||||
[[nodiscard]] double
|
||||
pressure_derivative_from_density(const double density) const {
|
||||
[[nodiscard]] double pressure_derivative_from_density(const double density) const {
|
||||
validate_nonnegativity(density, "density");
|
||||
if (density == 0.0) {
|
||||
return 0.0;
|
||||
|
||||
@@ -15,36 +15,28 @@ export namespace mean_field::physics {
|
||||
: m_angularVelocity(angularVelocity),
|
||||
m_center(center) {
|
||||
MFEM_VERIFY(
|
||||
m_angularVelocity.Size() == 3,
|
||||
"RigidRotation requires a three-dimensional "
|
||||
"angular-velocity vector."
|
||||
m_angularVelocity.Size() == 3, "RigidRotation requires a three-dimensional "
|
||||
"angular-velocity vector."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_center.Size() == 3,
|
||||
"RigidRotation requires a three-dimensional center."
|
||||
);
|
||||
MFEM_VERIFY(m_center.Size() == 3, "RigidRotation requires a three-dimensional center.");
|
||||
|
||||
for (int component = 0; component < 3; ++component) {
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(m_angularVelocity(component)),
|
||||
"RigidRotation received a non-finite "
|
||||
"angular-velocity component."
|
||||
std::isfinite(m_angularVelocity(component)), "RigidRotation received a non-finite "
|
||||
"angular-velocity component."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(m_center(component)),
|
||||
"RigidRotation received a non-finite center component."
|
||||
std::isfinite(m_center(component)), "RigidRotation received a non-finite center component."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] double
|
||||
potential(const mfem::Vector &physicalPosition) const {
|
||||
[[nodiscard]] double potential(const mfem::Vector &physicalPosition) const {
|
||||
MFEM_VERIFY(
|
||||
physicalPosition.Size() == 3,
|
||||
"RigidRotation::potential requires a "
|
||||
"three-dimensional position."
|
||||
physicalPosition.Size() == 3, "RigidRotation::potential requires a "
|
||||
"three-dimensional position."
|
||||
);
|
||||
|
||||
const double relativeX = physicalPosition(0) - m_center(0);
|
||||
@@ -53,14 +45,11 @@ export namespace mean_field::physics {
|
||||
|
||||
const double relativeZ = physicalPosition(2) - m_center(2);
|
||||
|
||||
const double crossX = m_angularVelocity(1) * relativeZ -
|
||||
m_angularVelocity(2) * relativeY;
|
||||
const double crossX = m_angularVelocity(1) * relativeZ - m_angularVelocity(2) * relativeY;
|
||||
|
||||
const double crossY = m_angularVelocity(2) * relativeX -
|
||||
m_angularVelocity(0) * relativeZ;
|
||||
const double crossY = m_angularVelocity(2) * relativeX - m_angularVelocity(0) * relativeZ;
|
||||
|
||||
const double crossZ = m_angularVelocity(0) * relativeY -
|
||||
m_angularVelocity(1) * relativeX;
|
||||
const double crossZ = m_angularVelocity(0) * relativeY - m_angularVelocity(1) * relativeX;
|
||||
|
||||
return 0.5 * (crossX * crossX + crossY * crossY + crossZ * crossZ);
|
||||
}
|
||||
@@ -70,48 +59,101 @@ export namespace mean_field::physics {
|
||||
const mfem::Vector &physicalPositionVariation
|
||||
) const {
|
||||
MFEM_VERIFY(
|
||||
physicalPosition.Size() == 3,
|
||||
"RigidRotation derivative requires a "
|
||||
"three-dimensional position."
|
||||
physicalPosition.Size() == 3, "RigidRotation derivative requires a "
|
||||
"three-dimensional position."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
physicalPositionVariation.Size() == 3,
|
||||
"RigidRotation derivative requires a "
|
||||
"three-dimensional direction."
|
||||
physicalPositionVariation.Size() == 3, "RigidRotation derivative requires a "
|
||||
"three-dimensional direction."
|
||||
);
|
||||
|
||||
double angularVelocitySquared = 0.0;
|
||||
double angularVelocityDotPosition = 0.0;
|
||||
|
||||
for (int component = 0; component < 3; ++component) {
|
||||
const double relativePosition =
|
||||
physicalPosition(component) - m_center(component);
|
||||
const double relativePosition = physicalPosition(component) - m_center(component);
|
||||
|
||||
angularVelocitySquared +=
|
||||
m_angularVelocity(component) * m_angularVelocity(component);
|
||||
angularVelocitySquared += m_angularVelocity(component) * m_angularVelocity(component);
|
||||
|
||||
angularVelocityDotPosition +=
|
||||
m_angularVelocity(component) * relativePosition;
|
||||
angularVelocityDotPosition += m_angularVelocity(component) * relativePosition;
|
||||
}
|
||||
|
||||
double derivative = 0.0;
|
||||
|
||||
for (int component = 0; component < 3; ++component) {
|
||||
const double relativePosition =
|
||||
physicalPosition(component) - m_center(component);
|
||||
const double relativePosition = physicalPosition(component) - m_center(component);
|
||||
|
||||
const double gradientComponent =
|
||||
angularVelocitySquared * relativePosition -
|
||||
angularVelocityDotPosition * m_angularVelocity(component);
|
||||
const double gradientComponent = angularVelocitySquared * relativePosition -
|
||||
angularVelocityDotPosition * m_angularVelocity(component);
|
||||
|
||||
derivative +=
|
||||
gradientComponent * physicalPositionVariation(component);
|
||||
derivative += gradientComponent * physicalPositionVariation(component);
|
||||
}
|
||||
|
||||
return derivative;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gradient of the positive rigid-rotation potential
|
||||
*
|
||||
* Psi = 0.5 |Omega x (x - x_0)|^2.
|
||||
*
|
||||
* This points away from the rotation axis. The rotational
|
||||
* displacement residual uses its negative.
|
||||
*/
|
||||
void potential_gradient(
|
||||
const mfem::Vector &physicalPosition,
|
||||
mfem::Vector &gradient
|
||||
) const {
|
||||
MFEM_VERIFY(
|
||||
physicalPosition.Size() == 3, "RigidRotation::potential_gradient requires a "
|
||||
"three-dimensional position."
|
||||
);
|
||||
|
||||
double angularVelocitySquared = 0.0;
|
||||
double angularVelocityDotPosition = 0.0;
|
||||
|
||||
for (int component = 0; component < 3; ++component) {
|
||||
const double relativePosition = physicalPosition(component) - m_center(component);
|
||||
|
||||
angularVelocitySquared += m_angularVelocity(component) * m_angularVelocity(component);
|
||||
|
||||
angularVelocityDotPosition += m_angularVelocity(component) * relativePosition;
|
||||
}
|
||||
|
||||
gradient.SetSize(3);
|
||||
|
||||
for (int component = 0; component < 3; ++component) {
|
||||
const double relativePosition = physicalPosition(component) - m_center(component);
|
||||
|
||||
gradient(component) = angularVelocitySquared * relativePosition -
|
||||
angularVelocityDotPosition * m_angularVelocity(component);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hessian action of Psi. The Hessian is constant for rigid
|
||||
* rotation, so only the physical-position direction is required.
|
||||
*/
|
||||
void potential_gradient_directional_derivative(
|
||||
const mfem::Vector &physicalPositionVariation,
|
||||
mfem::Vector &gradientVariation
|
||||
) const {
|
||||
MFEM_VERIFY(
|
||||
physicalPositionVariation.Size() == 3, "RigidRotation gradient derivative requires a "
|
||||
"three-dimensional direction."
|
||||
);
|
||||
|
||||
const double angularVelocitySquared = m_angularVelocity * m_angularVelocity;
|
||||
|
||||
const double angularVelocityDotVariation = m_angularVelocity * physicalPositionVariation;
|
||||
|
||||
gradientVariation.SetSize(3);
|
||||
gradientVariation = physicalPositionVariation;
|
||||
gradientVariation *= angularVelocitySquared;
|
||||
gradientVariation.Add(-angularVelocityDotVariation, m_angularVelocity);
|
||||
}
|
||||
|
||||
[[nodiscard]] const mfem::Vector &angular_velocity() const noexcept {
|
||||
return m_angularVelocity;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user