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 : // StochasticTools includes 11 : #include "PODResidualTransfer.h" 12 : #include "NonlinearSystemBase.h" 13 : 14 : registerMooseObject("StochasticToolsApp", PODResidualTransfer); 15 : 16 : InputParameters 17 204 : PODResidualTransfer::validParams() 18 : { 19 204 : InputParameters params = PODSamplerSolutionTransfer::validParams(); 20 204 : params.addClassDescription("Transfers residual vectors from the sub-application to a " 21 : "a container in the Trainer object."); 22 204 : params.suppressParameter<MultiMooseEnum>("direction"); 23 204 : params.suppressParameter<MultiAppName>("multi_app"); 24 204 : return params; 25 0 : } 26 : 27 88 : PODResidualTransfer::PODResidualTransfer(const InputParameters & parameters) 28 88 : : PODSamplerSolutionTransfer(parameters) 29 : { 30 88 : if (hasToMultiApp()) 31 0 : paramError("to_multi_app", "To and between multiapp directions are not implemented"); 32 88 : } 33 : 34 : void 35 80 : PODResidualTransfer::execute() 36 : { 37 80 : const unsigned int total_base_num = _trainer.getSumBaseSize(); 38 : 39 : // Looping over sub-apps 40 336 : for (unsigned int base_i = 0; base_i < total_base_num; ++base_i) 41 512 : if (getFromMultiApp()->hasLocalApp(base_i)) 42 160 : transferResidual(base_i, base_i); 43 80 : } 44 : 45 : void 46 0 : PODResidualTransfer::executeFromMultiapp() 47 : { 48 0 : transferResidual(_global_index, processor_id()); 49 0 : } 50 : 51 : void 52 160 : PODResidualTransfer::transferResidual(dof_id_type base_i, dof_id_type multi_app_i) 53 : { 54 160 : const std::vector<std::string> & var_names = _trainer.getVarNames(); 55 : const std::vector<std::string> & tag_names = _trainer.getTagNames(); 56 : const std::vector<std::string> & tag_types = _trainer.getTagTypes(); 57 : 58 : // Getting reference to the non-linear system 59 320 : FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(multi_app_i); 60 : NonlinearSystemBase & nl = app_problem.getNonlinearSystemBase(/*nl_sys_num=*/0); 61 : 62 : // Looping over the residual tags and extracting the corresponding vector. 63 900 : for (unsigned int tag_i = 0; tag_i < tag_names.size(); ++tag_i) 64 : { 65 : // If the tag corresponds to an independent operator, it is enough to 66 : // transfer it once. 67 1590 : if (base_i > 0 && (tag_types[tag_i] == "src" || tag_types[tag_i] == "src_dir")) 68 170 : continue; 69 : 70 570 : TagID tag_id = app_problem.getVectorTagID(tag_names[tag_i]); 71 : 72 : // Fetching the corresponding residual vector and extracting the parts for 73 : // each variable. 74 570 : NumericVector<Number> & full_residual = nl.getVector(tag_id); 75 570 : std::vector<DenseVector<Real>> split_residual(var_names.size()); 76 : 77 1140 : for (unsigned int var_i = 0; var_i < var_names.size(); ++var_i) 78 : { 79 : // Getting the DoF indices of the variable. 80 570 : nl.setVariableGlobalDoFs(var_names[var_i]); 81 : const std::vector<dof_id_type> & var_dofs = nl.getVariableGlobalDoFs(); 82 : 83 : // Extracting the corresponding part of the residual vector. 84 570 : full_residual.localize(split_residual[var_i].get_values(), var_dofs); 85 : } 86 : 87 : // Inserting the contribution of this residual into the reduced operator in 88 : // the trainer. 89 570 : _trainer.addToReducedOperator(base_i, tag_i, split_residual); 90 570 : } 91 160 : }