23 "given a user-defined definition of the cross section.");
24 params.
addParam<std::vector<SubdomainName>>(
26 "The list of blocks in which to search for cross sectional nodes to compute the variable " 28 params.
addRequiredParam<Point>(
"axis_direction",
"Direction of the structural component's axis");
30 "Structural component reference starting point from which the " 31 "input parameter 'lengths' applies.");
33 std::numeric_limits<Real>::max(),
34 "Radial distance with respect to the body axis within which nodes are " 35 "considered to belong to this " 36 "structural component. Used to disambiguate multiple components that share " 37 "the same mesh block.");
39 "variables",
"Variables for the cross section output. These variables must be nodal.");
43 "Positions along axis from reference_point at which to compute average values.",
44 "Use the 'positions' parameter instead");
48 "Positions along axis from reference_point at which to compute average values.");
52 "Vector normal to a symmetry plane, used if the section has a symmetry plane through it. " 53 "Causes the variables to be treated as components of a vector and zeros out the compomnent " 54 "in the direction normal to symmetry_plane. Three variables must be defined in 'variables' " 55 "to use this option.");
58 "Maximum axial distance of nodes from the specified axial lengths to " 59 "consider them in the cross-section average");
61 "require_equal_node_counts",
63 "Whether to require the number of nodes at each axial location to be equal");
69 _mesh(_app.actionWarehouse().
mesh()),
70 _variables(getParam<
std::vector<VariableName>>(
"variables")),
71 _direction(getParam<Point>(
"axis_direction")),
72 _reference_point(getParam<Point>(
"reference_point")),
73 _positions(isParamSetByUser(
"lengths") ? getParam<
std::vector<
Real>>(
"lengths")
74 : getParam<
std::vector<
Real>>(
"positions")),
75 _have_symmetry_plane(isParamSetByUser(
"symmetry_plane")),
77 _automatically_locate_positions(_positions.size() == 0),
78 _tolerance(getParam<
Real>(
"tolerance")),
79 _number_of_nodes(_positions.size()),
80 _cross_section_maximum_radius(getParam<
Real>(
"cross_section_maximum_radius")),
81 _require_equal_node_counts(getParam<bool>(
"require_equal_node_counts")),
82 _need_mesh_initializations(true)
85 paramError(
"lengths",
"The 'lengths' and 'positions' parameters cannot both be set.");
88 paramError(
"lengths",
"If 'lengths' is specified, at least one value must be provided");
91 paramError(
"positions",
"If 'positions' is specified, at least one value must be provided");
93 if (
_mesh->dimension() != 3)
94 mooseError(
"The AverageSectionValueSampler postprocessor can only be used with three " 95 "dimensional meshes.");
98 paramError(
"axis_direction",
"Axis direction must be a unit vector.");
111 "One or more of the specified variables do not exist in this system.");
115 "One or more of the specified variables are not defined at the nodes.");
123 mooseError(
"Vector defined in 'symmetry_plane' cannot have a norm of zero");
127 "If 'symmetry_plane' is prescribed, three variables must be provided (for the x, " 128 "y, z vector components, in that order)");
130 ": \nTreating the variables as vector components (" +
_variables[0] +
", " +
132 ") and zeroing out the component normal to the prescribed 'symmetry_plane'\n");
177 mooseError(
"No nodes were found in AverageSectionValueSampler postprocessor.");
194 std::ostringstream pos_out;
199 "Node counts do not match for all axial positions. If this behavior " 200 "is desired to accommodate nonuniform meshes, set " 201 "'require_equal_node_counts=false'\n Axial Node\n Position Count\n" +
213 auto * active_nodes =
_mesh->getActiveSemiLocalNodeRange();
215 std::vector<std::vector<Real>> output_vector_partial(
_variables.size(),
220 for (
const auto & node : *active_nodes)
222 const std::set<SubdomainID> & node_blk_ids =
_mesh->getNodeBlockIds(*node);
228 if (node_blk_ids.find(i) != node_blk_ids.end())
244 this_node_vars[0], this_node_vars[1], this_node_vars[2]);
246 this_node_vars[0] = this_node_vec_var(0);
247 this_node_vars[1] = this_node_vec_var(1);
248 this_node_vars[2] = this_node_vec_var(2);
252 output_vector_partial[
j][li] += this_node_vars[
j];
269 const Point relative_distance{
273 const Real in_plane_distance =
279 return std::numeric_limits<Real>::max();
281 return axial_position;
291 std::vector<Real> pos_vec;
294 std::set<Real> pos_set;
297 auto * nodes =
_mesh->getLocalNodeRange();
299 for (
const auto node : *nodes)
301 const std::set<SubdomainID> & node_blk_ids =
_mesh->getNodeBlockIds(*node);
305 if (node_blk_ids.find(i) != node_blk_ids.end())
307 bool found_match =
false;
309 if (axial_position == std::numeric_limits<Real>::max())
311 for (
auto & pos : pos_vec)
313 const Real dist_to_plane = std::abs(axial_position - pos);
321 pos_vec.emplace_back(axial_position);
328 for (
const auto & posv : pos_vec)
330 bool found_match =
false;
331 for (
auto & poss : pos_set)
340 pos_set.insert(posv);
342 for (
const auto & poss : pos_set)
const Real _cross_section_maximum_radius
Tolerance to disambiguate cross section locations in different components within the same block...
virtual const NumericVector< Number > *const & currentSolution() const=0
virtual void meshChanged() override
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
const bool _have_symmetry_plane
Whether a symmetry plane has been defined by the user.
auto norm() const -> decltype(std::norm(Real()))
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
const bool _require_equal_node_counts
Whether to require the number of nodes at each axial location to be equal.
std::vector< unsigned int > _number_of_nodes
Number of nodes for computing output (local and global).
virtual void execute() override
unsigned int number() const
void mooseInfo(Args &&... args) const
const Point _direction
Axis direction of the structural component.
const Parallel::Communicator & _communicator
void automaticallyLocatePositions()
Automatically identify all axial positions of nodes within the component and store their unique value...
virtual const std::string & name() const
AverageSectionValueSampler(const InputParameters ¶meters)
std::vector< SubdomainID > _block_ids
std::vector< unsigned int > _var_numbers
Indices of the variables in their systems.
const Point _reference_point
Starting or reference point of the structural component to locate nodes on the cross section...
static InputParameters validParams()
RealVectorValue _symmetry_plane
Vector normal to a symmetry plane, optionally defined if the section has a symmetry plane...
static InputParameters validParams()
const T & getParam(const std::string &name) const
registerMooseObject("SolidMechanicsApp", AverageSectionValueSampler)
std::vector< Real > _positions
Axial positions along the component at which average values are computed.
Real axialPosition(const Node &node) const
Determine axial distance of the point from the component's reference point.
void paramError(const std::string ¶m, Args... args) const
unsigned int number() const
VectorPostprocessorValue & declareVector(const std::string &vector_name)
virtual bool hasVariable(const std::string &var_name) const
const bool _automatically_locate_positions
Whether to automatically locate positions along section for averaging field values.
bool isNodal() const override
const std::shared_ptr< MooseMesh > & _mesh
Reference to the mesh.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseVariableFE< T > & getFieldVariable(THREAD_ID tid, const std::string &var_name)
std::vector< VariableName > _variables
Variables to output.
const Real _tolerance
Tolerance to identify nodes on the user-prescribed cross section.
std::vector< VectorPostprocessorValue * > _output_vector
Vector of outputs, where each entry is the vector of average values for single variable at the select...
IntRange< T > make_range(T beg, T end)
virtual void initialSetup() override
void mooseError(Args &&... args) const
const InputParameters & parameters() const
bool _need_mesh_initializations
Whether node locations need to be identified and nodes at positions need to be counted.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
processor_id_type processor_id() const
auto index_range(const T &sizable)
virtual void initialize() override
virtual void finalize() override