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 "PODSamplerSolutionTransfer.h" 12 : #include "NonlinearSystemBase.h" 13 : #include "Sampler.h" 14 : 15 : registerMooseObject("StochasticToolsApp", PODSamplerSolutionTransfer); 16 : 17 : InputParameters 18 612 : PODSamplerSolutionTransfer::validParams() 19 : { 20 612 : InputParameters params = StochasticToolsTransfer::validParams(); 21 612 : params.addClassDescription("Transfers solution vectors from the sub-applications to a " 22 : "a container in the Trainer object and back."); 23 1224 : params.addRequiredParam<UserObjectName>("trainer_name", 24 : "Trainer object that contains the solutions" 25 : " for different samples."); 26 612 : return params; 27 0 : } 28 : 29 268 : PODSamplerSolutionTransfer::PODSamplerSolutionTransfer(const InputParameters & parameters) 30 : : StochasticToolsTransfer(parameters), 31 : SurrogateModelInterface(this), 32 268 : _pod_multi_app(hasFromMultiApp() 33 268 : ? std::dynamic_pointer_cast<PODFullSolveMultiApp>(getFromMultiApp()) 34 356 : : std::dynamic_pointer_cast<PODFullSolveMultiApp>(getToMultiApp())), 35 536 : _trainer(getSurrogateTrainer<PODReducedBasisTrainer>("trainer_name")) 36 : { 37 264 : if (!_pod_multi_app) 38 0 : paramError("multi_app", "The Multiapp given is not a PODFullsolveMultiapp!"); 39 264 : } 40 : 41 : void 42 256 : PODSamplerSolutionTransfer::initialSetup() 43 : { 44 256 : const auto multi_app = hasFromMultiApp() ? getFromMultiApp() : getToMultiApp(); 45 : 46 : // Checking if the subapplication has the requested variables 47 256 : const std::vector<std::string> & var_names = _trainer.getVarNames(); 48 256 : const dof_id_type n = multi_app->numGlobalApps(); 49 1060 : for (MooseIndex(n) i = 0; i < n; i++) 50 : { 51 808 : if (multi_app->hasLocalApp(i)) 52 1036 : for (auto var_name : var_names) 53 520 : if (!multi_app->appProblemBase(i).hasVariable(var_name)) 54 8 : mooseError("Variable '" + var_name + "' not found on sub-application ", i, "!"); 55 : } 56 252 : } 57 : 58 : void 59 164 : PODSamplerSolutionTransfer::execute() 60 : { 61 : 62 164 : const std::vector<std::string> & var_names = _trainer.getVarNames(); 63 : 64 : // Selecting the appropriate action based on the drection. 65 164 : switch (_direction) 66 : { 67 84 : case FROM_MULTIAPP: 68 : 69 : // Looping over sub-apps created for different samples 70 256 : for (dof_id_type i = _sampler_ptr->getLocalRowBegin(); i < _sampler_ptr->getLocalRowEnd(); 71 : ++i) 72 : { 73 : // Getting reference to the solution vector of the sub-app. 74 344 : FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(i); 75 : NonlinearSystemBase & nl = app_problem.getNonlinearSystemBase(/*nl_sys_num=*/0); 76 172 : NumericVector<Number> & solution = nl.solution(); 77 : 78 : // Looping over the variables to extract the corresponding solution values 79 : // and copy them into the container of the trainer. 80 344 : for (unsigned int v_index = 0; v_index < var_names.size(); ++v_index) 81 : { 82 : // Getting the corresponding DoF indices for the variable. 83 172 : nl.setVariableGlobalDoFs(var_names[v_index]); 84 : const std::vector<dof_id_type> & var_dofs = nl.getVariableGlobalDoFs(); 85 : 86 : // Initializing a temporary vector for the partial solution. 87 : std::shared_ptr<DenseVector<Real>> tmp = std::make_shared<DenseVector<Real>>(); 88 172 : solution.localize(tmp->get_values(), var_dofs); 89 : 90 : // Copying the temporary vector into the trainer. 91 172 : _trainer.addSnapshot(v_index, i, tmp); 92 : } 93 : } 94 : break; 95 : 96 : case TO_MULTIAPP: 97 : 98 : // Looping over all the variables in the trainer to copy the corresponding 99 : // basis vectors into the solution. 100 : unsigned int counter = 0; 101 160 : for (unsigned int var_i = 0; var_i < var_names.size(); ++var_i) 102 : { 103 : // Looping over the bases of the given variable and plugging them into 104 : // a sub-application. 105 80 : unsigned int var_base_num = _trainer.getBaseSize(var_i); 106 336 : for (unsigned int base_i = 0; base_i < var_base_num; ++base_i) 107 : { 108 512 : if (getToMultiApp()->hasLocalApp(counter)) 109 : { 110 : // Getting the reference to the solution vector in the subapp. 111 320 : FEProblemBase & app_problem = getToMultiApp()->appProblemBase(counter); 112 : NonlinearSystemBase & nl = app_problem.getNonlinearSystemBase(/*nl_sys_num=*/0); 113 160 : NumericVector<Number> & solution = nl.solution(); 114 : 115 : // Zeroing the solution to make sure that only the required part 116 : // is non-zero after copy. 117 160 : solution.zero(); 118 : 119 : // Getting the degrees of freedom for the given variable. 120 160 : nl.setVariableGlobalDoFs(var_names[var_i]); 121 : const std::vector<dof_id_type> & var_dofs = nl.getVariableGlobalDoFs(); 122 : 123 : // Fetching the basis vector and plugging it into the solution. 124 160 : const DenseVector<Real> & base_vector = _trainer.getBasisVector(var_i, base_i); 125 160 : solution.insert(base_vector, var_dofs); 126 160 : solution.close(); 127 : 128 : // Make sure that the sub-application uses this vector to evaluate the 129 : // residual. 130 160 : nl.setSolution(solution); 131 : } 132 256 : counter++; 133 : } 134 : } 135 : break; 136 : } 137 164 : } 138 : 139 : void 140 0 : PODSamplerSolutionTransfer::initializeFromMultiapp() 141 : { 142 0 : } 143 : 144 : void 145 0 : PODSamplerSolutionTransfer::executeFromMultiapp() 146 : { 147 0 : if (_pod_multi_app->snapshotGeneration()) 148 : { 149 0 : const std::vector<std::string> & var_names = _trainer.getVarNames(); 150 : 151 0 : const dof_id_type n = getFromMultiApp()->numGlobalApps(); 152 : 153 0 : for (MooseIndex(n) i = 0; i < n; i++) 154 : { 155 0 : if (getFromMultiApp()->hasLocalApp(i)) 156 : { 157 : // Getting reference to the solution vector of the sub-app. 158 0 : FEProblemBase & app_problem = getFromMultiApp()->appProblemBase(i); 159 : NonlinearSystemBase & nl = app_problem.getNonlinearSystemBase(/*nl_sys_num=*/0); 160 0 : NumericVector<Number> & solution = nl.solution(); 161 : 162 : // Looping over the variables to extract the corresponding solution values 163 : // and copy them into the container of the trainer. 164 0 : for (unsigned int var_i = 0; var_i < var_names.size(); ++var_i) 165 : { 166 : // Getting the corresponding DoF indices for the variable. 167 0 : nl.setVariableGlobalDoFs(var_names[var_i]); 168 : const std::vector<dof_id_type> & var_dofs = nl.getVariableGlobalDoFs(); 169 : 170 : // Initializing a temporary vector for the partial solution. 171 : std::shared_ptr<DenseVector<Real>> tmp = std::make_shared<DenseVector<Real>>(); 172 0 : solution.localize(tmp->get_values(), var_dofs); 173 : 174 : // Copying the temporary vector into the trainer. 175 0 : _trainer.addSnapshot(var_i, _global_index, tmp); 176 : } 177 : } 178 : } 179 : } 180 0 : } 181 : 182 : void 183 0 : PODSamplerSolutionTransfer::finalizeFromMultiapp() 184 : { 185 0 : } 186 : 187 : void 188 0 : PODSamplerSolutionTransfer::initializeToMultiapp() 189 : { 190 0 : } 191 : 192 : void 193 0 : PODSamplerSolutionTransfer::executeToMultiapp() 194 : { 195 0 : if (!_pod_multi_app->snapshotGeneration()) 196 : { 197 0 : const std::vector<std::string> & var_names = _trainer.getVarNames(); 198 0 : dof_id_type var_i = _trainer.getVariableIndex(_global_index); 199 : 200 : // Getting the reference to the solution vector in the subapp. 201 0 : FEProblemBase & app_problem = getToMultiApp()->appProblemBase(processor_id()); 202 : NonlinearSystemBase & nl = app_problem.getNonlinearSystemBase(/*nl_sys_num=*/0); 203 0 : NumericVector<Number> & solution = nl.solution(); 204 : 205 : // Zeroing the solution to make sure that only the required part 206 : // is non-zero after copy. 207 0 : solution.zero(); 208 : 209 : // Getting the degrees of freedom for the given variable. 210 0 : nl.setVariableGlobalDoFs(var_names[var_i]); 211 : const std::vector<dof_id_type> & var_dofs = nl.getVariableGlobalDoFs(); 212 : 213 : // Fetching the basis vector and plugging it into the solution. 214 0 : const DenseVector<Real> & base_vector = _trainer.getBasisVector(_global_index); 215 0 : solution.insert(base_vector, var_dofs); 216 0 : solution.close(); 217 : 218 : // Make sure that the sub-application uses this vector to evaluate the 219 : // residual. 220 0 : nl.setSolution(solution); 221 : } 222 0 : } 223 : 224 : void 225 0 : PODSamplerSolutionTransfer::finalizeToMultiapp() 226 : { 227 0 : }