www.mooseframework.org
PolycrystalCircles.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 "PolycrystalCircles.h"
11 #include "MooseMesh.h"
12 #include "MooseVariable.h"
13 
14 #include "libmesh/utility.h"
15 #include <fstream>
16 
17 registerMooseObject("PhaseFieldApp", PolycrystalCircles);
18 
21 {
23  params.addClassDescription(
24  "Polycrystal circles generated from a vector input or read from a file");
25  params.addParam<bool>("read_from_file",
26  false,
27  "Set to true to read the position and radius "
28  "vectors from a file rather than inputing them "
29  "manually");
30  params.addParam<bool>(
31  "columnar_3D", false, "3D microstructure will be columnar in the z-direction?");
32  params.addParam<std::vector<Real>>("x_positions", "x coordinate for each circle center");
33  params.addParam<std::vector<Real>>("y_positions", "y coordinate for each circle center");
34  params.addParam<std::vector<Real>>("z_positions", "z coordinate for each circle center");
35  params.addParam<std::vector<Real>>("radii", "The radius for each circle");
36  params.addParam<FileName>("file_name", "File containing circle centers and radii");
37  params.addParam<Real>("int_width", 0.0, "Width of diffuse interface");
38 
39  return params;
40 }
41 
43  : PolycrystalUserObjectBase(parameters),
44  _columnar_3D(getParam<bool>("columnar_3D")),
45  _int_width(getParam<Real>("int_width")),
46  _grain_num(0)
47 {
48 }
49 
50 void
52  std::vector<unsigned int> & grains) const
53 {
54  unsigned int n_grains = _centerpoints.size();
55  grains.resize(0);
56 
57  for (unsigned int i = 0; i < n_grains; ++i)
58  {
59  Real distance = 0;
60 
61  if (_columnar_3D)
62  {
63  Real d_x = (point(0) - _centerpoints[i](0)) * (point(0) - _centerpoints[i](0));
64  Real d_y = (point(1) - _centerpoints[i](1)) * (point(1) - _centerpoints[i](1));
65  distance = std::sqrt(d_x + d_y);
66  }
67  else
68  distance = _mesh.minPeriodicDistance(_vars[0]->number(), _centerpoints[i], point);
69 
70  if (distance < _radii[i] + _int_width)
71  grains.push_back(i);
72  }
73 }
74 
75 Real
76 PolycrystalCircles::getVariableValue(unsigned int op_index, const Point & p) const
77 {
78  std::vector<unsigned int> grain_ids;
79  getGrainsBasedOnPoint(p, grain_ids);
80 
81  unsigned int active_grain_on_op = invalid_id;
82  for (auto grain_id : grain_ids)
83  if (op_index == _grain_to_op.at(grain_id))
84  {
85  active_grain_on_op = grain_id;
86  break;
87  }
88 
89  return active_grain_on_op != invalid_id ? computeDiffuseInterface(p, active_grain_on_op) : 0.0;
90 }
91 
92 void
94 {
95  bool readfromfile = getParam<bool>("read_from_file");
96  if (readfromfile)
97  {
98  // Read file
99  const FileName file_name = getParam<FileName>("file_name");
100  MooseUtils::DelimitedFileReader txt_reader(file_name, &_communicator);
101 
102  txt_reader.read();
103  std::vector<std::string> col_names = txt_reader.getNames();
104  std::vector<std::vector<Real>> data = txt_reader.getData();
105  _grain_num = data[0].size();
106  _centerpoints.resize(_grain_num);
107 
108  std::array<int, 4> col_map = {{-1, -1, -1, -1}};
109 
110  for (unsigned int i = 0; i < col_names.size(); ++i)
111  {
112  // Check vector lengths
113  if (data[i].size() != _grain_num)
114  mooseError("Columns in ", file_name, " do not have uniform lengths.");
115 
116  // Map columns to variables
117  if (col_names[i] == "x")
118  col_map[X] = i;
119  else if (col_names[i] == "y")
120  col_map[Y] = i;
121  else if (col_names[i] == "z")
122  col_map[Z] = i;
123  else if (col_names[i] == "r")
124  col_map[R] = i;
125  }
126 
127  // Check all columns are included
128  if (col_map[X] == -1)
129  mooseError("No column 'x' in ", file_name, ".");
130  if (col_map[Y] == -1)
131  mooseError("No column 'y' in ", file_name, ".");
132  if (col_map[Z] == -1)
133  mooseError("No column 'z' in ", file_name, ".");
134  if (col_map[R] == -1)
135  mooseError("No column 'r' in ", file_name, ".");
136 
137  // Write data to variables
138  _radii.assign(data[col_map[R]].begin(), data[col_map[R]].end());
139  for (unsigned int i = 0; i < _grain_num; ++i)
140  {
141  _centerpoints[i](0) = data[col_map[X]][i];
142  _centerpoints[i](1) = data[col_map[Y]][i];
143  _centerpoints[i](2) = data[col_map[Z]][i];
144  }
145  }
146  else // if (readfromfile)
147  {
148  // Read vectors
149  std::vector<Real> x_c = getParam<std::vector<Real>>("x_positions");
150  std::vector<Real> y_c = getParam<std::vector<Real>>("y_positions");
151  std::vector<Real> z_c = getParam<std::vector<Real>>("z_positions");
152  std::vector<Real> r_c = getParam<std::vector<Real>>("radii");
153 
154  _grain_num = r_c.size();
155  _centerpoints.resize(_grain_num);
156 
157  // Check vector lengths
158  if (_grain_num != x_c.size())
159  mooseError("The vector length of x_positions does not match the length of radii");
160  else if (_grain_num != y_c.size())
161  mooseError("The vector length of y_positions does not match the length of radii");
162  else if (_grain_num != z_c.size())
163  mooseError("The vector length of z_positions does not match the length of radii");
164 
165  // Assign values
166  _radii.assign(r_c.begin(), r_c.end());
167  for (unsigned int i = 0; i < _grain_num; ++i)
168  {
169  _centerpoints[i](0) = x_c[i];
170  _centerpoints[i](1) = y_c[i];
171  _centerpoints[i](2) = z_c[i];
172  }
173  }
174 }
175 
176 Real
177 PolycrystalCircles::computeDiffuseInterface(const Point & p, const unsigned int & i) const
178 {
179  if (_int_width == 0)
180  return 1.0;
181 
182  Real d = 0;
183 
184  if (_columnar_3D)
185  {
186  Real d_x = (p(0) - _centerpoints[i](0)) * (p(0) - _centerpoints[i](0));
187  Real d_y = (p(1) - _centerpoints[i](1)) * (p(1) - _centerpoints[i](1));
188  d = std::sqrt(d_x + d_y);
189  }
190  else
191  d = _mesh.minPeriodicDistance(_vars[0]->number(), _centerpoints[i], p);
192 
193  return 0.5 * (1 - std::tanh(2.0 * (d - _radii[i]) / _int_width));
194 }
unsigned int _grain_num
Number of crystal grains to create.
std::map< unsigned int, unsigned int > _grain_to_op
A map of the grain_id to op.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const bool _columnar_3D
Whether to use columns or spheres in 3D geometries.
This object provides the base capability for creating proper polycrystal ICs.
registerMooseObject("PhaseFieldApp", PolycrystalCircles)
const Parallel::Communicator & _communicator
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
Real distance(const Point &p)
std::vector< Real > _radii
Radius for each circular grain created.
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
static const unsigned int invalid_id
virtual Real getVariableValue(unsigned int op_index, const Point &p) const override
Returns the variable value for a given op_index and mesh point.
Real minPeriodicDistance(unsigned int nonlinear_var_num, Point p, Point q) const
Real computeDiffuseInterface(const Point &p, const unsigned int &i) const
PolycrystalCircles(const InputParameters &parameters)
virtual void precomputeGrainStructure() override
This callback is triggered after the object is initialized and may be optionally overridden to do pre...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static InputParameters validParams()
void mooseError(Args &&... args) const
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.
void addClassDescription(const std::string &doc_string)
std::vector< Point > _centerpoints
x,y,z coordinates of circle centers
MooseMesh & _mesh
A reference to the mesh.
const Real _int_width
Interfacial width.
PolycrystalCircles creates a polycrystal made up of circles.
static InputParameters validParams()