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 : #include "MultiAppMFEMCopyTransfer.h" 13 : #include "FEProblemBase.h" 14 : #include "MultiApp.h" 15 : #include "SystemBase.h" 16 : #include <memory> 17 : #include "MFEMProblem.h" 18 : #include "MFEMMesh.h" 19 : 20 : registerMooseObject("MooseApp", MultiAppMFEMCopyTransfer); 21 : 22 : InputParameters 23 8678 : MultiAppMFEMCopyTransfer::validParams() 24 : { 25 8678 : InputParameters params = MultiAppTransfer::validParams(); 26 8678 : params.addRequiredParam<std::vector<AuxVariableName>>( 27 : "variable", "AuxVariable to store transferred value in."); 28 8678 : params.addRequiredParam<std::vector<VariableName>>("source_variable", 29 : "Variable to transfer from"); 30 8678 : params.addClassDescription("Copies variable values from one MFEM application to another"); 31 8678 : return params; 32 0 : } 33 : 34 24 : MultiAppMFEMCopyTransfer::MultiAppMFEMCopyTransfer(InputParameters const & params) 35 : : MultiAppTransfer(params), 36 24 : _from_var_names(getParam<std::vector<VariableName>>("source_variable")), 37 48 : _to_var_names(getParam<std::vector<AuxVariableName>>("variable")) 38 : { 39 0 : auto bad_problem = [this]() 40 : { 41 0 : mooseError(type(), 42 : " only works with MFEMProblem based applications. Check that all your inputs " 43 : "involved in this transfer are MFEMProblem based"); 44 24 : }; 45 24 : if (hasToMultiApp()) 46 : { 47 16 : if (!dynamic_cast<MFEMProblem *>(&getToMultiApp()->problemBase())) 48 0 : bad_problem(); 49 32 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 50 48 : if (getToMultiApp()->hasLocalApp(i) && 51 32 : !dynamic_cast<MFEMProblem *>(&getToMultiApp()->appProblemBase(i))) 52 0 : bad_problem(); 53 : } 54 24 : if (hasFromMultiApp()) 55 : { 56 16 : if (!dynamic_cast<MFEMProblem *>(&getFromMultiApp()->problemBase())) 57 0 : bad_problem(); 58 32 : for (const auto i : make_range(getFromMultiApp()->numGlobalApps())) 59 48 : if (getFromMultiApp()->hasLocalApp(i) && 60 32 : !dynamic_cast<MFEMProblem *>(&getFromMultiApp()->appProblemBase(i))) 61 0 : bad_problem(); 62 : } 63 24 : } 64 : 65 : // 66 : void 67 32 : MultiAppMFEMCopyTransfer::transfer(MFEMProblem & to_problem, MFEMProblem & from_problem) 68 : { 69 : // Redundant as source name is required? 70 32 : if (!numToVar()) 71 0 : mooseError("No transferred variables were specified, neither programmatically or through the " 72 : "'source_variable' parameter"); 73 32 : if (numToVar() != numFromVar()) 74 0 : mooseError("Number of variables transferred must be same in both systems."); 75 64 : for (unsigned v = 0; v < numToVar(); ++v) 76 : { 77 32 : auto & to_var = to_problem.getProblemData().gridfunctions.GetRef(getToVarName(v)); 78 32 : auto & from_var = from_problem.getProblemData().gridfunctions.GetRef(getFromVarName(v)); 79 : // TODO: Probably need more checking here to make sure the variables are 80 : // copyable - as per the MultiAppDofCopyTransfer 81 32 : to_var = from_var; 82 : } 83 32 : } 84 : 85 : void 86 32 : MultiAppMFEMCopyTransfer::execute() 87 : { 88 32 : TIME_SECTION("MultiAppMFEMCopyTransfer::execute", 5, "Copies variables"); 89 32 : if (_current_direction == TO_MULTIAPP) 90 : { 91 16 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 92 : { 93 8 : if (getToMultiApp()->hasLocalApp(i)) 94 : { 95 8 : transfer(static_cast<MFEMProblem &>(getToMultiApp()->appProblemBase(i)), 96 16 : static_cast<MFEMProblem &>(getToMultiApp()->problemBase())); 97 : } 98 : } 99 : } 100 24 : else if (_current_direction == FROM_MULTIAPP) 101 : { 102 16 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 103 : { 104 8 : if (getFromMultiApp()->hasLocalApp(i)) 105 : { 106 8 : transfer(static_cast<MFEMProblem &>(getFromMultiApp()->problemBase()), 107 16 : static_cast<MFEMProblem &>(getFromMultiApp()->appProblemBase(i))); 108 : } 109 : } 110 : } 111 16 : else if (_current_direction == BETWEEN_MULTIAPP) 112 : { 113 16 : int transfers_done = 0; 114 32 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 115 : { 116 16 : if (getFromMultiApp()->hasLocalApp(i)) 117 : { 118 16 : if (getToMultiApp()->hasLocalApp(i)) 119 : { 120 16 : transfer(static_cast<MFEMProblem &>(getToMultiApp()->appProblemBase(i)), 121 32 : static_cast<MFEMProblem &>(getFromMultiApp()->appProblemBase(i))); 122 16 : transfers_done++; 123 : } 124 : } 125 : } 126 16 : if (!transfers_done) 127 0 : mooseError("BETWEEN_MULTIAPP transfer not supported if there is not at least one subapp " 128 : "per multiapp involved on each rank"); 129 : } 130 32 : } 131 : 132 : void 133 8 : MultiAppMFEMCopyTransfer::checkSiblingsTransferSupported() const 134 : { 135 : // Check that we are in the supported configuration: same number of source and target apps 136 : // The allocation of the child apps on the processors must be the same 137 8 : if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps()) 138 : { 139 16 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 140 8 : if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1) 141 0 : mooseError("Child application allocation on parallel processes must be the same to support " 142 : "siblings variable field copy transfer"); 143 : } 144 : else 145 0 : mooseError("Number of source and target child apps must match for siblings transfer"); 146 8 : } 147 : 148 : #endif