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 237 : const std::shared_ptr<MultiApp> getMultiApp() const 49 : { 50 237 : 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 237 : else if (_from_multi_app) 53 237 : 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 : /** 63 : * Get the MultiApp to transfer data from 64 : */ 65 391195 : const std::shared_ptr<MultiApp> getFromMultiApp() const 66 : { 67 391195 : if (!_from_multi_app) 68 0 : mooseError( 69 : "A from_multiapp was requested but is unavailable. Check the from_multi_app parameter"); 70 : else 71 391195 : return _from_multi_app; 72 : } 73 : 74 : /** 75 : * Get the MultiApp to transfer data to 76 : */ 77 157292 : const std::shared_ptr<MultiApp> getToMultiApp() const 78 : { 79 157292 : if (!_to_multi_app) 80 0 : mooseError( 81 : "A to_multiapp was requested but is unavailable. Check the to_multi_app parameter"); 82 : else 83 157292 : return _to_multi_app; 84 : } 85 : 86 : /** 87 : * Get the name of thing being transferred from 88 : * @return the name of the multiapp or "Parent" 89 : */ 90 3442 : std::string getFromName() const 91 : { 92 3442 : if (_from_multi_app) 93 1959 : return _from_multi_app->name(); 94 : else 95 2966 : return "Parent"; 96 : } 97 : 98 : /** 99 : * Get the name of thing being transferred to 100 : * @return the name of the multiapp or "Parent" 101 : */ 102 3442 : std::string getToName() const 103 : { 104 3442 : if (_to_multi_app) 105 1483 : return _to_multi_app->name(); 106 : else 107 3918 : return "Parent"; 108 : } 109 : 110 : /** 111 : * Whether the transfer owns a non-null from_multi_app 112 : */ 113 83531 : bool hasFromMultiApp() const { return !(!_from_multi_app); } 114 : 115 : /** 116 : * Whether the transfer owns a non-null to_multi_app 117 : */ 118 1385 : bool hasToMultiApp() const { return !(!_to_multi_app); } 119 : 120 : /** 121 : * This method will fill information into the convenience member variables 122 : * (_to_problems, _from_meshes, etc.) 123 : */ 124 : virtual void getAppInfo(); 125 : 126 : /** 127 : * Add the option to skip coordinate collapsing in coordinate transformation operations 128 : * Note: this is used by Actions creating transfers as well 129 : */ 130 : static void addSkipCoordCollapsingParam(InputParameters & params); 131 : 132 : protected: 133 : /** 134 : * Add the execution order check parameter (to skip the warning if needed) 135 : */ 136 : static void addUserObjectExecutionCheckParam(InputParameters & params); 137 : 138 : /** 139 : * Add the bounding box factor parameter to the supplied input parameters 140 : */ 141 : static void addBBoxFactorParam(InputParameters & params); 142 : 143 : /** 144 : * Transform a bounding box according to the transformations in the provided coordinate 145 : * transformation object 146 : */ 147 : static void transformBoundingBox(libMesh::BoundingBox & box, 148 : const MultiAppCoordTransform & transform); 149 : 150 : /// Deprecated class attribute for compatibility with the apps 151 : std::shared_ptr<MultiApp> _multi_app; 152 : 153 : std::vector<FEProblemBase *> _to_problems; 154 : std::vector<FEProblemBase *> _from_problems; 155 : std::vector<libMesh::EquationSystems *> _to_es; 156 : std::vector<libMesh::EquationSystems *> _from_es; 157 : std::vector<MooseMesh *> _to_meshes; 158 : std::vector<MooseMesh *> _from_meshes; 159 : std::vector<Point> _to_positions; 160 : std::vector<Point> _from_positions; 161 : std::vector<std::unique_ptr<MultiAppCoordTransform>> _to_transforms; 162 : std::vector<std::unique_ptr<MultiAppCoordTransform>> _from_transforms; 163 : 164 : /// Whether to skip coordinate collapsing (transformations of coordinates between applications 165 : /// using different frames of reference) 166 : const bool _skip_coordinate_collapsing; 167 : 168 : /// True if displaced mesh is used for the source mesh, otherwise false 169 : bool _displaced_source_mesh; 170 : /// True if displaced mesh is used for the target mesh, otherwise false 171 : bool _displaced_target_mesh; 172 : 173 : /// Extend (or contract) bounding box by a factor in all directions 174 : /// Greater than one values of this member may be necessary because the nearest bounding 175 : /// box does not necessarily give you the closest node/element. It will depend 176 : /// on the partition and geometry. A node/element will more likely find its 177 : /// nearest source element/node by extending bounding boxes. If each of the 178 : /// bounding boxes covers the entire domain, a node/element will be able to 179 : /// find its nearest source element/node for sure, 180 : /// but at the same time, more communication will be involved and can be expensive. 181 : Real _bbox_factor; 182 : 183 : ///@{ 184 : /** 185 : * Return the bounding boxes of all the "from" domains, including all the domains not local to 186 : * this processor. There is a boundary restricted version which will return a degenerate minimum 187 : * boundary box (min, min, min, min, min, min) in the case where the source domain doesn't 188 : * have any active nodes on the boundary. 189 : * Note: bounding boxes are in the reference space when using coordinate transformations / 190 : * positions 191 : * Note: global bounding boxes are not indexed by app number. But rather outer indexing is by 192 : * process, then the inner indexing is by local app number. 193 : */ 194 : std::vector<libMesh::BoundingBox> getFromBoundingBoxes(); 195 : std::vector<libMesh::BoundingBox> getFromBoundingBoxes(BoundaryID boundary_id); 196 : ///@} 197 : 198 : /** 199 : * Return the number of "from" domains that each processor owns. 200 : * Note: same indexing as getFromBoundingBoxes 201 : */ 202 : std::vector<unsigned int> getFromsPerProc(); 203 : 204 : /** 205 : * If we are transferring to a multiapp, return the appropriate solution 206 : * vector 207 : */ 208 : libMesh::NumericVector<Real> & getTransferVector(unsigned int i_local, std::string var_name); 209 : 210 : /// Given local app index, returns global app index. 211 : std::vector<unsigned int> _to_local2global_map; 212 : /// Given local app index, returns global app index. 213 : std::vector<unsigned int> _from_local2global_map; 214 : 215 : /** 216 : * Return the global app index from the local index in the "from-multiapp" transfer direction 217 : */ 218 : unsigned int getGlobalSourceAppIndex(unsigned int i_from) const; 219 : /** 220 : * Return the global app index from the local index in the "to-multiapp" transfer direction 221 : */ 222 : unsigned int getGlobalTargetAppIndex(unsigned int i_to) const; 223 : /** 224 : * Return the local app index from the global index in the "from-multiapp" transfer direction. 225 : * We use the fact that global app indexes are consecutive on a given rank. 226 : */ 227 : unsigned int getLocalSourceAppIndex(unsigned int i_from) const; 228 : 229 : /** 230 : * Whether the transfer supports siblings transfer 231 : */ 232 0 : virtual void checkSiblingsTransferSupported() const 233 : { 234 0 : mooseError("Siblings transfer not supported. You cannot transfer both from a multiapp to " 235 : "another multiapp"); 236 : } 237 : 238 : /** 239 : * Checks the execute_on flags for user object transfers with user objects on the source app 240 : * which is also the parent app. This is to prevent a common mistake lagging the data from the 241 : * user object. 242 : */ 243 : void checkParentAppUserObjectExecuteOn(const std::string & object_name) const; 244 : 245 : /** 246 : * Error if executing this MooseObject on EXEC_TRANSFER in a source multiapp (from_multiapp, 247 : * e.g. child/sibling app). Note that, conversely, when the parent app is the source 248 : * application, it is usually \emph desired to use EXEC_TRANSFER for a MooseObject that 249 : * provides the values to transfer. 250 : * @param object_name name of the object to check the execute_on flags for 251 : */ 252 : void errorIfObjectExecutesOnTransferInSourceApp(const std::string & object_name) const; 253 : 254 : /** 255 : * Get the target app point from a point in the reference frame 256 : * @param p the point in the reference frame 257 : * @param local_i_to the local target problem into 258 : * @param phase the phase of the transfer where this is being attempted in case we have 259 : * to output an info message that the coordinate collapse is not being applied 260 : * @return the point in the target app frame 261 : */ 262 : Point getPointInTargetAppFrame(const Point & p, 263 : unsigned int local_i_to, 264 : const std::string & phase) const; 265 : 266 : /** 267 : * Get the source app point from a point in the reference frame 268 : * @param p the point in the reference frame 269 : * @param local_i_from the local source problem index 270 : * @param phase the phase of the transfer where this is being attempted in case we have 271 : * to output an info message that the coordinate collapse is not being applied 272 : * @return the point in the source app frame 273 : */ 274 : Point getPointInSourceAppFrame(const Point & p, 275 : unsigned int local_i_from, 276 : const std::string & phase) const; 277 : 278 : /** 279 : * Helper method for checking the 'check_multiapp_execute_on' flag. 280 : * 281 : * This method was added to allow the check to be delayed by child classes, 282 : * see StochasticToolsTransfer for an example. 283 : */ 284 : void checkMultiAppExecuteOn(); 285 : 286 : /** 287 : * Helper for checking a problem for a variable. 288 : * 289 : * @param fe_problem The problem that should contain the variable 290 : * @param var_name The name of the variable that should exist within the problem 291 : * @param param_name (optional) The input file parameter name for throwing paramError, if not 292 : * provided a mooseError is thrown. 293 : */ 294 : void checkVariable(const FEProblemBase & fe_problem, 295 : const VariableName & var_name, 296 : const std::string & param_name = "") const; 297 : 298 : /** 299 : * Extends bounding boxes to avoid missing points 300 : */ 301 : void extendBoundingBoxes(const Real factor, std::vector<libMesh::BoundingBox> & bboxes) const; 302 : 303 : private: 304 : /** 305 : * Whether this transfer handles non-translation-based transformations, e.g. whether it uses the 306 : * \p MooseAppCoordTransform object 307 : */ 308 6 : virtual bool usesMooseAppCoordTransform() const { return false; } 309 : 310 : /** 311 : * Shared implementation for getPointInSourceAppFrame / getPointInTargetAppFrame. 312 : * Calls transform.mapBack(p), skipping coordinate collapsing when a coordinate system type 313 : * change is present (the reverse mapping is not uniquely defined in that case). 314 : */ 315 : Point mapBackWithoutCollapsing(MultiAppCoordTransform & transform, 316 : const Point & p, 317 : const std::string & phase) const; 318 : 319 : /// The MultiApps this Transfer is transferring data to or from 320 : std::shared_ptr<MultiApp> _from_multi_app; 321 : std::shared_ptr<MultiApp> _to_multi_app; 322 : 323 : void getFromMultiAppInfo(); 324 : void getToMultiAppInfo(); 325 : 326 : /// The moose coordinate transformation object describing rotations, scaling, and coordinate 327 : /// system of the from application 328 : std::unique_ptr<MooseAppCoordTransform> _from_moose_app_transform; 329 : 330 : /// The moose coordinate transformation object describing rotations, scaling, and coordinate 331 : /// system of the to application 332 : std::unique_ptr<MooseAppCoordTransform> _to_moose_app_transform; 333 : };