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 "MultiAppPostprocessorToAuxScalarTransfer.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", MultiAppPostprocessorToAuxScalarTransfer); 24 : 25 : InputParameters 26 14463 : MultiAppPostprocessorToAuxScalarTransfer::validParams() 27 : { 28 14463 : InputParameters params = MultiAppTransfer::validParams(); 29 28926 : params.addClassDescription("Transfers from a postprocessor to a scalar auxiliary variable."); 30 57852 : params.addRequiredParam<PostprocessorName>( 31 : "from_postprocessor", "The name of the Postprocessor to transfer the value from."); 32 43389 : params.addRequiredParam<VariableName>( 33 : "to_aux_scalar", "The name of the scalar AuxVariable to transfer the value to."); 34 14463 : MultiAppTransfer::addUserObjectExecutionCheckParam(params); 35 : 36 14463 : return params; 37 0 : } 38 : 39 99 : MultiAppPostprocessorToAuxScalarTransfer::MultiAppPostprocessorToAuxScalarTransfer( 40 99 : const InputParameters & parameters) 41 : : MultiAppTransfer(parameters), 42 99 : _from_pp_name(getParam<PostprocessorName>("from_postprocessor")), 43 297 : _to_aux_name(getParam<VariableName>("to_aux_scalar")) 44 : { 45 99 : if (_directions.size() != 1) 46 0 : paramError("direction", "This transfer is only unidirectional"); 47 99 : } 48 : 49 : void 50 255 : MultiAppPostprocessorToAuxScalarTransfer::execute() 51 : { 52 1275 : TIME_SECTION("MultiAppPostprocessorToAuxScalarTransfer::execute()", 53 : 5, 54 : "Performing transfer between a scalar variable and a postprocessor"); 55 : 56 : // Execute the postprocessor if it was specified to execute on TRANSFER 57 255 : switch (_current_direction) 58 : { 59 110 : case TO_MULTIAPP: 60 : { 61 110 : checkParentAppUserObjectExecuteOn(_from_pp_name); 62 110 : _fe_problem.computeUserObjectByName(EXEC_TRANSFER, Moose::PRE_AUX, _from_pp_name); 63 110 : _fe_problem.computeUserObjectByName(EXEC_TRANSFER, Moose::POST_AUX, _from_pp_name); 64 110 : break; 65 : } 66 95 : case FROM_MULTIAPP: 67 95 : errorIfObjectExecutesOnTransferInSourceApp(_from_pp_name); 68 : } 69 : 70 : // Perform action based on the transfer direction 71 255 : switch (_current_direction) 72 : { 73 : // MultiApp -> MultiApp 74 50 : case BETWEEN_MULTIAPP: 75 : { 76 150 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 77 : { 78 100 : if (getFromMultiApp()->hasLocalApp(i)) 79 : { 80 : // Extract the postprocessor that is being transferred 81 76 : FEProblemBase & from_problem = getFromMultiApp()->appProblemBase(i); 82 76 : Real pp_value = from_problem.getPostprocessorValueByName(_from_pp_name); 83 : 84 76 : if (getToMultiApp()->hasLocalApp(i)) 85 : { 86 : // Get reference to the AuxVariable where the postprocessor will be passed 87 : MooseVariableScalar & scalar = 88 76 : getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name); 89 : 90 76 : scalar.reinit(); 91 : 92 : // Set all values of the AuxVariable to the value of the postprocessor 93 76 : scalar.setValues(pp_value); 94 : 95 : // Update the solution 96 76 : scalar.insert(scalar.sys().solution()); 97 76 : scalar.sys().solution().close(); 98 : } 99 : } 100 : } 101 50 : break; 102 : } 103 : 104 : // main app -> MultiApp 105 110 : case TO_MULTIAPP: 106 : { 107 : // Extract the postprocessor that is being transferred 108 110 : FEProblemBase & from_problem = getToMultiApp()->problemBase(); 109 110 : Real pp_value = from_problem.getPostprocessorValueByName(_from_pp_name); 110 : 111 : // Loop through each of the sub apps 112 330 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 113 220 : if (getToMultiApp()->hasLocalApp(i)) 114 : { 115 : // Get reference to the AuxVariable where the postprocessor will be passed 116 : MooseVariableScalar & scalar = 117 166 : getToMultiApp()->appProblemBase(i).getScalarVariable(_tid, _to_aux_name); 118 : 119 166 : scalar.reinit(); 120 : 121 : // Set all values of the AuxVariable to the value of the postprocessor 122 166 : scalar.setValues(pp_value); 123 : 124 : // Update the solution 125 166 : scalar.insert(scalar.sys().solution()); 126 166 : scalar.sys().solution().close(); 127 : } 128 110 : break; 129 : } 130 : 131 : // MultiApp -> main app 132 95 : case FROM_MULTIAPP: 133 : { 134 : // The number of sub applications 135 95 : unsigned int num_apps = getFromMultiApp()->numGlobalApps(); 136 : 137 : // The AuxVariable for storing the postprocessor values from the sub app 138 : MooseVariableScalar & scalar = 139 95 : getFromMultiApp()->problemBase().getScalarVariable(_tid, _to_aux_name); 140 : 141 : // Ensure that the variable is up to date 142 95 : scalar.reinit(); 143 : 144 : // The dof indices for the scalar variable of interest 145 95 : auto && dof = scalar.dofIndices(); 146 : 147 : // Error if there is a size mismatch between the scalar AuxVariable and the number of sub apps 148 95 : if (num_apps != scalar.sln().size()) 149 16 : mooseError("The number of sub apps (", 150 : num_apps, 151 : ") must be equal to the order of the scalar AuxVariable (", 152 8 : scalar.order(), 153 : ")"); 154 : 155 : // Loop over each sub-app and populate the AuxVariable values from the postprocessors 156 296 : for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++) 157 209 : if (getFromMultiApp()->hasLocalApp(i) && getFromMultiApp()->isRootProcessor()) 158 : // Note: This can't be done using MooseScalarVariable::insert() because different 159 : // processors will be setting dofs separately. 160 316 : scalar.sys().solution().set( 161 158 : dof[i], 162 316 : getFromMultiApp()->appProblemBase(i).getPostprocessorValueByName(_from_pp_name)); 163 : 164 87 : scalar.sys().solution().close(); 165 : 166 87 : break; 167 : } 168 : } 169 247 : } 170 : 171 : void 172 26 : MultiAppPostprocessorToAuxScalarTransfer::checkSiblingsTransferSupported() const 173 : { 174 : // Check that we are in the supported configuration: same number of source and target apps 175 : // The allocation of the child apps on the processors must be the same 176 26 : if (getFromMultiApp()->numGlobalApps() == getToMultiApp()->numGlobalApps()) 177 : { 178 78 : for (const auto i : make_range(getToMultiApp()->numGlobalApps())) 179 52 : if (getFromMultiApp()->hasLocalApp(i) + getToMultiApp()->hasLocalApp(i) == 1) 180 0 : mooseError("Child application allocation on parallel processes must be the same to support " 181 : "siblings postprocessor to scalar variable transfer"); 182 : } 183 : else 184 0 : mooseError("Number of source and target child apps must match for siblings transfer"); 185 26 : }