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 "SLKKSMultiPhaseConcentration.h" 11 : 12 : registerMooseObject("PhaseFieldApp", SLKKSMultiPhaseConcentration); 13 : 14 : InputParameters 15 40 : SLKKSMultiPhaseConcentration::validParams() 16 : { 17 40 : auto params = SLKKSMultiPhaseBase::validParams(); 18 40 : params.addClassDescription( 19 : "SLKKS multi-phase model kernel to enforce $c_i = \\sum_j h_j\\sum_k a_{jk} c_{ijk}$. " 20 : "The non-linear variable of this kernel is a phase's sublattice concentration"); 21 80 : params.addRequiredCoupledVar("c", "Physical concentration"); 22 40 : return params; 23 0 : } 24 : 25 : // Phase interpolation func 26 21 : SLKKSMultiPhaseConcentration::SLKKSMultiPhaseConcentration(const InputParameters & parameters) 27 21 : : SLKKSMultiPhaseBase(parameters), _l(-1), _prop_h(_nh), _prop_dhdeta(_nh) 28 : { 29 : // Fetch switching functions and their derivatives 30 63 : for (std::size_t i = 0; i < _nh; ++i) 31 : { 32 42 : _prop_h[i] = &getMaterialPropertyByName<Real>(_h_names[i]); 33 42 : _prop_dhdeta[i].resize(_neta); 34 : 35 : // Get derivatives of switching functions w.r.t. order parameters 36 126 : for (std::size_t j = 0; j < _neta; ++j) 37 84 : _prop_dhdeta[i][j] = &getMaterialPropertyDerivativeByName<Real>(_h_names[i], _eta_names[j]); 38 : } 39 : 40 : // Determine position of the nonlinear variable 41 105 : for (std::size_t i = 0; i < _ncs; ++i) 42 84 : if (coupled("cs", i) == _var.number()) 43 21 : _l = i; 44 : 45 : // Check to make sure the nonlinear variable is in the cs list 46 21 : if (_l < 0) 47 0 : paramError("cs", "One of the listed variables must be the kernel variable"); 48 21 : } 49 : 50 : Real 51 42180 : SLKKSMultiPhaseConcentration::precomputeQpResidual() 52 : { 53 : // sum over phases 54 : std::size_t k = 0; 55 : Real sum = 0.0; 56 126540 : for (std::size_t i = 0; i < _nh; ++i) 57 : { 58 : // sum sublattice concentrations 59 : Real csum = 0.0; 60 253080 : for (unsigned int j = 0; j < _ns[i]; ++j) 61 : { 62 168720 : csum += (*_cs[k])[_qp] * _a_cs[k]; 63 168720 : k++; 64 : } 65 84360 : sum += (*_prop_h[i])[_qp] * csum; 66 : } 67 42180 : return sum - _c[_qp]; 68 : } 69 : 70 : Real 71 69840 : SLKKSMultiPhaseConcentration::precomputeQpJacobian() 72 : { 73 69840 : return (*_prop_h[_phase[_l]])[_qp] * _phi[_j][_qp] * _a_cs[_l]; 74 : } 75 : 76 : Real 77 838080 : SLKKSMultiPhaseConcentration::computeQpOffDiagJacobian(unsigned int jvar) 78 : { 79 838080 : if (jvar == _c_var) 80 139680 : return -_test[_i][_qp] * _phi[_j][_qp]; 81 : 82 698400 : auto csvar = mapJvarToCvar(jvar, _cs_map); 83 698400 : if (csvar >= 0) 84 419040 : return _test[_i][_qp] * (*_prop_h[_phase[csvar]])[_qp] * _phi[_j][_qp] * _a_cs[csvar]; 85 : 86 279360 : auto etavar = mapJvarToCvar(jvar, _eta_map); 87 279360 : if (etavar >= 0) 88 : { 89 : Real sum = 0.0; 90 1396800 : for (unsigned int i = 0; i < _ncs; ++i) 91 1117440 : sum += (*_prop_dhdeta[_phase[i]][etavar])[_qp] * (*_cs[i])[_qp] * _a_cs[i]; 92 : 93 279360 : return _test[_i][_qp] * sum * _phi[_j][_qp]; 94 : } 95 : 96 : return 0.0; 97 : }