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 1124 : GeneralOptimization::validParams() 20 : { 21 1124 : InputParameters params = OptimizationReporterBase::validParams(); 22 : 23 2248 : params.addRequiredParam<ReporterValueName>( 24 : "objective_name", "Preferred name of reporter value defining the objective."); 25 2248 : params.addParam<std::vector<dof_id_type>>( 26 : "num_values", 27 : "Number of parameter values associated with each parameter group in 'parameter_names'."); 28 2248 : 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 2248 : 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 2248 : 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 2248 : 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 1124 : 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 1124 : return params; 51 0 : } 52 : 53 562 : GeneralOptimization::GeneralOptimization(const InputParameters & parameters) 54 : : OptimizationReporterBase(parameters), 55 1124 : _objective_val(declareValueByName<Real>(getParam<ReporterValueName>("objective_name"), 56 : REPORTER_MODE_REPLICATED)), 57 562 : _num_values_reporter( 58 562 : isParamValid("num_values_name") 59 562 : ? &declareValueByName<std::vector<dof_id_type>>( 60 : getParam<ReporterValueName>("num_values_name"), REPORTER_MODE_REPLICATED) 61 562 : : nullptr) 62 : { 63 562 : } 64 : 65 : Real 66 7004 : GeneralOptimization::computeObjective() 67 : { 68 : Real val = 0; 69 7004 : if (_tikhonov_coeff > 0.0) 70 : { 71 : Real param_norm_sqr = 0; 72 1368 : for (const auto & data : _parameters) 73 2313 : for (const auto & param_val : *data) 74 1629 : param_norm_sqr += param_val * param_val; 75 : // We multiply by 0.5 to maintain backwards compatibility. 76 684 : val += 0.5 * _tikhonov_coeff * param_norm_sqr; 77 : } 78 7004 : return _objective_val + val; 79 : } 80 : 81 : dof_id_type 82 774 : GeneralOptimization::getNumParams() const 83 : { 84 774 : 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 774 : return _ndof; 92 : } 93 : 94 : void 95 412 : 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 1236 : 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 412 : if (_num_values_reporter) 104 0 : _nvalues = *_num_values_reporter; 105 : else 106 1236 : _nvalues = getParam<std::vector<dof_id_type>>("num_values"); 107 : 108 412 : _ndof = std::accumulate(_nvalues.begin(), _nvalues.end(), 0); 109 : 110 : // size checks 111 412 : 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 994 : for (const auto & param_id : make_range(_nparams)) 117 : { 118 586 : _gradients[param_id]->resize(_nvalues[param_id]); 119 : 120 586 : std::vector<Real> ic(parseInputData("initial_condition", 0, param_id)); 121 : std::vector<Real> lb( 122 586 : parseInputData("lower_bounds", std::numeric_limits<Real>::lowest(), param_id)); 123 : std::vector<Real> ub( 124 586 : parseInputData("upper_bounds", std::numeric_limits<Real>::max(), param_id)); 125 : 126 582 : _lower_bounds.insert(_lower_bounds.end(), lb.begin(), lb.end()); 127 582 : _upper_bounds.insert(_upper_bounds.end(), ub.begin(), ub.end()); 128 : 129 582 : _parameters[param_id]->assign(ic.begin(), ic.end()); 130 582 : } 131 408 : }