21 #include "libmesh/system.h" 30 params.
addParam<
unsigned int>(
"num_nearest_points",
32 "Number of nearest source (from) points will be chosen to " 33 "construct a value for the target point. All points will be " 34 "selected from the same origin mesh!");
38 params.
addParam<
bool>(
"group_subapps",
40 "Whether to group source locations and values from all subapps " 41 "when working with a nearest-position or source mesh-division");
49 _num_nearest_points(getParam<unsigned
int>(
"num_nearest_points")),
50 _group_subapps(getParam<bool>(
"group_subapps"))
54 "We do not support using both nearest positions matching and checking if target " 55 "points are within an app domain because the KDTrees for nearest-positions matching " 56 "are (currently) built with data from multiple applications.");
59 paramError(
"use_nearest_position",
"Cannot use nearest positions with mesh divisions");
65 "This option is only available for using mesh divisions or nearest positions regions");
70 "Cannot group subapps when considering nearest-location data as we would lose " 71 "track of the division index of the source locations");
75 "When using the 'nearest child application' data, the source data (positions and values) " 76 "are grouped on a per-application basis, so it cannot be agglomerated over all child " 77 "applications.\nNote that the option to use nearest applications for source restrictions, " 78 "but further split each child application's domain by regions closest to each position " 79 "(here the the child application's centroid), which could be conceived when " 80 "'group_subapps' = false, is also not available.");
93 "This transfer has only been implemented with a uniform number of source mesh " 94 "divisions across all source applications");
99 const unsigned int var_index)
110 const Elem * elem)
const 116 const auto & node = elem->
node_ptr(i_node);
117 const auto & node_blocks =
mesh.getNodeBlockIds(*node);
118 std::set<SubdomainID> u;
119 std::set_intersection(
blocks.begin(),
123 std::inserter(u, u.begin()));
151 unsigned int nested_loop_on_app_index)
const 158 return nested_loop_on_app_index;
198 const Point & pt)
const 209 const unsigned int mesh_div,
210 const unsigned int i_from)
const 218 auto position_index = i_from;
237 mooseError(
"Nearest-positions + source_app_must_contain_point not implemented");
250 "We should not be receiving point requests with an invalid " 251 "source mesh division index");
257 mesh_div != kd_div_index)
264 mesh_div != kd_div_index)
280 unsigned int source_index,
281 std::pair<Real, Real> & outgoing_val,
302 Real val_sum = 0, dist_sum = 0;
303 for (
const auto index : return_index)
310 const auto new_distance = dist_sum / return_dist_sqr.size();
311 if (new_distance < outgoing_val.second)
312 outgoing_val = {val_sum / return_index.size(), new_distance};
319 unsigned int num_equidistant_problems = 0;
335 _local_kdtrees[i_from]->neighborSearch(pt, num_search, return_index, return_dist_sqr);
336 auto num_found = return_dist_sqr.size();
345 mooseInfo(
"Search value conflict cannot find the origin point due to the " 346 "non-uniqueness of the coordinate collapsing reverse mapping");
349 std::vector<std::pair<Real, std::size_t>> zipped_nearest_points;
351 zipped_nearest_points.push_back(std::make_pair(return_dist_sqr[i], return_index[i]));
352 std::sort(zipped_nearest_points.begin(), zipped_nearest_points.end());
359 if (num_found > 1 && num_found == num_search &&
360 MooseUtils::absoluteFuzzyEqual(zipped_nearest_points[num_found - 1].first,
361 zipped_nearest_points[num_found - 2].first))
372 for (
const auto i :
make_range(num_search - 1))
374 auto index = zipped_nearest_points[i].second;
379 if (MooseUtils::absoluteFuzzyEqual(dist_sum / return_dist_sqr.size(), outgoing_val.second))
381 num_equidistant_problems++;
382 if (num_equidistant_problems > 1)
void mooseInfo(Args &&... args) const
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
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.
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 ...
bool _source_app_must_contain_point
Whether the source app mesh must actually contain the points for them to be considered or whether the...
const bool _skip_coordinate_collapsing
Whether to skip coordinate collapsing (transformations of coordinates between applications using diff...
Point getPointInSourceAppFrame(const Point &p, unsigned int local_i_from, const std::string &phase) const
Get the source app point from a point in the reference frame.
Point getPointInSourceKDTreeFrame(unsigned int i_source, const Point &pt) const
Transform a point into the frame used for KD-tree queries.
void registerConflict(unsigned int problem, dof_id_type dof_id, Point p, Real dist, bool local)
Register a potential value conflict, e.g.
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
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::unique_ptr< libMesh::PointLocatorBase > > _from_point_locators
Point locators, useful to examine point location with regards to domain restriction.
bool inBlocks(const std::set< SubdomainID > &blocks, const MooseMesh &mesh, const Elem *elem) const override
FEProblemBase & _fe_problem
static InputParameters validParams()
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...
bool inMesh(const libMesh::PointLocatorBase *const pl, const Point &pt) 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.
unsigned int _num_sources
Number of KD-Trees to create.
const Positions * _nearest_positions_obj
MultiAppGeneralFieldKDTreeTransferBase(const InputParameters ¶meters)
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.
virtual void prepareEvaluationOfInterpValues(const unsigned int var_index) override
std::vector< MooseMesh * > _from_meshes
virtual unsigned int n_nodes() const=0
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
bool _search_value_conflicts
Whether to look for conflicts between origin points, multiple valid values for a target point...
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
unsigned int getNumPositions(bool initial=false) const
}
virtual void buildKDTrees(const unsigned int var_index)=0
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
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.
const Node * node_ptr(const unsigned int i) const
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
IntRange< T > make_range(T beg, T end)
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...
bool checkRestrictionsForSource(const Point &pt, const unsigned int valid_mesh_div, const unsigned int i_from) const
Examine all spatial restrictions that could preclude this source from being a valid source for this p...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
unsigned int _num_nearest_points
Number of points to consider.
virtual 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.
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
void ErrorVector unsigned int
std::vector< std::shared_ptr< KDTree > > _local_kdtrees
KD-Trees for all the local source apps.
It is a general field transfer.
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.
const ExecFlagType EXEC_INITIAL