Line data Source code
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 : 10 : #pragma once 11 : 12 : // MOOSE includes 13 : #include "Transfer.h" 14 : #include "MultiMooseEnum.h" 15 : #include "MultiApp.h" 16 : #include "MooseAppCoordTransform.h" 17 : 18 : #include "libmesh/bounding_box.h" 19 : 20 : class MooseMesh; 21 : 22 : /** 23 : * Base class for all MultiAppTransfer objects. 24 : * 25 : * MultiAppTransfers are objects that push and pull values to and from 26 : * MultiApp objects from and to the main (parent app) system. 27 : * 28 : * Classes that inherit from this class still need to override the 29 : * execute() method from Transfer. 30 : */ 31 : class MultiAppTransfer : public Transfer 32 : { 33 : public: 34 : static InputParameters validParams(); 35 : 36 : MultiAppTransfer(const InputParameters & parameters); 37 : 38 : /** 39 : * Utility to verify that the variable in the destination system exists. 40 : */ 41 : void variableIntegrityCheck(const AuxVariableName & var_name, bool is_from_multiapp) const; 42 : 43 : void initialSetup() override; 44 : 45 : /** 46 : * Use this getter to obtain the MultiApp for transfers with a single direction 47 : */ 48 270 : const std::shared_ptr<MultiApp> getMultiApp() const 49 : { 50 270 : if (_from_multi_app && _to_multi_app && _from_multi_app != _to_multi_app) 51 0 : mooseError("Unclear which app you want to retrieve from Transfer ", name()); 52 270 : else if (_from_multi_app) 53 270 : return _from_multi_app; 54 0 : else if (_to_multi_app) 55 0 : return _to_multi_app; 56 0 : else if (_multi_app) 57 0 : return _multi_app; 58 : else 59 0 : mooseError("Should not get here, there should be a multiapp"); 60 : } 61 : 62 : /// Get the MultiApp to transfer data from 63 422389 : const std::shared_ptr<MultiApp> getFromMultiApp() const 64 : { 65 422389 : if (!_from_multi_app) 66 0 : mooseError( 67 : "A from_multiapp was requested but is unavailable. Check the from_multi_app parameter"); 68 : else 69 422389 : return _from_multi_app; 70 : } 71 : 72 : /// Get the MultiApp to transfer data to 73 164934 : const std::shared_ptr<MultiApp> getToMultiApp() const 74 : { 75 164934 : if (!_to_multi_app) 76 0 : mooseError( 77 : "A to_multiapp was requested but is unavailable. Check the to_multi_app parameter"); 78 : else 79 164934 : return _to_multi_app; 80 : } 81 : 82 : /** 83 : * Get the name of thing being transferred from 84 : * @return the name of the multiapp or "Parent" 85 : */ 86 3446 : std::string getFromName() const 87 : { 88 3446 : if (_from_multi_app) 89 1947 : return _from_multi_app->name(); 90 : else 91 2998 : return "Parent"; 92 : } 93 : 94 : /** 95 : * Get the name of thing being transferred to 96 : * @return the name of the multiapp or "Parent" 97 : */ 98 3446 : std::string getToName() const 99 : { 100 3446 : if (_to_multi_app) 101 1499 : return _to_multi_app->name(); 102 : else 103 3894 : return "Parent"; 104 : } 105 : 106 : /// Whether the transfer owns a non-null from_multi_app 107 86118 : bool hasFromMultiApp() const { return !(!_from_multi_app); } 108 : 109 : /// Whether the transfer owns a non-null to_multi_app 110 736 : bool hasToMultiApp() const { return !(!_to_multi_app); } 111 : 112 : /** 113 : * This method will fill information into the convenience member variables 114 : * (_to_problems, _from_meshes, etc.) 115 : */ 116 : virtual void getAppInfo(); 117 : 118 : /** 119 : * Add the option to skip coordinate collapsing in coordinate transformation operations 120 : * Note: this is used by Actions creating transfers as well 121 : */ 122 : static void addSkipCoordCollapsingParam(InputParameters & params); 123 : 124 : protected: 125 : /** 126 : * Add the execution order check parameter (to skip the warning if needed) 127 : */ 128 : static void addUserObjectExecutionCheckParam(InputParameters & params); 129 : 130 : /** 131 : * Add the bounding box factor parameter to the supplied input parameters 132 : */ 133 : static void addBBoxFactorParam(InputParameters & params); 134 : 135 : /** 136 : * Transform a bounding box according to the transformations in the provided coordinate 137 : * transformation object 138 : */ 139 : static void transformBoundingBox(libMesh::BoundingBox & box, 140 : const MultiAppCoordTransform & transform); 141 : 142 : /// Deprecated class attribute for compatibility with the apps 143 : std::shared_ptr<MultiApp> _multi_app; 144 : 145 : std::vector<FEProblemBase *> _to_problems; 146 : std::vector<FEProblemBase *> _from_problems; 147 : std::vector<libMesh::EquationSystems *> _to_es; 148 : std::vector<libMesh::EquationSystems *> _from_es; 149 : std::vector<MooseMesh *> _to_meshes; 150 : std::vector<MooseMesh *> _from_meshes; 151 : std::vector<Point> _to_positions; 152 : std::vector<Point> _from_positions; 153 : std::vector<std::unique_ptr<MultiAppCoordTransform>> _to_transforms; 154 : std::vector<std::unique_ptr<MultiAppCoordTransform>> _from_transforms; 155 : 156 : /// Whether to skip coordinate collapsing (transformations of coordinates between applications 157 : /// using different frames of reference) 158 : const bool _skip_coordinate_collapsing; 159 : 160 : /// True if displaced mesh is used for the source mesh, otherwise false 161 : bool _displaced_source_mesh; 162 : /// True if displaced mesh is used for the target mesh, otherwise false 163 : bool _displaced_target_mesh; 164 : 165 : /// Extend (or contract) bounding box by a factor in all directions 166 : /// Greater than one values of this member may be necessary because the nearest bounding 167 : /// box does not necessarily give you the closest node/element. It will depend 168 : /// on the partition and geometry. A node/element will more likely find its 169 : /// nearest source element/node by extending bounding boxes. If each of the 170 : /// bounding boxes covers the entire domain, a node/element will be able to 171 : /// find its nearest source element/node for sure, 172 : /// but at the same time, more communication will be involved and can be expensive. 173 : Real _bbox_factor; 174 : 175 : ///@{ 176 : /** 177 : * Return the bounding boxes of all the "from" domains, including all the domains not local to 178 : * this processor. There is a boundary restricted version which will return a degenerate minimum 179 : * boundary box (min, min, min, min, min, min) in the case where the source domain doesn't 180 : * have any active nodes on the boundary. 181 : * Note: bounding boxes are in the reference space when using coordinate transformations / 182 : * positions 183 : * Note: global bounding boxes are not indexed by app number. But rather outer indexing is by 184 : * process, then the inner indexing is by local app number. 185 : */ 186 : std::vector<libMesh::BoundingBox> getFromBoundingBoxes(); 187 : std::vector<libMesh::BoundingBox> getFromBoundingBoxes(BoundaryID boundary_id); 188 : ///@} 189 : 190 : /** 191 : * Return the number of "from" domains that each processor owns. 192 : * Note: same indexing as getFromBoundingBoxes 193 : */ 194 : std::vector<unsigned int> getFromsPerProc(); 195 : 196 : /** 197 : * If we are transferring to a multiapp, return the appropriate solution 198 : * vector 199 : */ 200 : libMesh::NumericVector<Real> & getTransferVector(unsigned int i_local, std::string var_name); 201 : 202 : /// Given local app index, returns global app index. 203 : std::vector<unsigned int> _to_local2global_map; 204 : /// Given local app index, returns global app index. 205 : std::vector<unsigned int> _from_local2global_map; 206 : 207 : /// Return the global app index from the local index in the "from-multiapp" transfer direction 208 : unsigned int getGlobalSourceAppIndex(unsigned int i_from) const; 209 : /// Return the global app index from the local index in the "to-multiapp" transfer direction 210 : unsigned int getGlobalTargetAppIndex(unsigned int i_to) const; 211 : /// Return the local app index from the global index in the "from-multiapp" transfer direction 212 : /// We use the fact that global app indexes are consecutive on a given rank 213 : unsigned int getLocalSourceAppIndex(unsigned int i_from) const; 214 : 215 : /// Whether the transfer supports siblings transfer 216 0 : virtual void checkSiblingsTransferSupported() const 217 : { 218 0 : mooseError("Siblings transfer not supported. You cannot transfer both from a multiapp to " 219 : "another multiapp"); 220 : } 221 : 222 : /// Checks the execute_on flags for user object transfers with user objects on the source app 223 : /// which is also the parent app. This is to prevent a common mistake lagging the data from the 224 : /// user object 225 : void checkParentAppUserObjectExecuteOn(const std::string & object_name) const; 226 : 227 : /** 228 : * Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, 229 : * e.g. child/sibling app). Note that, conversely, when the parent app is the source 230 : * application, it is usually \emph desired to use EXEC_TRANSFER for a MooseObject that 231 : * provides the values to transfer. 232 : * @param object_name name of the object to check the execute_on flags for 233 : */ 234 : void errorIfObjectExecutesOnTransferInSourceApp(const std::string & object_name) const; 235 : 236 : /** 237 : * Get the target app point from a point in the reference frame 238 : * @param p the point in the reference frame 239 : * @param local_i_to the local target problem into 240 : * @param phase the phase of the transfer where this is being attempted in case we have 241 : * to output an info message that the coordinate collapse is not being applied 242 : * @return the point in the target app frame 243 : */ 244 : Point getPointInTargetAppFrame(const Point & p, 245 : unsigned int local_i_to, 246 : const std::string & phase) const; 247 : 248 : /** 249 : * Helper method for checking the 'check_multiapp_execute_on' flag. 250 : * 251 : * This method was added to allow the check to be delayed by child classes, 252 : * see StochasticToolsTransfer for an example. 253 : */ 254 : void checkMultiAppExecuteOn(); 255 : 256 : /** 257 : * Helper for checking a problem for a variable. 258 : * 259 : * @param fe_problem The problem that should contain the variable 260 : * @param var_name The name of the variable that should exist within the problem 261 : * @param param_name (optional) The input file parameter name for throwing paramError, if not 262 : * provided a mooseError is thrown. 263 : */ 264 : void checkVariable(const FEProblemBase & fe_problem, 265 : const VariableName & var_name, 266 : const std::string & param_name = "") const; 267 : 268 : /// Extends bounding boxes to avoid missing points 269 : void extendBoundingBoxes(const Real factor, std::vector<libMesh::BoundingBox> & bboxes) const; 270 : 271 : private: 272 : /** 273 : * Whether this transfer handles non-translation-based transformations, e.g. whether it uses the 274 : * \p MooseAppCoordTransform object 275 : */ 276 8 : virtual bool usesMooseAppCoordTransform() const { return false; } 277 : 278 : /// The MultiApps this Transfer is transferring data to or from 279 : std::shared_ptr<MultiApp> _from_multi_app; 280 : std::shared_ptr<MultiApp> _to_multi_app; 281 : 282 : void getFromMultiAppInfo(); 283 : void getToMultiAppInfo(); 284 : 285 : /// The moose coordinate transformation object describing rotations, scaling, and coordinate 286 : /// system of the from application 287 : std::unique_ptr<MooseAppCoordTransform> _from_moose_app_transform; 288 : 289 : /// The moose coordinate transformation object describing rotations, scaling, and coordinate 290 : /// system of the to application 291 : std::unique_ptr<MooseAppCoordTransform> _to_moose_app_transform; 292 : };