22 "Reporter to hold measurement and simulation data for optimization problems");
25 "Measurement values collected from locations given by measurement_points");
26 params.
addParam<std::vector<Point>>(
"measurement_points",
27 "Point locations corresponding to each measurement value");
28 params.
addParam<std::vector<Real>>(
"measurement_times",
29 "Times corresponding to each measurement value");
31 params.
addParam<FileName>(
"measurement_file",
32 "CSV file with measurement value and coordinates (value, x, y, z).");
34 "file_xcoord",
"x",
"x coordinate column name from measurement_file csv being read in.");
36 "file_ycoord",
"y",
"y coordinate column name from csv file being read in.");
38 "file_zcoord",
"z",
"z coordinate column name from csv file being read in.");
40 "file_time",
"time",
"time column name from csv file being read in.");
41 params.
addParam<std::vector<std::string>>(
42 "file_variable_weights", {},
"variable weight column names from csv file being read in.");
44 "file_value",
"value",
"measurement value column name from csv file being read in.");
46 params.
addParam<std::vector<std::string>>(
47 "variable_weight_names",
48 "Vector of weight reporter names that will create a reporter to transfer weights into. The " 49 "ordering of these weight reporter names corresponds to the ordering used in variable.");
50 params.
addParam<std::vector<VariableName>>(
51 "variable",
"Vector of variable names to sample at measurement points.");
52 params.
addParam<ReporterValueName>(
"objective_name",
53 "Name of reporter value defining the objective.");
55 "Input Measurement Data");
57 "file_value file_variable_weights",
58 "File Measurement Data");
65 _measurement_xcoord(this->template declareValueByName<
std::vector<
Real>>(
67 _measurement_ycoord(this->template declareValueByName<
std::vector<
Real>>(
69 _measurement_zcoord(this->template declareValueByName<
std::vector<
Real>>(
71 _measurement_time(this->template declareValueByName<
std::vector<
Real>>(
73 _measurement_values(this->template declareValueByName<
std::vector<
Real>>(
75 _simulation_values(this->template declareValueByName<
std::vector<
Real>>(
77 _misfit_values(this->template declareValueByName<
std::vector<
Real>>(
"misfit_values",
79 _objective_val(this->isParamSetByUser(
"objective_name")
80 ? this->template declareValueByName<
Real>(
81 this->template getParam<ReporterValueName>(
"objective_name"),
83 : this->template declareUnusedValue<
Real>())
86 if (this->isParamValid(
"measurement_file") && this->isParamValid(
"measurement_points"))
87 mooseError(
"Input file can only define a single input for measurement data. Use only " 88 "measurement_file or measurement_points, but never both");
89 else if (this->isParamValid(
"measurement_file"))
91 else if (this->isParamValid(
"measurement_points"))
96 if (this->isParamValid(
"variable"))
98 std::vector<VariableName> var_names(
99 this->
template getParam<std::vector<VariableName>>(
"variable"));
100 for (
const auto &
name : var_names)
101 _var_vec.push_back(&this->_fe_problem.getVariable(
102 this->_tid,
name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_STANDARD));
104 if (this->isParamValid(
"variable_weight_names"))
106 std::vector<std::string> weight_names(
107 this->
template getParam<std::vector<std::string>>(
"variable_weight_names"));
108 for (
const auto &
name : weight_names)
124 if (this->isParamValid(
"variable") && this->isParamValid(
"variable_weight_names") &&
128 "variable_weight_names",
129 "The same number of names must be in both 'variable_weight_names' and 'variable'.");
133 template <
typename T>
138 _objective_val = computeMisfitValue();
141 template <
typename T>
145 if (_var_vec.empty())
152 const std::size_t nvals = _measurement_values.size();
153 _simulation_values.resize(nvals, 0.0);
154 _misfit_values.resize(nvals);
156 errorCheckDataSize();
157 for (
const auto var_index :
make_range(_var_vec.size()))
159 const auto & sys = _var_vec[var_index]->sys().system();
160 const auto vnum = _var_vec[var_index]->number();
163 std::vector<Real> weights(_variable_weights.empty()
164 ? std::vector<Real>(_measurement_xcoord.size(), 1)
165 : (*_variable_weights[var_index]));
170 const Point point(_measurement_xcoord[i], _measurement_ycoord[i], _measurement_zcoord[i]);
171 const Real val = sys.point_value(vnum, point,
false);
173 _simulation_values[i] += weights[i] * val;
174 _misfit_values[i] = _simulation_values[i] - _measurement_values[i];
180 template <
typename T>
184 std::string xName = this->
template getParam<std::string>(
"file_xcoord");
185 std::string yName = this->
template getParam<std::string>(
"file_ycoord");
186 std::string zName = this->
template getParam<std::string>(
"file_zcoord");
187 std::string tName = this->
template getParam<std::string>(
"file_time");
188 std::string valueName = this->
template getParam<std::string>(
"file_value");
189 std::vector<std::string> weightNames =
190 this->
template getParam<std::vector<std::string>>(
"file_variable_weights");
192 bool found_x =
false;
193 bool found_y =
false;
194 bool found_z =
false;
195 bool found_t =
false;
196 bool found_value =
false;
201 auto const & names = reader.
getNames();
202 auto const & data = reader.
getData();
204 const std::size_t rows = data[0].size();
205 for (std::size_t i = 0; i < names.size(); ++i)
208 if (data[i].size() != rows)
209 this->paramError(
"file",
"Mismatching column lengths in file");
211 if (names[i] == xName)
213 _measurement_xcoord = data[i];
216 else if (names[i] == yName)
218 _measurement_ycoord = data[i];
221 else if (names[i] == zName)
223 _measurement_zcoord = data[i];
226 else if (names[i] == tName)
228 _measurement_time = data[i];
231 else if (names[i] == valueName)
233 _measurement_values = data[i];
236 else if (std::find(weightNames.begin(), weightNames.end(), names[i]) != weightNames.end())
238 _weight_names_weights_map.emplace(names[i],
239 &(this->
template declareValueByName<std::vector<Real>>(
241 _weight_names_weights_map[names[i]]->assign(data[i].begin(), data[i].end());
248 "measurement_file",
"Column with name '", xName,
"' missing from measurement file");
251 "measurement_file",
"Column with name '", yName,
"' missing from measurement file");
254 "measurement_file",
"Column with name '", zName,
"' missing from measurement file");
256 _measurement_time.assign(rows, 0);
259 "measurement_file",
"Column with name '", valueName,
"' missing from measurement file");
260 if (_weight_names_weights_map.size() != weightNames.size())
262 std::string
out(
"\n Measurement file column names: ");
263 for (
const auto &
name : names)
265 out +=
"\n file_variable_weights names: ";
266 for (
const auto &
name : weightNames)
270 "Not all of the file_variable_weights names were found in the measurement_file.",
275 template <
typename T>
279 if (!this->
template getParam<std::vector<std::string>>(
"file_variable_weights").empty())
281 "measurement_values",
282 "file_variable_weights cannot be used with measurement data read from the input " 283 "file, use measure_file input instead.");
285 for (
const auto & p : this->
template getParam<std::vector<Point>>(
"measurement_points"))
287 _measurement_xcoord.push_back(p(0));
288 _measurement_ycoord.push_back(p(1));
289 _measurement_zcoord.push_back(p(2));
292 if (this->isParamValid(
"measurement_times"))
293 _measurement_time = this->
template getParam<std::vector<Real>>(
"measurement_times");
295 _measurement_time.assign(_measurement_xcoord.size(), 0.0);
297 if (this->isParamValid(
"measurement_values"))
298 _measurement_values = this->
template getParam<std::vector<Real>>(
"measurement_values");
300 this->paramError(
"measurement_values",
"Input file must contain measurement points and values");
303 template <
typename T>
307 const std::size_t nvals = _measurement_values.size();
308 std::string msg =
"";
309 if (_measurement_xcoord.size() != nvals)
310 msg +=
"x-coordinate data (" + std::to_string(_measurement_xcoord.size()) +
"), ";
311 if (_measurement_ycoord.size() != nvals)
312 msg +=
"y-coordinate data (" + std::to_string(_measurement_ycoord.size()) +
"), ";
313 if (_measurement_zcoord.size() != nvals)
314 msg +=
"z-coordinate data (" + std::to_string(_measurement_zcoord.size()) +
"), ";
315 if (_measurement_time.size() != nvals)
316 msg +=
"time data (" + std::to_string(_measurement_time.size()) +
"), ";
319 std::string(msg.begin(), msg.end() - 2),
320 " does not match number of entries in value data (",
321 std::to_string(nvals),
325 template <
typename T>
330 for (
auto & misfit : _misfit_values)
331 val += misfit * misfit;
void errorCheckDataSize()
helper to check data sizes
std::vector< Real > & _measurement_values
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
std::vector< Real > & _measurement_xcoord
void mooseError(Args &&... args)
virtual void execute() override
void readMeasurementsFromFile()
parse measurement data from csv file
OptimizationDataTempl(const InputParameters ¶meters)
void readMeasurementsFromInput()
parse measurement data from input file
InputParameters validParams()
void computeMisfit()
Compute misfit vectors from the simulations and measurement values.
std::map< std::string, std::vector< Real > * > _weight_names_weights_map
Weight names to reporter values map created from input file.
std::vector< std::vector< Real > * > _variable_weights
Weight names to reporter values.
const std::vector< std::vector< T > > & getData() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
Real computeMisfitValue()
Compute half the sum of the misfit (squared) values.
const ReporterMode REPORTER_MODE_REPLICATED
const std::vector< std::string > & getNames() const
std::vector< MooseVariableFieldBase * > _var_vec
variable
registerMooseObject("OptimizationApp", OptimizationData)
std::vector< Real > & _misfit_values
difference between simulation and measurement values at measurement xyzt
static InputParameters validParams()