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 14385 : MultiAppScalarToAuxScalarTransfer::validParams() 27 : { 28 14385 : InputParameters params = MultiAppTransfer::validParams(); 29 14385 : params.addClassDescription("Transfers data from a scalar variable to an auxiliary scalar " 30 : "variable from different applications."); 31 14385 : params.addRequiredParam<VariableName>("source_variable", 32 : "The name of the scalar variable to " 33 : "transfer the value from."); 34 14385 : params.addRequiredParam<VariableName>("to_aux_scalar", 35 : "The name of the scalar auxiliary variable to " 36 : "transfer the value to."); 37 14385 : return params; 38 0 : } 39 : 40 60 : MultiAppScalarToAuxScalarTransfer::MultiAppScalarToAuxScalarTransfer( 41 60 : const InputParameters & parameters) 42 : : MultiAppTransfer(parameters), 43 60 : _from_variable_name(getParam<VariableName>("source_variable")), 44 120 : _to_aux_name(getParam<VariableName>("to_aux_scalar")) 45 : { 46 60 : if (_directions.size() != 1) 47 0 : paramError("direction", "This transfer is only unidirectional"); 48 60 : } 49 : 50 : void 51 1040 : MultiAppScalarToAuxScalarTransfer::execute() 52 : { 53 1040 : TIME_SECTION( 54 : "MultiAppScalarToAuxScalarTransfer::execute()", 5, "Performing a scalar variable transfer"); 55 : 56 : // Perform action based on the transfer direction 57 1040 : switch (_current_direction) 58 : { 59 : // main app to multi_app 60 17 : case TO_MULTIAPP: 61 : { 62 : // Extract the scalar variable that is being transferred 63 17 : FEProblemBase & from_problem = getToMultiApp()->problemBase(); 64 : MooseVariableScalar * from_variable = 65 17 : &from_problem.getScalarVariable(_tid, _from_variable_name); 66 : 67 : // Loop through each of the sub apps 68 30 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 69 17 : if (getToMultiApp()->hasLocalApp(i)) 70 : { 71 : // Get reference to the scalar variable that will be written 72 : MooseVariableScalar * to_variable = 73 17 : &getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name); 74 : 75 17 : to_variable->reinit(); 76 : 77 : // Determine number of DOFs that we're going to read and write 78 17 : auto && to_dof = to_variable->dofIndices(); 79 17 : auto & from_values = from_variable->sln(); 80 : 81 : // Check that the DOF matches 82 17 : 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 91 : for (MooseIndex(from_values) j = 0; j < from_values.size(); ++j) 88 78 : to_variable->sys().solution().set(to_dof[j], from_values[j]); 89 : 90 13 : to_variable->sys().solution().close(); 91 : } 92 13 : break; 93 : } 94 : 95 : // multi_app to main app 96 17 : case FROM_MULTIAPP: 97 : { 98 : // The AuxVariable that will be modified with data from the subapp 99 : MooseVariableScalar * to_variable = 100 17 : &getFromMultiApp()->problemBase().getScalarVariable(_tid, _to_aux_name); 101 : 102 : // Ensure that the variable is up to date 103 17 : to_variable->reinit(); 104 : 105 : // The dof indices for the scalar variable of interest 106 17 : auto && to_dof = to_variable->dofIndices(); 107 : 108 : // Loop over each sub-app and populate the AuxVariable values 109 30 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 110 : { 111 17 : if (getFromMultiApp()->hasLocalApp(i) && getFromMultiApp()->isRootProcessor()) 112 : { 113 : // Extract the scalar variable that is being transferred 114 14 : FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i); 115 : MooseVariableScalar * from_variable = 116 14 : &from_problem.getScalarVariable(_tid, _from_variable_name); 117 : 118 : // Loop over the scalar aux variable that we're going to write 119 14 : auto & from_values = from_variable->sln(); 120 : 121 : // Check that DOFs match 122 14 : 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 70 : for (MooseIndex(from_values) j = 0; j < from_values.size(); ++j) 128 60 : to_variable->sys().solution().set(to_dof[j], from_values[j]); 129 : } 130 : } 131 13 : to_variable->sys().solution().close(); 132 : 133 13 : break; 134 : } 135 : 136 : // multi_app to multi_app 137 1006 : case BETWEEN_MULTIAPP: 138 : { 139 3018 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 140 : { 141 2012 : if (getFromMultiApp()->hasLocalApp(i)) 142 : { 143 : // The AuxVariable that will be modified with data from the subapp 144 : MooseVariableScalar * from_variable = 145 1484 : &getFromMultiApp()->appProblemBase(i).getScalarVariable(_tid, _from_variable_name); 146 : 147 : // Ensure that the variable is up to date 148 1484 : from_variable->reinit(); 149 : 150 1484 : if (getToMultiApp()->hasLocalApp(i)) 151 : { 152 : // Get reference to the scalar variable that will be written 153 : MooseVariableScalar * to_variable = 154 1484 : &getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name); 155 : 156 1484 : to_variable->reinit(); 157 : 158 : // Determine number of DOFs that we're going to read and write 159 1484 : auto && to_dof = to_variable->dofIndices(); 160 1484 : auto & from_values = from_variable->sln(); 161 : 162 : // Check that the DOF matches 163 1484 : 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 5194 : for (MooseIndex(from_values) k = 0; k < from_values.size(); ++k) 169 3710 : to_variable->sys().solution().set(to_dof[k], from_values[k]); 170 : 171 1484 : to_variable->sys().solution().close(); 172 : } 173 : } 174 : } 175 1006 : break; 176 : } 177 : } 178 1032 : } 179 : 180 : void 181 26 : 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 26 : if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps()) 186 : { 187 78 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 188 52 : 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 26 : }