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 "MultiAppVariableValueSampleTransfer.h" 11 : 12 : // MOOSE includes 13 : #include "FEProblem.h" 14 : #include "MooseMesh.h" 15 : #include "MooseTypes.h" 16 : #include "MooseVariableFE.h" 17 : #include "MultiApp.h" 18 : #include "SystemBase.h" 19 : 20 : #include "libmesh/meshfree_interpolation.h" 21 : #include "libmesh/numeric_vector.h" 22 : #include "libmesh/system.h" 23 : 24 : using namespace libMesh; 25 : 26 : registerMooseObject("MooseApp", MultiAppVariableValueSampleTransfer); 27 : 28 : InputParameters 29 14333 : MultiAppVariableValueSampleTransfer::validParams() 30 : { 31 14333 : InputParameters params = MultiAppTransfer::validParams(); 32 14333 : params.addClassDescription( 33 : "Transfers the value of a variable within the master application at each sub-application " 34 : "position and transfers the value to a field variable on the sub-application(s)."); 35 14333 : params.addRequiredParam<AuxVariableName>( 36 : "variable", "The auxiliary variable to store the transferred values in."); 37 14333 : params.addRequiredParam<VariableName>("source_variable", "The variable to transfer from."); 38 14333 : return params; 39 0 : } 40 : 41 34 : MultiAppVariableValueSampleTransfer::MultiAppVariableValueSampleTransfer( 42 34 : const InputParameters & parameters) 43 : : MultiAppTransfer(parameters), 44 34 : _to_var_name(getParam<AuxVariableName>("variable")), 45 68 : _from_var_name(getParam<VariableName>("source_variable")) 46 : { 47 34 : if (_directions.size() != 1 || (isParamValid("from_multi_app") && isParamValid("to_multi_app"))) 48 0 : paramError("direction", "This transfer is only unidirectional"); 49 : 50 34 : if (hasFromMultiApp()) 51 0 : paramError("from_multi_app", "This transfer direction has not been implemented"); 52 34 : } 53 : 54 : void 55 34 : MultiAppVariableValueSampleTransfer::initialSetup() 56 : { 57 34 : MultiAppTransfer::initialSetup(); 58 : 59 34 : variableIntegrityCheck(_to_var_name, false); 60 : 61 34 : if (isParamValid("from_multi_app")) 62 0 : getFromMultiApp()->problemBase().mesh().errorIfDistributedMesh( 63 : "MultiAppVariableValueSampleTransfer"); 64 34 : if (isParamValid("to_multi_app")) 65 34 : getToMultiApp()->problemBase().mesh().errorIfDistributedMesh( 66 : "MultiAppVariableValueSampleTransfer"); 67 34 : } 68 : 69 : void 70 32 : MultiAppVariableValueSampleTransfer::execute() 71 : { 72 32 : TIME_SECTION( 73 : "MultiAppVariableValueSampleTransfer::execute()", 5, "Sampling a variable for transfer"); 74 : 75 32 : switch (_current_direction) 76 : { 77 32 : case TO_MULTIAPP: 78 : { 79 32 : FEProblemBase & from_problem = getToMultiApp()->problemBase(); 80 : MooseVariableField<Real> & from_var = static_cast<MooseVariableField<Real> &>( 81 32 : from_problem.getActualFieldVariable(0, _from_var_name)); 82 32 : SystemBase & from_system_base = from_var.sys(); 83 32 : SubProblem & from_sub_problem = from_system_base.subproblem(); 84 : 85 32 : MooseMesh & from_mesh = from_problem.mesh(); 86 : 87 32 : std::unique_ptr<PointLocatorBase> pl = from_mesh.getPointLocator(); 88 : 89 96 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 90 : { 91 64 : Real value = -std::numeric_limits<Real>::max(); 92 : 93 : { // Get the value of the variable at the point where this multiapp is in the master domain 94 : 95 64 : Point multi_app_position = getToMultiApp()->position(i); 96 : 97 64 : std::vector<Point> point_vec(1, multi_app_position); 98 : 99 : // First find the element the hit lands in 100 64 : const Elem * elem = (*pl)(multi_app_position); 101 : 102 64 : if (elem && elem->processor_id() == from_mesh.processor_id()) 103 : { 104 46 : from_sub_problem.setCurrentSubdomainID(elem, 0); 105 46 : from_sub_problem.reinitElemPhys(elem, point_vec, 0); 106 : 107 : mooseAssert(from_var.sln().size() == 1, "No values in u!"); 108 46 : value = from_var.sln()[0]; 109 : } 110 : 111 64 : _communicator.max(value); 112 : 113 64 : if (value == -std::numeric_limits<Real>::max()) 114 0 : mooseError("Transfer failed to sample point value at point: ", multi_app_position); 115 64 : } 116 : 117 64 : if (getToMultiApp()->hasLocalApp(i)) 118 : { 119 46 : Moose::ScopedCommSwapper swapper(getToMultiApp()->comm()); 120 : 121 : // Loop over the master nodes and set the value of the variable 122 46 : System * to_sys = find_sys(getToMultiApp()->appProblemBase(i).es(), _to_var_name); 123 : 124 46 : unsigned int sys_num = to_sys->number(); 125 46 : unsigned int var_num = to_sys->variable_number(_to_var_name); 126 : 127 46 : NumericVector<Real> & solution = getToMultiApp()->appTransferVector(i, _to_var_name); 128 : 129 46 : MooseMesh & mesh = getToMultiApp()->appProblemBase(i).mesh(); 130 : 131 11178 : for (const auto & node : as_range(mesh.localNodesBegin(), mesh.localNodesEnd())) 132 : { 133 5566 : if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node 134 : { 135 : // The zero only works for LAGRANGE! 136 5566 : dof_id_type dof = node->dof_number(sys_num, var_num, 0); 137 : 138 5566 : solution.set(dof, value); 139 : } 140 46 : } 141 46 : solution.close(); 142 46 : getToMultiApp()->appProblemBase(i).es().update(); 143 46 : } 144 : } 145 : 146 32 : break; 147 32 : } 148 0 : case FROM_MULTIAPP: 149 : { 150 0 : mooseError("Doesn't make sense to transfer a sampled variable's value from a MultiApp!!"); 151 : break; 152 : } 153 : } 154 32 : }