www.mooseframework.org
AverageGrainVolume.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 
8 #include "AverageGrainVolume.h"
9 #include "FeatureFloodCount.h"
10 #include "MooseMesh.h"
11 #include "Assembly.h"
12 #include "MooseVariable.h"
13 
14 #include "libmesh/quadrature.h"
15 
16 template <>
17 InputParameters
19 {
20  InputParameters params = validParams<GeneralPostprocessor>();
21  params.addClassDescription("Calculate average grain area in a polycrystal");
22 
30  // Mode 1: Use the GrainTracker
31  params.addParam<UserObjectName>("feature_counter",
32  "The FeatureFloodCount UserObject to get values from.");
33 
34  // Mode 2: Calculate grain volumes adirectly
35  params.addCoupledVarWithAutoBuild(
36  "variable", "var_name_base", "op_num", "Array of coupled variables");
37  params.addParam<unsigned int>("grain_num", "number of grains to create");
38  return params;
39 }
40 
41 AverageGrainVolume::AverageGrainVolume(const InputParameters & parameters)
42  : GeneralPostprocessor(parameters),
43  Coupleable(this, false),
44  MooseVariableDependencyInterface(),
45  _mesh(_subproblem.mesh()),
46  _assembly(_subproblem.assembly(0)),
47  _q_point(_assembly.qPoints()),
48  _qrule(_assembly.qRule()),
49  _JxW(_assembly.JxW()),
50  _coord(_assembly.coordTransformation()),
51  _feature_counter(isParamValid("feature_counter")
52  ? &getUserObject<FeatureFloodCount>("feature_counter")
53  : nullptr)
54 {
55  if (!_feature_counter)
56  {
57  if (isParamValid("variable") && isParamValid("grain_num"))
58  {
59  auto num_coupled_vars = coupledComponents("variable");
60  if (num_coupled_vars != getParam<unsigned int>("grain_num"))
61  mooseError("The number of grains must match the number of OPs if a feature_counter is not "
62  "supplied");
63 
64  _vals.resize(num_coupled_vars);
65  for (unsigned int i = 0; i < num_coupled_vars; ++i)
66  _vals[i] = &coupledValue("variable", i);
67 
68  _feature_volumes.resize(num_coupled_vars);
69 
70  // Build a reflexive map (ops map to grains directly)
71  _static_var_to_feature.resize(num_coupled_vars);
72  for (auto i = beginIndex(_static_var_to_feature); i < num_coupled_vars; ++i)
74  }
75  else
76  mooseError("Must supply either a feature_counter object or coupled variables and grain_num");
77  }
78  else
79  {
80  const auto & coupled_vars = _feature_counter->getCoupledVars();
81  _vals.reserve(coupled_vars.size());
82 
83  for (auto & coupled_var : coupled_vars)
84  _vals.emplace_back(&coupled_var->sln());
85 
86  addMooseVariableDependency(coupled_vars);
87  }
88 }
89 
90 void
92 {
93  auto num_features = _feature_volumes.size();
94 
95  // When using FeatureFloodCount, the number of grains may not be fixed. Resize as appropriate
96  if (_feature_counter)
97  num_features = _feature_counter->getTotalFeatureCount();
98 
99  _feature_volumes.assign(num_features, 0);
100 }
101 
102 void
104 {
105  auto num_features = _feature_volumes.size();
106 
107  const auto end = _mesh.getMesh().active_local_elements_end();
108  for (auto el = _mesh.getMesh().active_local_elements_begin(); el != end; ++el)
109  {
110  const Elem * elem = *el;
111  _fe_problem.prepare(elem, 0);
112  _fe_problem.reinitElem(elem, 0);
113 
114  const std::vector<unsigned int> & var_to_feature_ptr =
117 
118  accumulateVolumes(var_to_feature_ptr, num_features);
119  }
120 }
121 
122 void
123 AverageGrainVolume::accumulateVolumes(const std::vector<unsigned int> & var_to_features,
124  std::size_t libmesh_dbg_var(num_features))
125 {
126  for (auto var_index = beginIndex(var_to_features); var_index < var_to_features.size();
127  ++var_index)
128  {
129  // Only sample "active" variables
130  if (var_to_features[var_index] != FeatureFloodCount::invalid_id)
131  {
132  auto feature_id = var_to_features[var_index];
133  mooseAssert(feature_id < num_features, "Feature ID out of range");
134  auto integral_value = computeIntegral(var_index);
135 
136  _feature_volumes[feature_id] += integral_value;
137  }
138  }
139 }
140 
141 Real
142 AverageGrainVolume::computeIntegral(std::size_t var_index) const
143 {
144  Real sum = 0;
145 
146  for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp)
147  sum += _JxW[qp] * _coord[qp] * (*_vals[var_index])[qp];
148 
149  return sum;
150 }
151 
152 Real
154 {
155  _communicator.sum(_feature_volumes);
156 
157  Real total_volume = 0;
158  for (auto & volume : _feature_volumes)
159  total_volume += volume;
160 
161  return total_volume / _feature_volumes.size();
162 }
std::vector< unsigned int > _static_var_to_feature
virtual Real getValue() override
const FeatureFloodCount * _feature_counter
AverageGrainVolume(const InputParameters &parameters)
virtual void execute() override
void accumulateVolumes(const std::vector< unsigned int > &var_to_features, std::size_t libmesh_dbg_var(num_features))
const MooseArray< Real > & _coord
std::vector< Real > _feature_volumes
const MooseArray< Real > & _JxW
virtual std::size_t getTotalFeatureCount() const
Returns the total feature count (active and inactive ids, useful for sizing vectors) ...
virtual void initialize() override
const std::vector< MooseVariable * > & getCoupledVars() const
Returns a const vector to the coupled variable pointers.
This object will mark nodes or elements of continuous regions all with a unique number for the purpos...
InputParameters validParams< AverageGrainVolume >()
static const unsigned int invalid_id
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.
MooseMesh & _mesh
A reference to the mesh.
Real computeIntegral(std::size_t var_index) const
std::vector< const VariableValue * > _vals