feat(libmeanfield): centrifugal + pressure
This commit is contained in:
@@ -4,93 +4,116 @@ module;
|
||||
|
||||
export module mean_field:quadrature.mfem;
|
||||
export import :quadrature.policy;
|
||||
export import :integrators.centrifugal;
|
||||
import :field.mfem;
|
||||
|
||||
export namespace mean_field::quadrature {
|
||||
struct MfemRule {
|
||||
Resolution resolution;
|
||||
const mfem::IntegrationRule* integration_rule;
|
||||
const mfem::IntegrationRule *integration_rule;
|
||||
};
|
||||
|
||||
class RuleFactory {
|
||||
public:
|
||||
explicit RuleFactory(
|
||||
Policy policy
|
||||
);
|
||||
MfemRule get(
|
||||
const Query& query,
|
||||
mfem::Geometry::Type geometry
|
||||
) const;
|
||||
MfemRule get(
|
||||
Term term,
|
||||
explicit RuleFactory(Policy policy);
|
||||
MfemRule
|
||||
get(const Query &query,
|
||||
mfem::Geometry::Type geometry) const;
|
||||
MfemRule
|
||||
get(Term term,
|
||||
QuadratureRole role,
|
||||
mfem::Geometry::Type geometry,
|
||||
int base_order,
|
||||
utils::DOMAINS domain = utils::DOMAINS::ALL,
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
MappingKind mapping = MappingKind::none) const;
|
||||
|
||||
Resolution configure_gravity_hdiv_mass(
|
||||
mfem::VectorFEMassIntegrator& integrator,
|
||||
mfem::VectorFEMassIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement& element,
|
||||
const mfem::ElementTransformation& transformation,
|
||||
const mfem::FiniteElement &element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
utils::DOMAINS domain = utils::DOMAINS::ALL,
|
||||
MappingKind mapping = MappingKind::none
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
Resolution configure_gravity_divergence(
|
||||
mfem::VectorFEDivergenceIntegrator& integrator,
|
||||
mfem::VectorFEDivergenceIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement& trial_element,
|
||||
const mfem::FiniteElement& test_element,
|
||||
const mfem::ElementTransformation& transformation,
|
||||
const mfem::FiniteElement &trial_element,
|
||||
const mfem::FiniteElement &test_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
utils::DOMAINS domain = utils::DOMAINS::ALL,
|
||||
MappingKind mapping = MappingKind::none
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
Resolution configure_gravity_boundary(
|
||||
mfem::VectorFEBoundaryFluxLFIntegrator& integrator,
|
||||
mfem::VectorFEBoundaryFluxLFIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement& boundary_element,
|
||||
const mfem::FiniteElement &boundary_element,
|
||||
utils::DOMAINS domain = utils::DOMAINS::VACUUM,
|
||||
MappingKind mapping = MappingKind::none
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
Resolution configure_gravity_source(
|
||||
mfem::DomainLFIntegrator& integrator,
|
||||
mfem::DomainLFIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement& test_element,
|
||||
const mfem::ElementTransformation& transformation,
|
||||
const mfem::FiniteElement &test_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
int coefficient_order,
|
||||
utils::DOMAINS domain = utils::DOMAINS::STELLAR,
|
||||
MappingKind mapping = MappingKind::none
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
template<typename IntegratorType>
|
||||
Resolution configure_gravity_source(
|
||||
mfem::MixedScalarMassIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement &trial_element,
|
||||
const mfem::FiniteElement &test_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
int coefficient_order,
|
||||
utils::DOMAINS domain = utils::DOMAINS::STELLAR,
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
Resolution configure_centrifugal(
|
||||
integrators::CentrifugalForceIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement &density_element,
|
||||
const mfem::FiniteElement &velocity_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
int position_order,
|
||||
utils::DOMAINS domain = utils::DOMAINS::STELLAR,
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
template <typename IntegratorType>
|
||||
Resolution configure(
|
||||
IntegratorType& integrator,
|
||||
IntegratorType &integrator,
|
||||
Term term,
|
||||
QuadratureRole role,
|
||||
mfem::Geometry::Type geometry,
|
||||
int base_order,
|
||||
utils::DOMAINS domain = utils::DOMAINS::ALL,
|
||||
MappingKind mapping = MappingKind::none
|
||||
MappingKind mapping = MappingKind::none
|
||||
) const;
|
||||
|
||||
|
||||
private:
|
||||
Policy policy;
|
||||
};
|
||||
|
||||
RuleFactory::RuleFactory(Policy policy) : policy(std::move(policy)) {}
|
||||
RuleFactory::RuleFactory(Policy policy) : policy(std::move(policy)) {
|
||||
}
|
||||
|
||||
MfemRule RuleFactory::get(
|
||||
const Query& query,
|
||||
const Query &query,
|
||||
const mfem::Geometry::Type geometry
|
||||
) const {
|
||||
const Resolution resolution = policy.resolve(query);
|
||||
const mfem::IntegrationRule& integration_rule = mfem::IntRules.Get(geometry, resolution.order);
|
||||
return {.resolution = resolution, .integration_rule = &integration_rule};
|
||||
const mfem::IntegrationRule &integration_rule =
|
||||
mfem::IntRules.Get(geometry, resolution.order);
|
||||
return {
|
||||
.resolution = resolution, .integration_rule = &integration_rule
|
||||
};
|
||||
}
|
||||
|
||||
MfemRule RuleFactory::get(
|
||||
@@ -102,87 +125,197 @@ export namespace mean_field::quadrature {
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
Query query{.term = term};
|
||||
query.domain = domain;
|
||||
query.mapping = mapping;
|
||||
query.role = role;
|
||||
query.domain = domain;
|
||||
query.mapping = mapping;
|
||||
query.role = role;
|
||||
query.base_order = base_order;
|
||||
return get(query, geometry);
|
||||
}
|
||||
|
||||
Resolution RuleFactory::configure_gravity_hdiv_mass(
|
||||
mfem::VectorFEMassIntegrator& integrator,
|
||||
mfem::VectorFEMassIntegrator &integrator,
|
||||
const QuadratureRole role,
|
||||
const mfem::FiniteElement& element,
|
||||
const mfem::ElementTransformation& transformation,
|
||||
const mfem::FiniteElement &element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
const int base_order = 2 * element.GetOrder() + transformation.OrderW();
|
||||
return configure(integrator, Term::gravity_hdiv_mass, role, element.GetGeomType(), base_order, domain, mapping);
|
||||
using GravityField = field::Field<field::Gravity>;
|
||||
MFEM_VERIFY(
|
||||
element.GetOrder() == field::Gravity::Flux::familyOrder + 1,
|
||||
"The H(div) element order does not match the registered gravity "
|
||||
"flux."
|
||||
);
|
||||
const Query query =
|
||||
GravityField::make_query<field::Gravity::Form::HDivMass>(
|
||||
role, transformation.OrderW(), {}, domain, mapping
|
||||
);
|
||||
const auto [resolution, integration_rule] =
|
||||
get(query, element.GetGeomType());
|
||||
integrator.SetIntegrationRule(*integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
Resolution RuleFactory::configure_gravity_divergence(
|
||||
mfem::VectorFEDivergenceIntegrator& integrator,
|
||||
mfem::VectorFEDivergenceIntegrator &integrator,
|
||||
const QuadratureRole role,
|
||||
const mfem::FiniteElement& trial_element,
|
||||
const mfem::FiniteElement& test_element,
|
||||
const mfem::ElementTransformation& transformation,
|
||||
const mfem::FiniteElement &trial_element,
|
||||
const mfem::FiniteElement &test_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
const Query query = {
|
||||
.term = Term::gravity_divergence,
|
||||
.role = role,
|
||||
.domain = domain,
|
||||
.mapping = mapping,
|
||||
.trial_order = trial_element.GetOrder(),
|
||||
.test_order = test_element.GetOrder(),
|
||||
.geometry_weight_order = transformation.OrderW()
|
||||
};
|
||||
using GravityField = field::Field<field::Gravity>;
|
||||
MFEM_VERIFY(
|
||||
trial_element.GetOrder() == field::Gravity::Flux::familyOrder + 1,
|
||||
"The divergence trial element does not match the registered "
|
||||
"gravity flux."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
test_element.GetOrder() == field::Gravity::Potential::familyOrder,
|
||||
"The divergence test element does not match the registered "
|
||||
"gravity potential."
|
||||
);
|
||||
const Query query =
|
||||
GravityField::make_query<field::Gravity::Form::DivergenceCoupling>(
|
||||
role, transformation.OrderW(), {}, domain, mapping
|
||||
);
|
||||
|
||||
const auto [resolution, integration_rule] = get(query, trial_element.GetGeomType());
|
||||
const auto [resolution, integration_rule] =
|
||||
get(query, trial_element.GetGeomType());
|
||||
integrator.SetIntegrationRule(*integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
Resolution RuleFactory::configure_gravity_boundary(
|
||||
mfem::VectorFEBoundaryFluxLFIntegrator& integrator,
|
||||
mfem::VectorFEBoundaryFluxLFIntegrator &integrator,
|
||||
const QuadratureRole role,
|
||||
const mfem::FiniteElement& boundary_element,
|
||||
const mfem::FiniteElement &boundary_element,
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
const int base_order = 2 * boundary_element.GetOrder();
|
||||
return configure(integrator, Term::gravity_boundary, role, boundary_element.GetGeomType(), base_order, domain, mapping);
|
||||
}
|
||||
|
||||
Resolution RuleFactory::configure_gravity_source(
|
||||
mfem::DomainLFIntegrator& integrator,
|
||||
const QuadratureRole role,
|
||||
const mfem::FiniteElement& test_element,
|
||||
const mfem::ElementTransformation& transformation,
|
||||
const int coefficient_order,
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
const Query query = {
|
||||
.term = Term::gravity_source,
|
||||
.role = role,
|
||||
.domain = domain,
|
||||
.mapping = mapping,
|
||||
.test_order = test_element.GetOrder(),
|
||||
.coefficient_order = coefficient_order,
|
||||
.geometry_weight_order = transformation.OrderW()
|
||||
};
|
||||
|
||||
const auto [resolution, integration_rule] = get(query, test_element.GetGeomType());
|
||||
using GravityField = field::Field<field::Gravity>;
|
||||
MFEM_VERIFY(
|
||||
boundary_element.GetOrder() == field::Gravity::Flux::familyOrder,
|
||||
"The boundary element does not match the registered gravity-flux "
|
||||
"normal trace."
|
||||
);
|
||||
const Query query =
|
||||
GravityField::make_query<field::Gravity::Form::Boundary>(
|
||||
role, 0, {}, domain, mapping
|
||||
);
|
||||
const auto [resolution, integration_rule] =
|
||||
get(query, boundary_element.GetGeomType());
|
||||
integrator.SetIntegrationRule(*integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
template<typename IntegratorType>
|
||||
Resolution RuleFactory::configure_gravity_source(
|
||||
mfem::DomainLFIntegrator &integrator,
|
||||
const QuadratureRole role,
|
||||
const mfem::FiniteElement &test_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
const int coefficient_order,
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
using GravityField = field::Field<field::Gravity>;
|
||||
MFEM_VERIFY(
|
||||
test_element.GetOrder() == field::Gravity::Potential::familyOrder,
|
||||
"The gravity-source test element does not match the registered "
|
||||
"gravity potential."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
coefficient_order == field::Density::Scalar::familyOrder,
|
||||
"The gravity-source coefficient order does not match the "
|
||||
"registered density field."
|
||||
);
|
||||
const Query query =
|
||||
GravityField::make_query<field::Gravity::Form::SourceLinear>(
|
||||
role, transformation.OrderW(), {}, domain, mapping
|
||||
);
|
||||
|
||||
const auto [resolution, integration_rule] =
|
||||
get(query, test_element.GetGeomType());
|
||||
integrator.SetIntegrationRule(*integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
Resolution RuleFactory::configure_gravity_source(
|
||||
mfem::MixedScalarMassIntegrator &integrator,
|
||||
QuadratureRole role,
|
||||
const mfem::FiniteElement &trial_element,
|
||||
const mfem::FiniteElement &test_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
int coefficient_order,
|
||||
utils::DOMAINS domain,
|
||||
MappingKind mapping
|
||||
) const {
|
||||
MFEM_VERIFY(
|
||||
trial_element.GetGeomType() == test_element.GetGeomType(),
|
||||
"Gravity source trial and test elements must use the same geometry."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
trial_element.GetGeomType() == transformation.GetGeometryType(),
|
||||
"Gravity source element and transformation geometries must agree."
|
||||
);
|
||||
|
||||
using GravityField = field::Field<field::Gravity>;
|
||||
MFEM_VERIFY(
|
||||
trial_element.GetOrder() == field::Density::Scalar::familyOrder,
|
||||
"The gravity-source trial element does not match the registered "
|
||||
"density field."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
test_element.GetOrder() == field::Gravity::Potential::familyOrder,
|
||||
"The gravity-source test element does not match the registered "
|
||||
"gravity potential."
|
||||
);
|
||||
MFEM_VERIFY(
|
||||
coefficient_order == 0,
|
||||
"The mapped gravity-source coefficient order must be zero; "
|
||||
"density order is supplied by the registered trial field."
|
||||
);
|
||||
const Query query =
|
||||
GravityField::make_query<field::Gravity::Form::SourceProjection>(
|
||||
role, transformation.OrderW(), {}, domain, mapping
|
||||
);
|
||||
|
||||
const auto [resolution, integration_rule] =
|
||||
get(query, transformation.GetGeometryType());
|
||||
integrator.SetIntRule(integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
Resolution RuleFactory::configure_centrifugal(
|
||||
integrators::CentrifugalForceIntegrator &integrator,
|
||||
const QuadratureRole role,
|
||||
const mfem::FiniteElement &density_element,
|
||||
const mfem::FiniteElement &velocity_element,
|
||||
const mfem::ElementTransformation &transformation,
|
||||
const int position_order,
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
const Query query = {
|
||||
.term = Term::centrifugal,
|
||||
.role = role,
|
||||
.domain = domain,
|
||||
.mapping = mapping,
|
||||
.trial_order = density_element.GetOrder(),
|
||||
.test_order = velocity_element.GetOrder(),
|
||||
.coefficient_order = position_order,
|
||||
.geometry_weight_order = transformation.OrderW()
|
||||
};
|
||||
|
||||
const auto [resolution, integration_rule] =
|
||||
get(query, velocity_element.GetGeomType());
|
||||
integrator.SetIntegrationRule(*integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
template <typename IntegratorType>
|
||||
Resolution RuleFactory::configure(
|
||||
IntegratorType& integrator,
|
||||
IntegratorType &integrator,
|
||||
const Term term,
|
||||
const QuadratureRole role,
|
||||
const mfem::Geometry::Type geometry,
|
||||
@@ -190,9 +323,10 @@ export namespace mean_field::quadrature {
|
||||
const utils::DOMAINS domain,
|
||||
const MappingKind mapping
|
||||
) const {
|
||||
const auto [resolution, integration_rule] = get(term, role, geometry, base_order, domain, mapping);
|
||||
const auto [resolution, integration_rule] =
|
||||
get(term, role, geometry, base_order, domain, mapping);
|
||||
integrator.SetIntegrationRule(*integration_rule);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace mean_field::quadrature
|
||||
|
||||
@@ -2,7 +2,9 @@ module;
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
export module mean_field:quadrature.policy;
|
||||
export import :utils.misc;
|
||||
@@ -13,11 +15,19 @@ export namespace mean_field::quadrature {
|
||||
gravity_divergence,
|
||||
gravity_source,
|
||||
gravity_boundary,
|
||||
centrifugal,
|
||||
density_projection,
|
||||
eos_closure,
|
||||
hydrostatic_equilibrium,
|
||||
isobaric_surface,
|
||||
mesh_extension,
|
||||
mass_conservation,
|
||||
mass_normalization,
|
||||
center_of_mass,
|
||||
quadrupole,
|
||||
gravitational_energy,
|
||||
pressure_integral,
|
||||
pressure_force,
|
||||
virial,
|
||||
error_norm
|
||||
};
|
||||
@@ -29,19 +39,9 @@ export namespace mean_field::quadrature {
|
||||
projection
|
||||
};
|
||||
|
||||
enum class MappingKind {
|
||||
none,
|
||||
affine,
|
||||
general,
|
||||
kelvin
|
||||
};
|
||||
enum class MappingKind { none, affine, general, kelvin };
|
||||
|
||||
enum class Mode {
|
||||
fast,
|
||||
production,
|
||||
reference,
|
||||
convergence
|
||||
};
|
||||
enum class Mode { fast, production, reference, convergence };
|
||||
|
||||
struct RuleControl {
|
||||
std::optional<int> fixed_order;
|
||||
@@ -55,17 +55,24 @@ export namespace mean_field::quadrature {
|
||||
RuleControl projection;
|
||||
};
|
||||
|
||||
|
||||
struct RuleSet {
|
||||
RuleControl gravity_hdiv_mass;
|
||||
RuleControl gravity_divergence;
|
||||
RuleControl gravity_source;
|
||||
RuleControl gravity_boundary;
|
||||
RuleControl centrifugal;
|
||||
RuleControl density_projection;
|
||||
RuleControl eos_closure;
|
||||
RuleControl hydrostatic_equilibrium;
|
||||
RuleControl isobaric_surface;
|
||||
RuleControl mesh_extension;
|
||||
RuleControl mass_conservation;
|
||||
RuleControl mass_normalization;
|
||||
RuleControl center_of_mass;
|
||||
RuleControl quadrupole;
|
||||
RuleControl gravitational_energy;
|
||||
RuleControl pressure_integral;
|
||||
RuleControl pressure_force;
|
||||
RuleControl virial;
|
||||
RuleControl error_norm;
|
||||
RoleControls roles;
|
||||
@@ -74,12 +81,12 @@ export namespace mean_field::quadrature {
|
||||
|
||||
struct Query {
|
||||
Term term;
|
||||
QuadratureRole role = QuadratureRole::discretization;
|
||||
utils::DOMAINS domain = utils::DOMAINS::ALL;
|
||||
MappingKind mapping = MappingKind::none;
|
||||
int trial_order = 0;
|
||||
int test_order = 0;
|
||||
int coefficient_order = 0;
|
||||
QuadratureRole role = QuadratureRole::discretization;
|
||||
utils::DOMAINS domain = utils::DOMAINS::ALL;
|
||||
MappingKind mapping = MappingKind::none;
|
||||
int trial_order = 0;
|
||||
int test_order = 0;
|
||||
int coefficient_order = 0;
|
||||
int geometry_weight_order = 0;
|
||||
std::optional<int> base_order;
|
||||
};
|
||||
@@ -96,16 +103,16 @@ export namespace mean_field::quadrature {
|
||||
};
|
||||
|
||||
struct QuadratureManifestOptions {
|
||||
bool enabled = false;
|
||||
bool enabled = false;
|
||||
bool include_repeated_queries = false;
|
||||
std::optional<std::string> output_file;
|
||||
};
|
||||
|
||||
struct QuadratureValidationOptions {
|
||||
bool require_explicit_base_order = false;
|
||||
bool require_explicit_mfem_rule = false;
|
||||
bool reject_negative_boosts = true;
|
||||
bool report_unused_overrides = true;
|
||||
bool require_explicit_mfem_rule = false;
|
||||
bool reject_negative_boosts = true;
|
||||
bool report_unused_overrides = true;
|
||||
};
|
||||
|
||||
struct QuadratureRoleOptions {
|
||||
@@ -116,7 +123,7 @@ export namespace mean_field::quadrature {
|
||||
};
|
||||
|
||||
struct QuadratureOptions {
|
||||
Mode mode = Mode::production;
|
||||
Mode mode = Mode::production;
|
||||
int global_boost = 0;
|
||||
std::optional<int> fallback_fixed_order;
|
||||
|
||||
@@ -124,11 +131,19 @@ export namespace mean_field::quadrature {
|
||||
QuadratureTermOptions gravity_divergence;
|
||||
QuadratureTermOptions gravity_source;
|
||||
QuadratureTermOptions gravity_boundary;
|
||||
QuadratureTermOptions centrifugal;
|
||||
QuadratureTermOptions density_projection;
|
||||
QuadratureTermOptions eos_closure;
|
||||
QuadratureTermOptions hydrostatic_equilibrium;
|
||||
QuadratureTermOptions isobaric_surface;
|
||||
QuadratureTermOptions mesh_extension;
|
||||
QuadratureTermOptions mass_conservation;
|
||||
QuadratureTermOptions mass_normalization;
|
||||
QuadratureTermOptions center_of_mass;
|
||||
QuadratureTermOptions quadrupole;
|
||||
QuadratureTermOptions gravitational_energy;
|
||||
QuadratureTermOptions pressure_integral;
|
||||
QuadratureTermOptions pressure_force;
|
||||
QuadratureTermOptions virial;
|
||||
QuadratureTermOptions error_norm;
|
||||
|
||||
@@ -139,44 +154,51 @@ export namespace mean_field::quadrature {
|
||||
QuadratureValidationOptions validation;
|
||||
};
|
||||
|
||||
RuleSet make_rule_set(Mode mode, int global_boost = 0);
|
||||
RuleSet make_rule_set(
|
||||
Mode mode,
|
||||
int global_boost = 0
|
||||
);
|
||||
|
||||
class Policy {
|
||||
public:
|
||||
explicit Policy(RuleSet rule_set);
|
||||
Resolution resolve(const Query& query) const;
|
||||
Resolution resolve(const Query &query) const;
|
||||
|
||||
private:
|
||||
const RuleControl& get_control(Term term) const;
|
||||
static int compute_base_order(const Query& query) ;
|
||||
const RuleControl& get_role_control(QuadratureRole role) const;
|
||||
const RuleControl &get_control(Term term) const;
|
||||
static int compute_base_order(const Query &query);
|
||||
const RuleControl &get_role_control(QuadratureRole role) const;
|
||||
|
||||
RuleSet rule_set;
|
||||
};
|
||||
|
||||
RuleSet make_rule_set(const Mode mode, const int global_boost) {
|
||||
RuleSet make_rule_set(
|
||||
const Mode mode,
|
||||
const int global_boost
|
||||
) {
|
||||
RuleSet rule_set;
|
||||
|
||||
switch (mode) {
|
||||
case Mode::fast:
|
||||
case Mode::production:
|
||||
case Mode::convergence:
|
||||
rule_set.fallback.boost = global_boost;
|
||||
break;
|
||||
case Mode::reference:
|
||||
rule_set.fallback.boost = global_boost + 8;
|
||||
break;
|
||||
case Mode::fast:
|
||||
case Mode::production:
|
||||
case Mode::convergence:
|
||||
rule_set.fallback.boost = global_boost;
|
||||
break;
|
||||
case Mode::reference:
|
||||
rule_set.fallback.boost = global_boost + 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return rule_set;
|
||||
}
|
||||
|
||||
Policy::Policy(RuleSet rule_set) : rule_set(std::move(rule_set)) {}
|
||||
Policy::Policy(RuleSet rule_set) : rule_set(std::move(rule_set)) {
|
||||
}
|
||||
|
||||
Resolution Policy::resolve(const Query& query) const {
|
||||
const int base_order = compute_base_order(query);
|
||||
const RuleControl& term_control = get_control(query.term);
|
||||
const RuleControl& role_control = get_role_control(query.role);
|
||||
Resolution Policy::resolve(const Query &query) const {
|
||||
const int base_order = compute_base_order(query);
|
||||
const RuleControl &term_control = get_control(query.term);
|
||||
const RuleControl &role_control = get_role_control(query.role);
|
||||
std::optional<int> fixed_order;
|
||||
|
||||
if (term_control.fixed_order.has_value()) {
|
||||
@@ -189,49 +211,96 @@ export namespace mean_field::quadrature {
|
||||
|
||||
if (fixed_order.has_value()) {
|
||||
if (*fixed_order < 0) {
|
||||
throw std::invalid_argument("Quadrature fixed order cannot be negative.");
|
||||
throw std::invalid_argument(
|
||||
"Quadrature fixed order cannot be negative."
|
||||
);
|
||||
}
|
||||
|
||||
return {.base_order = base_order, .boost = 0, .order = *fixed_order, .used_fixed_order = true};
|
||||
return {
|
||||
.base_order = base_order,
|
||||
.boost = 0,
|
||||
.order = *fixed_order,
|
||||
.used_fixed_order = true
|
||||
};
|
||||
}
|
||||
|
||||
const int boost = rule_set.fallback.boost + role_control.boost + term_control.boost;
|
||||
const int boost =
|
||||
rule_set.fallback.boost + role_control.boost + term_control.boost;
|
||||
const int order = base_order + boost;
|
||||
|
||||
if (order < 0) {
|
||||
throw std::invalid_argument("Resolved quadrature order cannot be negative.");
|
||||
throw std::invalid_argument(
|
||||
"Resolved quadrature order cannot be negative."
|
||||
);
|
||||
}
|
||||
|
||||
return {.base_order = base_order, .boost = boost, .order = order, .used_fixed_order = false};
|
||||
return {
|
||||
.base_order = base_order,
|
||||
.boost = boost,
|
||||
.order = order,
|
||||
.used_fixed_order = false
|
||||
};
|
||||
}
|
||||
const RuleControl& Policy::get_control(const Term term) const {
|
||||
const RuleControl &Policy::get_control(const Term term) const {
|
||||
switch (term) {
|
||||
case Term::gravity_hdiv_mass: return rule_set.gravity_hdiv_mass;
|
||||
case Term::gravity_divergence: return rule_set.gravity_divergence;
|
||||
case Term::gravity_source: return rule_set.gravity_source;
|
||||
case Term::gravity_boundary: return rule_set.gravity_boundary;
|
||||
case Term::density_projection: return rule_set.density_projection;
|
||||
case Term::mass_conservation: return rule_set.mass_conservation;
|
||||
case Term::center_of_mass: return rule_set.center_of_mass;
|
||||
case Term::quadrupole: return rule_set.quadrupole;
|
||||
case Term::gravitational_energy: return rule_set.gravitational_energy;
|
||||
case Term::virial: return rule_set.virial;
|
||||
case Term::error_norm: return rule_set.error_norm;
|
||||
case Term::gravity_hdiv_mass:
|
||||
return rule_set.gravity_hdiv_mass;
|
||||
case Term::gravity_divergence:
|
||||
return rule_set.gravity_divergence;
|
||||
case Term::gravity_source:
|
||||
return rule_set.gravity_source;
|
||||
case Term::gravity_boundary:
|
||||
return rule_set.gravity_boundary;
|
||||
case Term::centrifugal:
|
||||
return rule_set.centrifugal;
|
||||
case Term::density_projection:
|
||||
return rule_set.density_projection;
|
||||
case Term::eos_closure:
|
||||
return rule_set.eos_closure;
|
||||
case Term::hydrostatic_equilibrium:
|
||||
return rule_set.hydrostatic_equilibrium;
|
||||
case Term::isobaric_surface:
|
||||
return rule_set.isobaric_surface;
|
||||
case Term::mesh_extension:
|
||||
return rule_set.mesh_extension;
|
||||
case Term::mass_conservation:
|
||||
return rule_set.mass_conservation;
|
||||
case Term::mass_normalization:
|
||||
return rule_set.mass_normalization;
|
||||
case Term::center_of_mass:
|
||||
return rule_set.center_of_mass;
|
||||
case Term::quadrupole:
|
||||
return rule_set.quadrupole;
|
||||
case Term::gravitational_energy:
|
||||
return rule_set.gravitational_energy;
|
||||
case Term::pressure_integral:
|
||||
return rule_set.pressure_integral;
|
||||
case Term::pressure_force:
|
||||
return rule_set.pressure_force;
|
||||
case Term::virial:
|
||||
return rule_set.virial;
|
||||
case Term::error_norm:
|
||||
return rule_set.error_norm;
|
||||
}
|
||||
|
||||
throw std::logic_error("Unknown quadrature term.");
|
||||
}
|
||||
|
||||
int Policy::compute_base_order(const Query& query) {
|
||||
int Policy::compute_base_order(const Query &query) {
|
||||
if (query.base_order.has_value()) {
|
||||
if (*query.base_order < 0) {
|
||||
throw std::invalid_argument("Quadrature base order cannot be negative.");
|
||||
throw std::invalid_argument(
|
||||
"Quadrature base order cannot be negative."
|
||||
);
|
||||
}
|
||||
return *query.base_order;
|
||||
}
|
||||
|
||||
if (query.trial_order < 0 || query.test_order < 0 || query.coefficient_order < 0 || query.geometry_weight_order < 0) {
|
||||
throw std::invalid_argument("Quadrature query orders cannot be negative.");
|
||||
if (query.trial_order < 0 || query.test_order < 0 ||
|
||||
query.coefficient_order < 0 || query.geometry_weight_order < 0) {
|
||||
throw std::invalid_argument(
|
||||
"Quadrature query orders cannot be negative."
|
||||
);
|
||||
}
|
||||
|
||||
int trial_order = query.trial_order;
|
||||
@@ -239,18 +308,24 @@ export namespace mean_field::quadrature {
|
||||
trial_order = std::max(0, trial_order - 1);
|
||||
}
|
||||
|
||||
return trial_order + query.test_order + query.coefficient_order + query.geometry_weight_order;
|
||||
return trial_order + query.test_order + query.coefficient_order +
|
||||
query.geometry_weight_order;
|
||||
}
|
||||
|
||||
const RuleControl& Policy::get_role_control(const QuadratureRole role) const {
|
||||
const RuleControl &
|
||||
Policy::get_role_control(const QuadratureRole role) const {
|
||||
switch (role) {
|
||||
case QuadratureRole::discretization: return rule_set.roles.discretization;
|
||||
case QuadratureRole::preconditioner: return rule_set.roles.preconditioner;
|
||||
case QuadratureRole::diagnostic: return rule_set.roles.diagnostic;
|
||||
case QuadratureRole::projection: return rule_set.roles.projection;
|
||||
case QuadratureRole::discretization:
|
||||
return rule_set.roles.discretization;
|
||||
case QuadratureRole::preconditioner:
|
||||
return rule_set.roles.preconditioner;
|
||||
case QuadratureRole::diagnostic:
|
||||
return rule_set.roles.diagnostic;
|
||||
case QuadratureRole::projection:
|
||||
return rule_set.roles.projection;
|
||||
}
|
||||
|
||||
throw std::logic_error("Unknown quadrature role.");
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace mean_field::quadrature
|
||||
|
||||
Reference in New Issue
Block a user