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