https://mooseframework.inl.gov
DiscreteNucleationMap.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 "DiscreteNucleationMap.h"
11 #include "MooseMesh.h"
12 #include "Executioner.h"
13 
14 #include "libmesh/quadrature.h"
15 
17 
20 {
22  params.addClassDescription("Generates a spatial smoothed map of all nucleation sites with the "
23  "data of the DiscreteNucleationInserter for use by the "
24  "DiscreteNucleation material.");
25  params.addParam<Real>("int_width", 0.0, "Nucleus interface width for smooth nuclei");
26  params.addRequiredParam<UserObjectName>("inserter", "DiscreteNucleationInserter user object");
27  params.addCoupledVar("periodic",
28  "Use the periodicity settings of this variable to populate the grain map");
29  // the mapping needs to run at timestep begin, which is after the adaptivity
30  // run of the previous timestep.
31  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
32  return params;
33 }
34 
36  : ElementUserObject(parameters),
37  _mesh_changed(false),
38  _inserter(getUserObject<DiscreteNucleationInserterBase>("inserter")),
39  _periodic(isCoupled("periodic") ? coupled("periodic") : -1),
40  _int_width(getParam<Real>("int_width")),
41  _nucleus_list(_inserter.getNucleusList())
42 {
43  _zero_map.assign(_fe_problem.getMaxQps(), 0.0);
44 }
45 
46 void
48 {
50  {
51  // If the last solve didn't converge, postpone the rebuild until the next timestep
53  {
54  _rebuild_map = true;
55  _nucleus_map.clear();
56  _force_rebuild_map = false;
57  }
58  else
59  {
60  _rebuild_map = false;
61  _force_rebuild_map = true;
62  }
63  }
64  else
65  _rebuild_map = false;
66 
67  _mesh_changed = false;
68 }
69 
70 void
72 {
73  if (_rebuild_map)
74  {
75  // reserve space for each quadrature point in the element
76  _elem_map.assign(_qrule->n_points(), 0);
77 
78  // store a random number for each quadrature point
79  unsigned int active_nuclei = 0;
80  for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp)
81  {
82  Real r = std::numeric_limits<Real>::max();
83 
84  // find the distance to the closest nucleus
85  Real local_radius = 0.0;
86  for (unsigned i = 0; i < _nucleus_list.size(); ++i)
87  {
88  // use a non-periodic or periodic distance
89  r = _periodic < 0
90  ? (_q_point[qp] - _nucleus_list[i].center).norm()
92 
93  // grab the radius of the nucleus that this qp is closest to
94  local_radius = _nucleus_list[i].radius;
95 
96  // compute intensity value with smooth interface
97  Real value = 0.0;
98  if (r <= local_radius - _int_width / 2.0) // Inside circle
99  {
100  active_nuclei++;
101  value = 1.0;
102  }
103  else if (r < local_radius + _int_width / 2.0) // Smooth interface
104  {
105  Real int_pos = (r - local_radius + _int_width / 2.0) / _int_width;
106  active_nuclei++;
107  value = (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0;
108  }
109  if (value > _elem_map[qp])
110  _elem_map[qp] = value;
111  }
112  }
113 
114  // if the map is not empty insert it
115  if (active_nuclei > 0)
116  _nucleus_map.insert(
117  std::pair<dof_id_type, std::vector<Real>>(_current_elem->id(), _elem_map));
118  }
119 }
120 
121 void
123 {
124  // if the map needs to be updated we merge the maps from all threads
125  if (_rebuild_map)
126  {
127  const auto & uo = static_cast<const DiscreteNucleationMap &>(y);
128  _nucleus_map.insert(uo._nucleus_map.begin(), uo._nucleus_map.end());
129  }
130 }
131 
132 void
134 {
135  _mesh_changed = true;
136 }
137 
138 const std::vector<Real> &
139 DiscreteNucleationMap::nuclei(const Elem * elem) const
140 {
141  NucleusMap::const_iterator i = _nucleus_map.find(elem->id());
142 
143  // if no entry in the map was found the element contains no nucleus
144  if (i == _nucleus_map.end())
145  return _zero_map;
146 
147  return i->second;
148 }
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) ...
bool _force_rebuild_map
If a timestep is repeated due to a failed solve, we don&#39;t want to rebuild the map.
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
Executioner * getExecutioner() 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
virtual bool lastSolveConverged() const=0
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