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 : #include "MultiAppScalarToAuxScalarTransfer.h" 11 : 12 : // MOOSE includes 13 : #include "FEProblem.h" 14 : #include "MooseTypes.h" 15 : #include "MooseVariableScalar.h" 16 : #include "MultiApp.h" 17 : #include "SystemBase.h" 18 : 19 : #include "libmesh/meshfree_interpolation.h" 20 : #include "libmesh/system.h" 21 : 22 : // Define the input parameters 23 : registerMooseObject("MooseApp", MultiAppScalarToAuxScalarTransfer); 24 : 25 : InputParameters 26 14377 : MultiAppScalarToAuxScalarTransfer::validParams() 27 : { 28 14377 : InputParameters params = MultiAppTransfer::validParams(); 29 14377 : params.addClassDescription("Transfers data from a scalar variable to an auxiliary scalar " 30 : "variable from different applications."); 31 14377 : params.addRequiredParam<VariableName>("source_variable", 32 : "The name of the scalar variable to " 33 : "transfer the value from."); 34 14377 : params.addRequiredParam<VariableName>("to_aux_scalar", 35 : "The name of the scalar auxiliary variable to " 36 : "transfer the value to."); 37 14377 : return params; 38 0 : } 39 : 40 56 : MultiAppScalarToAuxScalarTransfer::MultiAppScalarToAuxScalarTransfer( 41 56 : const InputParameters & parameters) 42 : : MultiAppTransfer(parameters), 43 56 : _from_variable_name(getParam<VariableName>("source_variable")), 44 112 : _to_aux_name(getParam<VariableName>("to_aux_scalar")) 45 : { 46 56 : if (_directions.size() != 1) 47 0 : paramError("direction", "This transfer is only unidirectional"); 48 56 : } 49 : 50 : void 51 930 : MultiAppScalarToAuxScalarTransfer::execute() 52 : { 53 930 : TIME_SECTION( 54 : "MultiAppScalarToAuxScalarTransfer::execute()", 5, "Performing a scalar variable transfer"); 55 : 56 : // Perform action based on the transfer direction 57 930 : switch (_current_direction) 58 : { 59 : // main app to multi_app 60 15 : case TO_MULTIAPP: 61 : { 62 : // Extract the scalar variable that is being transferred 63 15 : FEProblemBase & from_problem = getToMultiApp()->problemBase(); 64 : MooseVariableScalar * from_variable = 65 15 : &from_problem.getScalarVariable(_tid, _from_variable_name); 66 : 67 : // Loop through each of the sub apps 68 26 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 69 15 : if (getToMultiApp()->hasLocalApp(i)) 70 : { 71 : // Get reference to the scalar variable that will be written 72 : MooseVariableScalar * to_variable = 73 15 : &getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name); 74 : 75 15 : to_variable->reinit(); 76 : 77 : // Determine number of DOFs that we're going to read and write 78 15 : auto && to_dof = to_variable->dofIndices(); 79 15 : auto & from_values = from_variable->sln(); 80 : 81 : // Check that the DOF matches 82 15 : if (from_variable->sln().size() != to_variable->sln().size()) 83 4 : mooseError("Order of SCALAR variables do not match for sending and " 84 : "receiving data for the " 85 : "MultiAppScalarToAuxScalarTransfer!"); 86 : 87 77 : for (MooseIndex(from_values) j = 0; j < from_values.size(); ++j) 88 66 : to_variable->sys().solution().set(to_dof[j], from_values[j]); 89 : 90 11 : to_variable->sys().solution().close(); 91 : } 92 11 : break; 93 : } 94 : 95 : // multi_app to main app 96 15 : case FROM_MULTIAPP: 97 : { 98 : // The AuxVariable that will be modified with data from the subapp 99 : MooseVariableScalar * to_variable = 100 15 : &getFromMultiApp()->problemBase().getScalarVariable(_tid, _to_aux_name); 101 : 102 : // Ensure that the variable is up to date 103 15 : to_variable->reinit(); 104 : 105 : // The dof indices for the scalar variable of interest 106 15 : auto && to_dof = to_variable->dofIndices(); 107 : 108 : // Loop over each sub-app and populate the AuxVariable values 109 26 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 110 : { 111 15 : if (getFromMultiApp()->hasLocalApp(i) && getFromMultiApp()->isRootProcessor()) 112 : { 113 : // Extract the scalar variable that is being transferred 114 12 : FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i); 115 : MooseVariableScalar * from_variable = 116 12 : &from_problem.getScalarVariable(_tid, _from_variable_name); 117 : 118 : // Loop over the scalar aux variable that we're going to write 119 12 : auto & from_values = from_variable->sln(); 120 : 121 : // Check that DOFs match 122 12 : if (from_variable->sln().size() != to_variable->sln().size()) 123 4 : mooseError("Order of SCALAR variables do not match for sending and " 124 : "receiving data for the " 125 : "MultiAppScalarToAuxScalarTransfer!"); 126 : 127 56 : for (MooseIndex(from_values) j = 0; j < from_values.size(); ++j) 128 48 : to_variable->sys().solution().set(to_dof[j], from_values[j]); 129 : } 130 : } 131 11 : to_variable->sys().solution().close(); 132 : 133 11 : break; 134 : } 135 : 136 : // multi_app to multi_app 137 900 : case BETWEEN_MULTIAPP: 138 : { 139 2700 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 140 : { 141 1800 : if (getFromMultiApp()->hasLocalApp(i)) 142 : { 143 : // The AuxVariable that will be modified with data from the subapp 144 : MooseVariableScalar * from_variable = 145 1272 : &getFromMultiApp()->appProblemBase(i).getScalarVariable(_tid, _from_variable_name); 146 : 147 : // Ensure that the variable is up to date 148 1272 : from_variable->reinit(); 149 : 150 1272 : if (getToMultiApp()->hasLocalApp(i)) 151 : { 152 : // Get reference to the scalar variable that will be written 153 : MooseVariableScalar * to_variable = 154 1272 : &getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name); 155 : 156 1272 : to_variable->reinit(); 157 : 158 : // Determine number of DOFs that we're going to read and write 159 1272 : auto && to_dof = to_variable->dofIndices(); 160 1272 : auto & from_values = from_variable->sln(); 161 : 162 : // Check that the DOF matches 163 1272 : if (from_variable->sln().size() != to_variable->sln().size()) 164 0 : mooseError("Order of SCALAR variables do not match for sending and " 165 : "receiving data for the " 166 : "MultiAppScalarToAuxScalarTransfer!"); 167 : 168 4452 : for (MooseIndex(from_values) k = 0; k < from_values.size(); ++k) 169 3180 : to_variable->sys().solution().set(to_dof[k], from_values[k]); 170 : 171 1272 : to_variable->sys().solution().close(); 172 : } 173 : } 174 : } 175 900 : break; 176 : } 177 : } 178 922 : } 179 : 180 : void 181 24 : MultiAppScalarToAuxScalarTransfer::checkSiblingsTransferSupported() const 182 : { 183 : // Check that we are in the supported configuration: same number of source and target apps 184 : // The allocation of the child apps on the processors must be the same 185 24 : if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps()) 186 : { 187 72 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 188 48 : if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1) 189 0 : mooseError("Child application allocation on parallel processes must be the same to support " 190 : "siblings scalar variable transfer"); 191 : } 192 : else 193 0 : mooseError("Number of source and target child apps must match for siblings transfer"); 194 24 : }