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  parameters.paramError("function", "Function must be an OptimizationFunction.");
42 }
43 
44 void
46 {
47  // We are saving the integral for each time step.
48  // So create or grab the vector if the time has changed or this is our first time here.
49  _curr_time_ip = nullptr;
50  for (auto & pr : _time_ip)
51  if (MooseUtils::relativeFuzzyEqual(time, pr.first))
52  _curr_time_ip = &pr.second;
53  if (!_curr_time_ip)
54  {
55  _time_ip.emplace_back(time, std::vector<Real>());
56  _curr_time_ip = &_time_ip.back().second;
57  }
58  _curr_time_ip->clear();
59 
60  _actual_time =
62 }
63 
64 void
65 OptimizationFunctionInnerProductHelper::update(const Point & q_point, Real q_inner_product)
66 {
67  if (!_curr_time_ip)
68  mooseError("Internal error, 'setCurrentTime' needs to be called before calling 'update'.");
69 
70  const std::vector<Real> pg = _function->parameterGradient(_actual_time, q_point);
71  _curr_time_ip->resize(std::max(pg.size(), _curr_time_ip->size()), 0.0);
72  for (const auto & i : index_range(pg))
73  (*_curr_time_ip)[i] += q_inner_product * pg[i];
74 }
75 
76 void
78 {
79  _curr_time_ip->resize(std::max(_curr_time_ip->size(), other._curr_time_ip->size()), 0.0);
80  for (const auto & i : index_range(*other._curr_time_ip))
81  (*_curr_time_ip)[i] += (*other._curr_time_ip)[i];
82 }
83 
84 void
86 {
87  std::size_t nvar = _curr_time_ip->size();
88  _ip_problem.comm().max(nvar);
89  _curr_time_ip->resize(nvar, 0.0);
91 
92  if (!_ip_problem.isTransient())
93  result = (*_curr_time_ip);
94  else
95  {
96  // Make sure everything is the same size
97  for (const auto & it : _time_ip)
98  nvar = std::max(nvar, it.second.size());
99  for (auto & it : _time_ip)
100  it.second.resize(nvar);
101  result.assign(nvar, 0.0);
102 
103  // Integrate in time
104  std::sort(_time_ip.begin(),
105  _time_ip.end(),
106  [](const std::pair<Real, std::vector<Real>> & a,
107  const std::pair<Real, std::vector<Real>> & b) { return a.first < b.first; });
108  // We are integrating over the entire history here. Technically this can be done in an
109  // accumulative manner by storing the integration over previous time steps. However, this
110  // is a relatively cheap operation and considering all cases where time steps may be
111  // repeated would be difficult.
112  for (const auto & ti : _time_ip)
113  for (const auto & i : make_range(nvar))
114  result[i] += ti.second[i];
115  }
116 }
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)
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()
void paramError(const std::string &param, Args... args) const
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