21 #include "libmesh/system.h" 27 MultiAppGeneralFieldNearestNodeTransfer,
36 "Transfers field data at the MultiApp position by finding the value at the nearest " 37 "neighbor(s) in the origin application.");
47 params.
renameParam(
"use_nearest_app",
"assume_nearest_app_holds_nearest_location",
"");
51 std::vector<MooseEnum> source_types = {
52 MooseEnum(
"nodes centroids variable_default",
"variable_default")};
53 params.
addParam<std::vector<MooseEnum>>(
54 "source_type", source_types,
"Where to get the source values from for each source variable");
71 const auto & source_types = getParam<std::vector<MooseEnum>>(
"source_type");
75 mooseError(
"Not enough source types specified for this number of variables. Source types must " 76 "be specified for transfers with multiple variables");
94 if (source_types[var_index] ==
"nodes")
96 else if (source_types[var_index] ==
"centroids")
128 mooseError(
"Source variable cannot be sampled at nodes as it is discontinuous");
146 "Transfer is projecting from nearest-nodes to centroids. This is likely causing " 147 "floating point indetermination in the results because multiple nodes are 'nearest' to " 148 "a centroid. Please consider using a ProjectionAux to build an elemental source " 149 "variable (for example constant monomial) before transferring");
153 "Transfer is projecting from nearest-centroids to nodes. This is likely causing " 154 "floating point indetermination in the results because multiple centroids are " 155 "'nearest' to a node. Please consider using a ProjectionAux to build a nodal source " 156 "variable (for example linear Lagrange) before transferring");
164 "This transfer has only been implemented with a uniform number of source mesh " 165 "divisions across all source applications");
176 unsigned int max_leaf_size = 0;
183 for (
const auto app_i :
make_range(num_apps_per_tree))
204 for (
const auto & node : from_mesh.getMesh().local_node_ptr_range())
208 if (node->n_dofs(from_sys.
number(), from_var_num) < 1)
231 MeshDivisionTransferUse::MATCH_DIVISION_INDEX ||
234 MeshDivisionTransferUse::MATCH_SUBAPP_INDEX) &&
235 tree_division_index != node_div_index)
253 const auto dof = node->dof_number(from_sys.
number(), from_var_num, 0);
257 "Nearest-location is not implemented for this source variable type on " 258 "this mesh. Returning value at dof 0");
264 for (
auto & elem :
as_range(from_mesh.getMesh().local_elements_begin(),
265 from_mesh.getMesh().local_elements_end()))
267 if (elem->n_dofs(from_sys.
number(), from_var_num) < 1)
288 MeshDivisionTransferUse::MATCH_DIVISION_INDEX ||
290 MeshDivisionTransferUse::MATCH_SUBAPP_INDEX) &&
291 tree_division_index != elem_div_index)
295 const auto vertex_average = elem->vertex_average();
298 const auto transformed_vertex_average =
307 _local_points[i_source].push_back(transformed_vertex_average);
310 auto dof = elem->dof_number(from_sys.
number(), from_var_num, 0);
315 from_sys.
point_value(from_var_num, vertex_average, elem));
318 max_leaf_size =
std::max(max_leaf_size, from_mesh.getMaxLeafSize());
322 std::shared_ptr<KDTree> _kd_tree =
323 std::make_shared<KDTree>(
_local_points[i_source], max_leaf_size);
331 const std::vector<std::pair<Point, unsigned int>> & incoming_points,
332 std::vector<std::pair<Real, Real>> & outgoing_vals)
339 const std::vector<std::pair<Point, unsigned int>> & incoming_points,
340 std::vector<std::pair<Real, Real>> & outgoing_vals)
343 for (
const auto & [pt, mesh_div] : incoming_points)
346 bool point_found =
false;
virtual bool isNodal() const
Is this variable nodal.
registerMooseObjectRenamed("MooseApp", MultiAppGeneralFieldNearestNodeTransfer, "12/31/2024 24:00", MultiAppGeneralFieldNearestLocationTransfer)
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
registerMooseObject("MooseApp", MultiAppGeneralFieldNearestLocationTransfer)
unsigned int getNumDivisions() const
Number of divisions (nearest-positions or source mesh divisions) used when building KD-Trees...
const bool _group_subapps
Whether to group data when creating the nearest-point regions.
Base class for working with KDTrees in transfers, whether for interpolation or extrapolation.
void computeNumSources()
Pre-compute the number of sources Number of KDTrees used to hold the locations and variable value dat...
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 ...
std::vector< bool > _use_zero_dof_for_value
Whether we can just use the local zero-indexed dof to get the value from the solution.
unsigned int number() const
Get variable number coming from libMesh.
virtual libMesh::FEContinuity getContinuity() const
Return the continuity of this variable.
unsigned int getAppIndex(unsigned int kdtree_index, unsigned int app_index_in_tree) const
Get the index of the app when inside of a KD-Tree source loop, where multiple applications could be l...
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
std::vector< bool > _source_is_nodes
Whether the source of the values is at nodes (true) or centroids (false) for each variable...
std::vector< FEProblemBase * > _to_problems
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
bool inBlocks(const std::set< SubdomainID > &blocks, const MooseMesh &mesh, const Elem *elem) const override
This class provides an interface for common operations on field variables of both FE and FV types wit...
static InputParameters validParams()
std::vector< const MeshDivision * > _from_mesh_divisions
Division of the origin mesh.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
virtual void evaluateInterpValues(const unsigned int, const std::vector< std::pair< Point, unsigned int >> &incoming_points, std::vector< std::pair< Real, Real >> &outgoing_vals) override
bool closestToPosition(unsigned int pos_index, const Point &pt) const
Whether a point is closest to a position at the index specified than any other position.
unsigned int _num_sources
Number of KD-Trees to create.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
std::set< BoundaryID > _from_boundaries
Origin boundary(ies) restriction.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
auto max(const L &left, const R &right)
const Positions * _nearest_positions_obj
unsigned int variable_number(std::string_view var) const
void evaluateNearestNodeFromKDTrees(const Point &pt, unsigned int source_index, std::pair< Real, Real > &outgoing_val, bool &point_found)
Search all local KD-trees for the nearest node/element and update outgoing_val.
unsigned int getNumAppsPerTree() const
Number of applications which contributed nearest-locations to each KD-tree.
void mooseWarning(Args &&... args) const
unsigned int number() const
VariableName getFromVarName(unsigned int var_index) const
Get the source variable name, with the suffix for array/vector variables.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
std::unique_ptr< NumericVector< Number > > solution
MultiAppGeneralFieldNearestLocationTransfer(const InputParameters ¶meters)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
static InputParameters validParams()
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
void evaluateInterpValuesNearestNode(const std::vector< std::pair< Point, unsigned int >> &incoming_points, std::vector< std::pair< Real, Real >> &outgoing_vals)
const FEType & variable_type(const unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const MooseEnum & _to_mesh_division_behavior
How to use the target mesh divisions to restrict the transfer.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
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...
std::set< SubdomainID > _from_blocks
Origin block(s) restriction.
Performs a geometric interpolation based on the values at the nearest nodes to a target location in t...
void buildKDTrees(const unsigned int var_index) override
SystemBase & sys()
Get the system this variable is part of.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
std::vector< std::vector< Real > > _local_values
Values of the variable being transferred at all the points in _local_points.
bool onBoundaries(const std::set< BoundaryID > &boundaries, const MooseMesh &mesh, const Node *node) const
std::vector< std::vector< Point > > _local_points
All the nodes that meet the spatial restrictions in all the local source apps.
std::vector< FEProblemBase * > _from_problems
auto index_range(const T &sizable)
std::vector< std::shared_ptr< KDTree > > _local_kdtrees
KD-Trees for all the local source apps.
const MooseEnum & _from_mesh_division_behavior
How to use the origin mesh divisions to restrict the transfer.
const bool _use_nearest_app
Whether to keep track of the distance from the requested point to the app position.