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