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 "SCMSolutionTransferBase.h" 11 : #include "MultiApp.h" 12 : #include "FEProblemBase.h" 13 : #include "DisplacedProblem.h" 14 : #include "SubChannelMesh.h" 15 : 16 : InputParameters 17 264 : SCMSolutionTransferBase::validParams() 18 : { 19 264 : InputParameters params = MultiAppTransfer::validParams(); 20 528 : params.addRequiredParam<std::vector<AuxVariableName>>("variable", 21 : "The auxiliary variables to transfer."); 22 264 : return params; 23 0 : } 24 : 25 132 : SCMSolutionTransferBase::SCMSolutionTransferBase(const InputParameters & parameters) 26 264 : : MultiAppTransfer(parameters), _var_names(getParam<std::vector<AuxVariableName>>("variable")) 27 : { 28 132 : if (_directions.contains(Transfer::FROM_MULTIAPP)) 29 0 : paramError("from_multiapp", "This transfer works only into multi-app."); 30 132 : } 31 : 32 : void 33 109 : SCMSolutionTransferBase::initialSetup() 34 : { 35 109 : MultiAppTransfer::initialSetup(); 36 958 : for (std::size_t var_index = 0; var_index < _var_names.size(); ++var_index) 37 : { 38 : // No local app, we cannot examine the target variable 39 849 : if (_to_problems.empty()) 40 18 : continue; 41 : 42 : // Check source variable on regular subchannel problem 43 831 : MooseVariableFieldBase & from_var = _subproblem.getVariable( 44 : 0, _var_names[var_index], Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY); 45 831 : System & from_sys = from_var.sys().system(); 46 831 : const auto & fe_type = from_sys.variable_type(from_var.number()); 47 : 48 831 : if (fe_type.family != LAGRANGE || fe_type.order != FIRST) 49 0 : paramError("variable", 50 : "This transfer requires a first order Lagrange variable for the source variable"); 51 : 52 : // Check target variable in visualization mesh 53 831 : MooseVariableFieldBase & to_var = _to_problems[0]->getVariable( 54 831 : 0, _var_names[var_index], Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY); 55 : 56 831 : System & to_sys = to_var.sys().system(); 57 831 : const auto & fe_type_target = to_sys.variable_type(to_var.number()); 58 : 59 831 : if (fe_type_target.family != LAGRANGE || fe_type_target.order != FIRST) 60 0 : paramError("variable", 61 : "This transfer requires a first order Lagrange variable for the source variable"); 62 : } 63 109 : } 64 : 65 : void 66 203 : SCMSolutionTransferBase::execute() 67 : { 68 406 : TIME_SECTION( 69 : "MultiAppDetailedSolutionBaseTransfer::execute()", 5, "Transferring subchannel solutions"); 70 203 : getAppInfo(); 71 : 72 203 : switch (_current_direction) 73 : { 74 203 : case TO_MULTIAPP: 75 203 : transferToMultiApps(); 76 : break; 77 : 78 : default: 79 : break; 80 : } 81 203 : } 82 : 83 : void 84 203 : SCMSolutionTransferBase::transferToMultiApps() 85 : { 86 : mooseAssert(_from_meshes.size() == 1, "Only one source mesh can be active in this transfer."); 87 203 : if (dynamic_cast<SubChannelMesh *>(_from_meshes[0]) == nullptr) 88 0 : mooseError("This transfer works only with SubChannelMesh classes."); 89 : 90 812 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 91 406 : if (getToMultiApp()->hasLocalApp(i)) 92 193 : transferVarsToApp(i); 93 203 : } 94 : 95 : void 96 193 : SCMSolutionTransferBase::transferVarsToApp(unsigned int app_idx) 97 : { 98 193 : transferNodalVars(app_idx); 99 193 : } 100 : 101 : void 102 193 : SCMSolutionTransferBase::transferNodalVars(unsigned int app_idx) 103 : { 104 193 : Moose::ScopedCommSwapper swapper(getToMultiApp()->comm()); 105 : 106 193 : FEProblemBase & to_problem = getToMultiApp()->appProblemBase(app_idx); 107 : MooseMesh * mesh = NULL; 108 193 : if (_displaced_target_mesh && to_problem.getDisplacedProblem()) 109 0 : mesh = &to_problem.getDisplacedProblem()->mesh(); 110 : else 111 193 : mesh = &to_problem.mesh(); 112 : 113 193 : const SubChannelMesh & from_mesh = dynamic_cast<SubChannelMesh &>(*_from_meshes[0]); 114 193 : FEProblemBase & from_problem = *_from_problems[0]; 115 : 116 3904120 : for (auto & node : mesh->getMesh().local_node_ptr_range()) 117 : { 118 : // No local data to send 119 1951867 : if (processor_id() != 0) 120 465664 : continue; 121 1486203 : Node * from_node = getFromNode(from_mesh, *node); 122 : 123 15836861 : for (auto & var_name : _var_names) 124 : { 125 14350658 : System * to_sys = find_sys(to_problem.es(), var_name); 126 : unsigned int to_sys_num = to_sys->number(); 127 14350658 : unsigned int to_var_num = to_sys->variable_number(var_name); 128 : 129 14350658 : if (node->n_dofs(to_sys_num, to_var_num) > 0) 130 : { 131 14322734 : System * from_sys = find_sys(from_problem.es(), var_name); 132 : unsigned int from_sys_num = from_sys->number(); 133 14322734 : unsigned int from_var_num = from_sys->variable_number(var_name); 134 : 135 : swapper.forceSwap(); 136 : NumericVector<Real> * from_solution = from_sys->solution.get(); 137 14322734 : dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0); 138 14322734 : Real from_value = (*from_solution)(from_dof); 139 : swapper.forceSwap(); 140 : 141 28645468 : NumericVector<Real> & to_solution = getToMultiApp()->appTransferVector(app_idx, var_name); 142 14322734 : dof_id_type to_dof = node->dof_number(to_sys_num, to_var_num, 0); 143 14322734 : to_solution.set(to_dof, from_value); 144 : } 145 : } 146 193 : } 147 : 148 1894 : for (auto & var_name : _var_names) 149 : { 150 3402 : getToMultiApp()->appTransferVector(app_idx, var_name).close(); 151 1701 : find_sys(to_problem.es(), var_name)->update(); 152 : } 153 193 : }