www.mooseframework.org
DiscreteNucleation.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 "DiscreteNucleation.h"
11 #include "DiscreteNucleationMap.h"
12 
13 #include "libmesh/quadrature.h"
14 
15 registerMooseObject("PhaseFieldApp", DiscreteNucleation);
16 
19 {
21  params.addClassDescription("Free energy contribution for nucleating discrete particles");
22  params.addRequiredCoupledVar("op_names",
23  "List of variables to force to a target concentration value");
24  params.addRequiredParam<UserObjectName>("map", "DiscreteNucleationMap user object");
25  params.addRequiredParam<std::vector<Real>>("op_values", "List of target concentration values");
26  params.addParam<Real>("penalty", 20.0, "Penalty factor for enforcing the target concentrations");
27  MooseEnum penalty_mode("MATCH MIN MAX", "MATCH");
28  params.addParam<MooseEnum>(
29  "penalty_mode",
30  penalty_mode,
31  "Match the target concentration or take it as a minimum or maximum concentration target");
32  return params;
33 }
34 
37  _nvar(coupledComponents("op_names")),
38  _op_index(_nvar),
39  _op_values(getParam<std::vector<Real>>("op_values")),
40  _penalty(getParam<Real>("penalty")),
41  _penalty_mode(getParam<MooseEnum>("penalty_mode")),
42  _map(getUserObject<DiscreteNucleationMap>("map"))
43 {
44  // check inputs
45  if (_nvar != _op_values.size())
46  mooseError("The op_names and op_values parameter vectors must have the same number of entries");
47  if (_nvar != _args.size())
48  mooseError("Internal error.");
49 
50  // get libMesh variable numbers
51  for (unsigned int i = 0; i < _nvar; ++i)
52  _op_index[i] = argIndex(coupled("op_names", i));
53 }
54 
55 void
57 {
58  // check if a nucleation event list is available for the current element
59  const std::vector<Real> & nucleus = _map.nuclei(_current_elem);
60 
61  // calculate penalty
62  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
63  {
64  // clear penalty value
65  if (_prop_F)
66  (*_prop_F)[_qp] = 0.0;
67 
68  for (unsigned int i = 0; i < _nvar; ++i)
69  {
70  const unsigned ii = _op_index[i];
71 
72  // modify the penalty magnitude with the nucleus mask
73  const Real penalty = _penalty * nucleus[_qp];
74 
75  // deviation from the target concentration
76  Real dc = (*_args[ii])[_qp] - _op_values[i];
77 
78  // ignore above/below target values for min/max modes respectively
79  if ((_penalty_mode == 1 && dc > 0.0) || (_penalty_mode == 2 && dc < 0.0))
80  dc = 0.0;
81 
82  // build free energy correction
83  if (_prop_F)
84  (*_prop_F)[_qp] += dc * dc * penalty;
85 
86  // first derivative
87  if (_prop_dF[ii])
88  (*_prop_dF[ii])[_qp] = 2.0 * dc * penalty;
89 
90  // second derivatives
91  for (unsigned int jj = ii; jj < _nvar; ++jj)
92  {
93  if (_prop_d2F[ii][jj])
94  (*_prop_d2F[ii][jj])[_qp] = 2.0 * penalty;
95 
96  // third derivatives
98  for (unsigned int kk = jj; kk < _nvar; ++kk)
99  if (_prop_d3F[ii][jj][kk])
100  (*_prop_d3F[ii][jj][kk])[_qp] = 0.0;
101  }
102  }
103  }
104 }
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
This UserObject maintains a per QP map that indicates if a nucleus is present or not.
virtual void computeProperties()
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::vector< std::vector< GenericMaterialProperty< Real, is_ad > *> > _prop_d2F
static InputParameters validParams()
const unsigned int _penalty_mode
Match concentration exactly or use the target as a minumum or maximum value.
const Real _penalty
Nucleation free energy prefactor.
DiscreteNucleation(const InputParameters &params)
unsigned int argIndex(unsigned int i_var) const
registerMooseObject("PhaseFieldApp", DiscreteNucleation)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
Free energy penalty contribution to force the nucleation of subresolution particles.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
GenericMaterialProperty< Real, is_ad > * _prop_F
void mooseError(Args &&... args) const
const DiscreteNucleationMap & _map
UserObject providing a map of currently active nuclei.
void addClassDescription(const std::string &doc_string)
std::vector< std::vector< std::vector< GenericMaterialProperty< Real, is_ad > *> > > _prop_d3F
const std::vector< Real > & nuclei(const Elem *) const
std::vector< unsigned int > _op_index
map op_names indices to _args indices
std::vector< const GenericVariableValue< is_ad > *> _args
std::vector< GenericMaterialProperty< Real, is_ad > *> _prop_dF
static InputParameters validParams()
const std::vector< Real > _op_values
Target concentration values.