https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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"
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
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")
59 else if (_sort_by == "y")
61 else if (_sort_by == "z")
63 else if (_sort_by == "id")
65 // Sort by index for variables determined in setupVariables()
66}
67
68void
69SamplerBase::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
85 "The 'sort_by' parameter must be one of x/y/z/id or one of the sampled variable names: " +
87 }
88}
89
90void
91SamplerBase::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
106void
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
150}
151
152void
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
179void
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
246void
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}
InputParameters emptyInputParameters()
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
std::vector< Real > VectorPostprocessorValue
Definition MooseTypes.h:231
std::array< Real, 2 > values
Definition MortarUtils.C:52
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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...
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
Every object that can be built by the factory should be derived from this class.
Definition MooseObject.h:31
const libMesh::FEType & feType() const
Get the type of finite element object.
virtual bool isArray() const
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual bool isVector() const =0
Base class for VectorPostprocessors that need to do "sampling" of values in the domain.
Definition SamplerBase.h:38
std::vector< std::string > _variable_names
The variable names.
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...
std::vector< VectorPostprocessorValue * > _values
const std::string _sort_by
What to sort by.
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
VectorPostprocessorValue & _x
x coordinate of the points
VectorPostprocessorValue & _y
y coordinate of the points
const TransientBase *const _sampler_transient
Transient executioner used to determine if the last solve converged.
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
SamplerBase(const InputParameters &parameters, VectorPostprocessor *vpp, const libMesh::Parallel::Communicator &comm)
Definition SamplerBase.C:40
virtual void initialize()
Initialize the datastructures.
virtual void threadJoin(const SamplerBase &y)
Join the values.
VectorPostprocessor * _vpp
The child VectorPostprocessor.
VectorPostprocessorValue & _id
The node ID of each point.
VectorPostprocessorValue & _z
x coordinate of the points
virtual void finalize()
Finalize the values.
std::size_t _curr_num_samples
The number of samples added in the last execution.
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.
std::size_t _curr_total_samples
The full size of the vector since the last execution.
const libMesh::Parallel::Communicator & _comm
The communicator of the child.
std::set< std::size_t, std::greater< std::size_t > > _curr_indices
The indices of the samples in the last execution.
static InputParameters validParams()
Definition SamplerBase.C:24
processor_id_type rank() const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
virtual bool lastSolveConverged() const override
Whether or not the last solve converged.
Base class for Postprocessors that produce a vector of values.
bool containsCompleteHistory() const
Return whether or not this VectorPostprocessor contains complete history.
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
void indirectSort(RandomAccessIterator beg, RandomAccessIterator end, std::vector< size_t > &b)
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const unsigned int invalid_uint