diff --git a/src/smith/differentiable_numerics/field_store.cpp b/src/smith/differentiable_numerics/field_store.cpp index 20d0869ade..f319c9d61d 100644 --- a/src/smith/differentiable_numerics/field_store.cpp +++ b/src/smith/differentiable_numerics/field_store.cpp @@ -298,6 +298,22 @@ std::vector FieldStore::getStates(const std::string& weak_form_name) return fields_for_residual; } +std::vector FieldStore::getParameters(const std::string& weak_form_name) const +{ + SLIC_ERROR_ROOT_IF(weak_form_name_to_field_names_.count(weak_form_name) == 0, + axom::fmt::format("Weak form '{}' not found in FieldStore. Did you forget to call addReaction()?", + weak_form_name)); + + const auto& field_names = weak_form_name_to_field_names_.at(weak_form_name); + std::vector parameters_for_residual; + for (const auto& name : field_names) { + if (to_params_index_.count(name)) { + parameters_for_residual.push_back(getParameter(name)); + } + } + return parameters_for_residual; +} + std::vector FieldStore::getStatesFromVectors(const std::string& weak_form_name, const std::vector& state_fields, const std::vector& param_fields) const diff --git a/src/smith/differentiable_numerics/field_store.hpp b/src/smith/differentiable_numerics/field_store.hpp index d85b3a6338..f30ebf54e8 100644 --- a/src/smith/differentiable_numerics/field_store.hpp +++ b/src/smith/differentiable_numerics/field_store.hpp @@ -419,6 +419,13 @@ struct FieldStore { */ std::vector getStates(const std::string& weak_form_name) const; + /** + * @brief Get the parameter fields associated with a weak form. + * @param weak_form_name Name of the weak form. + * @return std::vector Parameter fields in weak-form argument order. + */ + std::vector getParameters(const std::string& weak_form_name) const; + /** * @brief Extract state fields for a weak form from provided state and parameter vectors. * @param weak_form_name Name of the weak form. diff --git a/src/smith/differentiable_numerics/system_base.cpp b/src/smith/differentiable_numerics/system_base.cpp index e13589eb90..6b69afd74f 100644 --- a/src/smith/differentiable_numerics/system_base.cpp +++ b/src/smith/differentiable_numerics/system_base.cpp @@ -57,8 +57,11 @@ std::vector SystemBase::solve(const TimeInfo& time_info) const } } - auto params = field_store->getParameterFields(); - std::vector> wk_params(weak_forms.size(), params); + std::vector> wk_params; + wk_params.reserve(weak_forms.size()); + for (const auto& weak_form : weak_forms) { + wk_params.push_back(field_store->getParameters(weak_form->name())); + } std::vector weak_form_ptrs; for (auto& p : weak_forms) { diff --git a/src/smith/differentiable_numerics/tests/test_multiphysics_time_integrator.cpp b/src/smith/differentiable_numerics/tests/test_multiphysics_time_integrator.cpp index c2cb034247..33cd0547d5 100644 --- a/src/smith/differentiable_numerics/tests/test_multiphysics_time_integrator.cpp +++ b/src/smith/differentiable_numerics/tests/test_multiphysics_time_integrator.cpp @@ -173,6 +173,36 @@ bool allNodesOnBoundary(const std::vector& nodes, double x_target) } // namespace +TEST(FieldStore, WeakFormParametersExcludeUnrelatedSharedParametersAndPreserveOrder) +{ + axom::sidre::DataStore datastore; + StateManager::initialize(datastore, "weak_form_parameter_filtering"); + + auto mesh = + std::make_shared(mfem::Mesh::MakeCartesian2D(2, 2, mfem::Element::QUADRILATERAL), "parameter_filter_mesh"); + auto field_store = std::make_shared(mesh, 10); + + FieldType> shape_displacement("shape_displacement"); + field_store->addShapeDisp(shape_displacement); + FieldType> unknown("unknown"); + field_store->addIndependent(unknown, std::make_shared()); + FieldType> first_parameter("first_parameter"); + FieldType> second_parameter("second_parameter"); + FieldType> unrelated_parameter("unrelated_parameter"); + field_store->addParameter(first_parameter); + field_store->addParameter(second_parameter); + field_store->addParameter(unrelated_parameter); + + field_store->createSpaces("parameter_filtered_weak_form", unknown.name, unknown, second_parameter, first_parameter); + auto parameters = field_store->getParameters("parameter_filtered_weak_form"); + + ASSERT_EQ(parameters.size(), 2u); + EXPECT_EQ(parameters[0].get()->name(), second_parameter.name); + EXPECT_EQ(parameters[1].get()->name(), first_parameter.name); + + StateManager::reset(); +} + TEST(MultiphysicsTimeIntegrator, CycleZeroUsesBcsForReactionFieldNotUnknownZero) { axom::sidre::DataStore datastore;