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 #include "IndirectSort.h"
12 #include "InputParameters.h"
13 #include "MooseEnum.h"
14 #include "MooseError.h"
15 #include "VectorPostprocessor.h"
16 #include "MooseVariableFieldBase.h"
17 #include "FEProblemBase.h"
18 #include "MooseApp.h"
19 #include "TransientBase.h"
20 
21 #include "libmesh/point.h"
22 
25 {
27 
28  params.addRequiredParam<std::string>(
29  "sort_by",
30  "What to sort the samples by. Options include 'x', 'y', 'z', 'id', and the name of any of "
31  "the sampled quantities (which each create a vector of the same name).");
32 
33  // The value from this VPP is naturally already on every processor
34  // TODO: Make this not the case! See #11415
35  params.set<bool>("_auto_broadcast") = false;
36 
37  return params;
38 }
39 
41  VectorPostprocessor * vpp,
43  : _sampler_params(parameters),
44  _vpp(vpp),
45  _comm(comm),
46  _sampler_transient(dynamic_cast<TransientBase *>(
47  parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")
48  ->getMooseApp()
49  .getExecutioner())),
50  _sort_by_index(libMesh::invalid_uint),
51  _x(vpp->declareVector("x")),
52  _y(vpp->declareVector("y")),
53  _z(vpp->declareVector("z")),
54  _id(vpp->declareVector("id")),
55  _sort_by(parameters.get<std::string>("sort_by"))
56 {
57  if (_sort_by == "x")
58  _sort_by_index = 0;
59  else if (_sort_by == "y")
60  _sort_by_index = 1;
61  else if (_sort_by == "z")
62  _sort_by_index = 2;
63  else if (_sort_by == "id")
64  _sort_by_index = 3;
65  // Sort by index for variables determined in setupVariables()
66 }
67 
68 void
69 SamplerBase::setupVariables(const std::vector<std::string> & variable_names)
70 {
71  _variable_names = variable_names;
72  _values.reserve(variable_names.size());
73 
74  for (const auto & variable_name : variable_names)
75  _values.push_back(&_vpp->declareVector(variable_name));
76 
77  // Find the index of the column to sort by for variables
79  {
80  const auto it = std::find(_variable_names.begin(), _variable_names.end(), _sort_by);
81  if (it != _variable_names.end())
82  _sort_by_index = 4 + it - _variable_names.begin();
83  else
84  mooseError(
85  "The 'sort_by' parameter must be one of x/y/z/id or one of the sampled variable names: " +
87  }
88 }
89 
90 void
91 SamplerBase::addSample(const Point & p, const Real & id, const std::vector<Real> & values)
92 {
93  _x.push_back(p(0));
94  _y.push_back(p(1));
95  _z.push_back(p(2));
96 
97  _id.push_back(id);
98 
99  mooseAssert(values.size() == _variable_names.size(), "Mismatch of variable names to vector size");
100  for (MooseIndex(values) i = 0; i < values.size(); ++i)
101  _values[i]->emplace_back(values[i]);
102 
104 }
105 
106 void
108 {
109  // Don't reset the vectors if we want to retain history
110  if (_vpp->containsCompleteHistory() && _comm.rank() == 0)
111  {
112  // If we are repeating the timestep due to an aborted solve, we want to throw away the last
113  // values
115  {
116  // Convenient to allocate a single variable for all the vpp values
117  std::vector<VectorPostprocessorValue *> vec_ptrs = {{&_x, &_y, &_z, &_id}};
118  vec_ptrs.insert(vec_ptrs.end(), _values.begin(), _values.end());
119  // Erase the elements from the last execution
120  for (auto vec_ptr : vec_ptrs)
121  {
122  // Vector may have already been restored, if so, skip the erasure
123  if (_curr_total_samples > vec_ptr->size())
124  {
125  mooseAssert(vec_ptr->size() == (_curr_total_samples - _curr_num_samples),
126  "Number of samples is not what is expected.");
127  continue;
128  }
129  for (auto ind : _curr_indices)
130  {
131  mooseAssert(ind < vec_ptr->size(), "Trying to remove a sample that doesn't exist.");
132  vec_ptr->erase(vec_ptr->begin() + ind);
133  }
134  }
135  }
136  _curr_indices.clear();
137  }
138  else
139  {
140  _x.clear();
141  _y.clear();
142  _z.clear();
143  _id.clear();
144 
145  std::for_each(
146  _values.begin(), _values.end(), [](VectorPostprocessorValue * vec) { vec->clear(); });
147  }
148 
149  _curr_num_samples = 0;
150 }
151 
152 void
154  const std::string & var_param_name) const
155 {
156  // A pointer to a MooseVariableFieldBase should never be SCALAR
157  mooseAssert(var_ptr->feType().family != SCALAR,
158  "Scalar variable '" + var_ptr->name() + "' cannot be sampled.");
159  mooseAssert(dynamic_cast<const MooseObject *>(_vpp), "Should have succeeded");
160  if (var_ptr->isVector())
161  dynamic_cast<const MooseObject *>(_vpp)->paramError(
162  var_param_name,
163  "The variable '",
164  var_ptr->name(),
165  "' is a vector variable. Sampling those is not currently supported in the "
166  "framework. It may be supported using a dedicated object in your application. Use "
167  "'VectorVariableComponentAux' auxkernel to copy those values into a regular field "
168  "variable");
169  if (var_ptr->isArray())
170  dynamic_cast<const MooseObject *>(_vpp)->paramError(
171  var_param_name,
172  "The variable '",
173  var_ptr->name(),
174  "' is an array variable. Sampling those is not currently supported in the "
175  "framework. It may be supported using a dedicated object in your application. Use "
176  "'ArrayVariableComponent' auxkernel to copy those values into a regular field variable");
177 }
178 
179 void
181 {
187  constexpr auto NUM_ID_VECTORS = 4;
188 
189  std::vector<VectorPostprocessorValue *> vec_ptrs;
190  vec_ptrs.reserve(_values.size() + NUM_ID_VECTORS);
191  // Initialize the pointer vector with the position and ID vectors
192  vec_ptrs = {{&_x, &_y, &_z, &_id}};
193  // Now extend the vector by all the remaining values vector before processing
194  vec_ptrs.insert(vec_ptrs.end(), _values.begin(), _values.end());
195 
196  // Gather up each of the partial vectors
197  for (auto vec_ptr : vec_ptrs)
198  _comm.allgather(*vec_ptr, /* identical buffer lengths = */ false);
199 
200  // Now create an index vector by using an indirect sort
201  std::vector<std::size_t> sorted_indices;
203  vec_ptrs[_sort_by_index]->begin(), vec_ptrs[_sort_by_index]->end(), sorted_indices);
204 
212  // This vector is used as temp storage to sort each of the remaining vectors according to the
213  // first
214  auto vector_length = sorted_indices.size();
215  VectorPostprocessorValue tmp_vector(vector_length);
216 
217 #ifndef NDEBUG
218  for (const auto vec_ptr : vec_ptrs)
219  if (vec_ptr->size() != vector_length)
220  mooseError("Vector length mismatch");
221 #endif
222 
223  // Sort each of the vectors using the same sorted indices
224  for (auto & vec_ptr : vec_ptrs)
225  {
226  for (MooseIndex(sorted_indices) j = 0; j < sorted_indices.size(); ++j)
227  tmp_vector[j] = (*vec_ptr)[sorted_indices[j]];
228 
229  // Swap vector storage with sorted vector
230  vec_ptr->swap(tmp_vector);
231  }
232 
233  // Gather the indices of samples from the last execution
234  // Used to determine which parts of the vector need to be erased if a solve fails
236  {
238  if (_comm.rank() == 0)
239  {
240  _curr_indices.insert(sorted_indices.end() - _curr_num_samples, sorted_indices.end());
241  _curr_total_samples = vec_ptrs[0]->size();
242  }
243  }
244 }
245 
246 void
248 {
249  _x.insert(_x.end(), y._x.begin(), y._x.end());
250  _y.insert(_y.end(), y._y.begin(), y._y.end());
251  _z.insert(_z.end(), y._z.begin(), y._z.end());
252 
253  _id.insert(_id.end(), y._id.begin(), y._id.end());
254 
255  for (MooseIndex(_variable_names) i = 0; i < _variable_names.size(); i++)
256  _values[i]->insert(_values[i]->end(), y._values[i]->begin(), y._values[i]->end());
257 
259 }
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:107
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:40
const libMesh::FEType & feType() const
Get the type of finite element object.
const unsigned int invalid_uint
SCALAR
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
const TransientBase *const _sampler_transient
Transient executioner used to determine if the last solve converged.
Definition: SamplerBase.h:113
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
processor_id_type rank() const
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const std::string _sort_by
What to sort by.
Definition: SamplerBase.h:135
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...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
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
virtual bool isVector() const =0
std::vector< VectorPostprocessorValue * > _values
Definition: SamplerBase.h:131
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
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:69
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:247
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:139
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.
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
VectorPostprocessorValue & _x
x coordinate of the points
Definition: SamplerBase.h:122
static InputParameters validParams()
Definition: SamplerBase.C:24
SamplerBase(const InputParameters &parameters, VectorPostprocessor *vpp, const libMesh::Parallel::Communicator &comm)
Definition: SamplerBase.C:40
virtual void finalize()
Finalize the values.
Definition: SamplerBase.C:180
std::vector< Real > VectorPostprocessorValue
Definition: MooseTypes.h:231
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:91
std::size_t _curr_total_samples
The full size of the vector since the last execution.
Definition: SamplerBase.h:141
unsigned int _sort_by_index
The index for what to sort by: x=0, y=1, z=2, then sampled variables in ordered specified in the para...
Definition: SamplerBase.h:119
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:137
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:153
const Elem & get(const ElemType type_in)