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:
@@ -1,135 +1,190 @@
|
||||
module;
|
||||
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
module mean_field;
|
||||
|
||||
import :operators.context.barotropic_closure_linearization;
|
||||
|
||||
namespace {
|
||||
void validate_finite_vector(
|
||||
const mfem::Vector &vector,
|
||||
const char *message
|
||||
) {
|
||||
for (int i = 0; i < vector.Size(); ++i) {
|
||||
MFEM_VERIFY(std::isfinite(vector(i)), message);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Stamp>
|
||||
void validate_dependency_transition(
|
||||
const Stamp &prepared,
|
||||
const Stamp &requested,
|
||||
const char *message
|
||||
) {
|
||||
MFEM_VERIFY(requested.CanFollow(prepared), message);
|
||||
MFEM_VERIFY(
|
||||
prepared.identity == requested.identity || prepared.revision != requested.revision,
|
||||
"A new barotropic-closure dependency identity must also carry a visibly different revision."
|
||||
);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace mean_field::operators::context::barotropic {
|
||||
BarotropicClosureLinearizationContext::
|
||||
BarotropicClosureLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope
|
||||
)
|
||||
BarotropicClosureLinearizationContext::BarotropicClosureLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const field::FieldDofMap &densityMap,
|
||||
const field::FieldDofMap &enthalpyMap,
|
||||
const field::FieldDofMap &displacementMap
|
||||
)
|
||||
: m_f(f),
|
||||
m_operator(
|
||||
f,
|
||||
domainMapper,
|
||||
barotrope
|
||||
) {
|
||||
m_domainMapper(domainMapper),
|
||||
m_densitySize(densityMap.reduced_size()),
|
||||
m_enthalpySize(enthalpyMap.reduced_size()),
|
||||
m_displacementSize(displacementMap.reduced_size()) {
|
||||
MFEM_VERIFY(m_f.mesh != nullptr, "BarotropicClosureLinearizationContext requires a mesh.");
|
||||
MFEM_VERIFY(m_f.densityFes != nullptr, "BarotropicClosureLinearizationContext requires the density FE space.");
|
||||
MFEM_VERIFY(
|
||||
m_f.densityFes != nullptr,
|
||||
"The closure linearization context requires the "
|
||||
"density finite-element space."
|
||||
m_f.enthalpyFes != nullptr, "BarotropicClosureLinearizationContext requires the enthalpy FE space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.enthalpyFes != nullptr,
|
||||
"The closure linearization context requires the "
|
||||
"enthalpy finite-element space."
|
||||
m_f.displacementFes != nullptr, "BarotropicClosureLinearizationContext requires the displacement FE space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.displacementFes != nullptr,
|
||||
"The closure linearization context requires the "
|
||||
"displacement finite-element space."
|
||||
m_domainMapper.GetDimension() == m_f.mesh->Dimension(),
|
||||
"The barotropic-closure context domain-mapper dimension does not match the mesh dimension."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
densityMap.full_size() == m_f.densityFes->GetTrueVSize(),
|
||||
"The density FieldDofMap does not match the density FE space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
enthalpyMap.full_size() == m_f.enthalpyFes->GetTrueVSize(),
|
||||
"The enthalpy FieldDofMap does not match the enthalpy FE space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
displacementMap.full_size() == m_f.displacementFes->GetTrueVSize(),
|
||||
"The displacement FieldDofMap does not match the displacement FE space."
|
||||
);
|
||||
}
|
||||
|
||||
void BarotropicClosureLinearizationContext::Prepare(
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
const BarotropicClosureRevisions &revisions
|
||||
BarotropicClosurePreparationReport BarotropicClosureLinearizationContext::Prepare(
|
||||
const BarotropicClosureStateView &state,
|
||||
const BarotropicClosureDependencies &dependencies
|
||||
) {
|
||||
MFEM_VERIFY(state.density.Size() == m_densitySize, "The supported closure density vector has the wrong size.");
|
||||
MFEM_VERIFY(
|
||||
baseDensityTrue.Size() == m_f.densityFes->GetTrueVSize(),
|
||||
"The closure base-density vector has the wrong size."
|
||||
state.enthalpy.Size() == m_enthalpySize, "The supported closure enthalpy vector has the wrong size."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
state.displacement.Size() == m_displacementSize,
|
||||
"The supported closure displacement vector has the wrong size."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
baseEnthalpyTrue.Size() == m_f.enthalpyFes->GetTrueVSize(),
|
||||
"The closure base-enthalpy vector has the wrong size."
|
||||
);
|
||||
validate_finite_vector(state.density, "The closure density state contains a non-finite value.");
|
||||
validate_finite_vector(state.enthalpy, "The closure enthalpy state contains a non-finite value.");
|
||||
validate_finite_vector(state.displacement, "The closure displacement state contains a non-finite value.");
|
||||
|
||||
MFEM_VERIFY(
|
||||
displacementTrue.Size() == m_f.displacementFes->GetTrueVSize(),
|
||||
"The closure displacement vector has the wrong size."
|
||||
);
|
||||
|
||||
if (m_isPrepared && revisions == m_revisions) {
|
||||
return;
|
||||
if (m_isPrepared) {
|
||||
validate_dependency_transition(
|
||||
m_dependencies.discretization, dependencies.discretization,
|
||||
"BarotropicClosureLinearizationContext received an older discretization revision for the same identity."
|
||||
);
|
||||
validate_dependency_transition(
|
||||
m_dependencies.density, dependencies.density,
|
||||
"BarotropicClosureLinearizationContext received an older density revision for the same identity."
|
||||
);
|
||||
validate_dependency_transition(
|
||||
m_dependencies.enthalpy, dependencies.enthalpy,
|
||||
"BarotropicClosureLinearizationContext received an older enthalpy revision for the same identity."
|
||||
);
|
||||
validate_dependency_transition(
|
||||
m_dependencies.displacement, dependencies.displacement,
|
||||
"BarotropicClosureLinearizationContext received an older displacement revision for the same identity."
|
||||
);
|
||||
}
|
||||
|
||||
m_operator.Prepare(baseDensityTrue, baseEnthalpyTrue, displacementTrue);
|
||||
const bool staticChanged = !m_isPrepared || dependencies.discretization != m_dependencies.discretization;
|
||||
const bool densityChanged = !m_isPrepared || dependencies.density != m_dependencies.density;
|
||||
const bool enthalpyChanged = !m_isPrepared || dependencies.enthalpy != m_dependencies.enthalpy;
|
||||
const bool displacementChanged = !m_isPrepared || dependencies.displacement != m_dependencies.displacement;
|
||||
|
||||
m_baseDensityTrue = baseDensityTrue;
|
||||
m_baseEnthalpyTrue = baseEnthalpyTrue;
|
||||
m_displacementTrue = displacementTrue;
|
||||
const bool geometryPreparationRequired = staticChanged || displacementChanged;
|
||||
const bool baseStatePreparationRequired =
|
||||
staticChanged || geometryPreparationRequired || densityChanged || enthalpyChanged;
|
||||
|
||||
m_revisions = revisions;
|
||||
m_isPrepared = true;
|
||||
++m_preparationCount;
|
||||
BarotropicClosurePreparationReport report;
|
||||
report.preparedStaticDependencies = staticChanged;
|
||||
report.preparedGeometryState = geometryPreparationRequired;
|
||||
report.preparedBaseState = baseStatePreparationRequired;
|
||||
|
||||
if (staticChanged || densityChanged) {
|
||||
m_baseDensity = state.density;
|
||||
report.updatedDensity = true;
|
||||
}
|
||||
if (staticChanged || enthalpyChanged) {
|
||||
m_baseEnthalpy = state.enthalpy;
|
||||
report.updatedEnthalpy = true;
|
||||
}
|
||||
if (geometryPreparationRequired) {
|
||||
m_displacement = state.displacement;
|
||||
report.updatedDisplacement = true;
|
||||
}
|
||||
|
||||
if (report.preparedStaticDependencies) {
|
||||
++m_statistics.staticPreparations;
|
||||
}
|
||||
if (report.preparedGeometryState) {
|
||||
++m_statistics.geometryPreparations;
|
||||
}
|
||||
if (report.preparedBaseState) {
|
||||
++m_statistics.baseStatePreparations;
|
||||
}
|
||||
|
||||
m_dependencies = dependencies;
|
||||
m_isPrepared = true;
|
||||
return report;
|
||||
}
|
||||
|
||||
bool BarotropicClosureLinearizationContext::IsPrepared() const noexcept {
|
||||
return m_isPrepared;
|
||||
}
|
||||
|
||||
bool BarotropicClosureLinearizationContext::MatchesRevisions(
|
||||
const BarotropicClosureRevisions &revisions
|
||||
bool BarotropicClosureLinearizationContext::MatchesDependencies(
|
||||
const BarotropicClosureDependencies &dependencies
|
||||
) const noexcept {
|
||||
return m_isPrepared && revisions == m_revisions;
|
||||
return m_isPrepared && dependencies == m_dependencies;
|
||||
}
|
||||
|
||||
std::uint64_t BarotropicClosureLinearizationContext::
|
||||
GetPreparationCount() const noexcept {
|
||||
return m_preparationCount;
|
||||
}
|
||||
|
||||
const BarotropicClosureRevisions &
|
||||
BarotropicClosureLinearizationContext::GetRevisions() const {
|
||||
const BarotropicClosureDependencies &BarotropicClosureLinearizationContext::GetDependencies() const {
|
||||
VerifyPrepared();
|
||||
return m_revisions;
|
||||
return m_dependencies;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
BarotropicClosureLinearizationContext::GetBaseDensityTrue() const {
|
||||
const BarotropicClosurePreparationStatistics &
|
||||
BarotropicClosureLinearizationContext::GetPreparationStatistics() const noexcept {
|
||||
return m_statistics;
|
||||
}
|
||||
|
||||
const mfem::Vector &BarotropicClosureLinearizationContext::GetBaseDensity() const {
|
||||
VerifyPrepared();
|
||||
return m_baseDensityTrue;
|
||||
return m_baseDensity;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
BarotropicClosureLinearizationContext::GetBaseEnthalpyTrue() const {
|
||||
const mfem::Vector &BarotropicClosureLinearizationContext::GetBaseEnthalpy() const {
|
||||
VerifyPrepared();
|
||||
return m_baseEnthalpyTrue;
|
||||
return m_baseEnthalpy;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
BarotropicClosureLinearizationContext::GetDisplacementTrue() const {
|
||||
const mfem::Vector &BarotropicClosureLinearizationContext::GetDisplacement() const {
|
||||
VerifyPrepared();
|
||||
return m_displacementTrue;
|
||||
}
|
||||
|
||||
const PreparedBarotropicClosureOperator &
|
||||
BarotropicClosureLinearizationContext::GetOperator() const noexcept {
|
||||
return m_operator;
|
||||
}
|
||||
|
||||
void BarotropicClosureLinearizationContext::BuildResidual(
|
||||
mfem::Vector &residual
|
||||
) const {
|
||||
VerifyPrepared();
|
||||
m_operator.BuildResidual(residual);
|
||||
return m_displacement;
|
||||
}
|
||||
|
||||
void BarotropicClosureLinearizationContext::VerifyPrepared() const {
|
||||
MFEM_VERIFY(
|
||||
m_isPrepared, "The barotropic-closure linearization context "
|
||||
"has not been prepared."
|
||||
);
|
||||
MFEM_VERIFY(m_isPrepared, "BarotropicClosureLinearizationContext has not been prepared.");
|
||||
}
|
||||
} // namespace mean_field::operators::context::barotropic
|
||||
} // namespace mean_field::operators::context::barotropic
|
||||
|
||||
@@ -12,9 +12,8 @@ namespace {
|
||||
const mfem::Vector &displacement_true
|
||||
) {
|
||||
MFEM_VERIFY(
|
||||
f.displacementFes != nullptr,
|
||||
"GravityFieldGeometryContext requires the "
|
||||
"displacement finite-element space."
|
||||
f.displacementFes != nullptr, "GravityFieldGeometryContext requires the "
|
||||
"displacement finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
displacement_true.Size() == f.displacementFes->GetTrueVSize(),
|
||||
@@ -25,18 +24,16 @@ namespace {
|
||||
|
||||
for (int i = 0; i < displacement_true.Size(); ++i) {
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(displacement_true(i)),
|
||||
"GravityFieldGeometryContext received a non-finite "
|
||||
"displacement "
|
||||
"value."
|
||||
std::isfinite(displacement_true(i)), "GravityFieldGeometryContext received a non-finite "
|
||||
"displacement "
|
||||
"value."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void validate_linearization_state(
|
||||
const mean_field::fem::FEM &f,
|
||||
const mean_field::operators::context::gravity_field::
|
||||
GravityFieldStateView &state
|
||||
const mean_field::operators::context::gravity_field::GravityFieldStateView &state
|
||||
) {
|
||||
MFEM_VERIFY(
|
||||
f.densityFes != nullptr, "GravityFieldLinearizationContext "
|
||||
@@ -44,19 +41,16 @@ namespace {
|
||||
"space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.gravityPotentialFes != nullptr,
|
||||
"GravityFieldLinearizationContext requires the gravity-potential "
|
||||
"finite-element space."
|
||||
f.gravityPotentialFes != nullptr, "GravityFieldLinearizationContext requires the gravity-potential "
|
||||
"finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.gravityFluxFes != nullptr,
|
||||
"GravityFieldLinearizationContext requires the "
|
||||
"gravity-gradient finite-element space."
|
||||
f.gravityFluxFes != nullptr, "GravityFieldLinearizationContext requires the "
|
||||
"gravity-gradient finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.displacementFes != nullptr,
|
||||
"GravityFieldLinearizationContext requires "
|
||||
"the displacement finite-element space."
|
||||
f.displacementFes != nullptr, "GravityFieldLinearizationContext requires "
|
||||
"the displacement finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
@@ -78,8 +72,7 @@ namespace {
|
||||
"with the wrong size."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
state.gravity_potential.Size() ==
|
||||
f.gravityPotentialFes->GetTrueVSize(),
|
||||
state.gravity_potential.Size() == f.gravityPotentialFes->GetTrueVSize(),
|
||||
"GravityFieldLinearizationContext received a gravity-potential "
|
||||
"vector "
|
||||
"with the wrong size."
|
||||
@@ -87,35 +80,31 @@ namespace {
|
||||
|
||||
for (int i = 0; i < state.density.Size(); ++i) {
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(state.density(i)),
|
||||
"GravityFieldLinearizationContext received a non-finite "
|
||||
"density "
|
||||
"value."
|
||||
std::isfinite(state.density(i)), "GravityFieldLinearizationContext received a non-finite "
|
||||
"density "
|
||||
"value."
|
||||
);
|
||||
}
|
||||
|
||||
for (int i = 0; i < state.displacement.Size(); ++i) {
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(state.displacement(i)),
|
||||
"GravityFieldLinearizationContext received a non-finite "
|
||||
"displacement "
|
||||
"value."
|
||||
std::isfinite(state.displacement(i)), "GravityFieldLinearizationContext received a non-finite "
|
||||
"displacement "
|
||||
"value."
|
||||
);
|
||||
}
|
||||
|
||||
for (int i = 0; i < state.gravity_gradient.Size(); ++i) {
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(state.gravity_gradient(i)),
|
||||
"GravityFieldLinearizationContext received a non-finite "
|
||||
"gravity-gradient value."
|
||||
std::isfinite(state.gravity_gradient(i)), "GravityFieldLinearizationContext received a non-finite "
|
||||
"gravity-gradient value."
|
||||
);
|
||||
}
|
||||
|
||||
for (int i = 0; i < state.gravity_potential.Size(); ++i) {
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(state.gravity_potential(i)),
|
||||
"GravityFieldLinearizationContext received a non-finite "
|
||||
"gravity-potential value."
|
||||
std::isfinite(state.gravity_potential(i)), "GravityFieldLinearizationContext received a non-finite "
|
||||
"gravity-potential value."
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -128,42 +117,33 @@ namespace mean_field::operators::context::gravity_field {
|
||||
)
|
||||
: m_fem(f),
|
||||
m_domain_mapper(domain_mapper) {
|
||||
MFEM_VERIFY(f.mesh != nullptr, "GravityFieldGeometryContext requires a mesh.");
|
||||
MFEM_VERIFY(
|
||||
f.mesh != nullptr, "GravityFieldGeometryContext requires a mesh."
|
||||
f.gravityFluxFes != nullptr, "GravityFieldGeometryContext requires the "
|
||||
"gravity-gradient finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.gravityFluxFes != nullptr,
|
||||
"GravityFieldGeometryContext requires the "
|
||||
"gravity-gradient finite-element space."
|
||||
f.densityFes != nullptr, "GravityFieldGeometryContext requires the density finite-element "
|
||||
"space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.densityFes != nullptr,
|
||||
"GravityFieldGeometryContext requires the density finite-element "
|
||||
"space."
|
||||
f.gravityPotentialFes != nullptr, "GravityFieldGeometryContext requires the gravity-potential "
|
||||
"finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.gravityPotentialFes != nullptr,
|
||||
"GravityFieldGeometryContext requires the gravity-potential "
|
||||
"finite-element space."
|
||||
f.displacementFes != nullptr, "GravityFieldGeometryContext requires the "
|
||||
"displacement finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.displacementFes != nullptr,
|
||||
"GravityFieldGeometryContext requires the "
|
||||
"displacement finite-element space."
|
||||
f.compactificationFes != nullptr, "GravityFieldGeometryContext requires the compactification "
|
||||
"finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.compactificationFes != nullptr,
|
||||
"GravityFieldGeometryContext requires the compactification "
|
||||
"finite-element space."
|
||||
f.compactificationCoordinate != nullptr, "GravityFieldGeometryContext requires the compactification "
|
||||
"coordinate."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.compactificationCoordinate != nullptr,
|
||||
"GravityFieldGeometryContext requires the compactification "
|
||||
"coordinate."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.quadratureFactory != nullptr,
|
||||
"GravityFieldGeometryContext requires the quadrature-rule factory."
|
||||
f.quadratureFactory != nullptr, "GravityFieldGeometryContext requires the quadrature-rule factory."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
domain_mapper.GetDimension() == f.mesh->Dimension(),
|
||||
@@ -192,11 +172,8 @@ namespace mean_field::operators::context::gravity_field {
|
||||
);
|
||||
}
|
||||
|
||||
const bool discretization_changed =
|
||||
!m_is_prepared ||
|
||||
discretization_revision != m_discretization_revision;
|
||||
const bool displacement_changed =
|
||||
!m_is_prepared || displacement_revision != m_displacement_revision;
|
||||
const bool discretization_changed = !m_is_prepared || discretization_revision != m_discretization_revision;
|
||||
const bool displacement_changed = !m_is_prepared || displacement_revision != m_displacement_revision;
|
||||
|
||||
GravityFieldGeometryPreparation preparation;
|
||||
|
||||
@@ -205,14 +182,8 @@ namespace mean_field::operators::context::gravity_field {
|
||||
}
|
||||
|
||||
if (discretization_changed) {
|
||||
auto mass_operator =
|
||||
std::make_unique<PreparedMappedHDivMassOperator>(
|
||||
m_fem, m_domain_mapper
|
||||
);
|
||||
auto source_operator =
|
||||
std::make_unique<PreparedMappedGravitySourceOperator>(
|
||||
m_fem, m_domain_mapper
|
||||
);
|
||||
auto mass_operator = std::make_unique<PreparedMappedHDivMassOperator>(m_fem, m_domain_mapper);
|
||||
auto source_operator = std::make_unique<PreparedMappedGravitySourceOperator>(m_fem, m_domain_mapper);
|
||||
|
||||
mass_operator->Prepare(displacement_true);
|
||||
source_operator->Prepare(displacement_true);
|
||||
@@ -229,9 +200,8 @@ namespace mean_field::operators::context::gravity_field {
|
||||
"no prepared H(div) mass operator."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
m_source_operator != nullptr,
|
||||
"GravityFieldGeometryContext has no prepared gravity source "
|
||||
"operator."
|
||||
m_source_operator != nullptr, "GravityFieldGeometryContext has no prepared gravity source "
|
||||
"operator."
|
||||
);
|
||||
|
||||
m_mass_operator->Prepare(displacement_true);
|
||||
@@ -251,26 +221,19 @@ namespace mean_field::operators::context::gravity_field {
|
||||
return preparation;
|
||||
}
|
||||
|
||||
const PreparedMappedHDivMassOperator &
|
||||
GravityFieldGeometryContext::GetMassOperator() const {
|
||||
const PreparedMappedHDivMassOperator &GravityFieldGeometryContext::GetMassOperator() const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared,
|
||||
"GravityFieldGeometryContext must be prepared before "
|
||||
"accessing its mass operator."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
m_mass_operator != nullptr,
|
||||
"GravityFieldGeometryContext has no prepared H(div) mass operator."
|
||||
m_is_prepared, "GravityFieldGeometryContext must be prepared before "
|
||||
"accessing its mass operator."
|
||||
);
|
||||
MFEM_VERIFY(m_mass_operator != nullptr, "GravityFieldGeometryContext has no prepared H(div) mass operator.");
|
||||
return *m_mass_operator;
|
||||
}
|
||||
|
||||
const PreparedMappedGravitySourceOperator &
|
||||
GravityFieldGeometryContext::GetSourceOperator() const {
|
||||
const PreparedMappedGravitySourceOperator &GravityFieldGeometryContext::GetSourceOperator() const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared,
|
||||
"GravityFieldGeometryContext must be prepared before "
|
||||
"accessing its source operator."
|
||||
m_is_prepared, "GravityFieldGeometryContext must be prepared before "
|
||||
"accessing its source operator."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
m_source_operator != nullptr, "GravityFieldGeometryContext has no "
|
||||
@@ -281,20 +244,17 @@ namespace mean_field::operators::context::gravity_field {
|
||||
|
||||
const mfem::Vector &GravityFieldGeometryContext::GetDisplacement() const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared,
|
||||
"GravityFieldGeometryContext must be prepared before "
|
||||
"accessing its displacement."
|
||||
m_is_prepared, "GravityFieldGeometryContext must be prepared before "
|
||||
"accessing its displacement."
|
||||
);
|
||||
return m_displacement_true;
|
||||
}
|
||||
|
||||
DiscretizationRevision
|
||||
GravityFieldGeometryContext::GetDiscretizationRevision() const noexcept {
|
||||
DiscretizationRevision GravityFieldGeometryContext::GetDiscretizationRevision() const noexcept {
|
||||
return m_discretization_revision;
|
||||
}
|
||||
|
||||
DisplacementRevision
|
||||
GravityFieldGeometryContext::GetDisplacementRevision() const noexcept {
|
||||
DisplacementRevision GravityFieldGeometryContext::GetDisplacementRevision() const noexcept {
|
||||
return m_displacement_revision;
|
||||
}
|
||||
|
||||
@@ -317,19 +277,16 @@ namespace mean_field::operators::context::gravity_field {
|
||||
"space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.gravityPotentialFes != nullptr,
|
||||
"GravityFieldLinearizationContext requires the gravity-potential "
|
||||
"finite-element space."
|
||||
f.gravityPotentialFes != nullptr, "GravityFieldLinearizationContext requires the gravity-potential "
|
||||
"finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.gravityFluxFes != nullptr,
|
||||
"GravityFieldLinearizationContext requires the "
|
||||
"gravity-gradient finite-element space."
|
||||
f.gravityFluxFes != nullptr, "GravityFieldLinearizationContext requires the "
|
||||
"gravity-gradient finite-element space."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
f.displacementFes != nullptr,
|
||||
"GravityFieldLinearizationContext requires "
|
||||
"the displacement finite-element space."
|
||||
f.displacementFes != nullptr, "GravityFieldLinearizationContext requires "
|
||||
"the displacement finite-element space."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -353,9 +310,8 @@ namespace mean_field::operators::context::gravity_field {
|
||||
"revision."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
revisions.density >= m_revisions.density,
|
||||
"GravityFieldLinearizationContext received an older density "
|
||||
"revision."
|
||||
revisions.density >= m_revisions.density, "GravityFieldLinearizationContext received an older density "
|
||||
"revision."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
revisions.gravity_gradient >= m_revisions.gravity_gradient,
|
||||
@@ -370,20 +326,16 @@ namespace mean_field::operators::context::gravity_field {
|
||||
);
|
||||
}
|
||||
|
||||
const bool discretization_changed =
|
||||
!m_is_prepared ||
|
||||
revisions.discretization != m_revisions.discretization;
|
||||
const bool density_changed = !m_is_prepared || discretization_changed ||
|
||||
revisions.density != m_revisions.density;
|
||||
const bool discretization_changed = !m_is_prepared || revisions.discretization != m_revisions.discretization;
|
||||
const bool density_changed =
|
||||
!m_is_prepared || discretization_changed || revisions.density != m_revisions.density;
|
||||
const bool gravity_gradient_changed =
|
||||
!m_is_prepared || discretization_changed ||
|
||||
revisions.gravity_gradient != m_revisions.gravity_gradient;
|
||||
!m_is_prepared || discretization_changed || revisions.gravity_gradient != m_revisions.gravity_gradient;
|
||||
|
||||
GravityFieldPreparationReport report;
|
||||
|
||||
report.geometry = m_geometry_context.Prepare(
|
||||
state.displacement, revisions.discretization, revisions.displacement
|
||||
);
|
||||
report.geometry =
|
||||
m_geometry_context.Prepare(state.displacement, revisions.discretization, revisions.displacement);
|
||||
|
||||
if (density_changed) {
|
||||
m_density_true = state.density;
|
||||
@@ -401,8 +353,7 @@ namespace mean_field::operators::context::gravity_field {
|
||||
return report;
|
||||
}
|
||||
|
||||
const GravityFieldGeometryContext &
|
||||
GravityFieldLinearizationContext::GetGeometryContext() const {
|
||||
const GravityFieldGeometryContext &GravityFieldLinearizationContext::GetGeometryContext() const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared, "GravityFieldLinearizationContext must be prepared "
|
||||
"before accessing its geometry context."
|
||||
@@ -418,8 +369,7 @@ namespace mean_field::operators::context::gravity_field {
|
||||
return m_density_true;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
GravityFieldLinearizationContext::GetGravityGradient() const {
|
||||
const mfem::Vector &GravityFieldLinearizationContext::GetGravityGradient() const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared, "GravityFieldLinearizationContext must be prepared "
|
||||
"before accessing its gravity gradient."
|
||||
@@ -427,8 +377,7 @@ namespace mean_field::operators::context::gravity_field {
|
||||
return m_gravity_gradient_true;
|
||||
}
|
||||
|
||||
const GravityFieldRevisions &
|
||||
GravityFieldLinearizationContext::GetRevisions() const {
|
||||
const GravityFieldRevisions &GravityFieldLinearizationContext::GetRevisions() const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared, "GravityFieldLinearizationContext must be prepared "
|
||||
"before accessing its revisions."
|
||||
|
||||
@@ -20,44 +20,37 @@ namespace {
|
||||
|
||||
void validate_state(
|
||||
const mean_field::fem::FEM &f,
|
||||
const mean_field::operators::context::hydrostatic::
|
||||
HydrostaticEquilibriumStateView &state
|
||||
const mean_field::operators::context::hydrostatic::HydrostaticEquilibriumStateView &state
|
||||
) {
|
||||
MFEM_VERIFY(
|
||||
f.enthalpyFes != nullptr,
|
||||
"HydrostaticEquilibriumContext requires the "
|
||||
"enthalpy finite-element space."
|
||||
f.enthalpyFes != nullptr, "HydrostaticEquilibriumContext requires the "
|
||||
"enthalpy finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
f.gravityPotentialFes != nullptr,
|
||||
"HydrostaticEquilibriumContext requires the "
|
||||
"gravity-potential finite-element space."
|
||||
f.gravityPotentialFes != nullptr, "HydrostaticEquilibriumContext requires the "
|
||||
"gravity-potential finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
f.displacementFes != nullptr,
|
||||
"HydrostaticEquilibriumContext requires the "
|
||||
"displacement finite-element space."
|
||||
f.displacementFes != nullptr, "HydrostaticEquilibriumContext requires the "
|
||||
"displacement finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
state.enthalpy.Size() == f.enthalpyFes->GetTrueVSize(),
|
||||
"HydrostaticEquilibriumContext received an "
|
||||
"enthalpy vector with the wrong size."
|
||||
state.enthalpy.Size() == f.enthalpyFes->GetTrueVSize(), "HydrostaticEquilibriumContext received an "
|
||||
"enthalpy vector with the wrong size."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
state.gravityPotential.Size() ==
|
||||
f.gravityPotentialFes->GetTrueVSize(),
|
||||
state.gravityPotential.Size() == f.gravityPotentialFes->GetTrueVSize(),
|
||||
"HydrostaticEquilibriumContext received a "
|
||||
"gravity-potential vector with the wrong size."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
state.displacement.Size() == f.displacementFes->GetTrueVSize(),
|
||||
"HydrostaticEquilibriumContext received a "
|
||||
"displacement vector with the wrong size."
|
||||
state.displacement.Size() == f.displacementFes->GetTrueVSize(), "HydrostaticEquilibriumContext received a "
|
||||
"displacement vector with the wrong size."
|
||||
);
|
||||
|
||||
validate_finite_vector(
|
||||
@@ -76,9 +69,8 @@ namespace {
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
std::isfinite(state.bernoulliConstant),
|
||||
"HydrostaticEquilibriumContext received a "
|
||||
"non-finite Bernoulli constant."
|
||||
std::isfinite(state.bernoulliConstant), "HydrostaticEquilibriumContext received a "
|
||||
"non-finite Bernoulli constant."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,34 +91,27 @@ namespace mean_field::operators::context::hydrostatic {
|
||||
)
|
||||
: m_f(f),
|
||||
m_domainMapper(domainMapper) {
|
||||
MFEM_VERIFY(m_f.mesh != nullptr, "HydrostaticEquilibriumContext requires a mesh.");
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.mesh != nullptr,
|
||||
"HydrostaticEquilibriumContext requires a mesh."
|
||||
m_f.enthalpyFes != nullptr, "HydrostaticEquilibriumContext requires the "
|
||||
"enthalpy finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.enthalpyFes != nullptr,
|
||||
"HydrostaticEquilibriumContext requires the "
|
||||
"enthalpy finite-element space."
|
||||
m_f.gravityPotentialFes != nullptr, "HydrostaticEquilibriumContext requires the "
|
||||
"gravity-potential finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.gravityPotentialFes != nullptr,
|
||||
"HydrostaticEquilibriumContext requires the "
|
||||
"gravity-potential finite-element space."
|
||||
m_f.displacementFes != nullptr, "HydrostaticEquilibriumContext requires the "
|
||||
"displacement finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.displacementFes != nullptr,
|
||||
"HydrostaticEquilibriumContext requires the "
|
||||
"displacement finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_domainMapper.GetDimension() == m_f.mesh->Dimension(),
|
||||
"The hydrostatic context's stateless "
|
||||
"domain-mapper dimension does not match the mesh "
|
||||
"dimension."
|
||||
m_domainMapper.GetDimension() == m_f.mesh->Dimension(), "The hydrostatic context's stateless "
|
||||
"domain-mapper dimension does not match the mesh "
|
||||
"dimension."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -168,44 +153,32 @@ namespace mean_field::operators::context::hydrostatic {
|
||||
);
|
||||
|
||||
validate_dependency_transition(
|
||||
m_dependencies.bernoulliConstant,
|
||||
dependencies.bernoulliConstant,
|
||||
m_dependencies.bernoulliConstant, dependencies.bernoulliConstant,
|
||||
"HydrostaticEquilibriumContext received an older "
|
||||
"Bernoulli-constant revision for the same identity."
|
||||
);
|
||||
}
|
||||
|
||||
const bool staticChanged =
|
||||
!m_isPrepared ||
|
||||
dependencies.discretization != m_dependencies.discretization;
|
||||
const bool staticChanged = !m_isPrepared || dependencies.discretization != m_dependencies.discretization;
|
||||
|
||||
const bool enthalpyChanged =
|
||||
!m_isPrepared || dependencies.enthalpy != m_dependencies.enthalpy;
|
||||
const bool enthalpyChanged = !m_isPrepared || dependencies.enthalpy != m_dependencies.enthalpy;
|
||||
|
||||
const bool gravityPotentialChanged =
|
||||
!m_isPrepared ||
|
||||
dependencies.gravityPotential != m_dependencies.gravityPotential;
|
||||
!m_isPrepared || dependencies.gravityPotential != m_dependencies.gravityPotential;
|
||||
|
||||
const bool displacementChanged =
|
||||
!m_isPrepared ||
|
||||
dependencies.displacement != m_dependencies.displacement;
|
||||
const bool displacementChanged = !m_isPrepared || dependencies.displacement != m_dependencies.displacement;
|
||||
|
||||
const bool rotationChanged =
|
||||
!m_isPrepared || dependencies.rotation != m_dependencies.rotation;
|
||||
const bool rotationChanged = !m_isPrepared || dependencies.rotation != m_dependencies.rotation;
|
||||
|
||||
const bool bernoulliConstantChanged =
|
||||
!m_isPrepared ||
|
||||
dependencies.bernoulliConstant != m_dependencies.bernoulliConstant;
|
||||
!m_isPrepared || dependencies.bernoulliConstant != m_dependencies.bernoulliConstant;
|
||||
|
||||
const bool geometryPreparationRequired =
|
||||
staticChanged || displacementChanged;
|
||||
const bool geometryPreparationRequired = staticChanged || displacementChanged;
|
||||
|
||||
const bool rotationPreparationRequired =
|
||||
geometryPreparationRequired || rotationChanged;
|
||||
const bool rotationPreparationRequired = geometryPreparationRequired || rotationChanged;
|
||||
|
||||
const bool baseStatePreparationRequired =
|
||||
rotationPreparationRequired || enthalpyChanged ||
|
||||
gravityPotentialChanged || bernoulliConstantChanged;
|
||||
rotationPreparationRequired || enthalpyChanged || gravityPotentialChanged || bernoulliConstantChanged;
|
||||
|
||||
HydrostaticPreparationReport report;
|
||||
|
||||
@@ -267,31 +240,26 @@ namespace mean_field::operators::context::hydrostatic {
|
||||
return m_isPrepared && dependencies == m_dependencies;
|
||||
}
|
||||
|
||||
const HydrostaticEquilibriumDependencies &
|
||||
HydrostaticEquilibriumContext::GetDependencies() const {
|
||||
const HydrostaticEquilibriumDependencies &HydrostaticEquilibriumContext::GetDependencies() const {
|
||||
VerifyPrepared();
|
||||
return m_dependencies;
|
||||
}
|
||||
|
||||
const HydrostaticPreparationStatistics &
|
||||
HydrostaticEquilibriumContext::GetPreparationStatistics() const noexcept {
|
||||
const HydrostaticPreparationStatistics &HydrostaticEquilibriumContext::GetPreparationStatistics() const noexcept {
|
||||
return m_statistics;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
HydrostaticEquilibriumContext::GetBaseEnthalpyTrue() const {
|
||||
const mfem::Vector &HydrostaticEquilibriumContext::GetBaseEnthalpyTrue() const {
|
||||
VerifyPrepared();
|
||||
return m_baseEnthalpyTrue;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
HydrostaticEquilibriumContext::GetBaseGravityPotentialTrue() const {
|
||||
const mfem::Vector &HydrostaticEquilibriumContext::GetBaseGravityPotentialTrue() const {
|
||||
VerifyPrepared();
|
||||
return m_baseGravityPotentialTrue;
|
||||
}
|
||||
|
||||
const mfem::Vector &
|
||||
HydrostaticEquilibriumContext::GetDisplacementTrue() const {
|
||||
const mfem::Vector &HydrostaticEquilibriumContext::GetDisplacementTrue() const {
|
||||
VerifyPrepared();
|
||||
return m_displacementTrue;
|
||||
}
|
||||
@@ -302,8 +270,6 @@ namespace mean_field::operators::context::hydrostatic {
|
||||
}
|
||||
|
||||
void HydrostaticEquilibriumContext::VerifyPrepared() const {
|
||||
MFEM_VERIFY(
|
||||
m_isPrepared, "HydrostaticEquilibriumContext has not been prepared."
|
||||
);
|
||||
MFEM_VERIFY(m_isPrepared, "HydrostaticEquilibriumContext has not been prepared.");
|
||||
}
|
||||
} // namespace mean_field::operators::context::hydrostatic
|
||||
|
||||
219
libmeanfield/impl/operators/contexts/pressure_force_context.cpp
Normal file
219
libmeanfield/impl/operators/contexts/pressure_force_context.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
module;
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
module mean_field;
|
||||
|
||||
import :operators.context.pressure_force;
|
||||
|
||||
namespace {
|
||||
void validate_finite_vector(
|
||||
const mfem::Vector &vector,
|
||||
const char *message
|
||||
) {
|
||||
for (int index = 0; index < vector.Size(); ++index) {
|
||||
MFEM_VERIFY(std::isfinite(vector(index)), message);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Dependency>
|
||||
void validate_dependency_transition(
|
||||
const Dependency &prepared,
|
||||
const Dependency &requested,
|
||||
const char *message
|
||||
) {
|
||||
MFEM_VERIFY(requested.CanFollow(prepared), message);
|
||||
|
||||
MFEM_VERIFY(
|
||||
prepared.identity == requested.identity || prepared.revision != requested.revision,
|
||||
"A new pressure-force dependency identity must also carry "
|
||||
"a visibly different revision."
|
||||
);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace mean_field::operators::context::pressure_force {
|
||||
PressureForceLinearizationContext::PressureForceLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const field::FieldDofMap &enthalpyMap,
|
||||
const field::FieldDofMap &displacementMap
|
||||
)
|
||||
: m_enthalpySize(enthalpyMap.reduced_size()),
|
||||
m_displacementSize(displacementMap.reduced_size()) {
|
||||
MFEM_VERIFY(f.mesh != nullptr, "PressureForceLinearizationContext requires a mesh.");
|
||||
|
||||
MFEM_VERIFY(
|
||||
f.enthalpyFes != nullptr, "PressureForceLinearizationContext requires the enthalpy "
|
||||
"finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
f.displacementFes != nullptr, "PressureForceLinearizationContext requires the displacement "
|
||||
"finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
domainMapper.GetDimension() == f.mesh->Dimension(), "The pressure-force context's stateless domain-mapper "
|
||||
"dimension does not match the mesh dimension."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
enthalpyMap.full_size() == f.enthalpyFes->GetTrueVSize(),
|
||||
"The pressure-force enthalpy FieldDofMap does not match the "
|
||||
"enthalpy finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
displacementMap.full_size() == f.displacementFes->GetTrueVSize(),
|
||||
"The pressure-force displacement FieldDofMap does not match "
|
||||
"the displacement finite-element space."
|
||||
);
|
||||
}
|
||||
|
||||
PressureForcePreparationReport PressureForceLinearizationContext::Prepare(
|
||||
const PressureForceStateView &state,
|
||||
const PressureForceDependencies &dependencies
|
||||
) {
|
||||
MFEM_VERIFY(
|
||||
state.enthalpy.Size() == m_enthalpySize, "PressureForceLinearizationContext received a supported "
|
||||
"enthalpy vector with the wrong size."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
state.displacement.Size() == m_displacementSize, "PressureForceLinearizationContext received a supported "
|
||||
"displacement vector with the wrong size."
|
||||
);
|
||||
|
||||
validate_finite_vector(
|
||||
state.enthalpy, "PressureForceLinearizationContext received a non-finite "
|
||||
"enthalpy value."
|
||||
);
|
||||
|
||||
validate_finite_vector(
|
||||
state.displacement, "PressureForceLinearizationContext received a non-finite "
|
||||
"displacement value."
|
||||
);
|
||||
|
||||
if (m_isPrepared) {
|
||||
validate_dependency_transition(
|
||||
m_dependencies.discretization, dependencies.discretization,
|
||||
"PressureForceLinearizationContext received an older "
|
||||
"discretization revision for the same identity."
|
||||
);
|
||||
|
||||
validate_dependency_transition(
|
||||
m_dependencies.enthalpy, dependencies.enthalpy,
|
||||
"PressureForceLinearizationContext received an older "
|
||||
"enthalpy revision for the same identity."
|
||||
);
|
||||
|
||||
validate_dependency_transition(
|
||||
m_dependencies.displacement, dependencies.displacement,
|
||||
"PressureForceLinearizationContext received an older "
|
||||
"displacement revision for the same identity."
|
||||
);
|
||||
}
|
||||
|
||||
const bool discretizationChanged =
|
||||
!m_isPrepared || dependencies.discretization != m_dependencies.discretization;
|
||||
|
||||
const bool enthalpyChanged = !m_isPrepared || dependencies.enthalpy != m_dependencies.enthalpy;
|
||||
|
||||
const bool displacementChanged = !m_isPrepared || dependencies.displacement != m_dependencies.displacement;
|
||||
|
||||
/*
|
||||
* Static data depend only on discretization.
|
||||
*
|
||||
* Geometry data depend on discretization and displacement.
|
||||
*
|
||||
* Material data depend on both geometry and enthalpy because
|
||||
* pressure and its enthalpy derivative are evaluated on the frozen
|
||||
* mapped state.
|
||||
*/
|
||||
const bool geometryPreparationRequired = discretizationChanged || displacementChanged;
|
||||
|
||||
const bool materialPreparationRequired = geometryPreparationRequired || enthalpyChanged;
|
||||
|
||||
PressureForcePreparationReport report;
|
||||
|
||||
report.preparedStaticDependencies = discretizationChanged;
|
||||
|
||||
report.preparedGeometryState = geometryPreparationRequired;
|
||||
|
||||
report.preparedMaterialState = materialPreparationRequired;
|
||||
|
||||
/*
|
||||
* A discretization change invalidates every frozen field because
|
||||
* their coordinate interpretation may have changed.
|
||||
*/
|
||||
if (discretizationChanged || enthalpyChanged) {
|
||||
m_baseEnthalpy = state.enthalpy;
|
||||
|
||||
report.updatedEnthalpy = true;
|
||||
}
|
||||
|
||||
if (geometryPreparationRequired) {
|
||||
m_displacement = state.displacement;
|
||||
|
||||
report.updatedDisplacement = true;
|
||||
}
|
||||
|
||||
if (report.preparedStaticDependencies) {
|
||||
++m_statistics.staticPreparations;
|
||||
}
|
||||
|
||||
if (report.preparedGeometryState) {
|
||||
++m_statistics.geometryPreparations;
|
||||
}
|
||||
|
||||
if (report.preparedMaterialState) {
|
||||
++m_statistics.materialPreparations;
|
||||
}
|
||||
|
||||
m_dependencies = dependencies;
|
||||
|
||||
m_isPrepared = true;
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
const PressureForcePreparationStatistics &
|
||||
PressureForceLinearizationContext::GetPreparationStatistics() const noexcept {
|
||||
return m_statistics;
|
||||
}
|
||||
|
||||
bool PressureForceLinearizationContext::IsPrepared() const noexcept {
|
||||
return m_isPrepared;
|
||||
}
|
||||
|
||||
bool PressureForceLinearizationContext::MatchesDependencies(
|
||||
const PressureForceDependencies &dependencies
|
||||
) const noexcept {
|
||||
return m_isPrepared && dependencies == m_dependencies;
|
||||
}
|
||||
|
||||
const PressureForceDependencies &PressureForceLinearizationContext::GetDependencies() const {
|
||||
VerifyPrepared();
|
||||
|
||||
return m_dependencies;
|
||||
}
|
||||
|
||||
const mfem::Vector &PressureForceLinearizationContext::GetBaseEnthalpy() const {
|
||||
VerifyPrepared();
|
||||
|
||||
return m_baseEnthalpy;
|
||||
}
|
||||
|
||||
const mfem::Vector &PressureForceLinearizationContext::GetDisplacement() const {
|
||||
VerifyPrepared();
|
||||
|
||||
return m_displacement;
|
||||
}
|
||||
|
||||
void PressureForceLinearizationContext::VerifyPrepared() const {
|
||||
MFEM_VERIFY(m_isPrepared, "PressureForceLinearizationContext has not been prepared.");
|
||||
}
|
||||
} // namespace mean_field::operators::context::pressure_force
|
||||
@@ -0,0 +1,203 @@
|
||||
module;
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
module mean_field;
|
||||
|
||||
import :operators.context.rotational_displacement_force;
|
||||
|
||||
namespace {
|
||||
void validate_finite_vector(
|
||||
const mfem::Vector &vector,
|
||||
const char *message
|
||||
) {
|
||||
for (int index = 0; index < vector.Size(); ++index) {
|
||||
MFEM_VERIFY(std::isfinite(vector(index)), message);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Dependency>
|
||||
void validate_dependency_transition(
|
||||
const Dependency &prepared,
|
||||
const Dependency &requested,
|
||||
const char *message
|
||||
) {
|
||||
MFEM_VERIFY(requested.CanFollow(prepared), message);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace mean_field::operators::context::rotational_displacement_force {
|
||||
RotationalDisplacementForceLinearizationContext::RotationalDisplacementForceLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper
|
||||
)
|
||||
: m_f(f) {
|
||||
MFEM_VERIFY(
|
||||
m_f.mesh != nullptr, "RotationalDisplacementForceLinearizationContext requires a "
|
||||
"mesh."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.densityFes != nullptr, "RotationalDisplacementForceLinearizationContext requires the "
|
||||
"density finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
m_f.displacementFes != nullptr, "RotationalDisplacementForceLinearizationContext requires the "
|
||||
"displacement finite-element space."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
domainMapper.GetDimension() == m_f.mesh->Dimension(),
|
||||
"The rotational-displacement-force context's stateless "
|
||||
"domain-mapper dimension does not match the mesh dimension."
|
||||
);
|
||||
}
|
||||
|
||||
RotationalDisplacementForcePreparationReport RotationalDisplacementForceLinearizationContext::Prepare(
|
||||
const RotationalDisplacementForceStateView &state,
|
||||
const RotationalDisplacementForceDependencies &dependencies
|
||||
) {
|
||||
MFEM_VERIFY(
|
||||
state.density.Size() == m_f.densityFes->GetTrueVSize(),
|
||||
"RotationalDisplacementForceLinearizationContext received a "
|
||||
"density vector with the wrong size."
|
||||
);
|
||||
|
||||
MFEM_VERIFY(
|
||||
state.displacement.Size() == m_f.displacementFes->GetTrueVSize(),
|
||||
"RotationalDisplacementForceLinearizationContext received a "
|
||||
"displacement vector with the wrong size."
|
||||
);
|
||||
|
||||
validate_finite_vector(
|
||||
state.density, "RotationalDisplacementForceLinearizationContext received a "
|
||||
"non-finite density value."
|
||||
);
|
||||
|
||||
validate_finite_vector(
|
||||
state.displacement, "RotationalDisplacementForceLinearizationContext received a "
|
||||
"non-finite displacement value."
|
||||
);
|
||||
|
||||
if (m_isPrepared) {
|
||||
validate_dependency_transition(
|
||||
m_dependencies.discretization, dependencies.discretization,
|
||||
"RotationalDisplacementForceLinearizationContext received "
|
||||
"an older discretization revision for the same identity."
|
||||
);
|
||||
|
||||
validate_dependency_transition(
|
||||
m_dependencies.density, dependencies.density,
|
||||
"RotationalDisplacementForceLinearizationContext received "
|
||||
"an older density revision for the same identity."
|
||||
);
|
||||
|
||||
validate_dependency_transition(
|
||||
m_dependencies.displacement, dependencies.displacement,
|
||||
"RotationalDisplacementForceLinearizationContext received "
|
||||
"an older displacement revision for the same identity."
|
||||
);
|
||||
|
||||
validate_dependency_transition(
|
||||
m_dependencies.rotation, dependencies.rotation,
|
||||
"RotationalDisplacementForceLinearizationContext received "
|
||||
"an older rotation revision for the same identity."
|
||||
);
|
||||
}
|
||||
|
||||
const bool discretizationChanged =
|
||||
!m_isPrepared || dependencies.discretization != m_dependencies.discretization;
|
||||
|
||||
const bool densityChanged = !m_isPrepared || dependencies.density != m_dependencies.density;
|
||||
|
||||
const bool displacementChanged = !m_isPrepared || dependencies.displacement != m_dependencies.displacement;
|
||||
|
||||
const bool rotationChanged = !m_isPrepared || dependencies.rotation != m_dependencies.rotation;
|
||||
|
||||
const bool geometryPreparationRequired = discretizationChanged || displacementChanged;
|
||||
|
||||
const bool rotationPreparationRequired = discretizationChanged || rotationChanged;
|
||||
|
||||
const bool baseStatePreparationRequired =
|
||||
geometryPreparationRequired || rotationPreparationRequired || densityChanged;
|
||||
|
||||
RotationalDisplacementForcePreparationReport report;
|
||||
|
||||
report.preparedStaticDependencies = discretizationChanged;
|
||||
report.preparedGeometryState = geometryPreparationRequired;
|
||||
report.preparedRotationDependencies = rotationPreparationRequired;
|
||||
report.preparedBaseState = baseStatePreparationRequired;
|
||||
|
||||
if (discretizationChanged || densityChanged) {
|
||||
m_baseDensityTrue = state.density;
|
||||
report.updatedDensity = true;
|
||||
}
|
||||
|
||||
if (geometryPreparationRequired) {
|
||||
m_displacementTrue = state.displacement;
|
||||
report.updatedDisplacement = true;
|
||||
}
|
||||
|
||||
if (report.preparedStaticDependencies) {
|
||||
++m_statistics.staticPreparations;
|
||||
}
|
||||
|
||||
if (report.preparedGeometryState) {
|
||||
++m_statistics.geometryPreparations;
|
||||
}
|
||||
|
||||
if (report.preparedRotationDependencies) {
|
||||
++m_statistics.rotationPreparations;
|
||||
}
|
||||
|
||||
if (report.preparedBaseState) {
|
||||
++m_statistics.baseStatePreparations;
|
||||
}
|
||||
|
||||
m_dependencies = dependencies;
|
||||
m_isPrepared = true;
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
bool RotationalDisplacementForceLinearizationContext::IsPrepared() const noexcept {
|
||||
return m_isPrepared;
|
||||
}
|
||||
|
||||
bool RotationalDisplacementForceLinearizationContext::MatchesDependencies(
|
||||
const RotationalDisplacementForceDependencies &dependencies
|
||||
) const noexcept {
|
||||
return m_isPrepared && dependencies == m_dependencies;
|
||||
}
|
||||
|
||||
const RotationalDisplacementForceDependencies &
|
||||
RotationalDisplacementForceLinearizationContext::GetDependencies() const {
|
||||
VerifyPrepared();
|
||||
return m_dependencies;
|
||||
}
|
||||
|
||||
const RotationalDisplacementForcePreparationStatistics &
|
||||
RotationalDisplacementForceLinearizationContext::GetPreparationStatistics() const noexcept {
|
||||
return m_statistics;
|
||||
}
|
||||
|
||||
const mfem::Vector &RotationalDisplacementForceLinearizationContext::GetBaseDensityTrue() const {
|
||||
VerifyPrepared();
|
||||
return m_baseDensityTrue;
|
||||
}
|
||||
|
||||
const mfem::Vector &RotationalDisplacementForceLinearizationContext::GetDisplacementTrue() const {
|
||||
VerifyPrepared();
|
||||
return m_displacementTrue;
|
||||
}
|
||||
|
||||
void RotationalDisplacementForceLinearizationContext::VerifyPrepared() const {
|
||||
MFEM_VERIFY(
|
||||
m_isPrepared, "RotationalDisplacementForceLinearizationContext has not been "
|
||||
"prepared."
|
||||
);
|
||||
}
|
||||
} // namespace mean_field::operators::context::rotational_displacement_force
|
||||
Reference in New Issue
Block a user