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