www.mooseframework.org
PointSamplerBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "PointSamplerBase.h"
11 
12 // MOOSE includes
13 #include "MooseMesh.h"
14 #include "Assembly.h"
15 
16 #include "libmesh/mesh_tools.h"
17 
20 {
22 
23  params += SamplerBase::validParams();
24 
25  params.addParam<PostprocessorName>(
26  "scaling", 1.0, "The postprocessor that the variables are multiplied with");
27  params.addParam<bool>(
28  "warn_discontinuous_face_values",
29  true,
30  "Whether to return a warning if a discontinuous variable is sampled on a face");
31 
32  return params;
33 }
34 
36  : GeneralVectorPostprocessor(parameters),
37  SamplerBase(parameters, this, _communicator),
38  _mesh(_subproblem.mesh()),
39  _pp_value(getPostprocessorValue("scaling")),
40  _warn_discontinuous_face_values(getParam<bool>("warn_discontinuous_face_values")),
41  _discontinuous_at_faces(false)
42 {
43 }
44 
45 void
47 {
48  // Generate new Ids if the point vector has grown (non-negative counting numbers)
49  if (_points.size() > _ids.size())
50  {
51  auto old_size = _ids.size();
52  _ids.resize(_points.size());
53  std::iota(_ids.begin() + old_size, _ids.end(), old_size);
54  }
55  // Otherwise sync the ids array to be smaller if the point vector has been shrunk
56  else if (_points.size() < _ids.size())
57  _ids.resize(_points.size());
58 
60 
61  // We do this here just in case it's been destroyed and recreated because of mesh adaptivity.
63 
64  // We may not find a requested point on a distributed mesh, and
65  // that's okay.
66  _pl->enable_out_of_mesh_mode();
67 
68  // Reset the point arrays
69  _found_points.assign(_points.size(), false);
70 
71  _point_values.resize(_points.size());
72  std::for_each(
73  _point_values.begin(), _point_values.end(), [](std::vector<Real> & vec) { vec.clear(); });
74 }
75 
76 void
78 {
79  // Save off for speed
80  const auto pid = processor_id();
81 
82  // Consolidate _found_points across processes to know which points were found
83  auto _global_found_points = _found_points;
84  _comm.sum(_global_found_points);
85 
86  // Keep track of maximum process ids for each point to only add it once
87  std::vector<unsigned int> max_pid(_found_points.size());
88  _comm.maxloc(_found_points, max_pid);
89 
90  for (MooseIndex(_found_points) i = 0; i < _found_points.size(); ++i)
91  {
92  // _global_found_points should contain all 1's at this point (ie every point was found by a
93  // proc)
94  if (pid == 0 && !_global_found_points[i])
95  mooseError("In ", name(), ", sample point not found: ", _points[i]);
96 
97  // only process that found the point has the value, and only process with max id should add
98  if (pid == max_pid[i] && _found_points[i])
100  }
101 
103 }
104 
105 const Elem *
107 {
108  const Elem * elem = nullptr;
110  {
111  libmesh_parallel_only(comm());
112 
113  // Get all possible elements the point may be in
114  std::set<const Elem *> candidate_elements;
115  (*_pl)(p, candidate_elements);
116 
117  // Look at all the element IDs
118  std::set<dof_id_type> candidate_ids;
119  for (auto candidate : candidate_elements)
120  candidate_ids.insert(candidate->id());
121 
122  comm().set_union(candidate_ids);
123 
124  // Domains without candidate elements will not own the lowest ID one
125  if (candidate_elements.size())
126  {
127  // If we know of the minimum, this will be valid. Otherwise, it'll be
128  // nullptr which is fine
129  elem = _mesh.queryElemPtr(*(candidate_ids.begin()));
130 
131  // Print a warning if it's on a face and a variable is discontinuous
132  if (_warn_discontinuous_face_values && candidate_ids.size() > 1)
133  mooseDoOnce(mooseWarning("A discontinuous variable is sampled on a face, at ", p));
134  }
135  }
136  else // continuous variables
137  {
138  // Get all possible elements the point may be in
139  // We cant just locate in one element because at the edge between two process domains, it could
140  // be that both domains find the element that is not within their domain
141  std::set<const Elem *> candidate_elements;
142  (*_pl)(p, candidate_elements);
143 
144  // Only keep the one that may be local
145  for (auto candidate : candidate_elements)
146  if (candidate->processor_id() == processor_id())
147  elem = candidate;
148  }
149 
150  if (elem && elem->processor_id() == processor_id())
151  return elem;
152 
153  return nullptr;
154 }
Base class for VectorPostprocessors that need to do "sampling" of values in the domain.
Definition: SamplerBase.h:36
virtual void initialize()
Initialize the datastructures.
Definition: SamplerBase.C:75
std::vector< Real > _ids
The ID to use for each point (yes, this is Real on purpose)
This class is here to combine the VectorPostprocessor interface and the base class VectorPostprocesso...
virtual void initialize()
Initialize the datastructures.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
std::vector< Point > _points
The points to evaluate at.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:56
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
virtual Elem * queryElemPtr(const dof_id_type i)
Definition: MooseMesh.C:2875
virtual void finalize()
Finalize.
std::vector< std::vector< Real > > _point_values
Vector of values per point.
const bool _warn_discontinuous_face_values
Whether to return a warning if a discontinuous variable is sampled on a face.
static InputParameters validParams()
const Elem * getLocalElemContainingPoint(const Point &p)
Find the local element that contains the point.
std::vector< short > _found_points
Whether or not the Point was found on this processor (short because bool and char don&#39;t work with MPI...
static InputParameters validParams()
void maxloc(T &r, unsigned int &max_id) const
bool _discontinuous_at_faces
Whether values are requested for objects that are discontinuous on faces.
static InputParameters validParams()
Definition: SamplerBase.C:22
PointSamplerBase(const InputParameters &parameters)
virtual void finalize()
Finalize the values.
Definition: SamplerBase.C:91
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:61
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
std::unique_ptr< PointLocatorBase > _pl
Point locator.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
MooseMesh & _mesh
The Mesh we&#39;re using.
const libMesh::Parallel::Communicator & _comm
The communicator of the child.
Definition: SamplerBase.h:100
processor_id_type processor_id() const
virtual std::unique_ptr< PointLocatorBase > getPointLocator() const
Proxy function to get a (sub)PointLocator from either the underlying libMesh mesh (default)...
Definition: MooseMesh.C:3479
void set_union(T &data, const unsigned int root_id) const