www.mooseframework.org
FauxGrainTracker.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 "FauxGrainTracker.h"
11 
12 // MOOSE includes
13 #include "MooseMesh.h"
14 #include "MooseVariable.h"
15 #include "Assembly.h"
16 
17 registerMooseObject("PhaseFieldApp", FauxGrainTracker);
18 
21 {
23  params.addClassDescription("Fake grain tracker object for cases where the number of grains is "
24  "equal to the number of order parameters.");
25 
26  return params;
27 }
28 
30  : FeatureFloodCount(parameters),
32  _grain_count(0),
33  _n_vars(_vars.size()),
34  _tracking_step(getParam<int>("tracking_step"))
35 {
36  // initialize faux data with identity map
37  _op_to_grains.resize(_n_vars);
38  for (MooseIndex(_op_to_grains) i = 0; i < _op_to_grains.size(); ++i)
39  _op_to_grains[i] = i;
40 
42 }
43 
45 
46 Real
49  std::size_t var_idx) const
50 {
51  if (var_idx == FeatureFloodCount::invalid_size_t)
52  var_idx = 0;
53 
54  mooseAssert(var_idx < _n_vars, "Index out of range");
55 
56  switch (field_type)
57  {
60  {
61  auto entity_it = _entity_id_to_var_num.find(entity_id);
62 
63  if (entity_it != _entity_id_to_var_num.end())
64  return entity_it->second;
65  else
66  return -1;
67  break;
68  }
69 
71  {
72  if (_periodic_node_map.size())
73  mooseDoOnce(mooseWarning(
74  "Centroids are not correct when using periodic boundaries, contact the MOOSE team"));
75 
76  // If this element contains the centroid of one of features, return it's index
77  const auto * elem_ptr = _mesh.elemPtr(entity_id);
78  for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
79  {
80  const auto centroid = _centroid.find(var_num);
81  if (centroid != _centroid.end())
82  if (elem_ptr->contains_point(centroid->second))
83  return 1;
84  }
85 
86  return 0;
87  }
88 
89  // We don't want to error here because this should be a drop in replacement for the real grain
90  // tracker.
91  // Instead we'll just return zero and continue
92  default:
93  return 0;
94  }
95 
96  return 0;
97 }
98 
99 const std::vector<unsigned int> &
101 {
102  const auto pos = _entity_var_to_features.find(elem_id);
103  if (pos != _entity_var_to_features.end())
104  {
105  mooseAssert(pos->second.size() == _n_vars, "Variable to feature vector not sized properly");
106  return pos->second;
107  }
108  else
109  return _empty_var_to_features;
110 }
111 
112 unsigned int
113 FauxGrainTracker::getFeatureVar(unsigned int feature_id) const
114 {
115  return feature_id;
116 }
117 
118 std::size_t
120 {
121  return _variables_used.size();
122 }
123 
124 std::size_t
126 {
127  return _grain_count;
128 }
129 
130 Point
131 FauxGrainTracker::getGrainCentroid(unsigned int grain_index) const
132 {
133  const auto grain_center = _centroid.find(grain_index);
134  mooseAssert(grain_center != _centroid.end(),
135  "Grain " << grain_index << " does not exist in data structure");
136 
137  return grain_center->second;
138 }
139 
140 void
142 {
143  _entity_id_to_var_num.clear();
144  _entity_var_to_features.clear();
145  _variables_used.clear();
146  if (_is_elemental)
147  {
148  _volume.clear();
149  _vol_count.clear();
150  _centroid.clear();
151  }
152 }
153 
154 void
156 {
157  TIME_SECTION("execute", 2, "Executing grain tracker");
158 
159  for (const auto & current_elem : _mesh.getMesh().active_local_element_ptr_range())
160  {
161  // Loop over elements or nodes and populate the data structure with the first variable with a
162  // value above a threshold
163  if (_is_elemental)
164  {
165  std::vector<Point> centroid(1, current_elem->vertex_average());
166  _fe_problem.reinitElemPhys(current_elem, centroid, 0);
167 
168  auto entity = current_elem->id();
169  auto insert_pair =
171  entity,
172  std::vector<unsigned int>(_n_vars, FeatureFloodCount::invalid_id));
173  auto & vec_ref = insert_pair.first->second;
174 
175  for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
176  {
177  auto entity_value = _vars[var_num]->sln()[0];
178 
179  if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) ||
180  (!_use_less_than_threshold_comparison && (entity_value <= _threshold)))
181  {
182  _entity_id_to_var_num[current_elem->id()] = var_num;
183  _variables_used.insert(var_num);
184  _volume[var_num] += _assembly.elementVolume(current_elem);
185  _vol_count[var_num]++;
186  // Sum the centroid values for now, we'll average them later
187  _centroid[var_num] += current_elem->vertex_average();
188  vec_ref[var_num] = var_num;
189  break;
190  }
191  }
192  }
193  else
194  {
195  unsigned int n_nodes = current_elem->n_vertices();
196  for (unsigned int i = 0; i < n_nodes; ++i)
197  {
198  const Node * current_node = current_elem->node_ptr(i);
199 
200  for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
201  {
202  auto entity_value = _vars[var_num]->getNodalValue(*current_node);
203  if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) ||
204  (!_use_less_than_threshold_comparison && (entity_value <= _threshold)))
205  {
206  _entity_id_to_var_num[current_node->id()] = var_num;
207  _variables_used.insert(var_num);
208  break;
209  }
210  }
211  }
212  }
213  }
214 
215  _grain_count = std::max(_grain_count, _variables_used.size());
216 }
217 
218 void
220 {
221  TIME_SECTION("finalize", 2, "Finalizing grain tracker");
222 
225 
226  if (_is_elemental)
227  for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
228  {
233  unsigned int vol_count;
234  std::vector<Real> grain_data(4);
235 
236  const auto count = _vol_count.find(var_num);
237  if (count != _vol_count.end())
238  vol_count = count->second;
239 
240  const auto vol = _volume.find(var_num);
241  if (vol != _volume.end())
242  grain_data[0] = vol->second;
243 
244  const auto centroid = _centroid.find(var_num);
245  if (centroid != _centroid.end())
246  {
247  grain_data[1] = centroid->second(0);
248  grain_data[2] = centroid->second(1);
249  grain_data[3] = centroid->second(2);
250  }
251  // combine centers & volumes from all MPI ranks
252  gatherSum(vol_count);
253  gatherSum(grain_data);
254  _volume[var_num] = grain_data[0];
255  _centroid[var_num] = {grain_data[1], grain_data[2], grain_data[3]};
256  _centroid[var_num] /= vol_count;
257  }
258 }
259 
260 Real
262 {
263  return static_cast<Real>(_variables_used.size());
264 }
265 
266 bool
267 FauxGrainTracker::doesFeatureIntersectBoundary(unsigned int /*feature_id*/) const
268 {
269  mooseDoOnce(mooseWarning("FauxGrainTracker::doesFeatureIntersectboundary() is unimplemented"));
270 
271  return false;
272 }
virtual ~FauxGrainTracker()
std::multimap< dof_id_type, dof_id_type > _periodic_node_map
The data structure which is a list of nodes that are constrained to other nodes based on the imposed ...
std::vector< unsigned int > _empty_var_to_features
This class defines the interface for the GrainTracking objects.
static const std::size_t invalid_size_t
virtual Elem * elemPtr(const dof_id_type i)
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
static InputParameters validParams()
virtual const std::vector< unsigned int > & getVarToFeatureVector(dof_id_type elem_id) const override
Returns a list of active unique feature ids for a particular element.
virtual void finalize() override
std::vector< unsigned int > _op_to_grains
Order parameter to grain indices (just a reflexive vector)
FauxGrainTracker(const InputParameters &parameters)
static InputParameters validParams()
const Parallel::Communicator & _communicator
virtual Point getGrainCentroid(unsigned int grain_id) const override
Returns the centroid for the given grain number.
std::pair< typename M::iterator, bool > moose_try_emplace(M &m, const typename M::key_type &k, Args &&... args)
std::map< unsigned int, unsigned int > _vol_count
The count of entities contributing to the volume calculation.
virtual bool doesFeatureIntersectBoundary(unsigned int feature_id) const override
Returns a Boolean indicating whether this feature intersects any boundary.
void mooseWarning(Args &&... args) const
virtual std::size_t getTotalFeatureCount() const override
Returns the total feature count (active and inactive ids, useful for sizing vectors) ...
std::set< unsigned int > _variables_used
Used as the lightweight grain counter.
const dof_id_type n_nodes
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
void gatherSum(T &value)
MeshBase & getMesh()
virtual void initialize() override
Real elementVolume(const Elem *elem) const
This object will mark nodes or elements of continuous regions all with a unique number for the purpos...
const bool _use_less_than_threshold_comparison
Use less-than when comparing values against the threshold value.
virtual Real getEntityValue(dof_id_type entity_id, FeatureFloodCount::FieldType field_type, std::size_t var_idx) const override
static const unsigned int invalid_id
std::map< dof_id_type, unsigned int > _entity_id_to_var_num
The mapping of entities to grains, in this case always the order parameter.
const Real _threshold
The threshold above (or below) where an entity may begin a new region (feature)
virtual void execute() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
FEProblemBase & _fe_problem
virtual std::size_t getNumberActiveGrains() const override
Returns the number of active grains current stored in the GrainTracker.
std::size_t _grain_count
Total Grain Count.
void addClassDescription(const std::string &doc_string)
registerMooseObject("PhaseFieldApp", FauxGrainTracker)
This class is a fake grain tracker object, it will not actually track grains nor remap them but will ...
std::map< unsigned int, Point > _centroid
The centroid of the feature (average of coordinates from entities participating in the volume calcula...
std::map< unsigned int, Real > _volume
The volume of the feature.
MooseMesh & _mesh
A reference to the mesh.
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid) override
const std::size_t _n_vars
void ErrorVector unsigned int
uint8_t dof_id_type
virtual unsigned int getFeatureVar(unsigned int feature_id) const override
Returns the variable representing the passed in feature.
void set_union(T &data, const unsigned int root_id) const
virtual Real getValue() const override