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)
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)
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)
345 outgoing_vals[i_pt].second = std::numeric_limits<Real>::max();
346 bool point_found =
false;
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.
registerMooseObjectRenamed("MooseApp", MultiAppGeneralFieldNearestNodeTransfer, "12/31/2024 24:00", MultiAppGeneralFieldNearestLocationTransfer)
registerMooseObject("MooseApp", MultiAppGeneralFieldNearestLocationTransfer)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
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...
virtual MooseMesh & mesh() override
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 ...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
virtual bool isNodal() const
Is this variable nodal.
virtual libMesh::FEContinuity getContinuity() const
Return the continuity of this variable.
SystemBase & sys()
Get the system this variable is part of.
unsigned int number() const
Get variable number coming from libMesh.
This class provides an interface for common operations on field variables of both FE and FV types wit...
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
Base class for working with KDTrees in transfers, whether for interpolation or extrapolation.
unsigned int getNumAppsPerTree() const
Number of applications which contributed nearest-locations to each KD-tree.
std::vector< std::vector< Point > > _local_points
All the nodes that meet the spatial restrictions in all the local source apps.
std::vector< std::shared_ptr< KDTree > > _local_kdtrees
KD-Trees for all the local source apps.
unsigned int _num_sources
Number of KD-Trees to create.
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...
std::vector< std::vector< Real > > _local_values
Values of the variable being transferred at all the points in _local_points.
static InputParameters validParams()
void computeNumSources()
Pre-compute the number of sources Number of KDTrees used to hold the locations and variable value dat...
const bool _group_subapps
Whether to group data when creating the nearest-point regions.
bool inBlocks(const std::set< SubdomainID > &blocks, const MooseMesh &mesh, const Elem *elem) const override
unsigned int getNumDivisions() const
Number of divisions (nearest-positions or source mesh divisions) used when building KD-Trees.
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.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
Performs a geometric interpolation based on the values at the nearest nodes to a target location in t...
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
std::vector< bool > _source_is_nodes
Whether the source of the values is at nodes (true) or centroids (false) for each variable.
void evaluateInterpValuesNearestNode(const std::vector< std::pair< Point, unsigned int > > &incoming_points, std::vector< std::pair< Real, Real > > &outgoing_vals)
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
void buildKDTrees(const unsigned int var_index) override
static InputParameters validParams()
MultiAppGeneralFieldNearestLocationTransfer(const InputParameters ¶meters)
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.
const bool _use_nearest_app
Whether to keep track of the distance from the requested point to the app position.
const Positions * _nearest_positions_obj
const MooseEnum & _from_mesh_division_behavior
How to use the origin mesh divisions to restrict the transfer.
const MooseEnum & _to_mesh_division_behavior
How to use the target mesh divisions to restrict the transfer.
bool onBoundaries(const std::set< BoundaryID > &boundaries, const MooseMesh &mesh, const Node *node) const
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.
std::set< SubdomainID > _from_blocks
Origin block(s) restriction.
std::vector< const MeshDivision * > _from_mesh_divisions
Division of the origin mesh.
VariableName getFromVarName(unsigned int var_index) const
Get the source variable name, with the suffix for array/vector variables.
std::set< BoundaryID > _from_boundaries
Origin boundary(ies) restriction.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
std::vector< FEProblemBase * > _from_problems
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
std::vector< FEProblemBase * > _to_problems
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
const FEType & variable_type(const unsigned int i) const
std::unique_ptr< NumericVector< Number > > solution
unsigned int variable_number(std::string_view var) const
unsigned int number() const
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
auto index_range(const T &sizable)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)