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"))
163 "The deprecated 'direction' parameter is meant to be used in conjunction with the " 164 "'multi_app' parameter");
167 "The deprecated 'direction' parameter is not meant to be used in conjunction with " 168 "the 'from_multi_app' or 'to_multi_app' parameters");
178 mooseWarning(
"MultiAppTransfer execute_on flags do not match associated from_multi_app " 179 "execute_on flags"));
184 mooseWarning(
"MultiAppTransfer execute_on flags do not match associated to_multi_app " 185 "execute_on flags"));
192 mooseWarning(
"MultiAppTransfer execute_on flags do not match associated to_multi_app " 193 "and from_multi_app execute_on flags"));
198 bool is_from_multiapp)
const 200 bool variable_found =
false;
201 bool has_an_app =
false;
210 variable_found =
true;
215 for (
unsigned int i = 0; i <
_to_multi_app->numGlobalApps(); i++)
220 variable_found =
true;
223 if (!variable_found && has_an_app)
224 mooseError(
"Cannot find variable ", var_name,
" for ",
name(),
" Transfer");
284 "I believe these should be the same. If not, then it will be difficult to define a " 285 "canonical reference frame.");
312 from_app_transform_construction_data =
314 ?
_to_multi_app->problemBase().coordTransform().minimalDataDescription()
315 :
_from_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
318 std::make_unique<MooseAppCoordTransform>(from_app_transform_construction_data);
322 to_app_transform_construction_data =
324 ?
_from_multi_app->problemBase().coordTransform().minimalDataDescription()
325 :
_to_multi_app->appProblemBase(0).coordTransform().minimalDataDescription();
328 std::make_unique<MooseAppCoordTransform>(to_app_transform_construction_data);
339 auto create_multiapp_transforms = [
this](
auto & transforms,
340 const auto & moose_app_transform,
341 const bool is_parent_app_transform,
342 const MultiApp *
const multiapp =
nullptr)
344 mooseAssert(is_parent_app_transform || multiapp,
345 "Coordinate transform must be created either for child app or parent app");
346 if (is_parent_app_transform)
348 transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
354 mooseAssert(transforms.size() == 0,
"transforms should not be initialized at this point");
355 for (
const auto i :
make_range(multiapp->numGlobalApps()))
357 transforms.push_back(std::make_unique<MultiAppCoordTransform>(moose_app_transform));
358 auto & transform = transforms[i];
360 if (multiapp->usingPositions())
361 transform->setTranslationVector(multiapp->position(i));
368 create_multiapp_transforms(
375 create_multiapp_transforms(
380 create_multiapp_transforms(
382 create_multiapp_transforms(
393 "' has non-translation transformations but it does not implement coordinate " 394 "transformations using the 'MooseAppCoordTransform' class. Your data transfers " 395 "will not be performed in the expected transformed frame");
407 check_transform_compatibility(*from_transform);
414 check_transform_compatibility(*to_transform);
422 std::vector<unsigned int> & map,
423 std::vector<FEProblemBase *> & problems,
424 std::vector<Point> & positions)
426 for (
unsigned int i_app = 0; i_app < multi_app.
numGlobalApps(); i_app++)
433 map.push_back(i_app);
434 problems.push_back(&subapp_problem);
436 positions.push_back(multi_app.
position(i_app));
445 mooseError(
"There is no to_multiapp to get info from");
454 mooseError(
"There is no from_multiapp to get info from");
468 const auto extension_factor = factor - 1;
477 for (
auto & box : bboxes)
489 auto width = box.second - box.first;
490 box.second += width * extension_factor;
491 box.first -= width * extension_factor;
495 std::vector<BoundingBox>
498 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
503 BoundingBox bbox = MeshTools::create_local_bounding_box(*
_from_meshes[i]);
512 bb_points[i] =
static_cast<std::pair<Point, Point>
>(bbox);
519 std::vector<BoundingBox> bboxes(bb_points.size());
520 for (
unsigned int i = 0; i < bb_points.size(); i++)
521 bboxes[i] = static_cast<BoundingBox>(bb_points[i]);
529 std::vector<BoundingBox>
532 std::vector<std::pair<Point, Point>> bb_points(
_from_meshes.size());
533 const Real min_r = std::numeric_limits<Real>::lowest();
539 Point
min(max_r, max_r, max_r);
540 Point
max(min_r, min_r, min_r);
541 bool at_least_one =
false;
545 for (
const auto & bnode : bnd_nodes)
547 if (bnode->_bnd_id == boundary_id &&
548 bnode->_node->processor_id() ==
_from_meshes[i]->processor_id())
551 const auto & node = *bnode->_node;
560 BoundingBox bbox(
min,
max);
573 bb_points[i] =
static_cast<std::pair<Point, Point>
>(bbox);
580 std::vector<BoundingBox> bboxes(bb_points.size());
581 for (
unsigned int i = 0; i < bb_points.size(); i++)
582 bboxes[i] = static_cast<BoundingBox>(bb_points[i]);
590 std::vector<unsigned int>
593 std::vector<unsigned int> froms_per_proc;
601 return froms_per_proc;
604 NumericVector<Real> &
607 mooseAssert(
_to_multi_app,
"getTransferVector only works for transfers to multiapps");
614 const VariableName & var_name,
615 const std::string & param_name)
const 619 if (param_name.empty())
620 mooseError(
"The variable '", var_name,
"' does not exist.");
622 paramError(param_name,
"The variable '", var_name,
"' does not exist.");
628 unsigned int local_i_to,
629 const std::string & phase)
const 632 if (to_transform->hasCoordinateSystemTypeChange())
635 mooseInfo(phase +
" cannot use the point in the target app frame due to the " 636 "non-uniqueness of the coordinate collapsing reverse mapping." 637 " Coordinate collapse is ignored for this operation");
638 to_transform->skipCoordinateCollapsing(
true);
639 const auto target_point = to_transform->mapBack(p);
640 to_transform->skipCoordinateCollapsing(
false);
644 return to_transform->mapBack(p);
651 "Out of bounds local from-app index");
659 "Out of bounds local to-app index");
689 if (!
isParamValid(
"warn_source_object_execution_schedule") ||
690 getParam<bool>(
"warn_source_object_execution_schedule"))
692 "This UserObject-derived class is being executed on '" +
694 "' and also providing values for the '" +
name() +
695 "' transfer, on that same execution schedule. Because user objects are " 696 "executed after transfers are, this means the values provided by this " 697 "user object are lagged. If you are ok with this, then set the " 698 "'warn_source_object_execution_schedule' parameter to false in this " 699 "Transfer. If not, then execute '" +
701 "' on TRANSFER by adding it to the 'execute_on' vector parameter.");
714 const auto & problem = app->appProblemBase(app->firstLocalApp());
716 std::vector<SetupInterface *> objects_with_exec_on;
717 problem.theWarehouse()
719 .template condition<AttribName>(object_name)
721 .queryInto(objects_with_exec_on);
722 if (objects_with_exec_on.size())
724 "' should not be executed on EXEC_TRANSFER, because this transfer has " 725 "indicated it does not support it.\nExecuting this object on TIMESTEP_END should be " 726 "sufficient to get updated values.");
libMesh::NumericVector< Real > & getTransferVector(unsigned int i_local, std::string var_name)
If we are transferring to a multiapp, return the appropriate solution vector.
virtual bool hasVariable(const std::string &var_name) const override
Whether or not this problem has the variable.
void mooseInfo(Args &&... args) const
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
bool hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
const ExecFlagType EXEC_TRANSFER
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
std::vector< libMesh::EquationSystems * > _to_es
A MultiMooseEnum object to hold "execute_on" flags.
std::unique_ptr< MooseAppCoordTransform > _to_moose_app_transform
The moose coordinate transformation object describing rotations, scaling, and coordinate system of th...
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
static void transformBoundingBox(libMesh::BoundingBox &box, const MultiAppCoordTransform &transform)
Transform a bounding box according to the transformations in the provided coordinate transformation o...
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 ...
const bool _skip_coordinate_collapsing
Whether to skip coordinate collapsing (transformations of coordinates between applications using diff...
MooseEnum _current_direction
void variableIntegrityCheck(const AuxVariableName &var_name, bool is_from_multiapp) const
Utility to verify that the variable in the destination system exists.
void setAdditionalValue(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
unsigned int getLocalSourceAppIndex(unsigned int i_from) const
Return the local app index from the global index in the "from-multiapp" transfer direction We use the...
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
static void addUserObjectExecutionCheckParam(InputParameters ¶ms)
Add the execution order check parameter (to skip the warning if needed)
const InputParameters & parameters() const
Get the parameters of the object.
void checkMultiAppExecuteOn()
Helper method for checking the 'check_multiapp_execute_on' flag.
std::shared_ptr< MultiApp > _from_multi_app
The MultiApps this Transfer is transferring data to or from.
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...
std::vector< FEProblemBase * > _to_problems
processor_id_type rank() const
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
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...
FEProblemBase & _fe_problem
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
std::vector< Point > _from_positions
const Parallel::Communicator & _communicator
std::shared_ptr< MultiApp > _multi_app
Deprecated class attribute for compatibility with the apps.
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
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.
auto max(const L &left, const R &right)
std::shared_ptr< MultiApp > getMultiApp(const std::string &multi_app_name) const
Get a MultiApp object by name.
std::vector< unsigned int > _to_local2global_map
Given local app index, returns global app index.
void checkVariable(const FEProblemBase &fe_problem, const VariableName &var_name, const std::string ¶m_name="") const
Helper for checking a problem for a variable.
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.
virtual bool usesMooseAppCoordTransform() const
Whether this transfer handles non-translation-based transformations, e.g.
processor_id_type n_processors() const
const std::string & name() const
Get the name of the class.
std::vector< libMesh::EquationSystems * > _from_es
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...
void errorIfObjectExecutesOnTransferInSourceApp(const std::string &object_name) const
Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, e.g.
unsigned int numGlobalApps() const
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
boundary_id_type BoundaryID
void getFromMultiAppInfo()
std::unique_ptr< MooseAppCoordTransform > _from_moose_app_transform
The moose coordinate transformation object describing rotations, scaling, and coordinate system of th...
const ExecFlagEnum & getExecuteOnEnum() const
Return the execute on MultiMooseEnum for this object.
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
static InputParameters validParams()
const std::string & type() const
Get the type of this class.
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
std::shared_ptr< MultiApp > _to_multi_app
std::string stringify(const T &t)
conversion to string
static InputParameters validParams()
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
bool usingPositions() const
Whether or not this MultiApp is using positions or its own way for constructing sub-apps.
std::vector< Point > _to_positions
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MultiMooseEnum _directions
The directions this Transfer is to be executed on.
Real _bbox_factor
Extend (or contract) bounding box by a factor in all directions Greater than one values of this membe...
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
IntRange< T > make_range(T beg, T end)
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
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...
const ExecFlagType EXEC_SAME_AS_MULTIAPP
std::vector< unsigned int > _from_local2global_map
Given local app index, returns global app index.
static void addBBoxFactorParam(InputParameters ¶ms)
Add the bounding box factor parameter to the supplied input parameters.
static void addSkipCoordCollapsingParam(InputParameters ¶ms)
Add the option to skip coordinate collapsing in coordinate transformation operations Note: this is us...
void extendBoundingBoxes(const Real factor, std::vector< libMesh::BoundingBox > &bboxes) const
Extends bounding boxes to avoid missing points.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
virtual void checkSiblingsTransferSupported() const
Whether the transfer supports siblings transfer.
void paramWarning(const std::string ¶m, Args... args) const
Emits a warning prefixed with the file and line number of the given param (from the input file) along...
A MultiApp represents one or more MOOSE applications that are running simultaneously.
virtual void getAppInfo()
This method will fill information into the convenience member variables (_to_problems, _from_meshes, etc.)
auto min(const L &left, const R &right)
std::vector< FEProblemBase * > _from_problems
auto index_range(const T &sizable)
Base class for user-specific data.
const Point & position(unsigned int app) const
The physical position of a global App number.
std::vector< MooseMesh * > _to_meshes
const ExecFlagType EXEC_POST_ADAPTIVITY
Base class for all Transfer objects.
const ExecFlagType EXEC_INITIAL