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 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 8666 : MultiAppMFEMCopyTransfer::validParams() 24 : { 25 8666 : InputParameters params = MultiAppTransfer::validParams(); 26 8666 : params.addRequiredParam<std::vector<AuxVariableName>>( 27 : "variable", "AuxVariable to store transferred value in."); 28 8666 : params.addRequiredParam<std::vector<VariableName>>("source_variable", 29 : "Variable to transfer from"); 30 8666 : params.addClassDescription("Copies variable values from one MFEM application to another"); 31 8666 : return params; 32 0 : } 33 : 34 18 : MultiAppMFEMCopyTransfer::MultiAppMFEMCopyTransfer(InputParameters const & params) 35 : : MultiAppTransfer(params), 36 18 : _from_var_names(getParam<std::vector<VariableName>>("source_variable")), 37 36 : _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 18 : }; 45 18 : if (hasToMultiApp()) 46 : { 47 12 : if (!dynamic_cast<MFEMProblem *>(&getToMultiApp()->problemBase())) 48 0 : bad_problem(); 49 24 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 50 36 : if (getToMultiApp()->hasLocalApp(i) && 51 24 : !dynamic_cast<MFEMProblem *>(&getToMultiApp()->appProblemBase(i))) 52 0 : bad_problem(); 53 : } 54 18 : if (hasFromMultiApp()) 55 : { 56 12 : if (!dynamic_cast<MFEMProblem *>(&getFromMultiApp()->problemBase())) 57 0 : bad_problem(); 58 24 : for (const auto i : make_range(getFromMultiApp()->numGlobalApps())) 59 36 : if (getFromMultiApp()->hasLocalApp(i) && 60 24 : !dynamic_cast<MFEMProblem *>(&getFromMultiApp()->appProblemBase(i))) 61 0 : bad_problem(); 62 : } 63 18 : } 64 : 65 : // 66 : void 67 24 : MultiAppMFEMCopyTransfer::transfer(MFEMProblem & to_problem, MFEMProblem & from_problem) 68 : { 69 : // Redundant as source name is required? 70 24 : if (!numToVar()) 71 0 : mooseError("No transferred variables were specified, neither programmatically or through the " 72 : "'source_variable' parameter"); 73 24 : if (numToVar() != numFromVar()) 74 0 : mooseError("Number of variables transferred must be same in both systems."); 75 48 : for (unsigned v = 0; v < numToVar(); ++v) 76 : { 77 24 : auto & to_var = to_problem.getProblemData().gridfunctions.GetRef(getToVarName(v)); 78 24 : 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 24 : to_var = from_var; 82 : } 83 24 : } 84 : 85 : void 86 24 : MultiAppMFEMCopyTransfer::execute() 87 : { 88 24 : TIME_SECTION("MultiAppMFEMCopyTransfer::execute", 5, "Copies variables"); 89 24 : if (_current_direction == TO_MULTIAPP) 90 : { 91 12 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 92 : { 93 6 : if (getToMultiApp()->hasLocalApp(i)) 94 : { 95 6 : transfer(static_cast<MFEMProblem &>(getToMultiApp()->appProblemBase(i)), 96 12 : static_cast<MFEMProblem &>(getToMultiApp()->problemBase())); 97 : } 98 : } 99 : } 100 18 : else if (_current_direction == FROM_MULTIAPP) 101 : { 102 12 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 103 : { 104 6 : if (getFromMultiApp()->hasLocalApp(i)) 105 : { 106 6 : transfer(static_cast<MFEMProblem &>(getFromMultiApp()->problemBase()), 107 12 : static_cast<MFEMProblem &>(getFromMultiApp()->appProblemBase(i))); 108 : } 109 : } 110 : } 111 12 : else if (_current_direction == BETWEEN_MULTIAPP) 112 : { 113 12 : int transfers_done = 0; 114 24 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 115 : { 116 12 : if (getFromMultiApp()->hasLocalApp(i)) 117 : { 118 12 : if (getToMultiApp()->hasLocalApp(i)) 119 : { 120 12 : transfer(static_cast<MFEMProblem &>(getToMultiApp()->appProblemBase(i)), 121 24 : static_cast<MFEMProblem &>(getFromMultiApp()->appProblemBase(i))); 122 12 : transfers_done++; 123 : } 124 : } 125 : } 126 12 : 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 24 : } 131 : 132 : void 133 6 : 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 6 : if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps()) 138 : { 139 12 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 140 6 : 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 6 : } 147 : 148 : #endif