Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
combined_system.hpp
Go to the documentation of this file.
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
36 #pragma once
37 
38 #include <vector>
39 #include <memory>
40 #include <tuple>
42 #include "smith/differentiable_numerics/field_store.hpp"
43 
44 namespace smith {
45 
59 struct CombinedSystem : public SystemBase {
60  std::vector<std::shared_ptr<SystemBase>> subsystems;
61 
64 
75  template <typename SubSystemType, typename MaterialType>
76  void setMaterialOn(std::shared_ptr<SubSystemType> sub, const MaterialType& material, const std::string& domain_name)
77  {
78  sub->setMaterial(material, domain_name);
79  }
80 };
81 
91 template <typename... SubSystems>
92 auto combineSystems(std::shared_ptr<SubSystems>... subs)
93 {
94  static_assert(sizeof...(subs) >= 2, "combineSystems requires at least two sub-systems");
95 
96  auto first_sub = std::get<0>(std::forward_as_tuple(subs...));
97  auto field_store = first_sub->field_store;
98 
99  auto combined = std::make_shared<CombinedSystem>();
100  combined->field_store = field_store;
101 
102  int max_stagger_iters = 1;
103  bool exact_staggered_steps = false;
104 
105  std::vector<std::shared_ptr<SystemBase>> post_solve_systems;
106  std::vector<std::vector<size_t>> subsystem_global_block_indices;
107 
108  (
109  [&](auto& sub) {
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);
115  }
116  subsystem_global_block_indices.push_back(global_block_indices);
117  if (sub->solver) {
118  max_stagger_iters = std::max(max_stagger_iters, sub->solver->maxStaggeredIterations());
119  exact_staggered_steps = exact_staggered_steps || sub->solver->exactStaggeredSteps();
120  }
121  for (auto& cz_sys : sub->cycle_zero_systems) {
122  combined->cycle_zero_systems.push_back(cz_sys);
123  }
124  post_solve_systems.insert(post_solve_systems.end(), sub->post_solve_systems.begin(),
125  sub->post_solve_systems.end());
126  }(subs),
127  ...);
128 
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]);
134  }
135 
136  combined->post_solve_systems = post_solve_systems;
137 
138  return combined;
139 }
140 
154 template <typename... SubSystems>
155 std::shared_ptr<SystemBase> combineSystems(std::shared_ptr<SystemSolver> solver, std::shared_ptr<SubSystems>... subs)
156 {
157  static_assert(sizeof...(subs) >= 2, "combineSystems requires at least two sub-systems");
158 
159  auto field_store = std::get<0>(std::forward_as_tuple(subs...))->field_store;
160 
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;
164 
165  (
166  [&](auto& sub) {
167  for (auto& wf : sub->weak_forms) {
168  wfs.push_back(wf);
169  }
170  for (auto& cz_sys : sub->cycle_zero_systems) {
171  cycle_zero_systems.push_back(cz_sys);
172  }
173  post_solve_systems.insert(post_solve_systems.end(), sub->post_solve_systems.begin(),
174  sub->post_solve_systems.end());
175  }(subs),
176  ...);
177 
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;
181 
182  return combined;
183 }
184 
185 } // namespace smith
Accelerator functionality.
Definition: smith.cpp:36
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.
Definition: dual.hpp:229
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.
Definition: system_base.hpp:52
SystemBase()=default
Construct an empty system shell.
Defines the SystemBase struct for common system functionality.