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 "NonlocalKernel.h" 11 : #include "Assembly.h" 12 : #include "MooseVariableFE.h" 13 : #include "Problem.h" 14 : #include "SubProblem.h" 15 : #include "SystemBase.h" 16 : #include "MooseMesh.h" 17 : 18 : #include "libmesh/threads.h" 19 : #include "libmesh/quadrature.h" 20 : 21 : InputParameters 22 42879 : NonlocalKernel::validParams() 23 : { 24 42879 : InputParameters params = Kernel::validParams(); 25 42879 : return params; 26 : } 27 : 28 45 : NonlocalKernel::NonlocalKernel(const InputParameters & parameters) : Kernel(parameters) 29 : { 30 45 : _mesh.errorIfDistributedMesh("NonlocalKernel"); 31 45 : mooseWarning("NonlocalKernel is a computationally expensive experimental capability used only " 32 : "for integral terms."); 33 45 : } 34 : 35 : void 36 252 : NonlocalKernel::computeJacobian() 37 : { 38 252 : prepareMatrixTag(_assembly, _var.number(), _var.number()); 39 252 : precalculateJacobian(); 40 1428 : for (_j = 0; _j < _phi.size(); 41 1176 : _j++) // looping order for _i & _j are reversed for performance improvement 42 : { 43 1176 : getUserObjectJacobian(_var.number(), _var.dofIndices()[_j]); 44 8904 : for (_i = 0; _i < _test.size(); _i++) 45 66192 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 46 58464 : _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpJacobian(); 47 : } 48 252 : accumulateTaggedLocalMatrix(); 49 : 50 252 : if (_has_diag_save_in) 51 : { 52 0 : unsigned int rows = _local_ke.m(); 53 0 : DenseVector<Number> diag(rows); 54 0 : for (unsigned int i = 0; i < rows; i++) 55 0 : diag(i) = _local_ke(i, i); 56 : 57 0 : for (const auto & var : _diag_save_in) 58 0 : var->sys().solution().add_vector(diag, var->dofIndices()); 59 0 : } 60 252 : } 61 : 62 : void 63 388 : NonlocalKernel::computeOffDiagJacobian(const unsigned int jvar_num) 64 : { 65 388 : if (jvar_num == _var.number()) 66 236 : computeJacobian(); 67 : else 68 : { 69 152 : const auto & jvar = getVariable(jvar_num); 70 : 71 152 : prepareMatrixTag(_assembly, _var.number(), jvar_num); 72 : 73 : // This (undisplaced) jvar could potentially yield the wrong phi size if this object is acting 74 : // on the displaced mesh 75 152 : const auto phi_size = jvar.dofIndices().size(); 76 : 77 152 : precalculateOffDiagJacobian(jvar_num); 78 456 : for (_j = 0; _j < phi_size; 79 304 : _j++) // looping order for _i & _j are reversed for performance improvement 80 : { 81 304 : getUserObjectJacobian(jvar_num, jvar.dofIndices()[_j]); 82 912 : for (_i = 0; _i < _test.size(); _i++) 83 1824 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 84 1216 : _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobian(jvar_num); 85 : } 86 152 : accumulateTaggedLocalMatrix(); 87 : } 88 388 : } 89 : 90 : void 91 208 : NonlocalKernel::computeNonlocalJacobian() 92 : { 93 208 : prepareMatrixTagNonlocal(_assembly, _var.number(), _var.number()); 94 : // compiling set of global IDs for the local DOFs on the element 95 208 : std::set<dof_id_type> local_dofindices(_var.dofIndices().begin(), _var.dofIndices().end()); 96 : // storing the global IDs for all the DOFs of the variable 97 208 : const std::vector<dof_id_type> & var_alldofindices = _var.allDofIndices(); 98 208 : unsigned int n_total_dofs = var_alldofindices.size(); 99 : 100 208 : precalculateJacobian(); 101 3520 : for (_k = 0; _k < n_total_dofs; 102 3312 : _k++) // looping order for _i & _k are reversed for performance improvement 103 : { 104 : // eliminating the local components 105 3312 : auto it = local_dofindices.find(var_alldofindices[_k]); 106 3312 : if (it == local_dofindices.end()) 107 : { 108 2224 : getUserObjectJacobian(_var.number(), var_alldofindices[_k]); 109 : // skip global DOFs that do not contribute to the jacobian 110 2224 : if (!globalDoFEnabled(_var, var_alldofindices[_k])) 111 0 : continue; 112 : 113 19440 : for (_i = 0; _i < _test.size(); _i++) 114 153792 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 115 136576 : _nonlocal_ke(_i, _k) += 116 136576 : _JxW[_qp] * _coord[_qp] * computeQpNonlocalJacobian(var_alldofindices[_k]); 117 : } 118 : } 119 208 : accumulateTaggedNonlocalMatrix(); 120 208 : } 121 : 122 : void 123 360 : NonlocalKernel::computeNonlocalOffDiagJacobian(unsigned int jvar) 124 : { 125 360 : if (jvar == _var.number()) 126 208 : computeNonlocalJacobian(); 127 : else 128 : { 129 152 : MooseVariableFEBase & jv = _sys.getVariable(_tid, jvar); 130 152 : prepareMatrixTagNonlocal(_assembly, _var.number(), jvar); 131 : // compiling set of global IDs for the local DOFs on the element 132 152 : std::set<dof_id_type> local_dofindices(jv.dofIndices().begin(), jv.dofIndices().end()); 133 : // storing the global IDs for all the DOFs of the variable 134 152 : const std::vector<dof_id_type> & jv_alldofindices = jv.allDofIndices(); 135 152 : unsigned int n_total_dofs = jv_alldofindices.size(); 136 : 137 152 : precalculateOffDiagJacobian(jvar); 138 608 : for (_k = 0; _k < n_total_dofs; 139 456 : _k++) // looping order for _i & _k are reversed for performance improvement 140 : { 141 : // eliminating the local components 142 456 : auto it = local_dofindices.find(jv_alldofindices[_k]); 143 456 : if (it == local_dofindices.end()) 144 : { 145 152 : getUserObjectJacobian(jvar, jv_alldofindices[_k]); 146 : // skip global DOFs that do not contribute to the jacobian 147 152 : if (!globalDoFEnabled(jv, jv_alldofindices[_k])) 148 0 : continue; 149 : 150 456 : for (_i = 0; _i < _test.size(); _i++) 151 912 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 152 1216 : _nonlocal_ke(_i, _k) += _JxW[_qp] * _coord[_qp] * 153 608 : computeQpNonlocalOffDiagJacobian(jvar, jv_alldofindices[_k]); 154 : } 155 : } 156 152 : accumulateTaggedNonlocalMatrix(); 157 152 : } 158 360 : }