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