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 : #ifdef MOOSE_MFEM_ENABLED 11 : 12 : #pragma once 13 : 14 : #include "MultiAppTransfer.h" 15 : 16 : /** 17 : * Virtual base class for MultiApp transfers to and/or from MFEMProblems. 18 : */ 19 : class MFEMMultiAppTransfer : public MultiAppTransfer 20 : { 21 : public: 22 : static InputParameters validParams(); 23 : MFEMMultiAppTransfer(InputParameters const & params); 24 : /// Set active source and destination problems, and execute variable transfer 25 : void execute() override; 26 : /// Allow sibling transfers 27 74 : void checkSiblingsTransferSupported() const override {} 28 : 29 : /// Getter for source variable name 30 1308 : const VariableName & getFromVarName(int i) const { return _from_var_names.at(i); } 31 : /// Getter for destination variable name 32 2515 : const VariableName & getToVarName(int i) const { return _to_var_names.at(i); } 33 : /// Return the number of source variables 34 721 : unsigned int numFromVar() const { return _from_var_names.size(); } 35 : /// Return for the number of destination variables 36 1602 : unsigned int numToVar() const { return _to_var_names.size(); } 37 : 38 : protected: 39 : /// Transfer all variables from active source problem to active destination problem. 40 : virtual void transferVariables(bool is_target_local) = 0; 41 : 42 : /// Set current problem to fetch source variables from 43 881 : void setActiveFromProblem(FEProblemBase & from_problem, const unsigned int global_app_index) 44 : { 45 881 : _active_from_problem = &from_problem; 46 881 : _active_from_global_app_index = global_app_index; 47 881 : } 48 : /// Set current problem to fetch destination variables from 49 859 : void setActiveToProblem(FEProblemBase & to_problem, const unsigned int global_app_index) 50 : { 51 859 : _active_to_problem = &to_problem; 52 859 : _active_to_global_app_index = global_app_index; 53 859 : } 54 : /// Getter for current problem containing source variables 55 1005 : virtual FEProblemBase & getActiveFromProblem() { return *_active_from_problem; } 56 : /// Getter for current problem containing destination variables 57 2515 : virtual FEProblemBase & getActiveToProblem() { return *_active_to_problem; } 58 : /// Getter for current destination problem global app index. 59 0 : virtual unsigned int & getActiveToProblemGlobalAppIndex() { return _active_to_global_app_index; } 60 : /// Getter for current destination problem global app index. 61 0 : virtual unsigned int & getActiveFromProblemGlobalAppIndex() 62 : { 63 0 : return _active_from_global_app_index; 64 : } 65 : 66 : /// Getter for the active source transform 67 329367 : const MultiAppCoordTransform & getActiveFromTransform() const 68 : { 69 329367 : return *_from_transforms[_active_from_global_app_index]; 70 : } 71 : /// Getter for the active destination transform 72 329367 : const MultiAppCoordTransform & getActiveToTransform() const 73 : { 74 329367 : return *_to_transforms[_active_to_global_app_index]; 75 : } 76 : /// Map a point in the active destination app frame to the active source app frame 77 329367 : libMesh::Point mapPointToActiveSourceFrame(const Point & point_in_target_frame) const 78 : { 79 329367 : return getActiveFromTransform().mapBack(getActiveToTransform()(point_in_target_frame)); 80 : } 81 : /// Get libMesh EquationSystem, which may or may not be displaced 82 : libMesh::EquationSystems & getlibMeshEquationSystem(FEProblemBase & problem, 83 : bool use_displaced) const; 84 : 85 : /// Set default value for transfers evaluated at points outside source mesh 86 : void setMFEMOutOfMeshValue(mfem::real_t mfem_out_of_mesh_value) 87 : { 88 : _mfem_out_of_mesh_value = mfem_out_of_mesh_value; 89 : } 90 : /// Getter for default value for transfers evaluated at points outside source mesh 91 216876 : mfem::real_t getMFEMOutOfMeshValue() const { return _mfem_out_of_mesh_value; } 92 : 93 : /// Templated method to check source and destination problems are of the expected types 94 : template <typename TO_PROBLEM, typename FROM_PROBLEM> 95 : void checkValidTransferProblemTypes(); 96 : 97 : private: 98 : /// Vector of source variable names to be transferred 99 : const std::vector<VariableName> & _from_var_names; 100 : /// Vector of destination variable names to transfer to 101 : const std::vector<VariableName> & _to_var_names; 102 : /// Pointer to active destination problem variable is being transferred to 103 : FEProblemBase * _active_to_problem{nullptr}; 104 : /// Pointer to active source problem variable is being transferred from 105 : FEProblemBase * _active_from_problem{nullptr}; 106 : /// Global app index for the active destination problem 107 : unsigned int _active_to_global_app_index{0}; 108 : /// Global app index for the active source problem 109 : unsigned int _active_from_global_app_index{0}; 110 : /// Default value to return for transfers from points outside the source mesh 111 : mfem::real_t _mfem_out_of_mesh_value{std::numeric_limits<mfem::real_t>::infinity()}; 112 : }; 113 : 114 : template <typename TO_PROBLEM, typename FROM_PROBLEM> 115 : inline void 116 721 : MFEMMultiAppTransfer::checkValidTransferProblemTypes() 117 : { 118 721 : auto bad_problem = [this]() 119 : { 120 0 : mooseError( 121 0 : type(), 122 : " is not compatible with the provided source and/or destination Problem types of the " 123 : "provided variables."); 124 : }; 125 : 126 721 : if (hasFromMultiApp()) 127 : { 128 : // Check if source sub-apps exist, and if so, if they are of the expected type 129 701 : if (getFromMultiApp()->numGlobalApps()) 130 : { 131 1402 : for (const auto i : make_range(getFromMultiApp()->numGlobalApps())) 132 2103 : if (getFromMultiApp()->hasLocalApp(i) && 133 1402 : !dynamic_cast<FROM_PROBLEM *>(&getFromMultiApp()->appProblemBase(i))) 134 0 : bad_problem(); 135 : } 136 : else // check source sub-app is of the expected type if it is the transfer source 137 0 : if (!dynamic_cast<FROM_PROBLEM *>(&getFromMultiApp()->problemBase())) 138 0 : bad_problem(); 139 : } 140 721 : if (hasToMultiApp()) 141 : { 142 : // Check if destination sub-apps exist, and if so, if they are of the expected type 143 107 : if (getToMultiApp()->numGlobalApps()) 144 : { 145 248 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 146 407 : if (getToMultiApp()->hasLocalApp(i) && 147 266 : !dynamic_cast<TO_PROBLEM *>(&getToMultiApp()->appProblemBase(i))) 148 0 : bad_problem(); 149 : } 150 : else // check destination sub-app is of the expected type if it is the transfer destination 151 0 : if (!dynamic_cast<TO_PROBLEM *>(&getToMultiApp()->problemBase())) 152 0 : bad_problem(); 153 : } 154 721 : } 155 : 156 : #endif