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.");
359 auto app0_root = [
this](
MultiApp & multiapp)
361 processor_id_type root = 0;
362 if (multiapp.hasLocalApp(0) && multiapp.isRootProcessor())
372 from_app_transform_construction_data =
373 _to_multi_app->problemBase().coordTransform().minimalDataDescription();
380 from_app_transform_construction_data =
381 _from_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
385 std::make_unique<MooseAppCoordTransform>(from_app_transform_construction_data);
391 to_app_transform_construction_data =
392 _from_multi_app->problemBase().coordTransform().minimalDataDescription();
399 to_app_transform_construction_data =
400 _to_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
404 std::make_unique<MooseAppCoordTransform>(to_app_transform_construction_data);
415 auto create_multiapp_transforms = [
this](
auto & transforms,
416 const auto & moose_app_transform,
417 const bool is_parent_app_transform,
418 const MultiApp *
const multiapp =
nullptr)
420 mooseAssert(is_parent_app_transform || multiapp,
421 "Coordinate transform must be created either for child app or parent app");
422 if (is_parent_app_transform)
424 transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
430 mooseAssert(transforms.size() == 0,
"transforms should not be initialized at this point");
431 for (
const auto i : make_range(multiapp->numGlobalApps()))
433 transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
434 auto & transform = transforms[i];
436 if (multiapp->usingPositions())
437 transform->setTranslationVector(multiapp->position(i));
444 create_multiapp_transforms(
451 create_multiapp_transforms(
456 create_multiapp_transforms(
458 create_multiapp_transforms(
469 "' has non-translation transformations but it does not implement coordinate "
470 "transformations using the 'MooseAppCoordTransform' class. Your data transfers "
471 "will not be performed in the expected transformed frame");
483 check_transform_compatibility(*from_transform);
490 check_transform_compatibility(*to_transform);
498 std::vector<unsigned int> & map,
499 std::vector<FEProblemBase *> & problems,
500 std::vector<Point> & positions)
502 for (
unsigned int i_app = 0; i_app < multi_app.
numGlobalApps(); i_app++)
509 map.push_back(i_app);
510 problems.push_back(&subapp_problem);
512 positions.push_back(multi_app.
position(i_app));
521 mooseError(
"There is no to_multiapp to get info from");
530 mooseError(
"There is no from_multiapp to get info from");
544 const auto extension_factor = factor - 1;
553 for (
auto & box : bboxes)
562 if (box.first(0) == std::numeric_limits<Real>::max())
565 auto width = box.second - box.first;
566 box.second += width * extension_factor;
567 box.first -= width * extension_factor;
571std::vector<BoundingBox>
574 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
588 bb_points[i] =
static_cast<std::pair<Point, Point>
>(bbox);
595 std::vector<BoundingBox> bboxes(bb_points.size());
596 for (
unsigned int i = 0; i < bb_points.size(); i++)
597 bboxes[i] =
static_cast<BoundingBox
>(bb_points[i]);
605std::vector<BoundingBox>
608 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
609 const Real min_r = std::numeric_limits<Real>::lowest();
610 const Real max_r = std::numeric_limits<Real>::max();
615 Point min(max_r, max_r, max_r);
616 Point max(min_r, min_r, min_r);
617 bool at_least_one =
false;
621 for (
const auto & bnode : bnd_nodes)
623 if (bnode->_bnd_id == boundary_id &&
624 bnode->_node->processor_id() ==
_from_meshes[i]->processor_id())
627 const auto & node = *bnode->_node;
630 min(i) = std::min(min(i), node(i));
631 max(i) = std::max(max(i), node(i));
636 BoundingBox bbox(min, max);
649 bb_points[i] =
static_cast<std::pair<Point, Point>
>(bbox);
656 std::vector<BoundingBox> bboxes(bb_points.size());
657 for (
unsigned int i = 0; i < bb_points.size(); i++)
658 bboxes[i] =
static_cast<BoundingBox
>(bb_points[i]);
666std::vector<unsigned int>
669 std::vector<unsigned int> froms_per_proc;
677 return froms_per_proc;
683 mooseAssert(
_to_multi_app,
"getTransferVector only works for transfers to multiapps");
690 const VariableName & var_name,
691 const std::string & param_name)
const
695 if (param_name.empty())
696 mooseError(
"The variable '", var_name,
"' does not exist.");
698 paramError(param_name,
"The variable '", var_name,
"' does not exist.");
705 const std::string & phase)
const
710 mooseInfo(phase +
" cannot use the point in the app frame due to the "
711 "non-uniqueness of the coordinate collapsing reverse mapping."
712 " Coordinate collapse is ignored for this operation");
714 const auto pt = transform.
mapBack(p);
724 unsigned int local_i_from,
725 const std::string & phase)
const
733 unsigned int local_i_to,
734 const std::string & phase)
const
743 "Out of bounds local from-app index");
751 "Out of bounds local to-app index");
781 if (!
isParamValid(
"warn_source_object_execution_schedule") ||
782 getParam<bool>(
"warn_source_object_execution_schedule"))
784 "This UserObject-derived class is being executed on '" +
786 "' and also providing values for the '" +
name() +
787 "' transfer, on that same execution schedule. Because user objects are "
788 "executed after transfers are, this means the values provided by this "
789 "user object are lagged. If you are ok with this, then set the "
790 "'warn_source_object_execution_schedule' parameter to false in this "
791 "Transfer. If not, then execute '" +
793 "' on TRANSFER by adding it to the 'execute_on' vector parameter.");
806 const auto & problem = app->appProblemBase(app->firstLocalApp());
808 std::vector<SetupInterface *> objects_with_exec_on;
809 problem.theWarehouse()
811 .template condition<AttribName>(object_name)
813 .queryInto(objects_with_exec_on);
814 if (objects_with_exec_on.size())
816 "' should not be executed on EXEC_TRANSFER, because this transfer has "
817 "indicated it does not support it.\nExecuting this object on TIMESTEP_END should be "
818 "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 to track the number and location of the child applica...
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
void max(const T &r, T &o, Request &req) 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