https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PolycrystalCircles.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 "PolycrystalCircles.h"
11#include "MooseMesh.h"
12#include "MooseVariable.h"
13
14#include "libmesh/utility.h"
15#include <fstream>
16
18
21{
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
50void
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
69
70 if (distance < _radii[i] + _int_width)
71 grains.push_back(i);
72 }
73}
74
75Real
76PolycrystalCircles::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
92void
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();
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();
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
176Real
177PolycrystalCircles::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
192
193 return 0.5 * (1 - std::tanh(2.0 * (d - _radii[i]) / _int_width));
194}
const Real p
registerMooseObject("PhaseFieldApp", PolycrystalCircles)
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
static const unsigned int invalid_id
MooseMesh & _mesh
A reference to the mesh.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
Real minPeriodicDistance(const unsigned int sys_num, const unsigned int var_num, const Point &p, const Point &q) const
const std::vector< std::string > & getNames() const
const std::vector< std::vector< T > > & getData() const
PolycrystalCircles creates a polycrystal made up of circles.
static InputParameters validParams()
PolycrystalCircles(const InputParameters &parameters)
virtual Real getVariableValue(unsigned int op_index, const Point &p) const override
Returns the variable value for a given op_index and mesh point.
unsigned int _grain_num
Number of crystal grains to create.
virtual void precomputeGrainStructure() override
This callback is triggered after the object is initialized and may be optionally overridden to do pre...
std::vector< Point > _centerpoints
x,y,z coordinates of circle centers
Real computeDiffuseInterface(const Point &p, const unsigned int &i) 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.
std::vector< Real > _radii
Radius for each circular grain created.
const Real _int_width
Interfacial width.
const bool _columnar_3D
Whether to use columns or spheres in 3D geometries.
This object provides the base capability for creating proper polycrystal ICs.
std::map< unsigned int, unsigned int > _grain_to_op
A map of the grain_id to op.
static InputParameters validParams()
const Parallel::Communicator & _communicator
Real distance(const Point &p)