14#include "libmesh/dof_map.h"
15#include "libmesh/remote_elem.h"
16#include "libmesh/parallel_ghost_sync.h"
17#include "libmesh/numeric_vector.h"
18#include "libmesh/parameters.h"
20#include <unordered_set>
31 params.
set<
bool>(
"use_displaced_mesh") =
false;
34 params.
addParam<std::vector<BoundaryName>>(
37 "Moving boundaries between subdomains. These boundaries (both sidesets and nodesets) will be "
38 "updated for elements that change subdomain. The subdomains that each moving "
39 "boundary lies between shall be specified using the parameter "
40 "'moving_boundary_subdomain_pairs'. If one boundary and multiple subdomain pairs are "
41 "specified, then it is assumed that the pairs all apply to the boundary. A boundary will be "
42 "created on the mesh if it does not already exist.");
43 params.
addParam<std::vector<std::vector<SubdomainName>>>(
44 "moving_boundary_subdomain_pairs",
46 "The subdomain pairs associated with each moving boundary. For each pair of subdomains, only "
47 "the element side from the first subdomain will be added to the moving boundary, i.e., the "
48 "side normal is pointing from the first subdomain to the second subdomain. The pairs shall "
49 "be delimited by ';'. If a pair only has one subdomain, the moving boundary is associated "
50 "with the subdomain's external boundary, i.e., when the elements have no neighboring "
53 params.
addParam<std::vector<SubdomainName>>(
54 "reinitialize_subdomains",
56 "By default, any element which changes subdomain is reinitialized. If a list of subdomains "
57 "(IDs or names) is provided, then only elements whose new subdomain is in the list will be "
58 "reinitialized. If an empty list is set, then no elements will be reinitialized.");
61 "old_subdomain_reinitialized",
63 "This parameter must be set with a non-empty list in 'reinitialize_subdomains'. When set to "
64 "the default true, the element's old subdomain is not considered when determining if an "
65 "element should be reinitialized. If set to false, only elements whose old subdomain was not "
66 "in 'reinitialize_subdomains' are reinitialized. ");
68 params.
addParam<std::vector<VariableName>>(
69 "reinitialize_variables", {},
"Which variables to reinitialize when subdomain changes.");
70 MooseEnum reinit_strategy(
"IC POLYNOMIAL_NEIGHBOR POLYNOMIAL_WHOLE POLYNOMIAL_NEARBY NONE",
"IC");
71 params.
addParam<std::vector<MooseEnum>>(
72 "reinitialization_strategy",
74 "The strategy used to reinitialize the solution when elements change subdomain. If multiple "
75 "strategies are provided, each strategy will be applied to the corresponding variable. If "
76 "only one strategy is provided, it will be applied to all variables.");
77 params.
addParam<std::vector<UserObjectName>>(
80 "List of NodalPatchRecovery UserObjects used for polynomial fitting during variable "
81 "reinitialization. Required only if 'reinitialization_strategy' includes "
82 "POLYNOMIAL_NEIGHBOR, POLYNOMIAL_WHOLE, or POLYNOMIAL_NEARBY.");
84 "nearby_kd_tree_leaf_max_size",
86 "Maximum number of elements in a leaf node of the K-D tree used to search for nearby "
87 "elements. Only needed if 'reinitialization_strategy' is set to POLYNOMIAL_NEARBY.");
89 "nearby_distance_threshold",
91 "Threshold for considering elements as 'nearby' in the K-D tree search. Only elements within "
92 "this distance will be considered for polynomial fitting.");
94 "restore_overridden_dofs",
96 "A list of boolean flags, one for each variable in 'reinitialize_variables', specifying "
97 "whether overridden DOF values should be restored after reinitialization for each variable. "
98 "This is useful when the solved values on these DOFs should be preserved. If the list is "
99 "empty, overridden DOF values will NOT be restored for any variable by default.");
101 params.
addParam<
bool>(
"skip_restore_subdomain_changes",
103 "Skip restoring the subdomain changes if the timestep is not advanced.");
112 _displaced_problem(_fe_problem.getDisplacedProblem().get()),
113 _displaced_mesh(_displaced_problem ? &_displaced_problem->
mesh() : nullptr),
114 _nl_sys(_fe_problem.getNonlinearSystemBase(systemNumber())),
115 _aux_sys(_fe_problem.getAuxiliarySystem()),
116 _t_step_old(declareRestartableData<
int>(
"t_step_old", 0)),
118 _skip_restore_subdomain_changes(getParam<bool>(
"skip_restore_subdomain_changes")),
119 _old_subdomain_reinitialized(getParam<bool>(
"old_subdomain_reinitialized")),
120 _pr_names(getParam<
std::vector<UserObjectName>>(
"polynomial_fitters")),
121 _reinit_vars(getParam<
std::vector<VariableName>>(
"reinitialize_variables")),
122 _leaf_max_size(getParam<
int>(
"nearby_kd_tree_leaf_max_size")),
123 _nearby_distance_threshold(getParam<double>(
"nearby_distance_threshold"))
130 const std::vector<SubdomainName> subdomain_names_to_reinitialize =
131 getParam<std::vector<SubdomainName>>(
"reinitialize_subdomains");
133 if (std::find(subdomain_names_to_reinitialize.begin(),
134 subdomain_names_to_reinitialize.end(),
135 "ANY_BLOCK_ID") != subdomain_names_to_reinitialize.end())
149 "'old_subdomain_reinitialized' can only be set to false if "
150 "reinitialize_subdomains does "
151 "not cover the whole model, otherwise no elements will be reinitialized as it is "
152 "impossible for an element's old subdomain to not be in the list.");
155 "'old_subdomain_reinitialized' can only be set to false if "
156 "reinitialize_subdomains is set to a non-empty list of subdomains, otherwise no "
157 "elements will be reinitialized, as it is impossible for an element's new subdomain "
158 "to be in the list.");
160 auto bnd_names = getParam<std::vector<BoundaryName>>(
"moving_boundaries");
162 const auto bnd_subdomains =
163 getParam<std::vector<std::vector<SubdomainName>>>(
"moving_boundary_subdomain_pairs");
165 if (bnd_names.size() == 1 && bnd_subdomains.size() > 1)
167 bnd_names.insert(bnd_names.end(), bnd_subdomains.size() - 1, bnd_names[0]);
168 bnd_ids.insert(bnd_ids.end(), bnd_subdomains.size() - 1, bnd_ids[0]);
170 else if (bnd_names.size() != bnd_subdomains.size())
172 "Each moving boundary must correspond to a pair of subdomains. ",
174 " boundaries are specified by the parameter 'moving_boundaries', while ",
175 bnd_subdomains.size(),
176 " subdomain pairs are provided. Alternatively, if one boundary and multiple "
177 "subdomain pairs are provided, then the subdomain pairs all apply to one boundary.");
179 for (
auto i : index_range(bnd_names))
183 if (bnd_subdomains[i].size() == 2)
186 else if (bnd_subdomains[i].size() == 1)
191 "Each subdomain pair must contain 1 or 2 subdomain names, but ",
192 bnd_subdomains[i].size(),
199 paramError(
"reinitialize_variables",
"Variable ", var_name,
" does not exist.");
204 const auto reinit_strategy_in = getParam<std::vector<MooseEnum>>(
"reinitialization_strategy");
205 const auto restore_overridden_dofs_in = getParam<std::vector<bool>>(
"restore_overridden_dofs");
207 if (std::any_of(reinit_strategy_in.begin(),
208 reinit_strategy_in.end(),
209 [](
const MooseEnum & val) {
return val ==
"POLYNOMIAL_NEARBY"; }) &&
211 mooseError(
"The 'nearby_distance_threshold' parameter must be set when using the "
212 "POLYNOMIAL_NEARBY reinitialization strategy.");
214 if (std::all_of(reinit_strategy_in.begin(),
215 reinit_strategy_in.end(),
216 [](
const MooseEnum & val) {
return val !=
"POLYNOMIAL_NEARBY"; }) &&
219 mooseWarning(
"The 'nearby_distance_threshold' and 'nearby_kd_tree_leaf_max_size' parameters "
220 "will be ignored because no 'reinitialization_strategy' is set to "
221 "POLYNOMIAL_NEARBY.");
223 if (reinit_strategy_in.size() == 1)
225 else if (reinit_strategy_in.size() ==
_reinit_vars.size())
226 for (
const auto & e : reinit_strategy_in)
230 "reinitialization_strategy",
231 "The 'reinitialization_strategy' parameter must have either a single value or a number "
232 "of values equal to the number of 'reinitialize_variables'. "
234 reinit_strategy_in.size(),
239 if (restore_overridden_dofs_in.size() == 1)
241 if (restore_overridden_dofs_in[0])
245 else if (restore_overridden_dofs_in.size() ==
_reinit_vars.size())
248 if (restore_overridden_dofs_in[i])
253 if (!restore_overridden_dofs_in.empty())
255 "restore_overridden_dofs",
256 "The 'restore_overridden_dofs' parameter must have either a single value or a number "
257 "of values equal to the number of 'reinitialize_variables'. "
259 restore_overridden_dofs_in.size(),
260 " restore_overridden_dofs for ",
275 std::size_t pr_count = 0;
284 "The number of polynomial fitters (",
286 ") is less than the number of variables to reinitialize with polynomial "
291 "The patch recovery UserObject's variable name must match the variable being "
292 "reinitialized in ElementSubdomainModifierBase.");
298 "Mismatch between number of reinitialization strategies using polynomial "
299 "extrapolation and polynomial fitters (expected: ",
315 for (
auto & [elem_id, subdomain] : moved_elem_reversed)
316 std::swap(subdomain.first, subdomain.second);
319 modify(moved_elem_reversed);
328 const std::unordered_map<dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems)
336 auto n_moved_elem = moved_elems.size();
338 if (n_moved_elem == 0)
377 false,
false,
false);
391 auto & bnd_info =
mesh.getMesh().get_boundary_info();
394 bnd_info.sideset_name(bnd_id) = bnd_name;
395 bnd_info.nodeset_name(bnd_id) = bnd_name;
401 const std::unordered_map<dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems,
404 for (
const auto & [elem_id, subdomain] : moved_elems)
407 auto elem =
mesh.elemPtr(elem_id);
408 const auto & [from, to] = subdomain;
409 mooseAssert(elem->subdomain_id() == from,
"Inconsistent element subdomain ID.");
410 elem->subdomain_id() = to;
418 Parallel::sync_dofobject_data_by_id(
419 mesh.getMesh().comm(),
mesh.getMesh().elements_begin(),
mesh.getMesh().elements_end(), sync);
425 auto curr_elem = elem;
427 for (
unsigned int i = curr_elem->level(); i > 0; --i)
430 curr_elem = curr_elem->parent();
431 curr_elem->subdomain_id() = subdomain_id;
437 const std::unordered_map<dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems)
445 const auto & sidesets =
_mesh.
getMesh().get_boundary_info().get_sideset_map();
447 for (
const auto & [elem_id, subdomain_assignment] : moved_elems)
452 for (
auto itr = sidesets.lower_bound(elem); itr != sidesets.upper_bound(elem); itr++)
456 for (
auto side : elem->side_index_range())
458 auto neigh = elem->neighbor_ptr(side);
469 auto neigh_side = neigh->which_neighbor_am_i(elem);
476 std::vector<const Elem *> active_neighs;
478 mooseAssert(!neigh->subactive(),
479 "The case where the active neighbor is an ancestor of this neighbor is not "
480 "handled at this time.");
481 neigh->active_family_tree_by_neighbor(active_neighs, elem);
483 for (
auto active_neigh : active_neighs)
495 unsigned short neigh_side)
497 const auto & sidesets =
_mesh.
getMesh().get_boundary_info().get_sideset_map();
508 for (
auto itr = sidesets.lower_bound(neigh); itr != sidesets.upper_bound(neigh); itr++)
513 subdomain_pair = {subdomain_pair.second, subdomain_pair.first};
522 auto & bnd_info =
mesh.getMesh().get_boundary_info();
525 auto nodesets = bnd_info.get_nodeset_map();
526 for (
const auto & [node_id, bnd] : nodesets)
528 bnd_info.remove_node(node_id, bnd);
531 std::unordered_map<processor_id_type,
532 std::vector<std::tuple<dof_id_type, unsigned short, BoundaryID>>>
533 add_ghost_sides, remove_ghost_sides;
537 for (
const auto & [side, bnd] :
sides)
538 bnd_info.remove_side(
mesh.elemPtr(elem_id), side, bnd);
543 auto elem =
mesh.elemPtr(elem_id);
544 for (
const auto & [side, bnd] :
sides)
546 bnd_info.remove_side(elem, side, bnd);
549 remove_ghost_sides[elem->processor_id()].push_back({elem_id, side, bnd});
553 Parallel::push_parallel_vector_data(
557 &bnd_info](processor_id_type,
558 const std::vector<std::tuple<dof_id_type, unsigned short, BoundaryID>> & received)
560 for (const auto & [elem_id, side, bnd] : received)
561 bnd_info.remove_side(mesh.elemPtr(elem_id), side, bnd);
566 for (
const auto & [side, bnd] :
sides)
567 bnd_info.add_side(
mesh.elemPtr(elem_id), side, bnd);
572 auto elem =
mesh.elemPtr(elem_id);
573 for (
const auto & [side, bnd] :
sides)
575 bnd_info.add_side(elem, side, bnd);
578 add_ghost_sides[elem->processor_id()].push_back({elem_id, side, bnd});
582 Parallel::push_parallel_vector_data(
586 &bnd_info](processor_id_type,
587 const std::vector<std::tuple<dof_id_type, unsigned short, BoundaryID>> & received)
589 for (const auto & [elem_id, side, bnd] : received)
590 bnd_info.add_side(mesh.elemPtr(elem_id), side, bnd);
593 bnd_info.parallel_sync_side_ids();
594 bnd_info.parallel_sync_node_ids();
602 switch (reinit_strategy)
624 mooseError(
"Unknown reinitialization strategy");
645 auto & bnd_info =
mesh.getMesh().get_boundary_info();
646 auto sidesets = bnd_info.get_sideset_map();
647 for (
const auto & i : sidesets)
650 auto side = i.second.first;
651 auto bnd = i.second.second;
654 bnd_info.remove_side(elem, side, bnd);
656 std::vector<const Elem *> elem_family;
657 elem->active_family_tree_by_side(elem_family, side);
658 for (
auto felem : elem_family)
659 bnd_info.add_side(felem, side, bnd);
663 bnd_info.parallel_sync_side_ids();
664 bnd_info.parallel_sync_node_ids();
669 const std::unordered_map<dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems)
680 std::unordered_map<processor_id_type, std::unordered_set<dof_id_type>> push_data_set;
681 std::unordered_map<processor_id_type, std::vector<dof_id_type>> push_data;
683 for (
const auto & [elem_id, subdomain] : moved_elems)
685 mooseAssert(
_mesh.
elemPtr(elem_id)->active(),
"Moved elements should be active");
693 const auto & [from, to] = subdomain;
710 for (
const auto & node : elem->node_ref_range())
712 if (neigh_id != elem_id)
716 push_data_set[neigh_elem->processor_id()].insert(elem_id);
719 for (
unsigned int i = 0; i < elem->n_nodes(); ++i)
724 for (
auto & [pid, s] : push_data_set)
725 push_data[pid] = {s.begin(), s.end()};
730 [
this](
const processor_id_type,
const std::vector<dof_id_type> & received_data)
732 for (
const auto &
id : received_data)
736 Parallel::push_parallel_vector_data(
_mesh.
comm(), push_data, push_receiver);
776 std::set<VariableName> ic_vars;
780 if (!ic_vars.empty())
793 "This code was written for a single nonlinear system");
811 const auto & dof_map = sys.get_dof_map();
813 const auto var_num = var.
number();
819 std::set<dof_id_type> reinitialized_dofs;
823 std::vector<dof_id_type> elem_dofs;
824 dof_map.dof_indices(elem, elem_dofs, var_num);
825 reinitialized_dofs.insert(elem_dofs.begin(), elem_dofs.end());
829 std::set<dof_id_type> existing_dofs;
834 std::vector<dof_id_type> elem_dofs;
835 dof_map.dof_indices(elem, elem_dofs, var_num);
836 existing_dofs.insert(elem_dofs.begin(), elem_dofs.end());
840 std::vector<dof_id_type> overridden_dofs;
841 std::set_intersection(reinitialized_dofs.begin(),
842 reinitialized_dofs.end(),
843 existing_dofs.begin(),
845 std::back_inserter(overridden_dofs));
848 std::vector<Number>
values;
849 for (
auto dof : overridden_dofs)
850 values.push_back(current_solution(dof));
861 const auto & dof_map = sys.dofMap();
864 std::unordered_map<processor_id_type, std::vector<std::pair<dof_id_type, Number>>> push_data;
866 for (
const int i : index_range(dof_ids))
871 push_data[dof_map.dof_owner(dof_ids[i])].emplace_back(dof_ids[i],
values[i]);
874 auto push_receiver = [&](
const processor_id_type,
875 const std::vector<std::pair<dof_id_type, Number>> & received_data)
877 for (
const auto & [
id, value] : received_data)
881 Parallel::push_parallel_vector_data(
_mesh.
comm(), push_data, push_receiver);
884 sol.localize(*sys.system().current_local_solution, sys.dofMap().get_send_list());
900 std::vector<Elem *> elems;
905 Elem *
const * elem_itr_begin =
const_cast<Elem *
const *
>(elems.data());
906 Elem *
const * elem_itr_end = elem_itr_begin + elems.size();
908 const auto elems_begin = MeshBase::const_element_iterator(
910 const auto elems_end = MeshBase::const_element_iterator(
925 std::vector<const BndNode *> nodes;
927 for (
auto bnd_node : *bnd_nodes)
930 nodes.push_back(bnd_node);
932 BndNode *
const * bnd_node_itr_begin =
const_cast<BndNode *
const *
>(nodes.data());
933 BndNode *
const * bnd_node_itr_end = bnd_node_itr_begin + nodes.size();
941 std::make_unique<ConstBndNodeRange>(bnd_nodes_begin, bnd_nodes_end);
953 std::vector<const Node *> nodes;
958 Node *
const * node_itr_begin =
const_cast<Node *
const *
>(nodes.data());
959 Node *
const * node_itr_end = node_itr_begin + nodes.size();
961 const auto nodes_begin = MeshBase::const_node_iterator(
963 const auto nodes_end = MeshBase::const_node_iterator(
973 ConstElemRange & elem_range,
976 for (
auto bnd : bnd_node_range)
978 const Node * bnode = bnd->_node;
988 NumericVector<Number> & old_solution = sys.
solutionOld();
992 DofMap & dof_map = sys.
dofMap();
993 std::vector<dof_id_type> dofs;
995 for (
auto & elem : elem_range)
997 std::vector<dof_id_type> elem_dofs;
999 dofs.insert(dofs.end(), elem_dofs.begin(), elem_dofs.end());
1002 for (
auto & bnd_node : bnd_node_range)
1004 std::vector<dof_id_type> bnd_node_dofs;
1005 dof_map.dof_indices(bnd_node->_node, bnd_node_dofs);
1006 dofs.insert(dofs.end(), bnd_node_dofs.begin(), bnd_node_dofs.end());
1010 for (
auto dof : dofs)
1012 old_solution.set(dof, current_solution(dof));
1014 older_solution->set(dof, current_solution(dof));
1017 old_solution.close();
1019 older_solution->close();
1034 auto & [candidate_elems, candidate_elem_ids] =
_evaluable_elems[sys.number()];
1036 std::vector<dof_id_type> elem_dofs;
1044 dof_map.dof_indices(elem, elem_dofs, vn);
1045 if (!elem_dofs.empty())
1047 candidate_elems.insert(elem);
1048 candidate_elem_ids.push_back(elem->id());
1052 auto & [candidate_elems, candidate_elem_ids] =
_evaluable_elems[sys.number()];
1057 switch (reinit_strategy)
1061 auto has_neighbor_in_reinit_elems = [&](
const Elem * elem) ->
bool
1063 for (
const auto & node : elem->node_ref_range())
1072 for (
const auto * elem : candidate_elems)
1073 if (has_neighbor_in_reinit_elems(elem))
1074 patch_elems.push_back(elem->id());
1080 patch_elems = candidate_elem_ids;
1085 std::vector<Point> kd_points;
1086 std::vector<dof_id_type> global_candidate_elem_ids;
1090 std::vector<std::pair<Point, dof_id_type>> pts_ids(candidate_elem_ids.size());
1091 for (std::size_t i = 0; i < candidate_elem_ids.size(); ++i)
1092 pts_ids[i] = {
_mesh.
elemPtr(candidate_elem_ids[i])->vertex_average(),
1093 candidate_elem_ids[i]};
1095 for (
const auto & [pt,
id] : pts_ids)
1097 kd_points.push_back(pt);
1098 global_candidate_elem_ids.push_back(
id);
1104 global_candidate_elem_ids = candidate_elem_ids;
1105 for (
const auto &
id : candidate_elem_ids)
1106 kd_points.push_back(
_mesh.
elemPtr(
id)->vertex_average());
1109 const auto kd_tree = std::make_unique<KDTree>(kd_points,
_leaf_max_size);
1111 std::vector<nanoflann::ResultItem<std::size_t, Real>> query_result;
1114 const Point & centroid =
_mesh.
elemPtr(elem_id)->vertex_average();
1116 for (
const auto & [qid, dist] : query_result)
1117 patch_elems.push_back(global_candidate_elem_ids[qid]);
1125 mooseError(
"Unknown reinitialization strategy");
1134 std::sort(patch_elems.begin(), patch_elems.end());
1135 patch_elems.erase(std::unique(patch_elems.begin(), patch_elems.end()), patch_elems.end());
1150 function_parameters.
set<std::vector<std::vector<unsigned int>>>(
"multi_index") = multi_index;
1152 std::vector<Real> coef_vec(coef.size());
1153 for (
auto i = 0; i < coef.size(); ++i)
1154 coef_vec[i] = coef(i);
1156 function_parameters.
set<std::vector<Real>>(
"multi_index_coefficients") = coef_vec;
1157 function_parameters.
set<
unsigned int>(
"dimension_for_projection") =
dim;
1160 auto poly_func = [](
const Point & p,
1162 const std::string &,
1165 const auto & multi_index =
1166 parameters.
get<std::vector<std::vector<unsigned int>>>(
"multi_index");
1167 const auto & coeffs =
parameters.
get<std::vector<Real>>(
"multi_index_coefficients");
1171 for (
unsigned int r = 0; r < multi_index.size(); r++)
1173 Real monomial = 1.0;
1174 for (
unsigned int d = 0; d < multi_index[r].size(); d++)
1176 const auto power = multi_index[r][d];
1182 val += coeffs[r] * monomial;
1189 auto poly_func_grad = [](
const Point & p,
1191 const std::string &,
1194 const unsigned int dim =
parameters.
get<
unsigned int>(
"dimension_for_projection");
1196 const auto & multi_index =
1197 parameters.
get<std::vector<std::vector<unsigned int>>>(
"multi_index");
1198 const auto & coeffs =
parameters.
get<std::vector<Real>>(
"multi_index_coefficients");
1202 for (
unsigned int r = 0; r < multi_index.size(); ++r)
1204 const auto & powers = multi_index[r];
1205 const Real coef = coeffs[r];
1207 for (
unsigned int d = 0; d <
dim; ++d)
1209 const auto power_d = powers[d];
1214 Real partial = coef * power_d;
1216 for (
unsigned int i = 0; i < powers.size(); ++i)
1221 partial *=
std::pow(p(i), powers[i] - 1);
1226 partial *=
std::pow(p(i), powers[i]);
1237 std::vector<VariableName> var_names = {var_name};
ReinitStrategy
Strategies for (re)initializing the solution:
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
std::array< Real, 2 > values
void ErrorVector unsigned int
std::map< VariableName, std::vector< dof_id_type > > _patch_elem_ids
A map from variable names to their corresponding patch element IDs.
void applySubdomainChanges(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID > > &moved_elems, MooseMesh &mesh)
std::map< VariableName, std::pair< std::vector< dof_id_type >, std::vector< Number > > > _overridden_values_on_reinit_elems
A map from variable name to a pair of: (1) a vector of DOF IDs associated with non-reinitialized node...
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _add_neighbor_sides
Neighbor sides to be added.
std::unordered_map< BoundaryID, BoundaryName > _moving_boundary_names
Boundary names associated with each moving boundary ID.
void restoreOverriddenDofValues(const VariableName &var_name)
Restore values to non-reinitialized DoFs on reinitialized elements.
std::unordered_set< dof_id_type > _semi_local_reinitialized_elems
Semi-local reinitialized elements: ghosted and local reinitialized elements.
std::vector< VariableName > _vars_to_restore_overridden_dofs
List of variable names for which overridden DOF values should be restored.
void timestepSetup() override
Gets called at the beginning of the timestep before this object is asked to do its job.
void createMovingBoundaries(MooseMesh &mesh)
Create moving boundaries.
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _add_element_sides
Element sides to be added.
void findReinitializedElemsAndNodes(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID > > &moved_elems)
void meshChanged() override
Called on this object when the mesh changes.
NonlinearSystemBase & _nl_sys
Nonlinear system.
std::map< VariableName, unsigned int > _var_name_to_pr_idx
map from variable name to the index of the nodal patch recovery user object in _pr
virtual void modify(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID > > &moved_elems)
Modify the element subdomains.
std::unique_ptr< ConstBndNodeRange > _reinitialized_bnd_node_range
Range of reinitialized boundary nodes.
const std::vector< UserObjectName > _pr_names
Names of the NodalPatchRecoveryVariable user objects.
void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
void gatherMovingBoundaryChanges(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID > > &moved_elems)
void applyIC()
Reinitialize variables on range of elements and nodes to be reinitialized.
bool nodeIsNewlyReinitialized(dof_id_type node_id) const
Determine if a node is newly reinitialized.
void storeOverriddenDofValues(const VariableName &var_name)
Store values from non-reinitialized DoFs on reinitialized elements Stores the value before re-initial...
std::unordered_map< SubdomainPair, BoundaryID > _moving_boundaries
std::unique_ptr< ConstElemRange > _reinitialized_elem_range
Range of reinitialized elements.
static InputParameters validParams()
MooseMesh * _displaced_mesh
Displaced mesh.
double _nearby_distance_threshold
Radius threshold for the k-d tree neighbor search.
bool _skip_restore_subdomain_changes
Skipping restoring the subdomain changes if the timestep is not advanced.
std::vector< SubdomainID > _subdomain_ids_to_reinitialize
Reinitialize moved elements whose new subdomain is in this list.
int & _t_step_old
Previous time step number.
std::vector< VariableName > _reinit_vars
List of variable names to be initialized for IC.
void extrapolatePolynomial(const VariableName &var_name)
Extrapolate polynomial for the given variable onto the reinitialized elements.
AuxiliarySystem & _aux_sys
Auxiliary system.
bool _restep
Whether this is a re-step.
std::vector< ReinitStrategy > _reinit_strategy
The strategies used to apply IC on newly activated elements, for each variable.
std::unordered_set< dof_id_type > _reinitialized_nodes
Reinitialized nodes.
const bool _old_subdomain_reinitialized
Whether to reinitialize moved elements whose old subdomain was in _reinitialize_subdomains.
std::map< unsigned int, std::pair< std::unordered_set< const Elem * >, std::vector< dof_id_type > > > _evaluable_elems
local evaluable elements before reinitializing the equation systems Key of the map is the system numb...
void applyMovingBoundaryChanges(MooseMesh &mesh)
ConstBndNodeRange & reinitializedBndNodeRange()
Range of reinitialized boundary nodes.
std::unique_ptr< ConstNodeRange > _reinitialized_node_range
Range of reinitialized nodes.
bool subdomainIsReinitialized(SubdomainID id) const
Determine if a subdomain is to be reinitialized.
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _remove_element_sides
Element sides to be removed.
ConstElemRange & reinitializedElemRange()
Range of reinitialized elements.
void initElementStatefulProps()
Reinitialize stateful material properties on range of elements and nodes to be reinitialized.
std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID > > _moved_elems
Cached moved elements for potential restore.
std::unordered_set< dof_id_type > _reinitialized_elems
Reinitialized elements.
void setOldAndOlderSolutions(SystemBase &sys, ConstElemRange &elem_range, ConstBndNodeRange &bnd_node_range)
Set old and older solutions to reinitialized elements and nodes.
void setAncestorsSubdomainIDs(Elem *elem, const SubdomainID subdomain_id)
Change the subdomain ID of all ancestor elements.
std::vector< NodalPatchRecoveryVariable * > _pr
Apply initial conditions using polynomial extrapolation.
std::pair< SubdomainID, SubdomainID > SubdomainPair
Moving boundaries associated with each subdomain pair.
ElementSubdomainModifierBase(const InputParameters ¶meters)
void gatherPatchElements(const VariableName &var_name, ReinitStrategy reinit_strategy)
Gather patch elements for reinitialized elements based on the reinitialization strategy.
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _remove_neighbor_sides
Neighbor sides to be removed.
ConstNodeRange & reinitializedNodeRange()
Range of reinitialized nodes.
void updateAMRMovingBoundary(MooseMesh &mesh)
Update boundaries for adaptive mesh from the parent to children elements.
int _leaf_max_size
KD-tree related members.
void gatherMovingBoundaryChangesHelper(const Elem *elem, unsigned short side, const Elem *neigh, unsigned short neigh_side)
void prepareVariableForReinitialization(const VariableName &var_name, ReinitStrategy reinit_strategy)
static InputParameters validParams()
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
virtual MooseVariable & getStandardVariable(const THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested MooseVariable which may be in any system.
void projectInitialConditionOnCustomRange(libMesh::ConstElemRange &elem_range, ConstBndNodeRange &bnd_node_range, const std::optional< std::set< VariableName > > &target_vars=std::nullopt)
Project initial conditions for custom elem_range and bnd_node_range This is needed when elements/boun...
AuxiliarySystem & getAuxiliarySystem()
virtual std::size_t numSolverSystems() const override
unsigned int systemNumForVariable(const VariableName &variable_name) const
void initElementStatefulProps(const libMesh::ConstElemRange &elem_range, const bool threaded)
Initialize stateful properties for elements in a specific elem_range This is needed when elements/bou...
const MaterialWarehouse & getMaterialWarehouse() const
void projectFunctionOnCustomRange(ConstElemRange &elem_range, Number(*func)(const Point &, const libMesh::Parameters &, const std::string &, const std::string &), Gradient(*func_grad)(const Point &, const libMesh::Parameters &, const std::string &, const std::string &), const libMesh::Parameters ¶ms, const std::vector< VariableName > &target_vars)
Project a function onto a range of elements for a given variable.
virtual std::vector< VariableName > getVariableNames()
Returns a list of all the variables in the problem (both from the NL and Aux systems.
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
virtual const SystemBase & getSystemBase(const unsigned int sys_num) const
Get constant reference to a system in this problem.
virtual void meshChanged(bool intermediate_change, bool contract_mesh, bool clean_refinement_flags)
Update data after a mesh change.
virtual libMesh::System & getSystem(const std::string &var_name) override
Returns the equation system containing the variable provided.
const InputParameters & parameters() const
Get the parameters of the object.
const std::string & name() const
Get the name of the class.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
virtual Elem * elemPtr(const dof_id_type i)
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
virtual bool isDistributedMesh() const
Returns the final Mesh distribution type.
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.
const std::unordered_map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected.
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side.
virtual const Node * nodePtr(const dof_id_type i) const
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
const libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems,...
bool hasActiveObjects(THREAD_ID tid=0) const
unsigned int number() const
Get variable number coming from libMesh.
Patch recovery from a coupled variable.
Base class for a system (of equations)
unsigned int number() const
Gets the number of this system.
NumericVector< Number > & solutionOld()
virtual bool hasVariable(const std::string &var_name) const
Query a system for a variable.
NumericVector< Number > & solutionOlder()
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
virtual bool hasSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time) const
Whether or not the system has the solution state (0 = current, 1 = old, 2 = older,...
NumericVector< Number > & solution()
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
int & _t_step
The number of the time step.
void gatherSum(T &value)
Gather the parallel sum of the variable passed in.
std::set< std::string > _depend_uo
Depend UserObjects that to be used both for determining user object sorting and by AuxKernel for find...
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
SystemBase & _sys
Reference to the system object for this user object.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
unsigned int variable_number(std::string_view var) const
virtual void set(const numeric_index_type i, const T value)=0
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
T & set(const std::string &)
std::unique_ptr< NumericVector< Number > > current_local_solution
const DofMap & get_dof_map() const
const SubdomainID ANY_BLOCK_ID
const SubdomainID INVALID_BLOCK_ID
const RemoteElem * remote_elem
MooseUnits pow(const MooseUnits &, int)
The definition of the const_bnd_node_iterator struct.