www.mooseframework.org
DiscreteNucleationMap.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 "DiscreteNucleationMap.h"
11 #include "MooseMesh.h"
12 
13 #include "libmesh/quadrature.h"
14 
16 
19 {
21  params.addClassDescription("Generates a spatial smoothed map of all nucleation sites with the "
22  "data of the DiscreteNucleationInserter for use by the "
23  "DiscreteNucleation material.");
24  params.addParam<Real>("int_width", 0.0, "Nucleus interface width for smooth nuclei");
25  params.addRequiredParam<UserObjectName>("inserter", "DiscreteNucleationInserter user object");
26  params.addCoupledVar("periodic",
27  "Use the periodicity settings of this variable to populate the grain map");
28  // the mapping needs to run at timestep begin, which is after the adaptivity
29  // run of the previous timestep.
30  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
31  return params;
32 }
33 
35  : ElementUserObject(parameters),
36  _mesh_changed(false),
37  _inserter(getUserObject<DiscreteNucleationInserterBase>("inserter")),
38  _periodic(isCoupled("periodic") ? coupled("periodic") : -1),
39  _int_width(getParam<Real>("int_width")),
40  _nucleus_list(_inserter.getNucleusList())
41 {
42  _zero_map.assign(_fe_problem.getMaxQps(), 0.0);
43 }
44 
45 void
47 {
49  {
50  _rebuild_map = true;
51  _nucleus_map.clear();
52  }
53  else
54  _rebuild_map = false;
55 
56  _mesh_changed = false;
57 }
58 
59 void
61 {
62  if (_rebuild_map)
63  {
64  // reserve space for each quadrature point in the element
65  _elem_map.assign(_qrule->n_points(), 0);
66 
67  // store a random number for each quadrature point
68  unsigned int active_nuclei = 0;
69  for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp)
70  {
71  Real r = std::numeric_limits<Real>::max();
72 
73  // find the distance to the closest nucleus
74  Real local_radius = 0.0;
75  for (unsigned i = 0; i < _nucleus_list.size(); ++i)
76  {
77  // use a non-periodic or periodic distance
78  r = _periodic < 0
79  ? (_q_point[qp] - _nucleus_list[i].center).norm()
81 
82  // grab the radius of the nucleus that this qp is closest to
83  local_radius = _nucleus_list[i].radius;
84 
85  // compute intensity value with smooth interface
86  Real value = 0.0;
87  if (r <= local_radius - _int_width / 2.0) // Inside circle
88  {
89  active_nuclei++;
90  value = 1.0;
91  }
92  else if (r < local_radius + _int_width / 2.0) // Smooth interface
93  {
94  Real int_pos = (r - local_radius + _int_width / 2.0) / _int_width;
95  active_nuclei++;
96  value = (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0;
97  }
98  if (value > _elem_map[qp])
99  _elem_map[qp] = value;
100  }
101  }
102 
103  // if the map is not empty insert it
104  if (active_nuclei > 0)
105  _nucleus_map.insert(
106  std::pair<dof_id_type, std::vector<Real>>(_current_elem->id(), _elem_map));
107  }
108 }
109 
110 void
112 {
113  // if the map needs to be updated we merge the maps from all threads
114  if (_rebuild_map)
115  {
116  const auto & uo = static_cast<const DiscreteNucleationMap &>(y);
117  _nucleus_map.insert(uo._nucleus_map.begin(), uo._nucleus_map.end());
118  }
119 }
120 
121 void
123 {
124  _mesh_changed = true;
125 }
126 
127 const std::vector<Real> &
128 DiscreteNucleationMap::nuclei(const Elem * elem) const
129 {
130  NucleusMap::const_iterator i = _nucleus_map.find(elem->id());
131 
132  // if no entry in the map was found the element contains no nucleus
133  if (i == _nucleus_map.end())
134  return _zero_map;
135 
136  return i->second;
137 }
const DiscreteNucleationInserterBase & _inserter
UserObject that manages nucleus insertin and deletion.
static InputParameters validParams()
const MooseArray< Point > & _q_point
This UserObject maintains a per QP map that indicates if a nucleus is present or not.
bool _mesh_changed
Did the mesh change since the last execution of this PP?
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual void threadJoin(const UserObject &y)
static InputParameters validParams()
int _periodic
variable number to use for minPeriodicDistance calls (i.e. use the periodicity of this variable) ...
T & set(const std::string &name, bool quiet_mode=false)
const std::vector< double > y
const Real _int_width
Nucleus interface width.
void addRequiredParam(const std::string &name, const std::string &doc_string)
DiscreteNucleationMap(const InputParameters &parameters)
This UserObject manages the insertion and expiration of nuclei in the simulation domain it manages a ...
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const ExecFlagType EXEC_TIMESTEP_BEGIN
std::vector< Real > _zero_map
Dummy map for elements without nuclei.
auto norm(const T &a) -> decltype(std::abs(a))
Real minPeriodicDistance(unsigned int nonlinear_var_num, Point p, Point q) const
void addCoupledVar(const std::string &name, const std::string &doc_string)
registerMooseObject("PhaseFieldApp", DiscreteNucleationMap)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const QBase *const & _qrule
const Elem *const & _current_elem
std::vector< Real > _elem_map
Buffer for building the per QP map.
FEProblemBase & _fe_problem
void addClassDescription(const std::string &doc_string)
const std::vector< Real > & nuclei(const Elem *) const
MooseMesh & _mesh
bool _rebuild_map
Do we need to rebuild the map during this timestep?
const DiscreteNucleationInserterBase::NucleusList & _nucleus_list
list of nuclei maintained bu the inserter object
static const std::string center
Definition: NS.h:28
uint8_t dof_id_type
const Real pi
unsigned int getMaxQps() const