20#include "libmesh/parallel_algebra.h"
21#include "libmesh/mesh_tools.h"
28 "The name of the MultiApp to transfer data with",
29 "Use to_multiapp & from_multiapp parameters now");
30 params.
addParam<MultiAppName>(
"from_multi_app",
"The name of the MultiApp to receive data from");
31 params.
addParam<MultiAppName>(
"to_multi_app",
"The name of the MultiApp to transfer the data to");
38#ifdef LIBMESH_ENABLE_AMR
42 params.
setDocString(
"execute_on", exec_enum.getDocString());
45 "check_multiapp_execute_on",
47 "When false the check between the multiapp and transfer execute on flags is not performed.");
48 params.
addParam<
bool>(
"displaced_source_mesh",
50 "Whether or not to use the displaced mesh for the source mesh.");
51 params.
addParam<
bool>(
"displaced_target_mesh",
53 "Whether or not to use the displaced mesh for the target mesh.");
65 "Multiply bounding box width (in all directions) by the prescribed factor. Values less than "
66 "1 will shrink the bounding box; values greater than 1 will enlarge the bounding box. It is "
67 "generally not advised to ever shrink the bounding box. On the other hand it may be helpful "
68 "to enlarge the bounding box. Larger bounding boxes will lead to more accurate determination "
69 "of the closest node/element with the tradeoff of more communication.");
76 "skip_coordinate_collapsing",
78 "Whether to skip coordinate collapsing (translation and rotation are still performed, only "
79 "XYZ, RZ etc collapsing is skipped) when performing mapping and inverse "
80 "mapping coordinate transformation operations. This parameter should only "
81 "be set by users who really know what they're doing.");
88 params.
addParam<
bool>(
"warn_source_object_execution_schedule",
90 "Emit a warning when the transfer execution schedule is detected to lag "
91 "information from the user object. Note that the check cannot detect all "
92 "potential wrong combinations of user-object/transfer execution schedules");
97 _skip_coordinate_collapsing(getParam<bool>(
"skip_coordinate_collapsing")),
98 _displaced_source_mesh(getParam<bool>(
"displaced_source_mesh")),
99 _displaced_target_mesh(getParam<bool>(
"displaced_target_mesh")),
100 _bbox_factor(isParamValid(
"bbox_factor") ? getParam<Real>(
"bbox_factor") : 1)
117 mooseError(
"from_multi_app and/or to_multi_app must be specified");
136 "BETWEN_MULTIAPP transfers should be specified using to/from_multi_app");
140 if (getParam<bool>(
"check_multiapp_execute_on"))
160 if (getParam<bool>(
"check_multiapp_execute_on") &&
isParamValid(
"execute_after_from_multiapp") &&
165 "This parameter is only obeyed when the from_multi_app and the transfer are "
166 "executing on the same execute_on flag.\nfrom_multi_app execution schedule: ",
168 "\nTransfer execution schedule: ",
170 "\nYou can disable this error by setting 'check_multiapp_execute_on' to false.");
175 "This parameter is only intended for modifying the execution schedule of "
176 "siblings transfers, e.g. transfers from a from_multi_app to a to_multi_app");
183 if (getParam<bool>(
"check_multiapp_execute_on") &&
_directions.
contains(
"between_multiapp") &&
186 _to_multi_app->getParam<
unsigned int>(
"execution_order_group") &&
193 "Transfer is set to execute after the 'from_multi_app' but the 'to_multi_app' is "
194 "executing before or in the same 'execution_order_group' as the 'from_multi_app'. "
195 "Thus the transfer is not actually executing in between the 'from_' and "
196 "'to_multi_app', but after both.\nfrom_multi_app execution order group: ",
198 "\nto_multi_app execution order group: ",
200 "\nYou can disable this warning by setting 'check_multiapp_execute_on' to false.");
207 "The deprecated 'direction' parameter is meant to be used in conjunction with the "
208 "'multi_app' parameter");
211 "The deprecated 'direction' parameter is not meant to be used in conjunction with "
212 "the 'from_multi_app' or 'to_multi_app' parameters");
222 mooseWarning(
"MultiAppTransfer execute_on flags do not match associated from_multi_app "
223 "execute_on flags"));
228 mooseWarning(
"MultiAppTransfer execute_on flags do not match associated to_multi_app "
229 "execute_on flags"));
236 mooseWarning(
"MultiAppTransfer execute_on flags do not match associated to_multi_app "
237 "and from_multi_app execute_on flags"));
242 bool is_from_multiapp)
const
244 bool variable_found =
false;
245 bool has_an_app =
false;
254 variable_found =
true;
259 for (
unsigned int i = 0; i <
_to_multi_app->numGlobalApps(); i++)
264 variable_found =
true;
267 if (!variable_found && has_an_app)
268 mooseError(
"Cannot find variable ", var_name,
" for ",
name(),
" Transfer");
328 "I believe these should be the same. If not, then it will be difficult to define a "
329 "canonical reference frame.");
356 from_app_transform_construction_data =
358 ?
_to_multi_app->problemBase().coordTransform().minimalDataDescription()
359 :
_from_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
362 std::make_unique<MooseAppCoordTransform>(from_app_transform_construction_data);
366 to_app_transform_construction_data =
368 ?
_from_multi_app->problemBase().coordTransform().minimalDataDescription()
369 :
_to_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
372 std::make_unique<MooseAppCoordTransform>(to_app_transform_construction_data);
383 auto create_multiapp_transforms = [
this](
auto & transforms,
384 const auto & moose_app_transform,
385 const bool is_parent_app_transform,
386 const MultiApp *
const multiapp =
nullptr)
388 mooseAssert(is_parent_app_transform || multiapp,
389 "Coordinate transform must be created either for child app or parent app");
390 if (is_parent_app_transform)
392 transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
398 mooseAssert(transforms.size() == 0,
"transforms should not be initialized at this point");
399 for (
const auto i : make_range(multiapp->numGlobalApps()))
401 transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
402 auto & transform = transforms[i];
404 if (multiapp->usingPositions())
405 transform->setTranslationVector(multiapp->position(i));
412 create_multiapp_transforms(
419 create_multiapp_transforms(
424 create_multiapp_transforms(
426 create_multiapp_transforms(
437 "' has non-translation transformations but it does not implement coordinate "
438 "transformations using the 'MooseAppCoordTransform' class. Your data transfers "
439 "will not be performed in the expected transformed frame");
451 check_transform_compatibility(*from_transform);
458 check_transform_compatibility(*to_transform);
466 std::vector<unsigned int> & map,
467 std::vector<FEProblemBase *> & problems,
468 std::vector<Point> & positions)
470 for (
unsigned int i_app = 0; i_app < multi_app.
numGlobalApps(); i_app++)
477 map.push_back(i_app);
478 problems.push_back(&subapp_problem);
480 positions.push_back(multi_app.
position(i_app));
489 mooseError(
"There is no to_multiapp to get info from");
498 mooseError(
"There is no from_multiapp to get info from");
512 const auto extension_factor = factor - 1;
521 for (
auto & box : bboxes)
530 if (box.first(0) == std::numeric_limits<Real>::max())
533 auto width = box.second - box.first;
534 box.second += width * extension_factor;
535 box.first -= width * extension_factor;
539std::vector<BoundingBox>
542 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
556 bb_points[i] =
static_cast<std::pair<Point, Point>
>(bbox);
563 std::vector<BoundingBox> bboxes(bb_points.size());
564 for (
unsigned int i = 0; i < bb_points.size(); i++)
565 bboxes[i] =
static_cast<BoundingBox
>(bb_points[i]);
573std::vector<BoundingBox>
576 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
577 const Real min_r = std::numeric_limits<Real>::lowest();
578 const Real max_r = std::numeric_limits<Real>::max();
583 Point min(max_r, max_r, max_r);
584 Point max(min_r, min_r, min_r);
585 bool at_least_one =
false;
589 for (
const auto & bnode : bnd_nodes)
591 if (bnode->_bnd_id == boundary_id &&
592 bnode->_node->processor_id() ==
_from_meshes[i]->processor_id())
595 const auto & node = *bnode->_node;
598 min(i) = std::min(min(i), node(i));
599 max(i) = std::max(max(i), node(i));
604 BoundingBox bbox(min, max);
617 bb_points[i] =
static_cast<std::pair<Point, Point>
>(bbox);
624 std::vector<BoundingBox> bboxes(bb_points.size());
625 for (
unsigned int i = 0; i < bb_points.size(); i++)
626 bboxes[i] =
static_cast<BoundingBox
>(bb_points[i]);
634std::vector<unsigned int>
637 std::vector<unsigned int> froms_per_proc;
645 return froms_per_proc;
651 mooseAssert(
_to_multi_app,
"getTransferVector only works for transfers to multiapps");
658 const VariableName & var_name,
659 const std::string & param_name)
const
663 if (param_name.empty())
664 mooseError(
"The variable '", var_name,
"' does not exist.");
666 paramError(param_name,
"The variable '", var_name,
"' does not exist.");
673 const std::string & phase)
const
678 mooseInfo(phase +
" cannot use the point in the app frame due to the "
679 "non-uniqueness of the coordinate collapsing reverse mapping."
680 " Coordinate collapse is ignored for this operation");
682 const auto pt = transform.
mapBack(p);
692 unsigned int local_i_from,
693 const std::string & phase)
const
701 unsigned int local_i_to,
702 const std::string & phase)
const
711 "Out of bounds local from-app index");
719 "Out of bounds local to-app index");
749 if (!
isParamValid(
"warn_source_object_execution_schedule") ||
750 getParam<bool>(
"warn_source_object_execution_schedule"))
752 "This UserObject-derived class is being executed on '" +
754 "' and also providing values for the '" +
name() +
755 "' transfer, on that same execution schedule. Because user objects are "
756 "executed after transfers are, this means the values provided by this "
757 "user object are lagged. If you are ok with this, then set the "
758 "'warn_source_object_execution_schedule' parameter to false in this "
759 "Transfer. If not, then execute '" +
761 "' on TRANSFER by adding it to the 'execute_on' vector parameter.");
774 const auto & problem = app->appProblemBase(app->firstLocalApp());
776 std::vector<SetupInterface *> objects_with_exec_on;
777 problem.theWarehouse()
779 .template condition<AttribName>(object_name)
781 .queryInto(objects_with_exec_on);
782 if (objects_with_exec_on.size())
784 "' should not be executed on EXEC_TRANSFER, because this transfer has "
785 "indicated it does not support it.\nExecuting this object on TIMESTEP_END should be "
786 "sufficient to get updated values.");
boundary_id_type BoundaryID
const ExecFlagType EXEC_TRANSFER
const ExecFlagType EXEC_SAME_AS_MULTIAPP
const ExecFlagType EXEC_POST_ADAPTIVITY
const ExecFlagType EXEC_INITIAL
A MultiMooseEnum object to hold "execute_on" flags.
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
std::shared_ptr< MultiApp > getMultiApp(const std::string &multi_app_name) const
Get a MultiApp object by name.
virtual bool hasVariable(const std::string &var_name) const override
Whether or not this problem has the variable.
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
const InputParameters & parameters() const
Get the parameters of the object.
const std::string & type() const
Get the type of this class.
const std::string & name() const
Get the name of the class.
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 ...
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...
void mooseInfo(Args &&... args) const
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
static void addSkipCoordCollapsingParam(InputParameters ¶ms)
Add the option to skip coordinate collapsing in coordinate transformation operations Note: this is us...
std::unique_ptr< MooseAppCoordTransform > _to_moose_app_transform
The moose coordinate transformation object describing rotations, scaling, and coordinate system of th...
libMesh::NumericVector< Real > & getTransferVector(unsigned int i_local, std::string var_name)
If we are transferring to a multiapp, return the appropriate solution vector.
std::vector< unsigned int > _to_local2global_map
Given local app index, returns global app index.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
std::vector< Point > _from_positions
virtual bool usesMooseAppCoordTransform() const
Whether this transfer handles non-translation-based transformations, e.g.
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp,...
unsigned int getLocalSourceAppIndex(unsigned int i_from) const
Return the local app index from the global 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< libMesh::EquationSystems * > _from_es
std::vector< unsigned int > _from_local2global_map
Given local app index, returns global app index.
std::vector< Point > _to_positions
virtual void checkSiblingsTransferSupported() const
Whether the transfer supports siblings transfer.
std::vector< MooseMesh * > _from_meshes
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
Point mapBackWithoutCollapsing(MultiAppCoordTransform &transform, const Point &p, const std::string &phase) const
Shared implementation for getPointInSourceAppFrame / getPointInTargetAppFrame.
static void addBBoxFactorParam(InputParameters ¶ms)
Add the bounding box factor parameter to the supplied input parameters.
std::vector< FEProblemBase * > _from_problems
static void addUserObjectExecutionCheckParam(InputParameters ¶ms)
Add the execution order check parameter (to skip the warning if needed)
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
virtual void getAppInfo()
This method will fill information into the convenience member variables (_to_problems,...
Point getPointInTargetAppFrame(const Point &p, unsigned int local_i_to, const std::string &phase) const
Get the target app point from a point in the reference frame.
std::unique_ptr< MooseAppCoordTransform > _from_moose_app_transform
The moose coordinate transformation object describing rotations, scaling, and coordinate system of th...
void checkVariable(const FEProblemBase &fe_problem, const VariableName &var_name, const std::string ¶m_name="") const
Helper for checking a problem for a variable.
MultiAppTransfer(const InputParameters ¶meters)
std::vector< libMesh::BoundingBox > getFromBoundingBoxes()
Return the bounding boxes of all the "from" domains, including all the domains not local to this proc...
void getFromMultiAppInfo()
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
unsigned int getGlobalTargetAppIndex(unsigned int i_to) const
Return the global app index from the local index in the "to-multiapp" transfer direction.
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
std::vector< FEProblemBase * > _to_problems
void checkParentAppUserObjectExecuteOn(const std::string &object_name) const
Checks the execute_on flags for user object transfers with user objects on the source app which is al...
std::shared_ptr< MultiApp > _from_multi_app
The MultiApps this Transfer is transferring data to or from.
void extendBoundingBoxes(const Real factor, std::vector< libMesh::BoundingBox > &bboxes) const
Extends bounding boxes to avoid missing points.
void checkMultiAppExecuteOn()
Helper method for checking the 'check_multiapp_execute_on' flag.
std::shared_ptr< MultiApp > _to_multi_app
std::vector< MooseMesh * > _to_meshes
static InputParameters validParams()
Real _bbox_factor
Extend (or contract) bounding box by a factor in all directions Greater than one values of this membe...
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
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.
std::vector< libMesh::EquationSystems * > _to_es
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
void variableIntegrityCheck(const AuxVariableName &var_name, bool is_from_multiapp) const
Utility to verify that the variable in the destination system exists.
std::shared_ptr< MultiApp > _multi_app
Deprecated class attribute for compatibility with the apps.
const bool _skip_coordinate_collapsing
Whether to skip coordinate collapsing (transformations of coordinates between applications using diff...
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
A MultiApp represents one or more MOOSE applications that are running simultaneously.
bool usingPositions() const
Whether or not this MultiApp is using positions or its own way for constructing sub-apps.
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
bool hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
const Point & position(unsigned int app) const
The physical position of a global App number.
unsigned int numGlobalApps() const
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
void setAdditionalValue(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
unsigned int get(unsigned int i) const
Indexing operator Operator to retrieve the id of an item from the MultiMooseEnum.
bool contains(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
const ExecFlagEnum & getExecuteOnEnum() const
Return the execute on MultiMooseEnum for this object.
void mooseWarning(Args &&... args) const
void paramWarning(const std::string ¶m, Args... args) const
processor_id_type rank() const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Base class for all Transfer objects.
static InputParameters validParams()
MultiMooseEnum _directions
The directions this Transfer is to be executed on.
FEProblemBase & _fe_problem
MooseEnum _current_direction
const bool _exec_after_source_app_exec
Whether a transfer executing on BETWEEN_MULTIAPPS and on the same execute_on flag should execute befo...
Base class for user-specific data.
const Parallel::Communicator & _communicator
processor_id_type n_processors() const
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
std::string stringify(const T &t)
conversion to string