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
|
||||
|
||||
Reference in New Issue
Block a user