https://mooseframework.inl.gov
SamplerBase.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 
10 #include "SamplerBase.h"
11 
12 // MOOSE includes
13 #include "IndirectSort.h"
14 #include "InputParameters.h"
15 #include "MooseEnum.h"
16 #include "MooseError.h"
17 #include "VectorPostprocessor.h"
18 #include "MooseVariableFieldBase.h"
20 #include "FEProblemBase.h"
21 #include "MooseApp.h"
22 #include "TransientBase.h"
23 
24 #include "libmesh/point.h"
25 
28 {
30 
31  MooseEnum sort_options("x y z id");
32  params.addRequiredParam<MooseEnum>("sort_by", sort_options, "What to sort the samples by");
33 
34  // The value from this VPP is naturally already on every processor
35  // TODO: Make this not the case! See #11415
36  params.set<bool>("_auto_broadcast") = false;
37 
38  return params;
39 }
40 
42  VectorPostprocessor * vpp,
44  : _sampler_params(parameters),
45  _vpp(vpp),
46  _comm(comm),
47  _sampler_transient(dynamic_cast<TransientBase *>(
48  parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")
49  ->getMooseApp()
50  .getExecutioner())),
51  _sort_by(parameters.get<MooseEnum>("sort_by")),
52  _x(vpp->declareVector("x")),
53  _y(vpp->declareVector("y")),
54  _z(vpp->declareVector("z")),
55  _id(vpp->declareVector("id"))
56 {
57 }
58 
59 void
60 SamplerBase::setupVariables(const std::vector<std::string> & variable_names)
61 {
62  _variable_names = variable_names;
63  _values.reserve(variable_names.size());
64 
65  for (const auto & variable_name : variable_names)
66  _values.push_back(&_vpp->declareVector(variable_name));
67 }
68 
69 void
70 SamplerBase::addSample(const Point & p, const Real & id, const std::vector<Real> & values)
71 {
72  _x.push_back(p(0));
73  _y.push_back(p(1));
74  _z.push_back(p(2));
75 
76  _id.push_back(id);
77 
78  mooseAssert(values.size() == _variable_names.size(), "Mismatch of variable names to vector size");
79  for (MooseIndex(values) i = 0; i < values.size(); ++i)
80  _values[i]->emplace_back(values[i]);
81 
83 }
84 
85 void
87 {
88  // Don't reset the vectors if we want to retain history
89  if (_vpp->containsCompleteHistory() && _comm.rank() == 0)
90  {
91  // If we are repeating the timestep due to an aborted solve, we want to throw away the last
92  // values
94  {
95  // Convenient to allocate a single variable for all the vpp values
96  std::vector<VectorPostprocessorValue *> vec_ptrs = {{&_x, &_y, &_z, &_id}};
97  vec_ptrs.insert(vec_ptrs.end(), _values.begin(), _values.end());
98  // Erase the elements from the last execution
99  for (auto vec_ptr : vec_ptrs)
100  {
101  // Vector may have already been restored, if so, skip the erasure
102  if (_curr_total_samples > vec_ptr->size())
103  {
104  mooseAssert(vec_ptr->size() == (_curr_total_samples - _curr_num_samples),
105  "Number of samples is not what is expected.");
106  continue;
107  }
108  for (auto ind : _curr_indices)
109  {
110  mooseAssert(ind < vec_ptr->size(), "Trying to remove a sample that doesn't exist.");
111  vec_ptr->erase(vec_ptr->begin() + ind);
112  }
113  }
114  }
115  _curr_indices.clear();
116  }
117  else
118  {
119  _x.clear();
120  _y.clear();
121  _z.clear();
122  _id.clear();
123 
124  std::for_each(
125  _values.begin(), _values.end(), [](VectorPostprocessorValue * vec) { vec->clear(); });
126  }
127 
128  _curr_num_samples = 0;
129 }
130 
131 void
133  const std::string & var_param_name) const
134 {
135  // A pointer to a MooseVariableFieldBase should never be SCALAR
136  mooseAssert(var_ptr->feType().family != SCALAR,
137  "Scalar variable '" + var_ptr->name() + "' cannot be sampled.");
138  mooseAssert(dynamic_cast<const MooseObject *>(_vpp), "Should have succeeded");
139  if (var_ptr->isVector())
140  dynamic_cast<const MooseObject *>(_vpp)->paramError(
141  var_param_name,
142  "The variable '",
143  var_ptr->name(),
144  "' is a vector variable. Sampling those is not currently supported in the "
145  "framework. It may be supported using a dedicated object in your application. Use "
146  "'VectorVariableComponentAux' auxkernel to copy those values into a regular field "
147  "variable");
148  if (var_ptr->isArray())
149  dynamic_cast<const MooseObject *>(_vpp)->paramError(
150  var_param_name,
151  "The variable '",
152  var_ptr->name(),
153  "' is an array variable. Sampling those is not currently supported in the "
154  "framework. It may be supported using a dedicated object in your application. Use "
155  "'ArrayVariableComponent' auxkernel to copy those values into a regular field variable");
156 }
157 
158 void
160 {
166  constexpr auto NUM_ID_VECTORS = 4;
167 
168  std::vector<VectorPostprocessorValue *> vec_ptrs;
169  vec_ptrs.reserve(_values.size() + NUM_ID_VECTORS);
170  // Initialize the pointer vector with the position and ID vectors
171  vec_ptrs = {{&_x, &_y, &_z, &_id}};
172  // Now extend the vector by all the remaining values vector before processing
173  vec_ptrs.insert(vec_ptrs.end(), _values.begin(), _values.end());
174 
175  // Gather up each of the partial vectors
176  for (auto vec_ptr : vec_ptrs)
177  _comm.allgather(*vec_ptr, /* identical buffer lengths = */ false);
178 
179  // Now create an index vector by using an indirect sort
180  std::vector<std::size_t> sorted_indices;
181  Moose::indirectSort(vec_ptrs[_sort_by]->begin(), vec_ptrs[_sort_by]->end(), sorted_indices);
182 
190  // This vector is used as temp storage to sort each of the remaining vectors according to the
191  // first
192  auto vector_length = sorted_indices.size();
193  VectorPostprocessorValue tmp_vector(vector_length);
194 
195 #ifndef NDEBUG
196  for (const auto vec_ptr : vec_ptrs)
197  if (vec_ptr->size() != vector_length)
198  mooseError("Vector length mismatch");
199 #endif
200 
201  // Sort each of the vectors using the same sorted indices
202  for (auto & vec_ptr : vec_ptrs)
203  {
204  for (MooseIndex(sorted_indices) j = 0; j < sorted_indices.size(); ++j)
205  tmp_vector[j] = (*vec_ptr)[sorted_indices[j]];
206 
207  // Swap vector storage with sorted vector
208  vec_ptr->swap(tmp_vector);
209  }
210 
211  // Gather the indices of samples from the last execution
212  // Used to determine which parts of the vector need to be erased if a solve fails
214  {
216  if (_comm.rank() == 0)
217  {
218  _curr_indices.insert(sorted_indices.end() - _curr_num_samples, sorted_indices.end());
219  _curr_total_samples = vec_ptrs[0]->size();
220  }
221  }
222 }
223 
224 void
226 {
227  _x.insert(_x.end(), y._x.begin(), y._x.end());
228  _y.insert(_y.end(), y._y.begin(), y._y.end());
229  _z.insert(_z.end(), y._z.begin(), y._z.end());
230 
231  _id.insert(_id.end(), y._id.begin(), y._id.end());
232 
233  for (MooseIndex(_variable_names) i = 0; i < _variable_names.size(); i++)
234  _values[i]->insert(_values[i]->end(), y._values[i]->begin(), y._values[i]->end());
235 
237 }
Base class for VectorPostprocessors that need to do "sampling" of values in the domain.
Definition: SamplerBase.h:37
virtual void initialize()
Initialize the datastructures.
Definition: SamplerBase.C:86
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
const libMesh::FEType & feType() const
Get the type of finite element object.
SCALAR
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
const TransientBase *const _sampler_transient
Transient executioner used to determine if the last solve converged.
Definition: SamplerBase.h:113
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1155
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void indirectSort(RandomAccessIterator beg, RandomAccessIterator end, std::vector< size_t > &b)
Definition: IndirectSort.h:68
const std::string & name() const override
Get the variable name.
processor_id_type rank() const
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::vector< std::string > _variable_names
The variable names.
Definition: SamplerBase.h:116
This class provides an interface for common operations on field variables of both FE and FV types wit...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
InputParameters emptyInputParameters()
VectorPostprocessorValue & _y
y coordinate of the points
Definition: SamplerBase.h:124
const unsigned int _sort_by
What to sort by.
Definition: SamplerBase.h:119
virtual bool isVector() const =0
std::vector< VectorPostprocessorValue * > _values
Definition: SamplerBase.h:131
void setupVariables(const std::vector< std::string > &variable_names)
You MUST call this in the constructor of the child class and pass down the name of the variables...
Definition: SamplerBase.C:60
bool containsCompleteHistory() const
Return whether or not this VectorPostprocessor contains complete history.
VectorPostprocessor * _vpp
The child VectorPostprocessor.
Definition: SamplerBase.h:107
virtual void threadJoin(const SamplerBase &y)
Join the values.
Definition: SamplerBase.C:225
virtual bool isArray() const
std::set< std::size_t, std::greater< std::size_t > > _curr_indices
The indices of the samples in the last execution.
Definition: SamplerBase.h:137
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
Definition: TransientBase.h:27
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
VectorPostprocessorValue & _x
x coordinate of the points
Definition: SamplerBase.h:122
static InputParameters validParams()
Definition: SamplerBase.C:27
SamplerBase(const InputParameters &parameters, VectorPostprocessor *vpp, const libMesh::Parallel::Communicator &comm)
Definition: SamplerBase.C:41
virtual void finalize()
Finalize the values.
Definition: SamplerBase.C:159
std::vector< Real > VectorPostprocessorValue
Definition: MooseTypes.h:203
VectorPostprocessorValue & _id
The node ID of each point.
Definition: SamplerBase.h:129
virtual void addSample(const Point &p, const Real &id, const std::vector< Real > &values)
Call this with the value of every variable at each point you want to sample at.
Definition: SamplerBase.C:70
std::size_t _curr_total_samples
The full size of the vector since the last execution.
Definition: SamplerBase.h:139
VectorPostprocessorValue & _z
x coordinate of the points
Definition: SamplerBase.h:126
const libMesh::Parallel::Communicator & _comm
The communicator of the child.
Definition: SamplerBase.h:110
virtual bool lastSolveConverged() const override
Whether or not the last solve converged.
std::size_t _curr_num_samples
The number of samples added in the last execution.
Definition: SamplerBase.h:135
Base class for Postprocessors that produce a vector of values.
void checkForStandardFieldVariableType(const MooseVariableFieldBase *const var_ptr, const std::string &var_param_name="variable") const
Checks whether the passed variable pointer corresponds to a regular single-valued field variable...
Definition: SamplerBase.C:132