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",
"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 (reinit_strategy_in.size() == 1)
216 else if (reinit_strategy_in.size() ==
_reinit_vars.size())
217 for (
const auto & e : reinit_strategy_in)
221 "reinitialization_strategy",
222 "The 'reinitialization_strategy' parameter must have either a single value or a number " 223 "of values equal to the number of 'reinitialize_variables'. " 225 reinit_strategy_in.size(),
230 if (restore_overridden_dofs_in.size() == 1)
232 if (restore_overridden_dofs_in[0])
236 else if (restore_overridden_dofs_in.size() ==
_reinit_vars.size())
239 if (restore_overridden_dofs_in[i])
244 if (!restore_overridden_dofs_in.empty())
246 "restore_overridden_dofs",
247 "The 'restore_overridden_dofs' parameter must have either a single value or a number " 248 "of values equal to the number of 'reinitialize_variables'. " 250 restore_overridden_dofs_in.size(),
251 " restore_overridden_dofs for ",
266 std::size_t pr_count = 0;
275 "The number of polynomial fitters (",
277 ") is less than the number of variables to reinitialize with polynomial " 282 "The patch recovery UserObject's variable name must match the variable being " 283 "reinitialized in ElementSubdomainModifierBase.");
289 "Mismatch between number of reinitialization strategies using polynomial " 290 "extrapolation and polynomial fitters (expected: ",
306 for (
auto & [elem_id, subdomain] : moved_elem_reversed)
307 std::swap(subdomain.first, subdomain.second);
310 modify(moved_elem_reversed);
319 const std::unordered_map<
dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems)
327 auto n_moved_elem = moved_elems.size();
329 if (n_moved_elem == 0)
368 false,
false,
false);
382 auto & bnd_info =
mesh.getMesh().get_boundary_info();
385 bnd_info.sideset_name(bnd_id) = bnd_name;
386 bnd_info.nodeset_name(bnd_id) = bnd_name;
392 const std::unordered_map<
dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems,
395 for (
const auto & [elem_id, subdomain] : moved_elems)
398 auto elem =
mesh.elemPtr(elem_id);
399 const auto & [from, to] = subdomain;
400 mooseAssert(elem->subdomain_id() == from,
"Inconsistent element subdomain ID.");
401 elem->subdomain_id() = to;
409 Parallel::sync_dofobject_data_by_id(
410 mesh.getMesh().comm(),
mesh.getMesh().elements_begin(),
mesh.getMesh().elements_end(), sync);
416 auto curr_elem = elem;
418 for (
unsigned int i = curr_elem->level(); i > 0; --i)
421 curr_elem = curr_elem->parent();
422 curr_elem->subdomain_id() = subdomain_id;
428 const std::unordered_map<
dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems)
436 const auto & sidesets =
_mesh.
getMesh().get_boundary_info().get_sideset_map();
438 for (
const auto & [elem_id, subdomain_assignment] : moved_elems)
443 for (
auto itr = sidesets.lower_bound(elem); itr != sidesets.upper_bound(elem); itr++)
447 for (
auto side : elem->side_index_range())
449 auto neigh = elem->neighbor_ptr(side);
460 auto neigh_side = neigh->which_neighbor_am_i(elem);
467 std::vector<const Elem *> active_neighs;
469 mooseAssert(!neigh->subactive(),
470 "The case where the active neighbor is an ancestor of this neighbor is not " 471 "handled at this time.");
472 neigh->active_family_tree_by_neighbor(active_neighs, elem);
474 for (
auto active_neigh : active_neighs)
486 unsigned short neigh_side)
488 const auto & sidesets =
_mesh.
getMesh().get_boundary_info().get_sideset_map();
499 for (
auto itr = sidesets.lower_bound(neigh); itr != sidesets.upper_bound(neigh); itr++)
504 subdomain_pair = {subdomain_pair.second, subdomain_pair.first};
513 auto & bnd_info =
mesh.getMesh().get_boundary_info();
516 auto nodesets = bnd_info.get_nodeset_map();
517 for (
const auto & [node_id, bnd] : nodesets)
519 bnd_info.remove_node(node_id, bnd);
523 std::vector<std::tuple<dof_id_type, unsigned short, BoundaryID>>>
524 add_ghost_sides, remove_ghost_sides;
528 for (
const auto & [side, bnd] :
sides)
529 bnd_info.remove_side(
mesh.elemPtr(elem_id), side, bnd);
534 auto elem =
mesh.elemPtr(elem_id);
535 for (
const auto & [side, bnd] :
sides)
537 bnd_info.remove_side(elem, side, bnd);
540 remove_ghost_sides[elem->processor_id()].push_back({elem_id, side, bnd});
544 Parallel::push_parallel_vector_data(
549 const std::vector<std::tuple<dof_id_type, unsigned short, BoundaryID>> & received)
551 for (
const auto & [elem_id, side, bnd] : received)
552 bnd_info.remove_side(
mesh.elemPtr(elem_id), side, bnd);
557 for (
const auto & [side, bnd] :
sides)
558 bnd_info.add_side(
mesh.elemPtr(elem_id), side, bnd);
563 auto elem =
mesh.elemPtr(elem_id);
564 for (
const auto & [side, bnd] :
sides)
566 bnd_info.add_side(elem, side, bnd);
569 add_ghost_sides[elem->processor_id()].push_back({elem_id, side, bnd});
573 Parallel::push_parallel_vector_data(
578 const std::vector<std::tuple<dof_id_type, unsigned short, BoundaryID>> & received)
580 for (
const auto & [elem_id, side, bnd] : received)
581 bnd_info.add_side(
mesh.elemPtr(elem_id), side, bnd);
584 bnd_info.parallel_sync_side_ids();
585 bnd_info.parallel_sync_node_ids();
593 switch (reinit_strategy)
614 mooseError(
"Unknown reinitialization strategy");
635 auto & bnd_info =
mesh.getMesh().get_boundary_info();
636 auto sidesets = bnd_info.get_sideset_map();
637 for (
const auto & i : sidesets)
640 auto side = i.second.first;
641 auto bnd = i.second.second;
644 bnd_info.remove_side(elem, side, bnd);
646 std::vector<const Elem *> elem_family;
647 elem->active_family_tree_by_side(elem_family, side);
648 for (
auto felem : elem_family)
649 bnd_info.add_side(felem, side, bnd);
653 bnd_info.parallel_sync_side_ids();
654 bnd_info.parallel_sync_node_ids();
659 const std::unordered_map<
dof_id_type, std::pair<SubdomainID, SubdomainID>> & moved_elems)
670 std::unordered_map<processor_id_type, std::unordered_set<dof_id_type>> push_data_set;
671 std::unordered_map<processor_id_type, std::vector<dof_id_type>> push_data;
673 for (
const auto & [elem_id, subdomain] : moved_elems)
675 mooseAssert(
_mesh.
elemPtr(elem_id)->active(),
"Moved elements should be active");
683 const auto & [from, to] = subdomain;
700 for (
const auto & node : elem->node_ref_range())
702 if (neigh_id != elem_id)
706 push_data_set[neigh_elem->processor_id()].insert(elem_id);
709 for (
unsigned int i = 0; i < elem->n_nodes(); ++i)
714 for (
auto & [pid, s] : push_data_set)
715 push_data[pid] = {s.begin(), s.end()};
722 for (
const auto &
id : received_data)
726 Parallel::push_parallel_vector_data(
_mesh.
comm(), push_data, push_receiver);
766 std::set<VariableName> ic_vars;
770 if (!ic_vars.empty())
783 "This code was written for a single nonlinear system");
801 const auto & dof_map = sys.get_dof_map();
803 const auto var_num = var.
number();
809 std::set<dof_id_type> reinitialized_dofs;
813 std::vector<dof_id_type> elem_dofs;
814 dof_map.dof_indices(elem, elem_dofs, var_num);
815 reinitialized_dofs.insert(elem_dofs.begin(), elem_dofs.end());
819 std::set<dof_id_type> existing_dofs;
824 std::vector<dof_id_type> elem_dofs;
825 dof_map.dof_indices(elem, elem_dofs, var_num);
826 existing_dofs.insert(elem_dofs.begin(), elem_dofs.end());
830 std::vector<dof_id_type> overridden_dofs;
831 std::set_intersection(reinitialized_dofs.begin(),
832 reinitialized_dofs.end(),
833 existing_dofs.begin(),
835 std::back_inserter(overridden_dofs));
838 std::vector<Number> values;
839 for (
auto dof : overridden_dofs)
840 values.push_back(current_solution(dof));
851 const auto & dof_map = sys.dofMap();
854 std::unordered_map<processor_id_type, std::vector<std::pair<dof_id_type, Number>>> push_data;
859 sol.set(dof_ids[i], values[i]);
861 push_data[dof_map.dof_owner(dof_ids[i])].emplace_back(dof_ids[i], values[i]);
865 const std::vector<std::pair<dof_id_type, Number>> & received_data)
867 for (
const auto & [
id,
value] : received_data)
871 Parallel::push_parallel_vector_data(
_mesh.
comm(), push_data, push_receiver);
874 sol.localize(*sys.system().current_local_solution, sys.dofMap().get_send_list());
890 std::vector<Elem *> elems;
895 Elem *
const * elem_itr_begin =
const_cast<Elem *
const *
>(elems.data());
896 Elem *
const * elem_itr_end = elem_itr_begin + elems.size();
898 const auto elems_begin = MeshBase::const_element_iterator(
900 const auto elems_end = MeshBase::const_element_iterator(
915 std::vector<const BndNode *> nodes;
917 for (
auto bnd_node : *bnd_nodes)
920 nodes.push_back(bnd_node);
922 BndNode *
const * bnd_node_itr_begin =
const_cast<BndNode *
const *
>(nodes.data());
923 BndNode *
const * bnd_node_itr_end = bnd_node_itr_begin + nodes.size();
931 std::make_unique<ConstBndNodeRange>(bnd_nodes_begin, bnd_nodes_end);
943 std::vector<const Node *> nodes;
948 Node *
const * node_itr_begin =
const_cast<Node *
const *
>(nodes.data());
949 Node *
const * node_itr_end = node_itr_begin + nodes.size();
951 const auto nodes_begin = MeshBase::const_node_iterator(
953 const auto nodes_end = MeshBase::const_node_iterator(
966 for (
auto bnd : bnd_node_range)
968 const Node * bnode = bnd->_node;
982 DofMap & dof_map = sys.
dofMap();
983 std::vector<dof_id_type> dofs;
985 for (
auto & elem : elem_range)
987 std::vector<dof_id_type> elem_dofs;
989 dofs.insert(dofs.end(), elem_dofs.begin(), elem_dofs.end());
992 for (
auto & bnd_node : bnd_node_range)
994 std::vector<dof_id_type> bnd_node_dofs;
995 dof_map.dof_indices(bnd_node->_node, bnd_node_dofs);
996 dofs.insert(dofs.end(), bnd_node_dofs.begin(), bnd_node_dofs.end());
1000 for (
auto dof : dofs)
1002 old_solution.
set(dof, current_solution(dof));
1004 older_solution->
set(dof, current_solution(dof));
1007 old_solution.
close();
1009 older_solution->
close();
1024 auto & [candidate_elems, candidate_elem_ids] =
_evaluable_elems[sys.number()];
1025 const auto & dof_map = sys.get_dof_map();
1026 std::vector<dof_id_type> elem_dofs;
1027 auto vn = sys.variable_number(static_cast<std::string>(var_name));
1034 dof_map.dof_indices(elem, elem_dofs, vn);
1035 if (!elem_dofs.empty())
1037 candidate_elems.insert(elem);
1038 candidate_elem_ids.push_back(elem->id());
1042 auto & [candidate_elems, candidate_elem_ids] =
_evaluable_elems[sys.number()];
1047 switch (reinit_strategy)
1051 auto has_neighbor_in_reinit_elems = [&](
const Elem * elem) ->
bool 1053 for (
const auto & node : elem->node_ref_range())
1062 for (
const auto * elem : candidate_elems)
1063 if (has_neighbor_in_reinit_elems(elem))
1064 patch_elems.push_back(elem->id());
1070 patch_elems = candidate_elem_ids;
1075 std::vector<Point> kd_points;
1076 std::vector<dof_id_type> global_candidate_elem_ids;
1080 std::vector<std::pair<Point, dof_id_type>> pts_ids(candidate_elem_ids.size());
1081 for (std::size_t i = 0; i < candidate_elem_ids.size(); ++i)
1082 pts_ids[i] = {
_mesh.
elemPtr(candidate_elem_ids[i])->vertex_average(),
1083 candidate_elem_ids[i]};
1085 for (
const auto & [pt,
id] : pts_ids)
1087 kd_points.push_back(pt);
1088 global_candidate_elem_ids.push_back(
id);
1094 global_candidate_elem_ids = candidate_elem_ids;
1095 for (
const auto &
id : candidate_elem_ids)
1096 kd_points.push_back(
_mesh.
elemPtr(
id)->vertex_average());
1099 const auto kd_tree = std::make_unique<KDTree>(kd_points,
_leaf_max_size);
1101 std::vector<nanoflann::ResultItem<std::size_t, Real>> query_result;
1104 const Point & centroid =
_mesh.
elemPtr(elem_id)->vertex_average();
1106 for (
const auto & [qid, dist] : query_result)
1107 patch_elems.push_back(global_candidate_elem_ids[qid]);
1112 mooseError(
"Unknown reinitialization strategy");
1121 std::sort(patch_elems.begin(), patch_elems.end());
1122 patch_elems.erase(std::unique(patch_elems.begin(), patch_elems.end()), patch_elems.end());
1137 function_parameters.
set<std::vector<std::vector<unsigned int>>>(
"multi_index") = multi_index;
1139 std::vector<Real> coef_vec(coef.size());
1140 for (
auto i = 0; i < coef.size(); ++i)
1141 coef_vec[i] = coef(i);
1143 function_parameters.
set<std::vector<Real>>(
"multi_index_coefficients") = coef_vec;
1144 function_parameters.
set<
unsigned int>(
"dimension_for_projection") =
dim;
1147 auto poly_func = [](
const Point & p,
1149 const std::string &,
1152 const auto & multi_index =
1153 parameters.
get<std::vector<std::vector<unsigned int>>>(
"multi_index");
1154 const auto & coeffs =
parameters.
get<std::vector<Real>>(
"multi_index_coefficients");
1158 for (
unsigned int r = 0; r < multi_index.size(); r++)
1160 Real monomial = 1.0;
1161 for (
unsigned int d = 0; d < multi_index[r].size(); d++)
1163 const auto power = multi_index[r][d];
1169 val += coeffs[r] * monomial;
1176 auto poly_func_grad = [](
const Point & p,
1178 const std::string &,
1181 const unsigned int dim =
parameters.
get<
unsigned int>(
"dimension_for_projection");
1183 const auto & multi_index =
1184 parameters.
get<std::vector<std::vector<unsigned int>>>(
"multi_index");
1185 const auto & coeffs =
parameters.
get<std::vector<Real>>(
"multi_index_coefficients");
1189 for (
unsigned int r = 0; r < multi_index.size(); ++r)
1191 const auto & powers = multi_index[r];
1192 const Real coef = coeffs[r];
1194 for (
unsigned int d = 0; d <
dim; ++d)
1196 const auto power_d = powers[d];
1201 Real partial = coef * power_d;
1203 for (
unsigned int i = 0; i < powers.size(); ++i)
1208 partial *=
std::pow(p(i), powers[i] - 1);
1213 partial *=
std::pow(p(i), powers[i]);
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 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.
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 VariableName &target_var)
Project a function onto a range of elements for a given variable.
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 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.
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
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()
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.
uint8_t processor_id_type
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()
void gatherSum(T &value)
Gather the parallel sum of the variable passed in.
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)
SystemBase & _sys
Reference to the system object for this user object.
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.
std::set< std::string > _depend_uo
Depend UserObjects that to be used both for determining user object sorting and by AuxKernel for find...
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)
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
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.
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