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