https://mooseframework.inl.gov
MultiAppGeneralFieldUserObjectTransfer.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 
12 // MOOSE includes
13 #include "DisplacedProblem.h"
14 #include "FEProblem.h"
15 #include "MooseMesh.h"
16 #include "MooseTypes.h"
17 #include "MooseVariableFE.h"
18 #include "UserObject.h"
19 #include "Positions.h"
20 
21 #include "libmesh/system.h"
22 #include "libmesh/mesh_function.h"
23 
25 
28 {
30  params.addClassDescription(
31  "Transfers user object spatial evaluations from an origin app onto a variable in the target "
32  "application.");
33 
34  params.set<std::vector<VariableName>>("source_variable") = std::vector<VariableName>{};
35  params.suppressParameter<std::vector<VariableName>>("source_variable");
36  params.addRequiredParam<UserObjectName>("source_user_object",
37  "The UserObject you want to transfer values from. "
38  "It must implement the SpatialValue() class routine");
39 
40  // Blanket ban on origin boundary restriction. User objects tend to extend beyond boundaries,
41  // and be able to be evaluated within a volume rather than only on a boundary
42  // This could be re-enabled for spatial user objects that are only defined on boundaries
43  params.suppressParameter<std::vector<BoundaryName>>("from_boundaries");
44  return params;
45 }
46 
48  const InputParameters & parameters)
49  : MultiAppGeneralFieldTransfer(parameters),
50  _user_object_name(getParam<UserObjectName>("source_user_object"))
51 {
52  if (_to_var_names.size() > 1)
53  paramError("variable", "Only one variable at a time is supported by this transfer");
54 
55  // Block restriction does not make sense if we're ok with extrapolating
56  if (isParamValid("from_blocks") && !_source_app_must_contain_point &&
57  !parameters.isParamSetByUser("extrapolation_constant"))
58  paramError("from_app_must_contain_point",
59  "Source block restriction cannot be used at the same type as allowing extrapolation"
60  " of values for a user object transfer (with 'from_app_must_contain_point=false') "
61  " unless an extrapolation constant is provided (with 'extrapolation_constant')");
62 
63  // Nearest point isn't well defined for sending app-based data from main app to a multiapp
64  if (_nearest_positions_obj && isParamValid("to_multi_app") && !isParamValid("from_multi_app"))
65  paramError("use_nearest_position",
66  "Cannot use nearest-position algorithm when sending from the main application");
67 }
68 
69 void
71 {
72  // Execute the user object if it was specified to execute on TRANSFER
73  switch (_current_direction)
74  {
75  case TO_MULTIAPP:
76  {
79  break;
80  }
81  case FROM_MULTIAPP:
83  }
84 
85  // Perfom the actual transfer
87 }
88 
89 void
91  const unsigned int /* var_index */)
92 {
93  _local_bboxes.clear();
96 }
97 
98 void
100  const std::vector<std::pair<Point, unsigned int>> & incoming_points,
101  std::vector<std::pair<Real, Real>> & outgoing_vals)
102 {
103  evaluateInterpValuesWithUserObjects(_local_bboxes, incoming_points, outgoing_vals);
104 }
105 
106 void
108  const std::vector<BoundingBox> & local_bboxes,
109  const std::vector<std::pair<Point, unsigned int>> & incoming_points,
110  std::vector<std::pair<Real, Real>> & outgoing_vals)
111 {
112  dof_id_type i_pt = 0;
113  for (auto & [pt, mesh_div] : incoming_points)
114  {
115  bool point_found = false;
116  outgoing_vals[i_pt].second = GeneralFieldTransfer::BetterOutOfMeshValue;
117 
118  // Loop on all local origin problems until:
119  // - we've found the point in an app and the value at that point is valid
120  // - or if looking for conflicts between apps, we must check them all
121  for (MooseIndex(_from_problems.size()) i_from = 0;
122  i_from < _from_problems.size() &&
123  (!point_found || _search_value_conflicts || _nearest_positions_obj);
124  ++i_from)
125  {
126  // User object spatialValue() evaluations do not provide a distance
127  Real distance = 1;
128  // Check spatial restrictions
129  if (!acceptPointInOriginMesh(i_from, local_bboxes, pt, mesh_div, distance))
130  continue;
131  else
132  {
133  const auto from_global_num = getGlobalSourceAppIndex(i_from);
134 
135  // Get user object from the local problem
136  const UserObject & user_object =
137  _from_problems[i_from]->getUserObjectBase(_user_object_name);
138 
139  // Use spatial value routine to compute the origin value to transfer
140  const auto local_pt = _from_transforms[from_global_num]->mapBack(pt);
141  auto val = user_object.spatialValue(local_pt);
142 
143  // Look for overlaps. The check is not active outside of overlap search because in that
144  // case we accept the first value from the lowest ranked process
145  // NOTE: There is no guarantee this will be the final value used among all problems
146  // but we register an overlap as soon as two values are possible from this rank
147  if (detectConflict(val, outgoing_vals[i_pt].first, distance, outgoing_vals[i_pt].second))
148  {
150  registerConflict(i_from, 0, pt, distance, true);
151  else
152  registerConflict(i_from, 0, local_pt, distance, true);
153  }
154 
155  // No need to consider decision factors if value is invalid
157  continue;
158  else
159  point_found = true;
160 
161  // Assign value
162  if (distance < outgoing_vals[i_pt].second)
163  {
164  outgoing_vals[i_pt].first = val;
165  outgoing_vals[i_pt].second = distance;
166  }
167  }
168  }
169 
170  if (!point_found)
171  outgoing_vals[i_pt] = {GeneralFieldTransfer::BetterOutOfMeshValue,
173 
174  // Move to next point
175  i_pt++;
176  }
177 }
const ExecFlagType EXEC_TRANSFER
Definition: Moose.C:53
bool _source_app_must_contain_point
Whether the source app mesh must actually contain the points for them to be considered or whether the...
MooseEnum _current_direction
Definition: Transfer.h:106
void evaluateInterpValuesWithUserObjects(const std::vector< BoundingBox > &local_bboxes, const std::vector< std::pair< Point, unsigned int >> &incoming_points, std::vector< std::pair< Real, Real >> &outgoing_vals)
void registerConflict(unsigned int problem, dof_id_type dof_id, Point p, Real dist, bool local)
Register a potential value conflict, e.g.
virtual void execute() override
Execute the transfer.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
virtual void execute() override
Execute the transfer.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
FEProblemBase & _fe_problem
Definition: Transfer.h:97
Real distance(const Point &p)
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn&#39;t required or valid in the derived class...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
const bool _use_bounding_boxes
Whether to use bounding boxes to determine the applications that may receive point requests then send...
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, e.g.
bool acceptPointInOriginMesh(unsigned int i_from, const std::vector< BoundingBox > &local_bboxes, const Point &pt, const unsigned int mesh_div, Real &distance) const
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
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.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool detectConflict(Real value_1, Real value_2, Real distance_1, Real distance_2) const
Detects whether two source values are valid and equidistant for a desired target location.
virtual void prepareEvaluationOfInterpValues(const unsigned int) override
virtual void evaluateInterpValues(const std::vector< std::pair< Point, unsigned int >> &incoming_points, std::vector< std::pair< Real, Real >> &outgoing_vals) override
Transfers values computed in the origin mesh by the source user object spatialValue() routine at loca...
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was set by the user.
const std::string _user_object_name
Name of the source user object in all the source problems.
registerMooseObject("MooseApp", MultiAppGeneralFieldUserObjectTransfer)
virtual Real spatialValue(const Point &) const
Optional interface function for "evaluating" a UserObject at a spatial position.
Definition: UserObject.h:95
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
void extractLocalFromBoundingBoxes(std::vector< BoundingBox > &local_bboxes)
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
const InputParameters & parameters() const
Get the parameters of the object.
MultiAppGeneralFieldUserObjectTransfer(const InputParameters &parameters)
virtual void computeUserObjectByName(const ExecFlagType &type, const Moose::AuxGroup &group, const std::string &name)
Compute an user object with the given name.
std::vector< FEProblemBase * > _from_problems
Base class for user-specific data.
Definition: UserObject.h:40
It is a general field transfer.
uint8_t dof_id_type