OGS
AssemblyMixin.cpp
Go to the documentation of this file.
1
11#include "AssemblyMixin.h"
12
13#include <range/v3/view/enumerate.hpp>
14#include <range/v3/view/for_each.hpp>
15#include <range/v3/view/transform.hpp>
16#include <range/v3/view/zip.hpp>
17#include <unordered_set>
18
21#include "Process.h"
22
23namespace
24{
25
27 std::vector<std::vector<std::string>> const& per_process_residuum_names,
28 std::vector<
29 std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>> const&
30 per_process_pvs)
31{
32 if (per_process_pvs.size() != per_process_residuum_names.size())
33 {
35 "The number of passed residuum names ({}) does not match the "
36 "number of processes ({}).",
37 per_process_residuum_names.size(), per_process_pvs.size());
38 }
39
40 auto check_sizes = [](std::size_t const process_id, auto const& rns_pvs)
41 {
42 auto const& [rns, pvs] = rns_pvs;
43
44 if (rns.size() != pvs.size())
45 {
47 "The number of passed residuum names ({}) does not match the "
48 "number of process variables ({}) for process {}.",
49 rns.size(), pvs.size(), process_id);
50 }
51 };
52 for (auto const& [process_id, rns_pvs] :
53 ranges::views::zip(per_process_residuum_names, per_process_pvs) |
54 ranges::views::enumerate)
55 {
56 check_sizes(process_id, rns_pvs);
57 }
58}
59
60std::vector<
61 std::vector<std::reference_wrapper<MeshLib::PropertyVector<double>>>>
63 MeshLib::Mesh& mesh,
64 std::vector<std::vector<std::string>> const& per_process_residuum_names,
65 std::vector<
66 std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>> const&
67 per_process_pvs)
68{
69 checkResiduumNamesVsProcessVariables(per_process_residuum_names,
70 per_process_pvs);
71
72 auto create_mesh_property_for_residuum =
73 [&mesh](std::pair<std::string const&,
74 ProcessLib::ProcessVariable const&> const&
75 residuum_name_process_variable)
76 -> std::reference_wrapper<MeshLib::PropertyVector<double>>
77 {
78 auto const& [rn, pv] = residuum_name_process_variable;
81 pv.getNumberOfGlobalComponents());
82 };
83
84 auto create_mesh_properties =
85 [&create_mesh_property_for_residuum](auto const& rns_pvs)
86 {
87 auto const& [rns, pvs] = rns_pvs;
88 return ranges::views::zip(rns, pvs) |
89 ranges::views::transform(create_mesh_property_for_residuum) |
90 ranges::to<std::vector<
91 std::reference_wrapper<MeshLib::PropertyVector<double>>>>;
92 };
93
94 return ranges::views::zip(per_process_residuum_names, per_process_pvs) |
95 ranges::views::transform(create_mesh_properties) |
96 ranges::to<std::vector<std::vector<
97 std::reference_wrapper<MeshLib::PropertyVector<double>>>>>;
98}
99} // namespace
100
101namespace ProcessLib
102{
104 MeshLib::Mesh const& mesh,
105 std::vector<
106 std::vector<std::reference_wrapper<MeshLib::PropertyVector<double>>>>&&
107 residuum_vectors)
108 : bulk_element_ids{*MeshLib::bulkElementIDs(mesh)},
109 bulk_node_ids{*MeshLib::bulkNodeIDs(mesh)},
110 residuum_vectors{std::move(residuum_vectors)}
111{
112}
113
115 MeshLib::Mesh& bulk_mesh,
116 std::vector<std::reference_wrapper<MeshLib::Mesh>> const& submeshes,
117 std::vector<std::vector<std::string>> const& residuum_names,
118 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>> const&
119 pvs)
120{
121 DBUG("AssemblyMixinBase initializeSubmeshOutput().");
122
123 submesh_assembly_data_.reserve(submeshes.size());
124 for (auto& mesh_ref : submeshes)
125 {
126 auto& mesh = mesh_ref.get();
127
128 submesh_assembly_data_.emplace_back(
129 mesh, createResiduumVectors(mesh, residuum_names, pvs));
130 }
131
133 createResiduumVectors(bulk_mesh, residuum_names, pvs);
134}
135
137{
138 DBUG("AssemblyMixin updateActiveElements().");
139
141 {
143 return;
144 }
145
146 ActiveElementIDsState const new_state =
147 process.getActiveElementIDs().empty()
150
153 {
154 // no update necessary
155 return;
156 }
157
158 // updating the active elements is necessary in all remaining cases, because
159 // of the following transitions between old and new states (deactivated
160 // subdomains present? yes/no; old state -> new state):
161 // * no -> yes - now there are deactivated subdomains
162 // * yes -> no - no deactivated subdomains anymore
163 // * yes -> yes - deactivated subdomains might have changed
165}
166
168{
169 DBUG("AssemblyMixinBase updateActiveElementsImpl().");
170
171 auto const& active_element_ids = process.getActiveElementIDs();
172
173 ActiveElementIDsState const new_state =
174 active_element_ids.empty()
177
179 {
180 // no deactivated subdomains, assemble on all elements as specified
181 // in the bulk_element_ids of the submeshes
182 for (auto& sad : submesh_assembly_data_)
183 {
184 // note: this copies the ID vector!
185 sad.active_element_ids = sad.bulk_element_ids;
186 }
187 }
188 else
189 {
190 // assemble each submesh on the intersection of the "global" active
191 // elements and the submesh
192 std::unordered_set<std::size_t> active_element_ids_set(
193 active_element_ids.begin(), active_element_ids.end());
194
195 for (auto& sad : submesh_assembly_data_)
196 {
197 auto& aeis = sad.active_element_ids;
198 auto& beis = sad.bulk_element_ids;
199 aeis.clear();
200 aeis.reserve(beis.getNumberOfTuples());
201
202 for (auto bei : beis)
203 {
204 if (active_element_ids_set.contains(bei))
205 {
206 aeis.push_back(bei);
207 }
208 }
209 }
210 }
211
212 ids_state_ = new_state;
213}
214
216 GlobalVector const& rhs,
217 NumLib::LocalToGlobalIndexMap const& local_to_global_index_map,
218 std::vector<std::reference_wrapper<MeshLib::PropertyVector<double>>>
219 residuum_vectors)
220{
221 for (std::size_t variable_id = 0; variable_id < residuum_vectors.size();
222 ++variable_id)
223 {
224 transformVariableFromGlobalVector(
225 rhs, variable_id, local_to_global_index_map,
226 residuum_vectors[variable_id].get(), std::negate<double>());
227 }
228}
229
231 int const process_id,
232 GlobalVector const& rhs,
233 NumLib::LocalToGlobalIndexMap const& local_to_global_index_map,
234 SubmeshAssemblyData const& sad)
235{
236 auto const& residuum_vectors = sad.residuum_vectors[process_id];
237 for (std::size_t variable_id = 0; variable_id < residuum_vectors.size();
238 ++variable_id)
239 {
240 transformVariableFromGlobalVector(
241 rhs, variable_id, local_to_global_index_map,
242 residuum_vectors[variable_id].get(), sad.bulk_node_ids,
243 std::negate<double>());
244 }
245}
246
247} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
Global vector based on Eigen vector.
Definition EigenVector.h:25
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)
static void copyResiduumVectorsToBulkMesh(GlobalVector const &rhs, NumLib::LocalToGlobalIndexMap const &local_to_global_index_map, std::vector< std::reference_wrapper< MeshLib::PropertyVector< double > > > residuum_vectors)
void updateActiveElementsImpl(Process const &process)
ActiveElementIDsState ids_state_
void updateActiveElements(ProcessLib::Process const &process)
static void copyResiduumVectorsToSubmesh(int const process_id, GlobalVector const &rhs, NumLib::LocalToGlobalIndexMap const &local_to_global_index_map, SubmeshAssemblyData const &sad)
std::vector< SubmeshAssemblyData > submesh_assembly_data_
std::vector< std::vector< std::reference_wrapper< MeshLib::PropertyVector< double > > > > residuum_vectors_bulk_
std::vector< std::size_t > const & getActiveElementIDs() const
Definition Process.h:167
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
MeshLib::PropertyVector< std::size_t > const & bulk_node_ids
SubmeshAssemblyData(MeshLib::Mesh const &mesh, std::vector< std::vector< std::reference_wrapper< MeshLib::PropertyVector< double > > > > &&residuum_vectors)