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 still define computeQpResidual(), computeQpJacobian(), and 25 : * computeQpOffDiagJacobian(), but their signatures are different from the base class. The signature 26 : * of computeQpResidual() expected to be defined in the derived class is as follows: 27 : * 28 : * @tparam Derived The object type 29 : * @param qp The local quadrature point index 30 : * @param datum The AssemblyDatum object of the current thread 31 : * @returns The vector component of the residual contribution that will be multiplied by the 32 : * gradient of the test function 33 : * 34 : * template <typename Derived> 35 : * KOKKOS_FUNCTION Real3 computeQpResidual(const unsigned int qp, 36 : * AssemblyDatum & datum) const; 37 : * 38 : * The signature of computeQpJacobian() and computeQpOffDiagJacobian() can be found in the code 39 : * below. 40 : */ 41 : class KernelGrad : public Kernel 42 : { 43 : public: 44 : static InputParameters validParams(); 45 : 46 : /** 47 : * Constructor 48 : */ 49 : KernelGrad(const InputParameters & parameters); 50 : 51 : /** 52 : * Default methods to prevent compile errors even when these methods were not defined in the 53 : * derived class 54 : */ 55 : ///@{ 56 : /** 57 : * Compute diagonal Jacobian contribution on a quadrature point 58 : * @tparam Derived The object type 59 : * @param j The trial function DOF index 60 : * @param qp The local quadrature point index 61 : * @param datum The AssemblyDatum object of the current thread 62 : * @returns The vector component of the Jacobian contribution that will be multiplied by the 63 : * gradient of the test function 64 : */ 65 : template <typename Derived> 66 0 : KOKKOS_FUNCTION Real3 computeQpJacobian(const unsigned int /* j */, 67 : const unsigned int /* qp */, 68 : AssemblyDatum & /* datum */) const 69 : { 70 0 : ::Kokkos::abort("Default computeQpJacobian() should never be called. Make sure you properly " 71 : "redefined this method in your class without typos."); 72 : 73 : return Real3(0); 74 : } 75 : /** 76 : * Compute off-diagonal Jacobian contribution on a quadrature point 77 : * @tparam Derived The object type 78 : * @param j The trial function DOF index 79 : * @param jvar The variable number for column 80 : * @param qp The local quadrature point index 81 : * @param datum The AssemblyDatum object of the current thread 82 : * @returns The vector component of the off-diagonal Jacobian contribution that will be multiplied 83 : * by the gradient of the test function 84 : */ 85 : template <typename Derived> 86 0 : KOKKOS_FUNCTION Real3 computeQpOffDiagJacobian(const unsigned int /* j */, 87 : const unsigned int /* jvar */, 88 : const unsigned int /* qp */, 89 : AssemblyDatum & /* datum */) const 90 : { 91 0 : ::Kokkos::abort( 92 : "Default computeQpOffDiagJacobian() should never be called. Make sure you properly " 93 : "redefined this method in your class without typos."); 94 : 95 : return Real3(0); 96 : } 97 : ///@} 98 : 99 : /** 100 : * Functions used to check if users have overriden the hook methods, whose calculations can be 101 : * skipped when not overriden 102 : * @returns The function pointer of the default hook method 103 : */ 104 : ///@{ 105 : template <typename Derived> 106 40330 : static auto defaultJacobian() 107 : { 108 40330 : return &KernelGrad::computeQpJacobian<Derived>; 109 : } 110 : template <typename Derived> 111 40330 : static auto defaultOffDiagJacobian() 112 : { 113 40330 : return &KernelGrad::computeQpOffDiagJacobian<Derived>; 114 : } 115 : ///@} 116 : 117 : /** 118 : * The parallel computation bodies that hide the base class methods to optimize for factoring 119 : * out the gradient of test function 120 : */ 121 : ///@{ 122 : template <typename Derived> 123 : KOKKOS_FUNCTION void computeResidualInternal(const Derived & kernel, AssemblyDatum & datum) const; 124 : template <typename Derived> 125 : KOKKOS_FUNCTION void computeJacobianInternal(const Derived & kernel, AssemblyDatum & datum) const; 126 : template <typename Derived> 127 : KOKKOS_FUNCTION void computeOffDiagJacobianInternal(const Derived & kernel, 128 : AssemblyDatum & datum) const; 129 : ///@} 130 : }; 131 : 132 : template <typename Derived> 133 : KOKKOS_FUNCTION void 134 384 : KernelGrad::computeResidualInternal(const Derived & kernel, AssemblyDatum & datum) const 135 : { 136 384 : ResidualObject::computeResidualInternal( 137 : datum, 138 384 : [&](Real * local_re, const unsigned int ib, const unsigned int ie) 139 : { 140 1920 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 141 : { 142 1536 : Real3 value = datum.JxW(qp) * kernel.template computeQpResidual<Derived>(qp, datum); 143 : 144 3072 : for (unsigned int i = ib; i < ie; ++i) 145 1536 : local_re[i] += value * _grad_test(datum, i, qp); 146 : } 147 : }); 148 384 : } 149 : 150 : template <typename Derived> 151 : KOKKOS_FUNCTION void 152 96 : KernelGrad::computeJacobianInternal(const Derived & kernel, AssemblyDatum & datum) const 153 : { 154 96 : ResidualObject::computeJacobianInternal( 155 : datum, 156 96 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j) 157 : { 158 480 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 159 : { 160 384 : Real3 value = datum.JxW(qp) * kernel.template computeQpJacobian<Derived>(j, qp, datum); 161 : 162 1920 : for (unsigned int i = ib; i < ie; ++i) 163 1536 : local_ke[i] += value * _grad_test(datum, i, qp); 164 : } 165 : }); 166 96 : } 167 : 168 : template <typename Derived> 169 : KOKKOS_FUNCTION void 170 0 : KernelGrad::computeOffDiagJacobianInternal(const Derived & kernel, AssemblyDatum & datum) const 171 : { 172 0 : ResidualObject::computeJacobianInternal( 173 : datum, 174 0 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j) 175 : { 176 0 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 177 : { 178 0 : Real3 value = datum.JxW(qp) * kernel.template computeQpOffDiagJacobian<Derived>( 179 : j, datum.jvar(), qp, datum); 180 : 181 0 : for (unsigned int i = ib; i < ie; ++i) 182 0 : local_ke[i] += value * _grad_test(datum, i, qp); 183 : } 184 : }); 185 0 : } 186 : 187 : } // namespace Moose::Kokkos