https://mooseframework.inl.gov
WebServerControl.h
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 
10 #pragma once
11 
12 #include "Control.h"
13 
15 
16 #include "libmesh/parallel_eigen.h"
17 
18 #include "tinyhttp/http.h"
19 
20 #include <atomic>
21 #include <memory>
22 #include <thread>
23 
28 class WebServerControl : public Control
29 {
30 public:
32 
35 
36  virtual void execute() override;
37 
41  static std::string stringifyJSONType(const miniJson::JsonType & json_type);
42 
47  template <typename T, miniJson::JsonType json_type>
48  static T getScalarJSONValue(const miniJson::Json & json_value);
49 
57  template <typename T>
58  static miniJson::Json toMiniJson(const T & value);
59 
61 
65  template <typename T>
66  class TypedValueBase : public ValueBase
67  {
68  public:
69  TypedValueBase(const std::string & name, const std::string & type) : ValueBase(name, type) {}
70  TypedValueBase(const std::string & name, const std::string & type, const T & value)
72  {
73  }
74 
76  using value_type = T;
77 
81  const T & value() const { return _value; }
82 
83  virtual void setControllableValue(WebServerControl & control) override final
84  {
85  control.comm().broadcast(_value);
86  control.setControllableValueByName<T>(name(), value());
87  }
88 
89  private:
91  T _value;
92  };
93 
97  template <typename T, miniJson::JsonType json_type>
98  class ScalarValue : public TypedValueBase<T>
99  {
100  public:
101  ScalarValue(const std::string & name, const std::string & type) : TypedValueBase<T>(name, type)
102  {
103  }
104  ScalarValue(const std::string & name,
105  const std::string & type,
106  const miniJson::Json & json_value)
107  : TypedValueBase<T>(name, type, getScalarJSONValue<T, json_type>(json_value))
108  {
109  }
110  };
111 
115  template <typename T, miniJson::JsonType json_type>
116  class VectorValue : public TypedValueBase<std::vector<T>>
117  {
118  public:
119  VectorValue(const std::string & name, const std::string & type)
120  : TypedValueBase<std::vector<T>>(name, type)
121  {
122  }
123  VectorValue(const std::string & name,
124  const std::string & type,
125  const miniJson::Json & json_value)
126  : TypedValueBase<std::vector<T>>(name, type, getVectorJSONValue(json_value))
127  {
128  }
129 
130  static std::vector<T> getVectorJSONValue(const miniJson::Json & json_value)
131  {
132  const auto from_json_type = json_value.getType();
133  if (from_json_type != miniJson::JsonType::kArray)
134  throw ValueBase::Exception("The value '" + json_value.serialize() + "' of type " +
135  stringifyJSONType(from_json_type) + " is not an array");
136 
137  const auto & array_value = json_value.toArray();
138  std::vector<T> value(array_value.size());
139  for (const auto i : index_range(array_value))
140  value[i] = getScalarJSONValue<T, json_type>(array_value[i]);
141  return value;
142  }
143  };
144 
148  class RealEigenMatrixValue : public TypedValueBase<RealEigenMatrix>
149  {
150  public:
151  RealEigenMatrixValue(const std::string & name, const std::string & type);
152  RealEigenMatrixValue(const std::string & name,
153  const std::string & type,
154  const miniJson::Json & json_value);
155  static RealEigenMatrix getMatrixJSONValue(const miniJson::Json & json_value);
156  };
157 
161  template <typename T, miniJson::JsonType json_type>
162  static char registerScalarType(const std::string type_name)
163  {
165  }
169  template <typename T, miniJson::JsonType json_type>
170  static char registerVectorType(const std::string type_name)
171  {
173  type_name + ">");
174  }
175 
180  {
181  return Moose::WebServerControlTypeRegistry().add<RealEigenMatrixValue>("RealEigenMatrix");
182  }
183 
184 private:
188  void startServer();
189 
193  bool currentlyWaiting() const { return _currently_waiting.load(); }
194 
196  std::atomic<bool> _currently_waiting;
197 
198  // Whether or not the solve should be terminated in the next execute() call
199  std::atomic<bool> _terminate_requested;
200 
202  std::unique_ptr<HttpServer> _server;
204  std::unique_ptr<std::thread> _server_thread;
205 
207  std::vector<std::unique_ptr<ValueBase>> _controlled_values;
210 };
211 
212 template <typename T, miniJson::JsonType json_type>
213 T
214 WebServerControl::getScalarJSONValue(const miniJson::Json & json_value)
215 {
216  const auto from_json_type = json_value.getType();
217  if (from_json_type != json_type)
218  throw ValueBase::Exception("The value " + json_value.serialize() + " of JSON type " +
219  stringifyJSONType(from_json_type) +
220  " is not of the expected JSON type " + stringifyJSONType(json_type));
221 
222  if constexpr (json_type == miniJson::JsonType::kBool)
223  return json_value.toBool();
224  else if constexpr (json_type == miniJson::JsonType::kNumber)
225  return json_value.toDouble();
226  else if constexpr (json_type == miniJson::JsonType::kString)
227  return json_value.toString();
228  ::mooseError("WebServerControl::getScalarJSONValue(): Not configured for parsing type ",
229  stringifyJSONType(from_json_type));
230 }
231 
232 // Explicit specialization
233 template <>
234 miniJson::Json WebServerControl::toMiniJson(const nlohmann::json & value);
Class that stores a RealEigenMatrix controllable value to be set.
std::atomic< bool > _currently_waiting
Whether or not the Control is currently waiting.
static char registerScalarType(const std::string type_name)
Registers a scalar parameter type to be controlled.
Starts a webserver that an external process can connect to in order to send JSON messages to control ...
static RealEigenMatrix getMatrixJSONValue(const miniJson::Json &json_value)
void startServer()
Internal method for starting the server.
Class that stores a scalar controllable value to be set.
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:127
RealEigenMatrixValue(const std::string &name, const std::string &type)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
WebServerControl(const InputParameters &parameters)
The base class for a value that is produced by this registry.
Common exception for parsing related errors in converting JSON to a value.
T _value
The underlying value.
static char registerVectorType(const std::string type_name)
Registers a vector parameter type to be controlled.
A static registry used to register and build values of different types for the WebServerControl.
Base class for a controllable value with a given type and name.
static miniJson::Json toMiniJson(const T &value)
Convert values to a miniJson::Json node.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
std::vector< std::unique_ptr< ValueBase > > _controlled_values
The values received to control; filled on rank 0 from the server and then broadcast.
TypedValueBase(const std::string &name, const std::string &type)
VectorValue(const std::string &name, const std::string &type)
std::mutex _controlled_values_mutex
Mutex to prevent threaded writes to _controlled_values.
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > RealEigenMatrix
Definition: MooseTypes.h:149
static T getScalarJSONValue(const miniJson::Json &json_value)
Class that stores a vector controllable value to be set.
ScalarValue(const std::string &name, const std::string &type, const miniJson::Json &json_value)
static std::string stringifyJSONType(const miniJson::JsonType &json_type)
std::atomic< bool > _terminate_requested
TypedValueBase(const std::string &name, const std::string &type, const T &value)
std::unique_ptr< std::thread > _server_thread
The server thread.
Base class for Control objects.
Definition: Control.h:34
virtual void execute() override
Execute the control.
virtual void setControllableValue(WebServerControl &control) override final
Sets the controllable value given the name and type via the controllable interface in control...
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...
Definition: MooseBase.h:267
ScalarValue(const std::string &name, const std::string &type)
static InputParameters validParams()
std::vector< T > value_type
The underlying type of the value.
static char add(const std::string &type_name)
Registers a type with string name type_name and the given derived type.
static std::vector< T > getVectorJSONValue(const miniJson::Json &json_value)
static char registerRealEigenMatrix()
Registers a vector parameter type to be controlled.
auto index_range(const T &sizable)
bool currentlyWaiting() const
std::unique_ptr< HttpServer > _server
The server.
VectorValue(const std::string &name, const std::string &type, const miniJson::Json &json_value)