10#ifdef MOOSE_LIBTORCH_ENABLED
24 params.
addClassDescription(
"Controls the value of multiple controllable input parameters using a "
25 "Libtorch-based neural network.");
27 "parameters",
"Controllable input parameters driven by the network.");
29 "observations",
"Postprocessors used as the current observation vector.");
31 "observation_shift_factors",
33 "Optional offsets applied to the observation values before scaling.");
35 "observation_scaling_factors",
37 "Optional multipliers applied after shifting the observation values.");
38 params.
addParam<std::string>(
"filename",
"File containing the controller network.");
39 params.
addParam<
bool>(
"torch_script_format",
41 "Whether 'filename' is a TorchScript module to evaluate as-is. Otherwise, "
42 "a network is built from 'num_neurons_per_layer' and "
43 "'activation_function', and only its parameters are read from the file.");
48 "Number of recent timesteps to stack into each network input.");
49 params.
addParam<std::vector<unsigned int>>(
50 "num_neurons_per_layer",
"Hidden-layer widths used when constructing the controller.");
51 params.
addParam<std::vector<std::string>>(
52 "activation_function",
53 std::vector<std::string>({
"relu"}),
54 "Activation name for each hidden layer, or one shared value for all layers.");
57 "action_scaling_factors",
59 "Per-action scaling embedded in the controller outputs so saved checkpoints stay in "
67 _old_observations(declareRestartableData<
std::vector<
std::vector<Real>>>(
"old_observations")),
68 _control_names(getParam<
std::vector<
std::string>>(
"parameters")),
69 _current_control_signals(declareRestartableData<
std::vector<Real>>(
70 "current_control_signals",
std::vector<Real>(_control_names.size(), 0.0))),
71 _observation_names(getParam<
std::vector<PostprocessorName>>(
"observations")),
72 _input_timesteps(getParam<unsigned
int>(
"input_timesteps")),
73 _observation_shift_factors(isParamSetByUser(
"observation_shift_factors")
74 ? getParam<
std::vector<Real>>(
"observation_shift_factors")
75 :
std::vector<Real>(_observation_names.size(), 0.0)),
76 _observation_scaling_factors(isParamSetByUser(
"observation_scaling_factors")
77 ? getParam<
std::vector<Real>>(
"observation_scaling_factors")
78 :
std::vector<Real>(_observation_names.size(), 1.0)),
79 _action_scaling_factors(isParamSetByUser(
"action_scaling_factors")
80 ? getParam<
std::vector<Real>>(
"action_scaling_factors")
81 :
std::vector<Real>(_control_names.size(), 1.0)),
82 _observation_history(_input_timesteps)
87 {
"num_neurons_per_layer",
"activation_function"},
88 !getParam<bool>(
"torch_script_format"));
92 "The number of shift factors is not the same as the number of observations!");
96 "The number of normalization coefficients is not the same as the number of "
101 "The number of normalization coefficients is not the same as the number of "
102 "controlled parameters!");
122 const auto & filename = getParam<std::string>(
"filename");
123 if (getParam<bool>(
"torch_script_format"))
124 _nn = std::make_shared<Moose::TorchScriptModule>(filename);
129 std::vector<unsigned int> num_neurons_per_layer =
130 getParam<std::vector<unsigned int>>(
"num_neurons_per_layer");
131 std::vector<std::string> activation_functions =
133 ? getParam<std::vector<std::string>>(
"activation_function")
134 : std::vector<std::string>({
"relu"});
135 const auto input_shift_factors =
137 const auto input_scaling_factors =
139 auto nn = std::make_shared<Moose::LibtorchArtificialNeuralNet>(filename,
142 num_neurons_per_layer,
143 activation_functions,
148 input_scaling_factors,
154 _nn = std::make_shared<Moose::LibtorchArtificialNeuralNet>(*nn);
156 catch (
const c10::Error & e)
159 "The requested pytorch parameter file could not be loaded. This can either be the"
160 "result of the file not existing or a misalignment in the generated container and"
161 "the data in the file. Make sure the dimensions of the generated neural net are the"
162 "same as the dimensions of the parameters in the input file!\n",
186 torch::Tensor action =
_nn->forward(input_tensor);
189 const bool is_torch_script =
191 for (
unsigned int control_i = 0; control_i < n_controls; ++control_i)
212 "The index of the requested control signal is not in the [0," +
219 const std::string & param_name,
220 const std::vector<std::string> & conditional_params,
221 bool should_be_defined)
224 for (
const auto & param : conditional_params)
227 "This parameter should",
228 (should_be_defined ?
" " :
" not "),
245 _nn = std::make_shared<Moose::LibtorchArtificialNeuralNet>(input_nn);
255 const auto input_shift_factors =
257 const auto input_scaling_factors =
261 for (
const auto input_i : index_range(raw_input))
263 (raw_input[input_i] - input_shift_factors[input_i]) * input_scaling_factors[input_i];
266 torch::Tensor input_tensor;
269 return input_tensor.transpose(0, 1);
276 mooseError(
"The neural network in the controller must exist!");
registerMooseObject("MooseApp", LibtorchNeuralNetControl)
void ErrorVector unsigned int
Base class for Control objects.
static InputParameters validParams()
Class constructor.
A time-dependent, neural network-based control of multiple input parameters.
const std::vector< Real > _action_scaling_factors
Multipliers for the actions.
virtual void execute() override
Execute the neural network to determine the controllable parameter values.
void conditionalParameterError(const std::string ¶m_name, const std::vector< std::string > &conditional_param, bool should_be_defined=true)
Function responsible for checking for potential user errors in the input file.
bool hasControlNeuralNet() const
Return true if the object already has a neural network.
virtual void initialSetup() override
Load any file-backed controller state after full object construction.
const unsigned int _input_timesteps
Number of timesteps to use as input data from the reporters (this influences how many past results ar...
virtual void loadControlNeuralNet(const Moose::LibtorchArtificialNeuralNet &input_nn)
Function responsible for loading the neural network for the controller.
Real getSignal(const unsigned int signal_index) const
Get the (signal_index)-th signal of the control neural net.
const std::vector< PostprocessorName > & _observation_names
Names of the postprocessors which contain the observations of the system.
const std::vector< Real > _observation_shift_factors
Shifting constants for the observations.
static InputParameters validParams()
Return the input parameters supported by this control.
const std::vector< Real > _observation_scaling_factors
Scaling constants (multipliers) for the observations.
LibtorchNeuralNetControl(const InputParameters ¶meters)
Construct using input parameters.
std::vector< Real > _current_observation
The values of the current observed postprocessor values.
std::vector< Real > & _current_control_signals
The control signals from the last evaluation of the controller, saved for recover/restart.
void updateCurrentObservation()
Refresh the current observation values from the linked postprocessors.
virtual void loadControlNeuralNetFromFile()
Load the controller neural network from the configured checkpoint file.
const std::vector< std::string > & _control_names
The names of the controllable parameters.
torch::Tensor prepareInputTensor()
Prepare the input tensor for the controller neural network.
std::shared_ptr< Moose::LibtorchNeuralNetBase > _nn
Pointer to the neural net object which is supposed to be used to control the parameter values.
const LibtorchObservationHistoryHelper _observation_history
Shared observation history stacking and factor-expansion helper.
std::vector< std::vector< Real > > & _old_observations
This variable is populated if the controller needs access to older values of the observed postprocess...
std::vector< const Real * > _observation_values
Links to the current observation postprocessor values.
const Moose::LibtorchNeuralNetBase & controlNeuralNet() const
Return a reference to the stored neural network.
void initializeHistory(const std::vector< Real > &observation, std::vector< std::vector< Real > > &old_observations) const
Fill the history buffer with copies of the current observation.
std::vector< Real > expandObservationFactors(const std::vector< Real > &observation_factors) const
Repeat per-observation-entry factors across all stacked timesteps.
void advanceHistory(const std::vector< Real > &observation, std::vector< std::vector< Real > > &old_observations) const
Advance the history buffer by inserting the latest observation.
std::vector< Real > stackCurrentObservation(const std::vector< Real > &observation, const std::vector< std::vector< Real > > &old_observations) const
Flatten the current observation together with its stored history.
const InputParameters & parameters() const
Get the parameters of the object.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Simple feed-forward neural net with optional affine input and output scaling.
This base class is meant to gather the functions and members common in every neural network based on ...
virtual const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name) const
Retrieve the value of the Postprocessor.
void vectorToTensor(const std::vector< DataType > &vector, torch::Tensor &tensor, const bool detach=false)
Utility function that converts a standard vector to a torch::Tensor.
void loadLibtorchArtificialNeuralNetState(Moose::LibtorchArtificialNeuralNet &nn, const std::string &filename)
Load an artificial-neural-network checkpoint written as a native libtorch state archive.