21#include "libmesh/system.h"
25 MultiAppGeneralFieldNearestNodeTransfer,
34 "Transfers field data at the MultiApp position by finding the value at the nearest "
35 "neighbor(s) in the origin application.");
45 params.
renameParam(
"use_nearest_app",
"assume_nearest_app_holds_nearest_location",
"");
49 std::vector<MooseEnum> source_types = {
50 MooseEnum(
"nodes centroids variable_default",
"variable_default")};
51 params.
addParam<std::vector<MooseEnum>>(
52 "source_type", source_types,
"Where to get the source values from for each source variable");
69 const auto & source_types = getParam<std::vector<MooseEnum>>(
"source_type");
73 mooseError(
"Not enough source types specified for this number of variables. Source types must "
74 "be specified for transfers with multiple variables");
88 System & from_sys = from_var.
sys().
system();
92 if (source_types[var_index] ==
"nodes")
94 else if (source_types[var_index] ==
"centroids")
116 if ((
_source_is_nodes[var_index] && fe_type.family == LAGRANGE && fe_type.order <= SECOND) ||
126 mooseError(
"Source variable cannot be sampled at nodes as it is discontinuous");
142 if (to_fe_type.order == CONSTANT)
144 "Transfer is projecting from nearest-nodes to centroids. This is likely causing "
145 "floating point indetermination in the results because multiple nodes are 'nearest' to "
146 "a centroid. Please consider using a ProjectionAux to build an elemental source "
147 "variable (for example constant monomial) before transferring");
151 "Transfer is projecting from nearest-centroids to nodes. This is likely causing "
152 "floating point indetermination in the results because multiple centroids are "
153 "'nearest' to a node. Please consider using a ProjectionAux to build a nodal source "
154 "variable (for example linear Lagrange) before transferring");
162 "This transfer has only been implemented with a uniform number of source mesh "
163 "divisions across all source applications");
174 unsigned int max_leaf_size = 0;
181 for (
const auto app_i : make_range(num_apps_per_tree))
196 System & from_sys = from_var.
sys().
system();
202 for (
const auto & node : from_mesh.getMesh().local_node_ptr_range())
206 if (node->n_dofs(from_sys.number(), from_var_num) < 1)
233 tree_division_index != node_div_index)
251 const auto dof = node->dof_number(from_sys.number(), from_var_num, 0);
252 _local_values[i_source].push_back((*from_sys.solution)(dof));
255 "Nearest-location is not implemented for this source variable type on "
256 "this mesh. Returning value at dof 0");
262 for (
auto & elem : as_range(from_mesh.getMesh().local_elements_begin(),
263 from_mesh.getMesh().local_elements_end()))
265 if (elem->n_dofs(from_sys.number(), from_var_num) < 1)
289 tree_division_index != elem_div_index)
293 const auto vertex_average = elem->vertex_average();
296 const auto transformed_vertex_average =
305 _local_points[i_source].push_back(transformed_vertex_average);
308 auto dof = elem->dof_number(from_sys.number(), from_var_num, 0);
309 _local_values[i_source].push_back((*from_sys.solution)(dof));
313 from_sys.point_value(from_var_num, vertex_average, elem));
316 max_leaf_size = std::max(max_leaf_size, from_mesh.getMaxLeafSize());
320 std::shared_ptr<KDTree> _kd_tree =
321 std::make_shared<KDTree>(
_local_points[i_source], max_leaf_size);
329 const std::vector<std::pair<Point, unsigned int>> & incoming_points,
330 std::vector<std::pair<Real, Real>> & outgoing_vals)
337 const std::vector<std::pair<Point, unsigned int>> & incoming_points,
338 std::vector<std::pair<Real, Real>> & outgoing_vals)
340 dof_id_type i_pt = 0;
341 for (
const auto & [pt, mesh_div] : incoming_points)
343 outgoing_vals[i_pt].second = std::numeric_limits<Real>::max();
344 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.
const FEType & variable_type(const unsigned int i) const
unsigned int variable_number(std::string_view var) const
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.