https://mooseframework.inl.gov
ParameterMeshOptimization.C
Go to the documentation of this file.
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 
11 
12 #include "AddVariableAction.h"
13 #include "ParameterMesh.h"
14 #include "libmesh/string_to_enum.h"
15 
16 using namespace libMesh;
17 
19 
22 {
24 
25  params.addClassDescription(
26  "Computes objective function, gradient and contains reporters for communicating between "
27  "optimizeSolve and subapps using mesh-based parameter definition.");
28 
29  params.addRequiredParam<std::vector<FileName>>(
30  "parameter_meshes", "Exodus file containing meshes describing parameters.");
31 
33  MultiMooseEnum families(family.getRawNames(), "LAGRANGE");
34  params.addParam<MultiMooseEnum>(
35  "parameter_families",
36  families,
37  "Specifies the family of FE shape functions for each group of parameters. If a single value "
38  "is "
39  "specified, then that value is used for all groups of parameters.");
41  MultiMooseEnum orders(order.getRawNames(), "FIRST");
42  params.addParam<MultiMooseEnum>(
43  "parameter_orders",
44  orders,
45  "Specifies the order of FE shape functions for each group of parameters. If a single value "
46  "is "
47  "specified, then that value is used for all groups of parameters.");
48 
49  params.addParam<unsigned int>(
50  "num_parameter_times", 1, "The number of time points the parameters represent.");
51 
52  params.addParam<std::vector<std::string>>(
53  "initial_condition_mesh_variable",
54  "Name of variable on parameter mesh to use as initial condition.");
55  params.addParam<std::vector<std::string>>(
56  "lower_bound_mesh_variable", "Name of variable on parameter mesh to use as lower bound.");
57  params.addParam<std::vector<std::string>>(
58  "upper_bound_mesh_variable", "Name of variable on parameter mesh to use as upper bound.");
59  params.addParam<std::vector<unsigned int>>(
60  "exodus_timesteps_for_parameter_mesh_variable",
61  "Timesteps to read all parameter group bounds and initial conditions from Exodus mesh. The "
62  "options are to give no timestep, a single timestep or \"num_parameter_times\" timesteps. "
63  "No timestep results in the final timestep from the mesh being used. A single timestep "
64  "results in values at that timestep being used for all timesteps. \"num_parameter_times\" "
65  "timesteps results in values from the mesh at those steps being used. The same timesteps "
66  "are used for all parameter groups and all meshes, the capability to define different "
67  "timesteps for different meshes is not supported.");
68 
69  return params;
70 }
71 
73  : GeneralOptimization(parameters)
74 {
75 }
76 
77 std::vector<Real>
78 ParameterMeshOptimization::parseExodusData(const std::vector<unsigned int> & exodus_timestep,
79  const ParameterMesh & pmesh,
80  const std::string & mesh_var_name,
81  unsigned int ntimes) const
82 {
83  unsigned int num_cont_params = pmesh.size() * ntimes;
84  std::vector<Real> parsed_data;
85  // read from mesh
86 
87  for (auto const & step : exodus_timestep)
88  {
89  std::vector<Real> data = pmesh.getParameterValues(mesh_var_name, step);
90  parsed_data.insert(parsed_data.end(), data.begin(), data.end());
91  }
92  if (parsed_data.size() != num_cont_params)
93  mooseError("Number of parameters assigned by ",
94  mesh_var_name,
95  " is not equal to the number of parameters on the mesh. Mesh contains ",
96  num_cont_params,
97  " parameters and ",
98  mesh_var_name,
99  " assigned ",
100  parsed_data.size(),
101  " parameters.");
102 
103  return parsed_data;
104 }
105 
106 void
108 {
109  if ((isParamValid("num_values_name") || isParamValid("num_values")))
110  paramError("num_values_name or num_values should not be used with ParameterMeshOptimization. "
111  "Instead the number of dofs is set by the parameter meshes.");
112 
113  _nvalues.resize(_nparams, 0);
114  // Fill the mesh information
115  const auto & meshes = getParam<std::vector<FileName>>("parameter_meshes");
116  const auto & families = getParam<MultiMooseEnum>("parameter_families");
117  const auto & orders = getParam<MultiMooseEnum>("parameter_orders");
118  const auto & ntimes = getParam<unsigned int>("num_parameter_times");
119 
120  // Fill exodus parameter bounds and IC information
121  std::vector<std::string> initial_condition_mesh_variable;
122  std::vector<std::string> lower_bound_mesh_variable;
123  std::vector<std::string> upper_bound_mesh_variable;
124  if (isParamValid("initial_condition_mesh_variable"))
125  initial_condition_mesh_variable =
126  getParam<std::vector<std::string>>("initial_condition_mesh_variable");
127  if (isParamValid("lower_bound_mesh_variable"))
128  lower_bound_mesh_variable = getParam<std::vector<std::string>>("lower_bound_mesh_variable");
129  if (isParamValid("upper_bound_mesh_variable"))
130  upper_bound_mesh_variable = getParam<std::vector<std::string>>("upper_bound_mesh_variable");
131 
132  std::vector<unsigned int> exodus_timestep;
133  if (isParamValid("exodus_timesteps_for_parameter_mesh_variable"))
134  exodus_timestep =
135  getParam<std::vector<unsigned int>>("exodus_timesteps_for_parameter_mesh_variable");
136  else // get last timestep in file
137  exodus_timestep = {std::numeric_limits<unsigned int>::max()};
138 
139  // now do a bunch of error checking
140  // Size checks for data
141  if (meshes.size() != _nparams)
142  paramError("parameter_meshes",
143  "There must be a mesh associated with each group of parameters.");
144  if (families.size() > 1 && families.size() != _nparams)
145  paramError("parameter_families",
146  "There must be a family associated with each group of parameters.");
147  if (orders.size() > 1 && orders.size() != _nparams)
148  paramError("parameter_orders",
149  "There must be an order associated with each group of parameters.");
150 
151  // error checking that initial conditions and bounds are only read from a single location
152  if (isParamValid("initial_condition_mesh_variable") && isParamValid("initial_condition"))
153  paramError("initial_condition_mesh_variable",
154  "Initial conditions for all parameter groups can only be defined by "
155  "initial_condition_mesh_variable or "
156  "initial_condition but not both.");
157  else if (isParamValid("lower_bound_mesh_variable") && isParamValid("lower_bounds"))
158  paramError(
159  "lower_bound_mesh_variable",
160  "Lower bounds for all parameter groups can only be defined by lower_bound_mesh_variable or "
161  "lower_bounds but not both.");
162  else if (isParamValid("upper_bound_mesh_variable") && isParamValid("upper_bounds"))
163  paramError(
164  "upper_bound_mesh_variable",
165  "Upper bounds for all parameter groups can only be defined by upper_bound_mesh_variable or "
166  "upper_bounds but not both.");
167 
168  // Make sure they did not specify too many timesteps
169  if (isParamValid("exodus_timesteps_for_parameter_mesh_variable") &&
170  (!isParamValid("lower_bound_mesh_variable") + !isParamValid("upper_bound_mesh_variable") +
171  !isParamValid("initial_condition_mesh_variable") ==
172  3))
173  paramError("\"exodus_timesteps_for_parameter_mesh_variable\" should only be specified if "
174  "reading values from a mesh.");
175  else if (exodus_timestep.size() != ntimes && exodus_timestep.size() != 1)
176  paramError("exodus_timesteps_for_parameter_mesh_variable",
177  "Number of timesteps to read mesh data specified by "
178  "\"exodus_timesteps_for_parameter_mesh_variable\" incorrect. "
179  "\"exodus_timesteps_for_parameter_mesh_variable\" can specify a single timestep or "
180  "\"num_parameter_times\" timesteps.");
181 
182  _ndof = 0;
183  for (const auto & param_id : make_range(_nparams))
184  {
185  // store off all the variable names that you might want to read from the mesh
186  std::vector<std::string> var_names;
187  if (isParamValid("initial_condition_mesh_variable"))
188  var_names.push_back(initial_condition_mesh_variable[param_id]);
189  if (isParamValid("lower_bound_mesh_variable"))
190  var_names.push_back(lower_bound_mesh_variable[param_id]);
191  if (isParamValid("upper_bound_mesh_variable"))
192  var_names.push_back(upper_bound_mesh_variable[param_id]);
193 
194  const std::string family = families.size() > 1 ? families[param_id] : families[0];
195  const std::string order = orders.size() > 1 ? orders[param_id] : orders[0];
196  const FEType fetype(Utility::string_to_enum<Order>(order),
197  Utility::string_to_enum<FEFamily>(family));
198 
199  ParameterMesh pmesh(fetype, meshes[param_id], var_names);
200  _nvalues[param_id] = pmesh.size() * ntimes;
201  _ndof += _nvalues[param_id];
202 
203  // read and assign initial conditions
204  std::vector<Real> initial_condition;
205  if (isParamValid("initial_condition_mesh_variable"))
207  exodus_timestep, pmesh, initial_condition_mesh_variable[param_id], ntimes);
208  else
209  initial_condition = parseInputData("initial_condition", 0, param_id);
210 
211  _parameters[param_id]->assign(initial_condition.begin(), initial_condition.end());
212 
213  // read and assign lower bound
214  std::vector<Real> lower_bound;
215  if (isParamValid("lower_bound_mesh_variable"))
216  lower_bound =
217  parseExodusData(exodus_timestep, pmesh, lower_bound_mesh_variable[param_id], ntimes);
218  else
219  lower_bound = parseInputData("lower_bounds", std::numeric_limits<Real>::lowest(), param_id);
220 
221  _lower_bounds.insert(_lower_bounds.end(), lower_bound.begin(), lower_bound.end());
222 
223  // read and assign upper bound
224  std::vector<Real> upper_bound;
225  if (isParamValid("upper_bound_mesh_variable"))
226  upper_bound =
227  parseExodusData(exodus_timestep, pmesh, upper_bound_mesh_variable[param_id], ntimes);
228  else
229  upper_bound = parseInputData("upper_bounds", std::numeric_limits<Real>::max(), param_id);
230 
231  _upper_bounds.insert(_upper_bounds.end(), upper_bound.begin(), upper_bound.end());
232 
233  // resize gradient vector to be filled later
234  _gradients[param_id]->resize(_nvalues[param_id]);
235  }
236 }
std::vector< Real > parseExodusData(const std::vector< unsigned int > &exodus_timestep, const ParameterMesh &pmesh, const std::string &mesh_var_name, unsigned int ntimes) const
Read initialization data off of parameter mesh and error check.
Utility class to use an Exodus mesh to define controllable parameters for optimization problems This ...
Definition: ParameterMesh.h:42
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static InputParameters validParams()
dof_id_type _ndof
Total number of parameters.
registerMooseObject("OptimizationApp", ParameterMeshOptimization)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
std::string getRawNames() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
static MooseEnum getNonlinearVariableFamilies()
const unsigned int _nparams
Number of parameter vectors.
bool isParamValid(const std::string &name) const
static MooseEnum getNonlinearVariableOrders()
ParameterMeshOptimization(const InputParameters &parameters)
std::vector< dof_id_type > _nvalues
Number of values for each parameter.
Number initial_condition(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
const T & getParam(const std::string &name) const
Mesh-based parameter optimization.
std::vector< Real > parseInputData(std::string type, Real default_value, unsigned int param_id) const
Function to to parse bounds and initial conditions from input file.
std::vector< Real > _lower_bounds
Bounds of the parameters.
void paramError(const std::string &param, Args... args) const
dof_id_type size() const
Definition: ParameterMesh.h:54
std::vector< std::vector< Real > * > _parameters
Parameter values declared as reporter data.
static InputParameters validParams()
std::vector< std::vector< Real > * > _gradients
Gradient values declared as reporter data.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
std::vector< Real > getParameterValues(std::string var_name, unsigned int timestep) const
Initializes parameter data and sets bounds in the main optmiization application getParameterValues is...
virtual void setICsandBounds() override
Sets the initial conditions and bounds right before it is needed.
Optimization reporter that interfaces with TAO.