www.mooseframework.org
PolycrystalVoronoi.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 "PolycrystalVoronoi.h"
11 #include "IndirectSort.h"
12 #include "MooseRandom.h"
13 #include "MooseMesh.h"
14 #include "MooseVariable.h"
15 #include "NonlinearSystemBase.h"
16 #include "DelimitedFileReader.h"
17 
18 registerMooseObject("PhaseFieldApp", PolycrystalVoronoi);
19 
20 template <>
21 InputParameters
23 {
24  InputParameters params = validParams<PolycrystalUserObjectBase>();
25  params.addClassDescription(
26  "Random Voronoi tessellation polycrystal (used by PolycrystalVoronoiAction)");
27  params.addParam<unsigned int>(
28  "grain_num", 0, "Number of grains being represented by the order parameters");
29  params.addParam<unsigned int>("rand_seed", 0, "The random seed");
30  params.addParam<bool>(
31  "columnar_3D", false, "3D microstructure will be columnar in the z-direction?");
32  params.addParam<FileName>(
33  "file_name",
34  "",
35  "File containing grain centroids, if file_name is provided, the centroids "
36  "from the file will be used.");
37  params.addParam<Real>("int_width", 0.0, "Width of diffuse interfaces");
38  return params;
39 }
40 
41 PolycrystalVoronoi::PolycrystalVoronoi(const InputParameters & parameters)
42  : PolycrystalUserObjectBase(parameters),
43  _grain_num(getParam<unsigned int>("grain_num")),
44  _columnar_3D(getParam<bool>("columnar_3D")),
45  _rand_seed(getParam<unsigned int>("rand_seed")),
46  _int_width(getParam<Real>("int_width")),
47  _file_name(getParam<FileName>("file_name"))
48 {
49  if (_file_name == "" && _grain_num == 0)
50  mooseError("grain_num must be provided if the grain centroids are not read from a file");
51 
52  if (_file_name != "" && _grain_num > 0)
53  mooseWarning("grain_num is ignored and will be determined from the file.");
54 }
55 
56 void
58  std::vector<unsigned int> & grains) const
59 {
60  grains.resize(0);
61  Real d_min = _range.norm();
62  Real distance;
63  auto n_grains = _centerpoints.size();
64  auto min_index = n_grains;
65 
66  // Find the closest centerpoint to the current point
67  for (MooseIndex(_centerpoints) grain = 0; grain < n_grains; ++grain)
68  {
69  distance = _mesh.minPeriodicDistance(_vars[0]->number(), _centerpoints[grain], point);
70  if (distance < d_min)
71  {
72  d_min = distance;
73  min_index = grain;
74  }
75  }
76  mooseAssert(min_index < n_grains, "Couldn't find closest Voronoi cell");
77  Point current_grain = _centerpoints[min_index];
78  grains.push_back(min_index); // closest centerpoint always gets included
79 
80  if (_int_width > 0.0)
81  for (MooseIndex(_centerpoints) grain = 0; grain < n_grains; ++grain)
82  if (grain != min_index)
83  {
84  Point next_grain = _centerpoints[grain];
85  Point N = findNormalVector(point, current_grain, next_grain);
86  Point cntr = findCenterPoint(point, current_grain, next_grain);
87  distance = N * (cntr - point);
88  if (distance < _int_width)
89  grains.push_back(grain); // also include all grains with nearby boundaries
90  }
91 }
92 
93 Real
94 PolycrystalVoronoi::getVariableValue(unsigned int op_index, const Point & p) const
95 {
96  std::vector<unsigned int> grain_ids;
97  getGrainsBasedOnPoint(p, grain_ids);
98 
99  // Now see if any of those grains are represented by the passed in order parameter
100  unsigned int active_grain_on_op = invalid_id;
101  for (auto grain_id : grain_ids)
102  if (op_index == _grain_to_op[grain_id])
103  {
104  active_grain_on_op = grain_id;
105  break;
106  }
107 
108  Real profile_val = 0.0;
109  if (active_grain_on_op != invalid_id)
110  profile_val = computeDiffuseInterface(p, active_grain_on_op, grain_ids);
111 
112  return profile_val;
113 }
114 
115 void
117 {
118  // Set up domain bounds with mesh tools
119  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
120  {
121  _bottom_left(i) = _mesh.getMinInDimension(i);
122  _top_right(i) = _mesh.getMaxInDimension(i);
123  }
125 
126  if (!_file_name.empty())
127  {
128  MooseUtils::DelimitedFileReader txt_reader(_file_name, &_communicator);
129 
130  txt_reader.read();
131  std::vector<std::string> col_names = txt_reader.getNames();
132  std::vector<std::vector<Real>> data = txt_reader.getData();
133  _grain_num = data[0].size();
134  _centerpoints.resize(_grain_num);
135 
136  for (unsigned int i = 0; i < col_names.size(); ++i)
137  {
138  // Check vector lengths
139  if (data[i].size() != _grain_num)
140  paramError("Columns in ", _file_name, " do not have uniform lengths.");
141  }
142 
143  for (unsigned int grain = 0; grain < _grain_num; ++grain)
144  {
145  _centerpoints[grain](0) = data[0][grain];
146  _centerpoints[grain](1) = data[1][grain];
147  if (col_names.size() > 2)
148  _centerpoints[grain](2) = data[2][grain];
149  else
150  _centerpoints[grain](2) = 0.0;
151  }
152  }
153  else
154  {
155  MooseRandom::seed(_rand_seed);
156 
157  // Randomly generate the centers of the individual grains represented by the Voronoi
158  // tessellation
159  _centerpoints.resize(_grain_num);
160  std::vector<Real> distances(_grain_num);
161 
162  for (auto grain = decltype(_grain_num)(0); grain < _grain_num; grain++)
163  {
164  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
165  _centerpoints[grain](i) = _bottom_left(i) + _range(i) * MooseRandom::rand();
166  if (_columnar_3D)
167  _centerpoints[grain](2) = _bottom_left(2) + _range(2) * 0.5;
168  }
169  }
170 }
171 
172 Real
174  const unsigned int & gr_index,
175  const std::vector<unsigned int> & grain_ids) const
176 {
177  Real val = 1.0;
178  Point current_grain = _centerpoints[gr_index];
179  for (auto i : grain_ids)
180  if (i != gr_index)
181  {
182  Point next_grain = _centerpoints[i];
183  Point N = findNormalVector(point, current_grain, next_grain);
184  Point cntr = findCenterPoint(point, current_grain, next_grain);
185  for (unsigned int vcomp = 0; vcomp < 3; ++vcomp)
186  if (N(vcomp) != 0.0)
187  {
188  Real L = findLinePoint(point, N, cntr, vcomp);
189  val *= 0.5 * (1.0 - std::tanh(2.0 * (point(vcomp) - L) * N(vcomp) / _int_width));
190  break;
191  }
192  }
193  return val;
194 }
195 
196 Point
197 PolycrystalVoronoi::findNormalVector(const Point & point, const Point & p1, const Point & p2) const
198 {
199  Point pa = point + _mesh.minPeriodicVector(_vars[0]->number(), point, p1);
200  Point pb = point + _mesh.minPeriodicVector(_vars[0]->number(), point, p2);
201  Point N = pb - pa;
202  return N / N.norm();
203 }
204 
205 Point
206 PolycrystalVoronoi::findCenterPoint(const Point & point, const Point & p1, const Point & p2) const
207 {
208  Point pa = point + _mesh.minPeriodicVector(_vars[0]->number(), point, p1);
209  Point pb = point + _mesh.minPeriodicVector(_vars[0]->number(), point, p2);
210  return 0.5 * (pa + pb);
211 }
212 
213 Real
215  const Point & N,
216  const Point & cntr,
217  const unsigned int vcomp) const
218 {
219  const Real l_sum = N((vcomp + 1) % 3) * (point((vcomp + 1) % 3) - cntr((vcomp + 1) % 3)) +
220  N((vcomp + 2) % 3) * (point((vcomp + 2) % 3) - cntr((vcomp + 2) % 3));
221 
222  return cntr(vcomp) - l_sum / N(vcomp);
223 }
PolycrystalVoronoi::_top_right
Point _top_right
Definition: PolycrystalVoronoi.h:43
validParams< PolycrystalVoronoi >
InputParameters validParams< PolycrystalVoronoi >()
Definition: PolycrystalVoronoi.C:22
FeatureFloodCount::_mesh
MooseMesh & _mesh
A reference to the mesh.
Definition: FeatureFloodCount.h:581
PolycrystalVoronoi::getVariableValue
virtual Real getVariableValue(unsigned int op_index, const Point &p) const override
Returns the variable value for a given op_index and mesh point.
Definition: PolycrystalVoronoi.C:94
PolycrystalUserObjectBase::_grain_to_op
std::vector< unsigned int > _grain_to_op
A vector indicating which op is assigned to each grain.
Definition: PolycrystalUserObjectBase.h:150
PolycrystalVoronoi::findNormalVector
Point findNormalVector(const Point &point, const Point &p1, const Point &p2) const
Definition: PolycrystalVoronoi.C:197
PolycrystalVoronoi::_file_name
const FileName _file_name
Definition: PolycrystalVoronoi.h:48
PolycrystalVoronoi::findLinePoint
Real findLinePoint(const Point &point, const Point &N, const Point &cntr, const unsigned int dim) const
Definition: PolycrystalVoronoi.C:214
PolycrystalUserObjectBase
This object provides the base capability for creating proper polycrystal ICs.
Definition: PolycrystalUserObjectBase.h:27
PolycrystalVoronoi::_centerpoints
std::vector< Point > _centerpoints
Definition: PolycrystalVoronoi.h:46
PolycrystalVoronoi::_rand_seed
const unsigned int _rand_seed
Definition: PolycrystalVoronoi.h:39
PolycrystalVoronoi::_bottom_left
Point _bottom_left
Definition: PolycrystalVoronoi.h:42
PolycrystalVoronoi::_columnar_3D
const bool _columnar_3D
Definition: PolycrystalVoronoi.h:37
PolycrystalVoronoi::findCenterPoint
Point findCenterPoint(const Point &point, const Point &p1, const Point &p2) const
Definition: PolycrystalVoronoi.C:206
registerMooseObject
registerMooseObject("PhaseFieldApp", PolycrystalVoronoi)
FeatureFloodCount::_vars
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
Definition: FeatureFloodCount.h:566
PolycrystalVoronoi::precomputeGrainStructure
virtual void precomputeGrainStructure() override
This callback is triggered after the object is initialized and may be optionally overridden to do pre...
Definition: PolycrystalVoronoi.C:116
PolycrystalVoronoi::PolycrystalVoronoi
PolycrystalVoronoi(const InputParameters &parameters)
Definition: PolycrystalVoronoi.C:41
FeatureFloodCount::invalid_id
static const unsigned int invalid_id
Definition: FeatureFloodCount.h:94
PolycrystalVoronoi
Definition: PolycrystalVoronoi.h:20
PolycrystalVoronoi.h
PolycrystalVoronoi::computeDiffuseInterface
Real computeDiffuseInterface(const Point &point, const unsigned int &gr_index, const std::vector< unsigned int > &grain_ids) const
Definition: PolycrystalVoronoi.C:173
validParams< PolycrystalUserObjectBase >
InputParameters validParams< PolycrystalUserObjectBase >()
Definition: PolycrystalUserObjectBase.C:24
PolycrystalVoronoi::_int_width
const Real _int_width
Definition: PolycrystalVoronoi.h:40
PolycrystalVoronoi::_grain_num
unsigned int _grain_num
The number of grains to create.
Definition: PolycrystalVoronoi.h:35
PolycrystalVoronoi::getGrainsBasedOnPoint
virtual void getGrainsBasedOnPoint(const Point &point, std::vector< unsigned int > &grains) const override
Method for retrieving active grain IDs based on some point in the mesh.
Definition: PolycrystalVoronoi.C:57
PolycrystalVoronoi::_range
Point _range
Definition: PolycrystalVoronoi.h:44