Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 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 : #pragma once 11 : 12 : #include "KokkosKernel.h" 13 : 14 : namespace Moose::Kokkos 15 : { 16 : 17 : /** 18 : * The base class for a user to derive their own Kokkos kernels where the residual is of the form 19 : * 20 : * $(\dots, \nabla\psi_i)$ 21 : * 22 : * i.e. the gradient of the test function $(\nabla\psi_i)$ can be factored out for optimization. 23 : * 24 : * The user should now define precomputeQpResidual(), precomputeQpJacobian(), and 25 : * precomputeQpOffDiagJacobian() which do not include the gradient of the test function, instead of 26 : * the original hooks. The signature of precomputeQpResidual() expected to be defined in the derived 27 : * class is as follows: 28 : * 29 : * @tparam Derived The object type 30 : * @param qp The local quadrature point index 31 : * @param datum The AssemblyDatum object of the current thread 32 : * @returns The vector component of the residual contribution that will be multiplied by the 33 : * gradient of the test function 34 : * 35 : * template <typename Derived> 36 : * KOKKOS_FUNCTION Real3 precomputeQpResidual(const unsigned int qp, 37 : * AssemblyDatum & datum) const; 38 : * 39 : * The signature of precomputeQpJacobian() and precomputeQpOffDiagJacobian() can be found in the 40 : * code below. 41 : */ 42 : class KernelGrad : public Kernel 43 : { 44 : public: 45 : static InputParameters validParams(); 46 : 47 : /// KernelGrad hooks factor out the test-function gradient 48 : static constexpr bool use_precompute_hooks = true; 49 : 50 : /** 51 : * Constructor 52 : */ 53 : KernelGrad(const InputParameters & parameters); 54 : 55 : /** 56 : * Default methods to prevent compile errors even when these methods were not defined in the 57 : * derived class 58 : */ 59 : ///@{ 60 : /** 61 : * Compute diagonal Jacobian contribution on a quadrature point 62 : * @tparam Derived The object type 63 : * @param j The trial function DOF index 64 : * @param qp The local quadrature point index 65 : * @param datum The AssemblyDatum object of the current thread 66 : * @returns The vector component of the Jacobian contribution that will be multiplied by the 67 : * gradient of the test function 68 : */ 69 : template <typename Derived> 70 0 : KOKKOS_FUNCTION Real3 precomputeQpJacobian(const unsigned int /* j */, 71 : const unsigned int /* qp */, 72 : AssemblyDatum & /* datum */) const 73 : { 74 0 : ::Kokkos::abort("Default precomputeQpJacobian() should never be called. Make sure you properly " 75 : "redefined this method in your class without typos."); 76 : 77 : return Real3(0); 78 : } 79 : /** 80 : * Compute off-diagonal Jacobian contribution on a quadrature point 81 : * @tparam Derived The object type 82 : * @param j The trial function DOF index 83 : * @param jvar The variable number for column 84 : * @param qp The local quadrature point index 85 : * @param datum The AssemblyDatum object of the current thread 86 : * @returns The vector component of the off-diagonal Jacobian contribution that will be multiplied 87 : * by the gradient of the test function 88 : */ 89 : template <typename Derived> 90 0 : KOKKOS_FUNCTION Real3 precomputeQpOffDiagJacobian(const unsigned int /* j */, 91 : const unsigned int /* jvar */, 92 : const unsigned int /* qp */, 93 : AssemblyDatum & /* datum */) const 94 : { 95 0 : ::Kokkos::abort( 96 : "Default precomputeQpOffDiagJacobian() should never be called. Make sure you properly " 97 : "redefined this method in your class without typos."); 98 : 99 : return Real3(0); 100 : } 101 : ///@} 102 : 103 : /** 104 : * Functions used to check if users have overriden the hook methods, whose calculations can be 105 : * skipped when not overriden 106 : * @returns The function pointer of the default hook method 107 : */ 108 : ///@{ 109 : template <typename Derived> 110 41399 : static auto defaultJacobian() 111 : { 112 41399 : return &KernelGrad::precomputeQpJacobian<Derived>; 113 : } 114 : template <typename Derived> 115 41399 : static auto defaultOffDiagJacobian() 116 : { 117 41399 : return &KernelGrad::precomputeQpOffDiagJacobian<Derived>; 118 : } 119 : ///@} 120 : 121 : /** 122 : * The parallel computation bodies that hide the base class methods to optimize for factoring 123 : * out the gradient of test function 124 : */ 125 : ///@{ 126 : template <typename Derived> 127 : KOKKOS_FUNCTION void computeResidualInternal(const Derived & kernel, AssemblyDatum & datum) const; 128 : template <typename Derived> 129 : KOKKOS_FUNCTION void computeJacobianInternal(const Derived & kernel, AssemblyDatum & datum) const; 130 : template <typename Derived> 131 : KOKKOS_FUNCTION void computeOffDiagJacobianInternal(const Derived & kernel, 132 : AssemblyDatum & datum) const; 133 : ///@} 134 : }; 135 : 136 : template <typename Derived> 137 : KOKKOS_FUNCTION void 138 96 : KernelGrad::computeResidualInternal(const Derived & kernel, AssemblyDatum & datum) const 139 : { 140 96 : ResidualObject::computeResidualInternal( 141 : datum, 142 96 : [&](Real * local_re, const unsigned int ib, const unsigned int ie) 143 : { 144 480 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 145 : { 146 384 : Real3 value = datum.J(qp).transpose() * 147 : (datum.JxW(qp) * kernel.template precomputeQpResidual<Derived>(qp, datum)); 148 : 149 1920 : for (unsigned int i = ib; i < ie; ++i) 150 1536 : local_re[i] += value * _grad_test.reference(datum, i, qp); 151 : } 152 : }); 153 96 : } 154 : 155 : template <typename Derived> 156 : KOKKOS_FUNCTION void 157 24 : KernelGrad::computeJacobianInternal(const Derived & kernel, AssemblyDatum & datum) const 158 : { 159 24 : ResidualObject::computeJacobianInternal( 160 : datum, 161 96 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j) 162 : { 163 480 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 164 : { 165 : Real3 value = 166 384 : datum.J(qp).transpose() * 167 : (datum.JxW(qp) * kernel.template precomputeQpJacobian<Derived>(j, qp, datum)); 168 : 169 1920 : for (unsigned int i = ib; i < ie; ++i) 170 1536 : local_ke[i] += value * _grad_test.reference(datum, i, qp); 171 : } 172 : }); 173 24 : } 174 : 175 : template <typename Derived> 176 : KOKKOS_FUNCTION void 177 0 : KernelGrad::computeOffDiagJacobianInternal(const Derived & kernel, AssemblyDatum & datum) const 178 : { 179 0 : ResidualObject::computeJacobianInternal( 180 : datum, 181 0 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j) 182 : { 183 0 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 184 : { 185 0 : Real3 value = datum.J(qp).transpose() * 186 : (datum.JxW(qp) * kernel.template precomputeQpOffDiagJacobian<Derived>( 187 : j, datum.jvar(), qp, datum)); 188 : 189 0 : for (unsigned int i = ib; i < ie; ++i) 190 0 : local_ke[i] += value * _grad_test.reference(datum, i, qp); 191 : } 192 : }); 193 0 : } 194 : 195 : } // namespace Moose::Kokkos