https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
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_var(isCoupled("periodic") ? getFieldVar("periodic", 0) : nullptr),
40 _int_width(getParam<Real>("int_width")),
41 _nucleus_list(_inserter.getNucleusList())
42{
43 _zero_map.assign(_fe_problem.getMaxQps(), 0.0);
44}
45
46void
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
70void
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
91 : (_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
121void
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
132void
137
138const std::vector<Real> &
139DiscreteNucleationMap::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}
registerMooseObject("PhaseFieldApp", DiscreteNucleationMap)
const std::vector< double > y
const ExecFlagType EXEC_TIMESTEP_BEGIN
Point center
This UserObject manages the insertion and expiration of nuclei in the simulation domain it manages a ...
This UserObject maintains a per QP map that indicates if a nucleus is present or not.
static InputParameters validParams()
bool _rebuild_map
Do we need to rebuild the map during this timestep?
const Real _int_width
Nucleus interface width.
DiscreteNucleationMap(const InputParameters &parameters)
bool _mesh_changed
Did the mesh change since the last execution of this PP?
std::vector< Real > _zero_map
Dummy map for elements without nuclei.
const DiscreteNucleationInserterBase & _inserter
UserObject that manages nucleus insertin and deletion.
bool _force_rebuild_map
If a timestep is repeated due to a failed solve, we don't want to rebuild the map.
const std::vector< Real > & nuclei(const Elem *) const
const MooseVariableFieldBase *const _periodic_var
variable to use for minPeriodicDistance calls (i.e. use the periodicity of this variable)
const DiscreteNucleationInserterBase::NucleusList & _nucleus_list
list of nuclei maintained bu the inserter object
std::vector< Real > _elem_map
Buffer for building the per QP map.
virtual void threadJoin(const UserObject &y)
static InputParameters validParams()
const QBase *const & _qrule
const Elem *const & _current_elem
MooseMesh & _mesh
const MooseArray< Point > & _q_point
virtual bool lastSolveConverged() const=0
unsigned int getMaxQps() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
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)
T & set(const std::string &name, bool quiet_mode=false)
void addCoupledVar(const std::string &name, const std::string &doc_string)
Executioner * getExecutioner() const
Real minPeriodicDistance(const unsigned int sys_num, const unsigned int var_num, const Point &p, const Point &q) const
FEProblemBase & _fe_problem
const Real pi