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 "MooseError.h" 11 : #include "MooseTypes.h" 12 : #include "GeneralOptimization.h" 13 : #include "libmesh/id_types.h" 14 : #include <numeric> 15 : 16 : registerMooseObject("OptimizationApp", GeneralOptimization); 17 : 18 : InputParameters 19 757 : GeneralOptimization::validParams() 20 : { 21 757 : InputParameters params = OptimizationReporterBase::validParams(); 22 : 23 1514 : params.addRequiredParam<ReporterValueName>( 24 : "objective_name", "Preferred name of reporter value defining the objective."); 25 1514 : params.addParam<std::vector<dof_id_type>>( 26 : "num_values", 27 : "Number of parameter values associated with each parameter group in 'parameter_names'."); 28 1514 : params.addParam<ReporterValueName>("num_values_name", 29 : "Reporter that holds the number of parameter values " 30 : "associated with each parameter group in 'parameter_names'."); 31 1514 : params.addParam<std::vector<std::vector<Real>>>( 32 : "initial_condition", 33 : "Initial conditions for each parameter. A vector is given for each parameter group. A " 34 : "single value can be given for each group and all parameters in that group will be set to " 35 : "that value. The default value is 0."); 36 1514 : params.addParam<std::vector<std::vector<Real>>>( 37 : "lower_bounds", 38 : "Lower bound for each parameter. A vector is given for each parameter group. A single " 39 : "value can be given for each group and all parameters in that group will be set to that " 40 : "value"); 41 1514 : params.addParam<std::vector<std::vector<Real>>>( 42 : "upper_bounds", 43 : "Upper bound for each parameter. A vector is given for each parameter group. A single " 44 : "value can be given for each group and all parameters in that group will be set to that " 45 : "value"); 46 : 47 757 : params.addClassDescription("Reporter that provides TAO with the objective, gradient, and " 48 : "constraint data, which are supplied by the reporters and " 49 : "postprocessors from the forward and adjoint subapps."); 50 757 : return params; 51 0 : } 52 : 53 379 : GeneralOptimization::GeneralOptimization(const InputParameters & parameters) 54 : : OptimizationReporterBase(parameters), 55 758 : _objective_val(declareValueByName<Real>(getParam<ReporterValueName>("objective_name"), 56 : REPORTER_MODE_REPLICATED)), 57 379 : _num_values_reporter( 58 379 : isParamValid("num_values_name") 59 379 : ? &declareValueByName<std::vector<dof_id_type>>( 60 : getParam<ReporterValueName>("num_values_name"), REPORTER_MODE_REPLICATED) 61 379 : : nullptr) 62 : { 63 379 : } 64 : 65 : Real 66 5785 : GeneralOptimization::computeObjective() 67 : { 68 : Real val = 0; 69 5785 : if (_tikhonov_coeff > 0.0) 70 : { 71 : Real param_norm_sqr = 0; 72 912 : for (const auto & data : _parameters) 73 1542 : for (const auto & param_val : *data) 74 1086 : param_norm_sqr += param_val * param_val; 75 : // We multiply by 0.5 to maintain backwards compatibility. 76 456 : val += 0.5 * _tikhonov_coeff * param_norm_sqr; 77 : } 78 5785 : return _objective_val + val; 79 : } 80 : 81 : dof_id_type 82 530 : GeneralOptimization::getNumParams() const 83 : { 84 530 : if (_ndof == 0) 85 0 : mooseError( 86 : "The number of parameters you have is zero and this shouldn't happen. Make sure you are " 87 : "running your forward problem on \'INITIAL\' if you are using a reporter transfer to " 88 : "supply " 89 : "that information."); 90 : 91 530 : return _ndof; 92 : } 93 : 94 : void 95 258 : GeneralOptimization::setICsandBounds() 96 : { 97 : // Check that one and only one set of parameters are given. 98 : // Set here because some derived reporters use a different method of 99 : // determining numbers of dofs 100 774 : if (!(isParamValid("num_values_name") ^ isParamValid("num_values"))) 101 0 : paramError("Need to supply one and only one of num_values_name or num_values."); 102 : 103 258 : if (_num_values_reporter) 104 0 : _nvalues = *_num_values_reporter; 105 : else 106 774 : _nvalues = getParam<std::vector<dof_id_type>>("num_values"); 107 : 108 258 : _ndof = std::accumulate(_nvalues.begin(), _nvalues.end(), 0); 109 : 110 : // size checks 111 258 : if (_parameter_names.size() != _nvalues.size()) 112 0 : paramError( 113 : "num_parameters", 114 : "There should be a number in \'num_parameters\' for each name in \'parameter_names\'."); 115 : 116 600 : for (const auto & param_id : make_range(_nparams)) 117 : { 118 344 : _gradients[param_id]->resize(_nvalues[param_id]); 119 : 120 344 : std::vector<Real> ic(parseInputData("initial_condition", 0, param_id)); 121 : std::vector<Real> lb( 122 344 : parseInputData("lower_bounds", std::numeric_limits<Real>::lowest(), param_id)); 123 : std::vector<Real> ub( 124 344 : parseInputData("upper_bounds", std::numeric_limits<Real>::max(), param_id)); 125 : 126 342 : _lower_bounds.insert(_lower_bounds.end(), lb.begin(), lb.end()); 127 342 : _upper_bounds.insert(_upper_bounds.end(), ub.begin(), ub.end()); 128 : 129 342 : _parameters[param_id]->assign(ic.begin(), ic.end()); 130 342 : } 131 256 : }