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.");
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);
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(
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(
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()};
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;
869 sol.set(dof_ids[i], values[i]);
871 push_data[dof_map.dof_owner(dof_ids[i])].emplace_back(dof_ids[i], values[i]);
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(
976 for (
auto bnd : bnd_node_range)
978 const Node * bnode = bnd->_node;
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()];
1035 const auto & dof_map = sys.get_dof_map();
1036 std::vector<dof_id_type> elem_dofs;
1037 auto vn = sys.variable_number(static_cast<std::string>(var_name));
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};
ConstNodeRange & reinitializedNodeRange()
Range of reinitialized nodes.
const std::vector< UserObjectName > _pr_names
Names of the NodalPatchRecoveryVariable user objects.
virtual void meshChanged(bool intermediate_change, bool contract_mesh, bool clean_refinement_flags)
Update data after a mesh change.
bool _restep
Whether this is a re-step.
int & _t_step_old
Previous time step number.
void gatherSum(T &value)
Gather the parallel sum of the variable passed in.
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems...
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
virtual libMesh::System & getSystem(const std::string &var_name) override
Returns the equation system containing the variable provided.
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
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 ...
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.
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 ...
NonlinearSystemBase & _nl_sys
Nonlinear system.
virtual Elem * elemPtr(const dof_id_type i)
void prepareVariableForReinitialization(const VariableName &var_name, ReinitStrategy reinit_strategy)
NumericVector< Number > & solution()
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
unsigned int number() const
Get variable number coming from libMesh.
static InputParameters validParams()
std::unordered_set< dof_id_type > _reinitialized_elems
Reinitialized elements.
void swap(std::vector< T > &data, const std::size_t idx0, const std::size_t idx1, const libMesh::Parallel::Communicator &comm)
Swap function for serial or distributed vector of data.
std::pair< SubdomainID, SubdomainID > SubdomainPair
Moving boundaries associated with each subdomain pair.
std::vector< VariableName > _vars_to_restore_overridden_dofs
List of variable names for which overridden DOF values should be restored.
void initElementStatefulProps()
Reinitialize stateful material properties on range of elements and nodes to be reinitialized.
void gatherPatchElements(const VariableName &var_name, ReinitStrategy reinit_strategy)
Gather patch elements for reinitialized elements based on the reinitialization strategy.
const InputParameters & parameters() const
Get the parameters of the object.
std::unordered_map< BoundaryID, BoundaryName > _moving_boundary_names
Boundary names associated with each moving boundary ID.
std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID > > _moved_elems
Cached moved elements for potential restore.
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
void gatherMovingBoundaryChanges(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID >> &moved_elems)
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
const Parallel::Communicator & comm() const
The definition of the const_bnd_node_iterator struct.
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...
std::vector< VariableName > _reinit_vars
List of variable names to be initialized for IC.
NumericVector< Number > & solutionOlder()
std::set< std::string > _depend_uo
Depend UserObjects that to be used both for determining user object sorting and by AuxKernel for find...
const MaterialWarehouse & getMaterialWarehouse() 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...
Base class for a system (of equations)
void gatherMovingBoundaryChangesHelper(const Elem *elem, unsigned short side, const Elem *neigh, unsigned short neigh_side)
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job...
bool _skip_restore_subdomain_changes
Skipping restoring the subdomain changes if the timestep is not advanced.
StoredRange< MeshBase::const_element_iterator, const Elem *> ConstElemRange
void updateAMRMovingBoundary(MooseMesh &mesh)
Update boundaries for adaptive mesh from the parent to children elements.
const SubdomainID INVALID_BLOCK_ID
virtual void modify(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID >> &moved_elems)
Modify the element subdomains.
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
uint8_t processor_id_type
void mooseWarning(Args &&... args) const
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
void createMovingBoundaries(MooseMesh &mesh)
Create moving boundaries.
virtual std::vector< VariableName > getVariableNames()
Returns a list of all the variables in the problem (both from the NL and Aux systems.
const std::string & name() const
Get the name of the class.
void storeOverriddenDofValues(const VariableName &var_name)
Store values from non-reinitialized DoFs on reinitialized elements Stores the value before re-initial...
int & _t_step
The number of the time step.
ReinitStrategy
Strategies for (re)initializing the solution:
static InputParameters validParams()
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
ConstElemRange & reinitializedElemRange()
Range of reinitialized elements.
std::unordered_set< dof_id_type > _semi_local_reinitialized_elems
Semi-local reinitialized elements: ghosted and local reinitialized elements.
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
void meshChanged() override
Called on this object when the mesh changes.
void setAncestorsSubdomainIDs(Elem *elem, const SubdomainID subdomain_id)
Change the subdomain ID of all ancestor elements.
void applySubdomainChanges(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID >> &moved_elems, MooseMesh &mesh)
std::unordered_set< dof_id_type > _reinitialized_nodes
Reinitialized nodes.
virtual const Node * nodePtr(const dof_id_type i) const
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
bool subdomainIsReinitialized(SubdomainID id) const
Determine if a subdomain is to be reinitialized.
int _leaf_max_size
KD-tree related members.
std::vector< SubdomainID > _subdomain_ids_to_reinitialize
Reinitialize moved elements whose new subdomain is in this list.
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
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, etc).
unsigned int number() const
Gets the number of this system.
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...
AuxiliarySystem & getAuxiliarySystem()
unsigned int systemNumForVariable(const VariableName &variable_name) const
virtual bool hasVariable(const std::string &var_name) const
Query a system for a variable.
std::vector< NodalPatchRecoveryVariable * > _pr
Apply initial conditions using polynomial extrapolation.
AuxiliarySystem & _aux_sys
Auxiliary system.
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.
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _add_element_sides
Element sides to be added.
void restoreOverriddenDofValues(const VariableName &var_name)
Restore values to non-reinitialized DoFs on reinitialized elements.
SystemBase & _sys
Reference to the system object for this user object.
virtual const SystemBase & getSystemBase(const unsigned int sys_num) const
Get constant reference to a system in this problem.
const SubdomainID ANY_BLOCK_ID
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _remove_element_sides
Element sides to be removed.
bool hasActiveObjects(THREAD_ID tid=0) const
void applyMovingBoundaryChanges(MooseMesh &mesh)
bool nodeIsNewlyReinitialized(dof_id_type node_id) const
Determine if a node is newly reinitialized.
T & set(const std::string &)
std::unique_ptr< ConstBndNodeRange > _reinitialized_bnd_node_range
Range of reinitialized boundary nodes.
std::map< VariableName, std::vector< dof_id_type > > _patch_elem_ids
A map from variable names to their corresponding patch element IDs.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
MooseMesh * _displaced_mesh
Displaced mesh.
std::vector< ReinitStrategy > _reinit_strategy
The strategies used to apply IC on newly activated elements, for each variable.
void applyIC()
Reinitialize variables on range of elements and nodes to be reinitialized.
std::unique_ptr< NumericVector< Number > > current_local_solution
std::unique_ptr< ConstElemRange > _reinitialized_elem_range
Range of reinitialized elements.
virtual void set(const numeric_index_type i, const Number value)=0
void setOldAndOlderSolutions(SystemBase &sys, ConstElemRange &elem_range, ConstBndNodeRange &bnd_node_range)
Set old and older solutions to reinitialized elements and nodes.
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. ...
Patch recovery from a coupled variable.
void findReinitializedElemsAndNodes(const std::unordered_map< dof_id_type, std::pair< SubdomainID, SubdomainID >> &moved_elems)
NumericVector< Number > & solutionOld()
processor_id_type processor_id() const
virtual bool isDistributedMesh() const
Returns the final Mesh distribution type.
virtual std::size_t numSolverSystems() const override
void timestepSetup() override
Gets called at the beginning of the timestep before this object is asked to do its job...
std::unique_ptr< ConstNodeRange > _reinitialized_node_range
Range of reinitialized nodes.
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.
MooseUnits pow(const MooseUnits &, int)
std::unordered_map< SubdomainPair, BoundaryID > _moving_boundaries
ConstBndNodeRange & reinitializedBndNodeRange()
Range of reinitialized boundary nodes.
double _nearby_distance_threshold
Radius threshold for the k-d tree neighbor search.
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
void ErrorVector unsigned int
auto index_range(const T &sizable)
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _remove_neighbor_sides
Neighbor sides to be removed.
const Elem & get(const ElemType type_in)
std::unordered_map< dof_id_type, std::unordered_map< unsigned short, BoundaryID > > _add_neighbor_sides
Neighbor sides to be added.
ElementSubdomainModifierBase(const InputParameters ¶meters)
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...
const bool _old_subdomain_reinitialized
Whether to reinitialize moved elements whose old subdomain was in _reinitialize_subdomains.
const std::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...
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.
void extrapolatePolynomial(const VariableName &var_name)
Extrapolate polynomial for the given variable onto the reinitialized elements.
const RemoteElem * remote_elem