6#include <range/v3/algorithm/sort.hpp>
7#include <range/v3/view/enumerate.hpp>
8#include <range/v3/view/for_each.hpp>
9#include <range/v3/view/transform.hpp>
10#include <range/v3/view/zip.hpp>
20 std::vector<std::vector<std::string>>
const& per_process_residuum_names,
22 std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>>
const&
25 if (per_process_pvs.size() != per_process_residuum_names.size())
28 "The number of passed residuum names ({}) does not match the "
29 "number of processes ({}).",
30 per_process_residuum_names.size(), per_process_pvs.size());
33 auto check_sizes = [](std::size_t
const process_id,
auto const& rns_pvs)
35 auto const& [rns, pvs] = rns_pvs;
37 if (rns.size() != pvs.size())
40 "The number of passed residuum names ({}) does not match the "
41 "number of process variables ({}) for process {}.",
42 rns.size(), pvs.size(), process_id);
45 for (
auto const& [process_id, rns_pvs] :
46 ranges::views::zip(per_process_residuum_names, per_process_pvs) |
47 ranges::views::enumerate)
49 check_sizes(process_id, rns_pvs);
54 std::vector<std::reference_wrapper<MeshLib::PropertyVector<double>>>>
57 std::vector<std::vector<std::string>>
const& per_process_residuum_names,
59 std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>>
const&
65 auto create_mesh_property_for_residuum =
66 [&mesh](std::pair<std::string
const&,
68 residuum_name_process_variable)
71 auto const& [rn, pv] = residuum_name_process_variable;
74 pv.getNumberOfGlobalComponents());
77 auto create_mesh_properties =
78 [&create_mesh_property_for_residuum](
auto const& rns_pvs)
80 auto const& [rns, pvs] = rns_pvs;
81 return ranges::views::zip(rns, pvs) |
82 ranges::views::transform(create_mesh_property_for_residuum) |
83 ranges::to<std::vector<
84 std::reference_wrapper<MeshLib::PropertyVector<double>>>>;
87 return ranges::views::zip(per_process_residuum_names, per_process_pvs) |
88 ranges::views::transform(create_mesh_properties) |
89 ranges::to<std::vector<std::vector<
90 std::reference_wrapper<MeshLib::PropertyVector<double>>>>>;
100 bool const use_monolithic_scheme)
103 if (is_linear && !use_monolithic_scheme)
106 "You requested to assemble only once in combination with staggered "
107 "coupling. This use case is not yet implemented.");
113 "You specified that the process simulated by OGS is linear. With "
114 "this optimization, the system is assembled only once, and the "
115 "non-linear solver performs a single iteration per time step. No "
116 "non-linearities will be resolved, and OGS will not detect whether "
117 "any exist. It is your responsibility to ensure that the assembled "
118 "systems are indeed linear; there is no safety net.\n"
120 "Be aware that non-linearities may arise in subtle ways. For "
121 "example, in an HT problem with a steady-state velocity field, if "
122 "the initial pressure field does not match the steady-state "
123 "condition (e.g., initialized to zero), then the steady-state "
124 "velocity field only emerges during the first iteration—making the "
125 "system effectively non-linear under this optimization.");
131 std::vector<std::reference_wrapper<MeshLib::Mesh>>
const& submeshes,
132 std::vector<std::vector<std::string>>
const& residuum_names,
133 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
const&
136 DBUG(
"AssemblyMixinBase initializeSubmeshOutput().");
138 auto const num_submeshes = submeshes.size();
140 if (num_submeshes == 0)
143 createResiduumVectors(bulk_mesh, residuum_names, pvs));
148 for (
auto& submesh_ref : submeshes)
150 auto& submesh = submesh_ref.get();
153 submesh, createResiduumVectors(submesh, residuum_names, pvs));
161 DBUG(
"AssemblyMixin updateActiveElements().");
192 DBUG(
"AssemblyMixinBase updateActiveElementsImpl().");
197 active_element_ids.empty()
207 sad.setAllElementsActive();
216 auto active_element_ids_copy{active_element_ids};
219 ranges::sort(active_element_ids_copy);
223 sad.setElementSelectionActive(active_element_ids_copy);
228 active_element_ids_copy);
241 for (std::size_t variable_id = 0; variable_id < residuum_vectors.size();
244 transformVariableFromGlobalVector(
245 rhs, variable_id, local_to_global_index_map,
246 residuum_vectors[variable_id].get(), std::negate<double>());
251 int const process_id,
257 for (std::size_t variable_id = 0; variable_id < residuum_vectors.size();
260 transformVariableFromGlobalVector(
261 rhs, variable_id, local_to_global_index_map,
262 residuum_vectors[variable_id].get(),
264 std::negate<double>());
MathLib::EigenVector GlobalVector
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Base class for Jacobian assemblers.
void initializeAssemblyOnSubmeshes(MeshLib::Mesh &bulk_mesh, std::vector< std::reference_wrapper< MeshLib::Mesh > > const &submeshes, std::vector< std::vector< std::string > > const &residuum_names, std::vector< std::vector< std::reference_wrapper< ProcessVariable > > > const &pvs)
AssemblyMixinBase(AbstractJacobianAssembler &jacobian_assembler, bool const is_linear, bool const use_monolithic_scheme)
Assembly::ParallelVectorMatrixAssembler pvma_
static void copyResiduumVectorsToBulkMesh(GlobalVector const &rhs, NumLib::LocalToGlobalIndexMap const &local_to_global_index_map, std::vector< std::reference_wrapper< MeshLib::PropertyVector< double > > > residuum_vectors)
@ NO_DEACTIVATED_SUBDOMAINS
@ HAS_DEACTIVATED_SUBDOMAINS
void updateActiveElementsImpl(Process const &process)
std::vector< AssembledMatrixCache > submesh_matrix_cache_
AssembledMatrixCache for each submesh.
static void copyResiduumVectorsToSubmesh(int const process_id, GlobalVector const &rhs, NumLib::LocalToGlobalIndexMap const &local_to_global_index_map, ProcessLib::Assembly::SubmeshAssemblyData const &sad)
ActiveElementIDsState ids_state_
void updateActiveElements(ProcessLib::Process const &process)
std::vector< ProcessLib::Assembly::SubmeshAssemblyData > submesh_assembly_data_
SubmeshAssemblyData for each submesh.
std::optional< ProcessLib::Assembly::BulkMeshAssemblyData > bulk_mesh_assembly_data_
Empty if submesh assembly is used.
std::vector< std::size_t > const & getActiveElementIDs() const
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)
void checkResiduumNamesVsProcessVariables(std::vector< std::vector< std::string > > const &per_process_residuum_names, std::vector< std::vector< std::reference_wrapper< ProcessLib::ProcessVariable > > > const &per_process_pvs)
std::vector< std::vector< std::reference_wrapper< MeshLib::PropertyVector< double > > > > createResiduumVectors(MeshLib::Mesh &mesh, std::vector< std::vector< std::string > > const &per_process_residuum_names, std::vector< std::vector< std::reference_wrapper< ProcessLib::ProcessVariable > > > const &per_process_pvs)
std::vector< std::vector< std::reference_wrapper< MeshLib::PropertyVector< double > > > > residuum_vectors
Residuum vectors for each process ID.
MeshLib::PropertyVector< std::size_t > const & bulk_node_ids