https://mooseframework.inl.gov
AverageGrainVolume.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 "AverageGrainVolume.h"
11 #include "FeatureFloodCount.h"
12 #include "MooseMesh.h"
13 #include "Assembly.h"
14 #include "MooseVariable.h"
15 #include "SystemBase.h"
16 
17 #include "libmesh/quadrature.h"
18 
19 registerMooseObject("PhaseFieldApp", AverageGrainVolume);
20 
23 {
25  params.addClassDescription("Calculate average grain area in a polycrystal");
26 
34  // Mode 1: Use the GrainTracker
35  params.addParam<UserObjectName>("feature_counter",
36  "The FeatureFloodCount UserObject to get values from.");
37 
38  // Mode 2: Calculate grain volumes adirectly
40  "variable", "var_name_base", "op_num", "Array of coupled variables");
41  params.addParam<unsigned int>("grain_num", "number of grains to create");
42  return params;
43 }
44 
46  : GeneralPostprocessor(parameters),
47  Coupleable(this, false),
49  _mesh(_subproblem.mesh()),
50  _assembly(_subproblem.assembly(0, _sys.number())),
51  _q_point(_assembly.qPoints()),
52  _qrule(_assembly.qRule()),
53  _JxW(_assembly.JxW()),
54  _coord(_assembly.coordTransformation()),
55  _feature_counter(isParamValid("feature_counter")
56  ? &getUserObject<FeatureFloodCount>("feature_counter")
57  : nullptr)
58 {
59  if (!_feature_counter)
60  {
61  if (isParamValid("variable") && isParamValid("grain_num"))
62  {
63  auto num_coupled_vars = coupledComponents("variable");
64  if (num_coupled_vars != getParam<unsigned int>("grain_num"))
65  mooseError("The number of grains must match the number of OPs if a feature_counter is not "
66  "supplied");
67 
68  _vals = coupledValues("variable");
69 
70  _feature_volumes.resize(num_coupled_vars);
71 
72  // Build a reflexive map (ops map to grains directly)
73  _static_var_to_feature.resize(num_coupled_vars);
74  for (MooseIndex(_static_var_to_feature) i = 0; i < num_coupled_vars; ++i)
76  }
77  else
78  mooseError("Must supply either a feature_counter object or coupled variables and grain_num");
79  }
80  else
81  {
82  const auto & coupled_vars = _feature_counter->getCoupledVars();
83  _vals.reserve(coupled_vars.size());
84 
85  for (auto & coupled_var : coupled_vars)
86  _vals.emplace_back(&coupled_var->sln());
87 
89  }
90 }
91 
92 void
94 {
95  auto num_features = _feature_volumes.size();
96 
97  // When using FeatureFloodCount, the number of grains may not be fixed. Resize as appropriate
98  if (_feature_counter)
99  num_features = _feature_counter->getTotalFeatureCount();
100 
101  _feature_volumes.assign(num_features, 0);
102 }
103 
104 void
106 {
107  auto num_features = _feature_volumes.size();
108  for (const auto & elem : _mesh.getMesh().active_local_element_ptr_range())
109  {
110  _fe_problem.prepare(elem, 0);
111  _fe_problem.reinitElem(elem, 0);
112 
113  const std::vector<unsigned int> & var_to_feature_ptr =
116 
117  accumulateVolumes(var_to_feature_ptr, num_features);
118  }
119 }
120 
121 void
122 AverageGrainVolume::accumulateVolumes(const std::vector<unsigned int> & var_to_features,
123  std::size_t libmesh_dbg_var(num_features))
124 {
125  for (MooseIndex(var_to_features) var_index = 0; var_index < var_to_features.size(); ++var_index)
126  {
127  // Only sample "active" variables
128  if (var_to_features[var_index] != FeatureFloodCount::invalid_id)
129  {
130  auto feature_id = var_to_features[var_index];
131  mooseAssert(feature_id < num_features, "Feature ID out of range");
132  auto integral_value = computeIntegral(var_index);
133 
134  _feature_volumes[feature_id] += integral_value;
135  }
136  }
137 }
138 
139 Real
140 AverageGrainVolume::computeIntegral(std::size_t var_index) const
141 {
142  Real sum = 0;
143 
144  for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp)
145  sum += _JxW[qp] * _coord[qp] * (*_vals[var_index])[qp];
146 
147  return sum;
148 }
149 
150 void
152 {
154 }
155 
156 Real
158 {
159  Real total_volume = 0;
160  for (auto & volume : _feature_volumes)
161  total_volume += volume;
162 
163  unsigned int active_features =
165 
166  return total_volume / active_features;
167 }
std::vector< unsigned int > _static_var_to_feature
const QBase *const & _qrule
std::size_t getNumberActiveFeatures() const
Return the number of active features.
AverageGrainVolume(const InputParameters &parameters)
virtual void execute() override
virtual void prepare(const Elem *elem, const THREAD_ID tid) override
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
Real computeIntegral(std::size_t var_index) const
virtual const std::vector< unsigned int > & getVarToFeatureVector(dof_id_type elem_id) const
Returns a list of active unique feature ids for a particular element.
const std::vector< MooseVariable * > & getCoupledVars() const
Returns a const vector to the coupled variable pointers.
virtual Real getValue() const override
MeshBase & mesh
virtual std::size_t getTotalFeatureCount() const
Returns the total feature count (active and inactive ids, useful for sizing vectors) ...
void accumulateVolumes(const std::vector< unsigned int > &var_to_features, std::size_t libmesh_dbg_var(num_features))
const MooseArray< Real > & _coord
bool isParamValid(const std::string &name) const
static InputParameters validParams()
std::vector< Real > _feature_volumes
const MooseArray< Real > & _JxW
virtual void initialize() override
void gatherSum(T &value)
MeshBase & getMesh()
virtual void reinitElem(const Elem *elem, const THREAD_ID tid) override
This object will mark nodes or elements of continuous regions all with a unique number for the purpos...
static const unsigned int invalid_id
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
unsigned int coupledComponents(const std::string &var_name) const
void addMooseVariableDependency(MooseVariableFieldBase *var)
std::vector< const VariableValue *> coupledValues(const std::string &var_name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addCoupledVarWithAutoBuild(const std::string &name, const std::string &base_name, const std::string &num_name, const std::string &doc_string)
FEProblemBase & _fe_problem
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
virtual void finalize() override
MooseMesh & _mesh
A reference to the mesh.
const FeatureFloodCount *const _feature_counter
registerMooseObject("PhaseFieldApp", AverageGrainVolume)
Compute the average grain area in a polycrystal.
const std::vector< MooseVariableFEBase * > & getFECoupledVars() const
Returns a const vector to the coupled MooseVariableFEBase pointers.
std::vector< const VariableValue * > _vals
static InputParameters validParams()