Line data Source code
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" 11 : #include "DiscreteNucleationMap.h" 12 : 13 : #include "libmesh/quadrature.h" 14 : 15 : registerMooseObject("PhaseFieldApp", DiscreteNucleation); 16 : 17 : InputParameters 18 403 : DiscreteNucleation::validParams() 19 : { 20 403 : InputParameters params = DerivativeFunctionMaterialBase::validParams(); 21 403 : params.addClassDescription("Free energy contribution for nucleating discrete particles"); 22 806 : params.addRequiredCoupledVar("op_names", 23 : "List of variables to force to a target concentration value"); 24 806 : params.addRequiredParam<UserObjectName>("map", "DiscreteNucleationMap user object"); 25 806 : params.addRequiredParam<std::vector<Real>>("op_values", "List of target concentration values"); 26 806 : params.addParam<Real>("penalty", 20.0, "Penalty factor for enforcing the target concentrations"); 27 806 : MooseEnum penalty_mode("MATCH MIN MAX", "MATCH"); 28 806 : 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 403 : return params; 33 403 : } 34 : 35 312 : DiscreteNucleation::DiscreteNucleation(const InputParameters & params) 36 : : DerivativeFunctionMaterialBase(params), 37 312 : _nvar(coupledComponents("op_names")), 38 312 : _op_index(_nvar), 39 624 : _op_values(getParam<std::vector<Real>>("op_values")), 40 624 : _penalty(getParam<Real>("penalty")), 41 624 : _penalty_mode(getParam<MooseEnum>("penalty_mode")), 42 624 : _map(getUserObject<DiscreteNucleationMap>("map")) 43 : { 44 : // check inputs 45 312 : if (_nvar != _op_values.size()) 46 0 : mooseError("The op_names and op_values parameter vectors must have the same number of entries"); 47 312 : if (_nvar != _args.size()) 48 0 : mooseError("Internal error."); 49 : 50 : // get libMesh variable numbers 51 624 : for (unsigned int i = 0; i < _nvar; ++i) 52 624 : _op_index[i] = argIndex(coupled("op_names", i)); 53 312 : } 54 : 55 : void 56 922468 : DiscreteNucleation::computeProperties() 57 : { 58 : // check if a nucleation event list is available for the current element 59 922468 : const std::vector<Real> & nucleus = _map.nuclei(_current_elem); 60 : 61 : // calculate penalty 62 4612340 : for (_qp = 0; _qp < _qrule->n_points(); ++_qp) 63 : { 64 : // clear penalty value 65 3689872 : if (_prop_F) 66 3689872 : (*_prop_F)[_qp] = 0.0; 67 : 68 7379744 : for (unsigned int i = 0; i < _nvar; ++i) 69 : { 70 3689872 : const unsigned ii = _op_index[i]; 71 : 72 : // modify the penalty magnitude with the nucleus mask 73 3689872 : const Real penalty = _penalty * nucleus[_qp]; 74 : 75 : // deviation from the target concentration 76 3689872 : Real dc = (*_args[ii])[_qp] - _op_values[i]; 77 : 78 : // ignore above/below target values for min/max modes respectively 79 3689872 : if ((_penalty_mode == 1 && dc > 0.0) || (_penalty_mode == 2 && dc < 0.0)) 80 : dc = 0.0; 81 : 82 : // build free energy correction 83 3689872 : if (_prop_F) 84 3689872 : (*_prop_F)[_qp] += dc * dc * penalty; 85 : 86 : // first derivative 87 3689872 : if (_prop_dF[ii]) 88 49872 : (*_prop_dF[ii])[_qp] = 2.0 * dc * penalty; 89 : 90 : // second derivatives 91 7379744 : for (unsigned int jj = ii; jj < _nvar; ++jj) 92 : { 93 3689872 : if (_prop_d2F[ii][jj]) 94 49872 : (*_prop_d2F[ii][jj])[_qp] = 2.0 * penalty; 95 : 96 : // third derivatives 97 3689872 : if (_third_derivatives) 98 99744 : for (unsigned int kk = jj; kk < _nvar; ++kk) 99 49872 : if (_prop_d3F[ii][jj][kk]) 100 49872 : (*_prop_d3F[ii][jj][kk])[_qp] = 0.0; 101 : } 102 : } 103 : } 104 922468 : }