https://mooseframework.inl.gov
Loading...
Searching...
No Matches
DiscreteNucleation.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 "DiscreteNucleation.h"
12
13#include "libmesh/quadrature.h"
14
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
55void
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}
registerMooseObject("PhaseFieldApp", DiscreteNucleation)
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
std::vector< std::vector< std::vector< GenericMaterialProperty< Real, is_ad > * > > > _prop_d3F
static InputParameters validParams()
std::vector< std::vector< GenericMaterialProperty< Real, is_ad > * > > _prop_d2F
std::vector< GenericMaterialProperty< Real, is_ad > * > _prop_dF
This UserObject maintains a per QP map that indicates if a nucleus is present or not.
const std::vector< Real > & nuclei(const Elem *) const
Free energy penalty contribution to force the nucleation of subresolution particles.
const DiscreteNucleationMap & _map
UserObject providing a map of currently active nuclei.
const std::vector< Real > _op_values
Target concentration values.
virtual void computeProperties()
static InputParameters validParams()
const Real _penalty
Nucleation free energy prefactor.
const unsigned int _penalty_mode
Match concentration exactly or use the target as a minumum or maximum value.
std::vector< unsigned int > _op_index
map op_names indices to _args indices
DiscreteNucleation(const InputParameters &params)
std::vector< const GenericVariableValue< is_ad > * > _args
unsigned int argIndex(unsigned int i_var) const
GenericMaterialProperty< Real, is_ad > * _prop_F
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
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)
void mooseError(Args &&... args) const