42 #include "smith/differentiable_numerics/field_store.hpp"
75 template <
typename SubSystemType,
typename MaterialType>
76 void setMaterialOn(std::shared_ptr<SubSystemType> sub,
const MaterialType& material,
const std::string& domain_name)
78 sub->setMaterial(material, domain_name);
91 template <
typename... SubSystems>
94 static_assert(
sizeof...(subs) >= 2,
"combineSystems requires at least two sub-systems");
96 auto first_sub = std::get<0>(std::forward_as_tuple(subs...));
97 auto field_store = first_sub->field_store;
99 auto combined = std::make_shared<CombinedSystem>();
100 combined->field_store = field_store;
102 int max_stagger_iters = 1;
103 bool exact_staggered_steps =
false;
105 std::vector<std::shared_ptr<SystemBase>> post_solve_systems;
106 std::vector<std::vector<size_t>> subsystem_global_block_indices;
110 std::vector<size_t> global_block_indices;
111 combined->subsystems.push_back(sub);
112 for (
auto& wf : sub->weak_forms) {
113 global_block_indices.push_back(combined->weak_forms.size());
114 combined->weak_forms.push_back(wf);
116 subsystem_global_block_indices.push_back(global_block_indices);
118 max_stagger_iters =
std::max(max_stagger_iters, sub->solver->maxStaggeredIterations());
119 exact_staggered_steps = exact_staggered_steps || sub->solver->exactStaggeredSteps();
121 for (
auto& cz_sys : sub->cycle_zero_systems) {
122 combined->cycle_zero_systems.push_back(cz_sys);
124 post_solve_systems.insert(post_solve_systems.end(), sub->post_solve_systems.begin(),
125 sub->post_solve_systems.end());
129 combined->solver = std::make_shared<SystemSolver>(max_stagger_iters, exact_staggered_steps);
130 for (
size_t i = 0; i < combined->subsystems.size(); ++i) {
131 const auto& sub = combined->subsystems[i];
132 SLIC_ERROR_IF(!sub->solver,
"Combined subsystem must have a solver");
133 combined->solver->appendStagesWithBlockMapping(*sub->solver, subsystem_global_block_indices[i]);
136 combined->post_solve_systems = post_solve_systems;
154 template <
typename... SubSystems>
155 std::shared_ptr<SystemBase>
combineSystems(std::shared_ptr<SystemSolver> solver, std::shared_ptr<SubSystems>... subs)
157 static_assert(
sizeof...(subs) >= 2,
"combineSystems requires at least two sub-systems");
159 auto field_store = std::get<0>(std::forward_as_tuple(subs...))->field_store;
161 std::vector<std::shared_ptr<WeakForm>> wfs;
162 std::vector<std::shared_ptr<SystemBase>> cycle_zero_systems;
163 std::vector<std::shared_ptr<SystemBase>> post_solve_systems;
167 for (
auto& wf : sub->weak_forms) {
170 for (
auto& cz_sys : sub->cycle_zero_systems) {
171 cycle_zero_systems.push_back(cz_sys);
173 post_solve_systems.insert(post_solve_systems.end(), sub->post_solve_systems.begin(),
174 sub->post_solve_systems.end());
178 auto combined = std::make_shared<SystemBase>(field_store, solver, wfs);
179 combined->cycle_zero_systems = cycle_zero_systems;
180 combined->post_solve_systems = post_solve_systems;
Accelerator functionality.
auto combineSystems(std::shared_ptr< SubSystems >... subs)
Combine two or more independently-built sub-systems into a CombinedSystem.
SMITH_HOST_DEVICE auto max(dual< gradient_type > a, double b)
Implementation of max for dual numbers.
A non-templated system wrapper that combines multiple sub-systems sharing one FieldStore.
void setMaterialOn(std::shared_ptr< SubSystemType > sub, const MaterialType &material, const std::string &domain_name)
Set a coupled material on all sub-systems.
std::vector< std::shared_ptr< SystemBase > > subsystems
Ordered sub-systems solved during each staggered sweep.
Base struct for physics systems containing common members and helper functions.
SystemBase()=default
Construct an empty system shell.
Defines the SystemBase struct for common system functionality.