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 28 : SLKKSMultiPhaseConcentration::validParams() 16 : { 17 28 : auto params = SLKKSMultiPhaseBase::validParams(); 18 28 : 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 56 : params.addRequiredCoupledVar("c", "Physical concentration"); 22 28 : return params; 23 0 : } 24 : 25 : // Phase interpolation func 26 15 : SLKKSMultiPhaseConcentration::SLKKSMultiPhaseConcentration(const InputParameters & parameters) 27 15 : : SLKKSMultiPhaseBase(parameters), _l(-1), _prop_h(_nh), _prop_dhdeta(_nh) 28 : { 29 : // Fetch switching functions and their derivatives 30 45 : for (std::size_t i = 0; i < _nh; ++i) 31 : { 32 30 : _prop_h[i] = &getMaterialPropertyByName<Real>(_h_names[i]); 33 30 : _prop_dhdeta[i].resize(_neta); 34 : 35 : // Get derivatives of switching functions w.r.t. order parameters 36 90 : for (std::size_t j = 0; j < _neta; ++j) 37 60 : _prop_dhdeta[i][j] = &getMaterialPropertyDerivativeByName<Real>(_h_names[i], _eta_names[j]); 38 : } 39 : 40 : // Determine position of the nonlinear variable 41 75 : for (std::size_t i = 0; i < _ncs; ++i) 42 60 : if (coupled("cs", i) == _var.number()) 43 15 : _l = i; 44 : 45 : // Check to make sure the nonlinear variable is in the cs list 46 15 : if (_l < 0) 47 0 : paramError("cs", "One of the listed variables must be the kernel variable"); 48 15 : } 49 : 50 : Real 51 35160 : SLKKSMultiPhaseConcentration::precomputeQpResidual() 52 : { 53 : // sum over phases 54 : std::size_t k = 0; 55 : Real sum = 0.0; 56 105480 : for (std::size_t i = 0; i < _nh; ++i) 57 : { 58 : // sum sublattice concentrations 59 : Real csum = 0.0; 60 210960 : for (unsigned int j = 0; j < _ns[i]; ++j) 61 : { 62 140640 : csum += (*_cs[k])[_qp] * _a_cs[k]; 63 140640 : k++; 64 : } 65 70320 : sum += (*_prop_h[i])[_qp] * csum; 66 : } 67 35160 : return sum - _c[_qp]; 68 : } 69 : 70 : Real 71 58200 : SLKKSMultiPhaseConcentration::precomputeQpJacobian() 72 : { 73 58200 : return (*_prop_h[_phase[_l]])[_qp] * _phi[_j][_qp] * _a_cs[_l]; 74 : } 75 : 76 : Real 77 698400 : SLKKSMultiPhaseConcentration::computeQpOffDiagJacobian(unsigned int jvar) 78 : { 79 698400 : if (jvar == _c_var) 80 116400 : return -_test[_i][_qp] * _phi[_j][_qp]; 81 : 82 582000 : auto csvar = mapJvarToCvar(jvar, _cs_map); 83 582000 : if (csvar >= 0) 84 349200 : return _test[_i][_qp] * (*_prop_h[_phase[csvar]])[_qp] * _phi[_j][_qp] * _a_cs[csvar]; 85 : 86 232800 : auto etavar = mapJvarToCvar(jvar, _eta_map); 87 232800 : if (etavar >= 0) 88 : { 89 : Real sum = 0.0; 90 1164000 : for (unsigned int i = 0; i < _ncs; ++i) 91 931200 : sum += (*_prop_dhdeta[_phase[i]][etavar])[_qp] * (*_cs[i])[_qp] * _a_cs[i]; 92 : 93 232800 : return _test[_i][_qp] * sum * _phi[_j][_qp]; 94 : } 95 : 96 : return 0.0; 97 : }