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 180 : SCMSolutionTransferBase::validParams() 18 : { 19 180 : InputParameters params = MultiAppTransfer::validParams(); 20 360 : params.addRequiredParam<std::vector<AuxVariableName>>("variable", 21 : "The auxiliary variables to transfer."); 22 180 : return params; 23 0 : } 24 : 25 90 : SCMSolutionTransferBase::SCMSolutionTransferBase(const InputParameters & parameters) 26 180 : : MultiAppTransfer(parameters), _var_names(getParam<std::vector<AuxVariableName>>("variable")) 27 : { 28 90 : if (_directions.contains(Transfer::FROM_MULTIAPP)) 29 0 : paramError("from_multiapp", "This transfer works only into multi-app."); 30 90 : } 31 : 32 : void 33 77 : SCMSolutionTransferBase::initialSetup() 34 : { 35 77 : MultiAppTransfer::initialSetup(); 36 644 : 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 567 : if (_to_problems.empty()) 40 16 : continue; 41 : 42 : // Check source variable on regular subchannel problem 43 551 : MooseVariableFieldBase & from_var = _subproblem.getVariable( 44 : 0, _var_names[var_index], Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY); 45 551 : System & from_sys = from_var.sys().system(); 46 551 : const auto & fe_type = from_sys.variable_type(from_var.number()); 47 : 48 551 : 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 551 : MooseVariableFieldBase & to_var = _to_problems[0]->getVariable( 54 551 : 0, _var_names[var_index], Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY); 55 : 56 551 : System & to_sys = to_var.sys().system(); 57 551 : const auto & fe_type_target = to_sys.variable_type(to_var.number()); 58 : 59 551 : 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 77 : } 64 : 65 : void 66 144 : SCMSolutionTransferBase::execute() 67 : { 68 288 : TIME_SECTION( 69 : "MultiAppDetailedSolutionBaseTransfer::execute()", 5, "Transferring subchannel solutions"); 70 144 : getAppInfo(); 71 : 72 144 : switch (_current_direction) 73 : { 74 144 : case TO_MULTIAPP: 75 144 : transferToMultiApps(); 76 : break; 77 : 78 : default: 79 : break; 80 : } 81 144 : } 82 : 83 : void 84 144 : SCMSolutionTransferBase::transferToMultiApps() 85 : { 86 : mooseAssert(_from_meshes.size() == 1, "Only one source mesh can be active in this transfer."); 87 144 : if (dynamic_cast<SubChannelMesh *>(_from_meshes[0]) == nullptr) 88 0 : mooseError("This transfer works only with SubChannelMesh classes."); 89 : 90 576 : for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++) 91 288 : if (getToMultiApp()->hasLocalApp(i)) 92 136 : transferVarsToApp(i); 93 144 : } 94 : 95 : void 96 136 : SCMSolutionTransferBase::transferVarsToApp(unsigned int app_idx) 97 : { 98 136 : transferNodalVars(app_idx); 99 136 : } 100 : 101 : void 102 136 : SCMSolutionTransferBase::transferNodalVars(unsigned int app_idx) 103 : { 104 136 : Moose::ScopedCommSwapper swapper(getToMultiApp()->comm()); 105 : 106 136 : FEProblemBase & to_problem = getToMultiApp()->appProblemBase(app_idx); 107 : MooseMesh * mesh = NULL; 108 136 : if (_displaced_target_mesh && to_problem.getDisplacedProblem()) 109 0 : mesh = &to_problem.getDisplacedProblem()->mesh(); 110 : else 111 136 : mesh = &to_problem.mesh(); 112 : 113 136 : const SubChannelMesh & from_mesh = dynamic_cast<SubChannelMesh &>(*_from_meshes[0]); 114 136 : FEProblemBase & from_problem = *_from_problems[0]; 115 : 116 2738344 : for (auto & node : mesh->getMesh().local_node_ptr_range()) 117 : { 118 : // No local data to send 119 1369036 : if (processor_id() != 0) 120 310916 : continue; 121 1058120 : Node * from_node = getFromNode(from_mesh, *node); 122 : 123 11135457 : for (auto & var_name : _var_names) 124 : { 125 10077337 : System * to_sys = find_sys(to_problem.es(), var_name); 126 : unsigned int to_sys_num = to_sys->number(); 127 10077337 : unsigned int to_var_num = to_sys->variable_number(var_name); 128 : 129 10077337 : if (node->n_dofs(to_sys_num, to_var_num) > 0) 130 : { 131 10050121 : System * from_sys = find_sys(from_problem.es(), var_name); 132 : unsigned int from_sys_num = from_sys->number(); 133 10050121 : 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 10050121 : dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0); 138 10050121 : Real from_value = (*from_solution)(from_dof); 139 : swapper.forceSwap(); 140 : 141 20100242 : NumericVector<Real> & to_solution = getToMultiApp()->appTransferVector(app_idx, var_name); 142 10050121 : dof_id_type to_dof = node->dof_number(to_sys_num, to_var_num, 0); 143 10050121 : to_solution.set(to_dof, from_value); 144 : } 145 : } 146 136 : } 147 : 148 1287 : for (auto & var_name : _var_names) 149 : { 150 2302 : getToMultiApp()->appTransferVector(app_idx, var_name).close(); 151 1151 : find_sys(to_problem.es(), var_name)->update(); 152 : } 153 136 : }