https://mooseframework.inl.gov
OptimizationFunctionInnerProductHelper.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 // MOOSE includes
13 #include "InputParameters.h"
14 #include "MooseError.h"
15 #include "FEProblemBase.h"
16 
17 // Optimization includes
18 #include "OptimizationFunction.h"
19 
22 {
24  params.addRequiredParam<FunctionName>("function", "Optimization function.");
25  params.addParam<Real>(
26  "reverse_time_end",
27  0.0,
28  "End time used for reversing the time integration when evaluating function derivative.");
29  return params;
30 }
31 
33  const InputParameters & parameters)
34  : _ip_problem(*parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
35  _function(dynamic_cast<const OptimizationFunction *>(&_ip_problem.getFunction(
36  parameters.get<FunctionName>("function"), parameters.get<THREAD_ID>("_tid")))),
37  _reverse_time_end(parameters.get<Real>("reverse_time_end")),
38  _simulation_time(_ip_problem.getMooseApp().getStartTime())
39 {
40  if (!_function)
41  mooseError("Function requested by ",
42  parameters.get<std::string>("_type"),
43  " must be an OptimizationFunction.");
44 }
45 
46 void
48 {
49  // We are saving the integral for each time step.
50  // So create or grab the vector if the time has changed or this is our first time here.
51  _curr_time_ip = nullptr;
52  for (auto & pr : _time_ip)
53  if (MooseUtils::relativeFuzzyEqual(time, pr.first))
54  _curr_time_ip = &pr.second;
55  if (!_curr_time_ip)
56  {
57  _time_ip.emplace_back(time, std::vector<Real>());
58  _curr_time_ip = &_time_ip.back().second;
59  }
60  _curr_time_ip->clear();
61 
62  _actual_time =
64 }
65 
66 void
67 OptimizationFunctionInnerProductHelper::update(const Point & q_point, Real q_inner_product)
68 {
69  if (!_curr_time_ip)
70  mooseError("Internal error, 'setCurrentTime' needs to be called before calling 'update'.");
71 
72  const std::vector<Real> pg = _function->parameterGradient(_actual_time, q_point);
73  _curr_time_ip->resize(std::max(pg.size(), _curr_time_ip->size()), 0.0);
74  for (const auto & i : index_range(pg))
75  (*_curr_time_ip)[i] += q_inner_product * pg[i];
76 }
77 
78 void
80 {
81  _curr_time_ip->resize(std::max(_curr_time_ip->size(), other._curr_time_ip->size()), 0.0);
82  for (const auto & i : index_range(*other._curr_time_ip))
83  (*_curr_time_ip)[i] += (*other._curr_time_ip)[i];
84 }
85 
86 void
88 {
89  std::size_t nvar = _curr_time_ip->size();
90  _ip_problem.comm().max(nvar);
91  _curr_time_ip->resize(nvar, 0.0);
93 
94  if (!_ip_problem.isTransient())
95  result = (*_curr_time_ip);
96  else
97  {
98  // Make sure everything is the same size
99  for (const auto & it : _time_ip)
100  nvar = std::max(nvar, it.second.size());
101  for (auto & it : _time_ip)
102  it.second.resize(nvar);
103  result.assign(nvar, 0.0);
104 
105  // Integrate in time
106  std::sort(_time_ip.begin(),
107  _time_ip.end(),
108  [](const std::pair<Real, std::vector<Real>> & a,
109  const std::pair<Real, std::vector<Real>> & b) { return a.first < b.first; });
110  // We are integrating over the entire history here. Technically this can be done in an
111  // accumulative manner by storing the integration over previous time steps. However, this
112  // is a relatively cheap operation and considering all cases where time steps may be
113  // repeated would be difficult.
114  for (const auto & ti : _time_ip)
115  for (const auto & i : make_range(nvar))
116  result[i] += ti.second[i];
117  }
118 }
std::vector< std::pair< Real, std::vector< Real > > > _time_ip
Vector holding data for each time.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void update(const Point &q_point, Real q_inner_product)
Accumulates integration for inner product by multiplying the given value by the function&#39;s parameterG...
void mooseError(Args &&... args)
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
void setCurrentTime(Real time, Real dt)
This function sets up member variables for the inner product accumulation at certain time...
void add(const OptimizationFunctionInnerProductHelper &other)
Accumulates inner product integration in _curr_time_ip vector from another object.
const Parallel::Communicator & comm() const
std::vector< Real > * _curr_time_ip
Vector for current time.
const OptimizationFunction *const _function
Function used in optimization.
FEProblemBase & _ip_problem
FEProblem used for getting system quantities.
const Real & _reverse_time_end
The final time when we want to reverse the time index in function evaluation.
void addRequiredParam(const std::string &name, const std::string &doc_string)
InputParameters emptyInputParameters()
virtual std::vector< Real > parameterGradient(Real t, const Point &pt) const =0
OptimizationFunctionInnerProductHelper(const InputParameters &parameters)
void getVector(std::vector< Real > &result)
Gathers _curr_time_ip from other processors and performs time integration.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real _actual_time
Time the actual problem is at, defined by _reverse_time_end.
Base class for functions used in inverse optimization The parameterDerivative function is used in adj...
void max(const T &r, T &o, Request &req) const
bool relativeFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
IntRange< T > make_range(T beg, T end)
virtual bool isTransient() const override
auto index_range(const T &sizable)
const Elem & get(const ElemType type_in)
unsigned int THREAD_ID