73 bool involved_in_constraints,
74 std::unordered_map<dof_id_type, dof_id_type> & uncondensed_global_to_local_map,
75 std::unordered_set<dof_id_type> & local_uncondensed_dofs_set,
77 nonlocal_uncondensed_dofs,
78 std::vector<dof_id_type> & elem_uncondensed_dofs,
80 std::unordered_set<dof_id_type> & constraint_dofs)
83 auto it = full_dof_constraints.find(full_dof_number);
84 const bool is_constrained = it != full_dof_constraints.end();
85 involved_in_constraints = involved_in_constraints || is_constrained;
88 involved_in_constraints,
89 uncondensed_global_to_local_map,
90 local_uncondensed_dofs_set,
91 nonlocal_uncondensed_dofs,
92 elem_uncondensed_dofs,
93 uncondensed_local_dof_number,
96 for (
const auto & [full_constraining_dof, weight] : it->second)
102 uncondensed_global_to_local_map,
103 local_uncondensed_dofs_set,
104 nonlocal_uncondensed_dofs,
105 elem_uncondensed_dofs,
106 uncondensed_local_dof_number,
116 std::vector<dof_id_type> elem_dofs, elem_uncondensed_dofs;
117 dof_id_type condensed_local_dof_number = 0, uncondensed_local_dof_number = 0;
118 std::unordered_map<dof_id_type, dof_id_type> *condensed_global_to_local_map =
nullptr,
119 *uncondensed_global_to_local_map =
nullptr;
120 std::set<unsigned int> full_vars_present_in_reduced_sys;
121 std::unordered_set<dof_id_type> local_uncondensed_dofs_set, constraint_dofs;
122 std::unordered_map<processor_id_type, std::unordered_set<dof_id_type>> nonlocal_uncondensed_dofs;
129 std::vector<dof_id_type> scalar_dof_indices;
131 for (
const auto vg_vn :
make_range(vg_description.n_variables()))
133 const auto vn = vg_description.number(vg_vn);
135 if (this->
comm().
rank() == last_pid)
136 local_uncondensed_dofs_set.insert(scalar_dof_indices.begin(),
137 scalar_dof_indices.end());
139 nonlocal_uncondensed_dofs[last_pid].insert(scalar_dof_indices.begin(),
140 scalar_dof_indices.end());
144 auto scalar_dofs_functor =
146 &uncondensed_global_to_local_map,
147 &local_uncondensed_dofs_set,
148 &nonlocal_uncondensed_dofs,
149 &elem_uncondensed_dofs,
150 &uncondensed_local_dof_number,
151 &constraint_dofs](
const Elem & ,
153 const std::vector<dof_id_type> & scalar_dof_indices) {
155 for (
const auto global_dof : scalar_dof_indices)
158 *uncondensed_global_to_local_map,
159 local_uncondensed_dofs_set,
160 nonlocal_uncondensed_dofs,
161 elem_uncondensed_dofs,
162 uncondensed_local_dof_number,
166 auto field_dofs_functor = [
this,
167 &condensed_local_dof_number,
168 &condensed_global_to_local_map,
169 &uncondensed_global_to_local_map,
170 &local_uncondensed_dofs_set,
171 &nonlocal_uncondensed_dofs,
172 &elem_uncondensed_dofs,
173 &uncondensed_local_dof_number,
174 &constraint_dofs](
const Elem & elem,
175 const unsigned int node_num,
176 const unsigned int var_num,
181 bool uncondensed_dof =
false;
186 "Users should not be providing continuous FEM variables to the uncondensed vars API");
187 uncondensed_dof =
true;
190 if (node_num !=
invalid_uint && !elem.is_internal(node_num))
191 uncondensed_dof =
true;
196 *uncondensed_global_to_local_map,
197 local_uncondensed_dofs_set,
198 nonlocal_uncondensed_dofs,
199 elem_uncondensed_dofs,
200 uncondensed_local_dof_number,
203 (*condensed_global_to_local_map)[field_dof] = condensed_local_dof_number++;
206 for (
auto elem :
_mesh.active_local_element_ptr_range())
209 condensed_local_dof_number = 0;
210 uncondensed_local_dof_number = 0;
211 condensed_global_to_local_map = &dof_data.condensed_global_to_local_map;
212 uncondensed_global_to_local_map = &dof_data.uncondensed_global_to_local_map;
214 const auto sub_id = elem->subdomain_id();
218 for (
const auto v :
make_range(var_group.n_variables()))
220 const auto var_num = var_group.
number(v);
221 dof_data.reduced_space_indices.resize(var_num + 1);
222 if (!var_group.active_on_subdomain(sub_id))
224 elem_uncondensed_dofs.clear();
231 if (!elem_uncondensed_dofs.empty())
233 auto & var_reduced_space_indices = dof_data.reduced_space_indices[var_num];
234 var_reduced_space_indices.insert(var_reduced_space_indices.end(),
235 elem_uncondensed_dofs.begin(),
236 elem_uncondensed_dofs.end());
237 full_vars_present_in_reduced_sys.insert(var_num);
253 std::unordered_map<processor_id_type, std::vector<dof_id_type>> nonlocal_uncondensed_dofs_mapvec;
254 for (
const auto & [pid, set] : nonlocal_uncondensed_dofs)
256 auto & vec = nonlocal_uncondensed_dofs_mapvec[pid];
257 vec.assign(set.begin(), set.end());
260 nonlocal_uncondensed_dofs.clear();
262 auto receive_needed_local_dofs =
264 const std::vector<dof_id_type> & local_dofs_to_insert) {
265 local_uncondensed_dofs_set.insert(local_dofs_to_insert.begin(), local_dofs_to_insert.end());
269 _mesh.
comm(), nonlocal_uncondensed_dofs_mapvec, receive_needed_local_dofs);
272 local_uncondensed_dofs_set.end());
273 local_uncondensed_dofs_set.clear();
288 std::unordered_map<dof_id_type, dof_id_type> full_dof_to_reduced_dof;
295 this->
_mesh,
false,
true);
318 const std::vector<dof_id_type> & full_dof_ids,
319 std::vector<dof_id_type> & reduced_dof_ids) {
320 reduced_dof_ids.resize(full_dof_ids.size());
322 reduced_dof_ids[i] = libmesh_map_find(full_dof_to_reduced_dof, full_dof_ids[i]);
325 auto action_functor =
327 const std::vector<dof_id_type> & full_dof_ids,
328 const std::vector<dof_id_type> & reduced_dof_ids) {
332 full_dof_to_reduced_dof[full_dof_ids[i]] = reduced_dof_ids[i];
337 nonlocal_uncondensed_dofs_mapvec,
341 nonlocal_uncondensed_dofs_mapvec.clear();
345 _reduced_vars.reserve(full_vars_present_in_reduced_sys.size());
346 unsigned int first_local_number = 0;
347 for (
const auto i :
index_range(full_vars_present_in_reduced_sys))
349 const auto full_var_num = *std::next(full_vars_present_in_reduced_sys.begin(), i);
353 cast_int<unsigned int>(i),
360 std::vector<dof_id_type> var_full_dof_indices;
364 auto & reduced_space_indices = dof_data.reduced_space_indices;
368 reduced_space_indices.erase(
370 reduced_space_indices.begin(),
371 reduced_space_indices.end(),
372 [&full_vars_present_in_reduced_sys, &i](
const std::vector<dof_id_type> &) {
373 return !full_vars_present_in_reduced_sys.count(i++);
375 reduced_space_indices.end());
377 libmesh_assert(reduced_space_indices.size() == full_vars_present_in_reduced_sys.size());
379 for (
auto & var_dof_indices : reduced_space_indices)
381 var_full_dof_indices = var_dof_indices;
382 var_dof_indices.clear();
383 for (
const auto full_dof : var_full_dof_indices)
384 var_dof_indices.push_back(libmesh_map_find(full_dof_to_reduced_dof, full_dof));
389 for (
const auto full_dof : constraint_dofs)
391 libmesh_map_find(full_dof_to_reduced_dof, full_dof);
392 constraint_dofs.clear();
396 for (
auto & elem : nvpg)
405 for (
auto *
const nd :
_mesh.active_node_ptr_range())