Add native spherical harmonic surface coordinates to coupled equilibrium
This commit is contained in:
@@ -172,6 +172,51 @@ export namespace mean_field::deformation {
|
||||
return m_surface.parameterCount();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool hasNodalRadialParameters() const noexcept {
|
||||
if constexpr (requires { PreparedSurface::hasNodalRadialParameters; }) {
|
||||
return PreparedSurface::hasNodalRadialParameters;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool supportsSurfaceParameterMetric() const noexcept {
|
||||
if constexpr (requires { PreparedSurface::hasCanonicalNodalVectorTrace; }) {
|
||||
return PreparedSurface::hasCanonicalNodalVectorTrace;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reference surface metrics need the prescription tangent before any
|
||||
// physical state has been prepared. Exposing that tangent avoids
|
||||
// making normalization depend on the arbitrary interior mesh lift.
|
||||
void applySurfaceJacobian(
|
||||
const mfem::Vector ¶meters,
|
||||
const mfem::Vector ¶meterDirection,
|
||||
mfem::Vector &surfaceDirection
|
||||
) const {
|
||||
requireCurrentDiscretization();
|
||||
requireParameterSize(parameters);
|
||||
requireParameterSize(parameterDirection);
|
||||
if (surfaceDirection.Size() != surfaceDisplacementSize()) {
|
||||
throw std::invalid_argument("The surface tangent output has an incompatible trace size.");
|
||||
}
|
||||
m_surface.applyJacobian(parameters, parameterDirection, surfaceDirection);
|
||||
}
|
||||
|
||||
void applySurfaceJacobianTranspose(
|
||||
const mfem::Vector ¶meters,
|
||||
const mfem::Vector &surfaceDual,
|
||||
mfem::Vector ¶meterDual
|
||||
) const {
|
||||
requireCurrentDiscretization();
|
||||
requireParameterSize(parameters);
|
||||
requireParameterSize(parameterDual);
|
||||
if (surfaceDual.Size() != surfaceDisplacementSize()) {
|
||||
throw std::invalid_argument("The surface transpose input has an incompatible trace size.");
|
||||
}
|
||||
m_surface.applyJacobianTranspose(parameters, surfaceDual, parameterDual);
|
||||
}
|
||||
|
||||
[[nodiscard]] int surfaceDisplacementSize() const noexcept {
|
||||
return m_surface.surfaceDisplacementSize();
|
||||
}
|
||||
@@ -580,6 +625,30 @@ export namespace mean_field::deformation {
|
||||
return m_implementation->parameterCount();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool hasNodalRadialParameters() const noexcept {
|
||||
return m_implementation->hasNodalRadialParameters();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool supportsSurfaceParameterMetric() const noexcept {
|
||||
return m_implementation->supportsSurfaceParameterMetric();
|
||||
}
|
||||
|
||||
void applySurfaceJacobian(
|
||||
const mfem::Vector ¶meters,
|
||||
const mfem::Vector ¶meterDirection,
|
||||
mfem::Vector &surfaceDirection
|
||||
) const {
|
||||
m_implementation->applySurfaceJacobian(parameters, parameterDirection, surfaceDirection);
|
||||
}
|
||||
|
||||
void applySurfaceJacobianTranspose(
|
||||
const mfem::Vector ¶meters,
|
||||
const mfem::Vector &surfaceDual,
|
||||
mfem::Vector ¶meterDual
|
||||
) const {
|
||||
m_implementation->applySurfaceJacobianTranspose(parameters, surfaceDual, parameterDual);
|
||||
}
|
||||
|
||||
[[nodiscard]] int surfaceDisplacementSize() const noexcept {
|
||||
return m_implementation->surfaceDisplacementSize();
|
||||
}
|
||||
@@ -654,10 +723,22 @@ export namespace mean_field::deformation {
|
||||
private:
|
||||
class Interface {
|
||||
public:
|
||||
virtual ~Interface() = default;
|
||||
virtual ~Interface() = default;
|
||||
|
||||
[[nodiscard]] virtual DomainDeformationDescriptor descriptor() const noexcept = 0;
|
||||
[[nodiscard]] virtual int parameterCount() const noexcept = 0;
|
||||
[[nodiscard]] virtual DomainDeformationDescriptor descriptor() const noexcept = 0;
|
||||
[[nodiscard]] virtual int parameterCount() const noexcept = 0;
|
||||
[[nodiscard]] virtual bool hasNodalRadialParameters() const noexcept = 0;
|
||||
[[nodiscard]] virtual bool supportsSurfaceParameterMetric() const noexcept = 0;
|
||||
virtual void applySurfaceJacobian(
|
||||
const mfem::Vector &,
|
||||
const mfem::Vector &,
|
||||
mfem::Vector &
|
||||
) const = 0;
|
||||
virtual void applySurfaceJacobianTranspose(
|
||||
const mfem::Vector &,
|
||||
const mfem::Vector &,
|
||||
mfem::Vector &
|
||||
) const = 0;
|
||||
[[nodiscard]] virtual int surfaceDisplacementSize() const noexcept = 0;
|
||||
[[nodiscard]] virtual int volumeDisplacementSize() const noexcept = 0;
|
||||
[[nodiscard]] virtual bool matchesCurrentDiscretization() const noexcept = 0;
|
||||
@@ -705,6 +786,46 @@ export namespace mean_field::deformation {
|
||||
[[nodiscard]] int parameterCount() const noexcept override {
|
||||
return m_preparedDeformation.parameterCount();
|
||||
}
|
||||
[[nodiscard]] bool hasNodalRadialParameters() const noexcept override {
|
||||
if constexpr (requires { m_preparedDeformation.hasNodalRadialParameters(); }) {
|
||||
return m_preparedDeformation.hasNodalRadialParameters();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
[[nodiscard]] bool supportsSurfaceParameterMetric() const noexcept override {
|
||||
if constexpr (requires(const PreparedDeformation &prepared, const mfem::Vector &x, mfem::Vector &y) {
|
||||
{ prepared.supportsSurfaceParameterMetric() } noexcept -> std::same_as<bool>;
|
||||
{ prepared.applySurfaceJacobian(x, x, y) } -> std::same_as<void>;
|
||||
{ prepared.applySurfaceJacobianTranspose(x, x, y) } -> std::same_as<void>;
|
||||
}) {
|
||||
return m_preparedDeformation.supportsSurfaceParameterMetric();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void applySurfaceJacobian(
|
||||
const mfem::Vector ¶meters,
|
||||
const mfem::Vector &direction,
|
||||
mfem::Vector &trace
|
||||
) const override {
|
||||
if constexpr (requires { m_preparedDeformation.applySurfaceJacobian(parameters, direction, trace); }) {
|
||||
m_preparedDeformation.applySurfaceJacobian(parameters, direction, trace);
|
||||
} else {
|
||||
throw std::logic_error("This domain deformation does not expose its surface tangent.");
|
||||
}
|
||||
}
|
||||
void applySurfaceJacobianTranspose(
|
||||
const mfem::Vector ¶meters,
|
||||
const mfem::Vector &trace,
|
||||
mfem::Vector &dual
|
||||
) const override {
|
||||
if constexpr (requires {
|
||||
m_preparedDeformation.applySurfaceJacobianTranspose(parameters, trace, dual);
|
||||
}) {
|
||||
m_preparedDeformation.applySurfaceJacobianTranspose(parameters, trace, dual);
|
||||
} else {
|
||||
throw std::logic_error("This domain deformation does not expose its surface transpose.");
|
||||
}
|
||||
}
|
||||
[[nodiscard]] int surfaceDisplacementSize() const noexcept override {
|
||||
return m_preparedDeformation.surfaceDisplacementSize();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user