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 "KokkosKernelBase.h" 13 : 14 : namespace Moose::Kokkos 15 : { 16 : 17 : /** 18 : * The base class for a user to derive their own Kokkos kernels using automatic differentiation 19 : * (AD). 20 : * 21 : * The user should define computeQpResidual() as inlined public method in their derived class (not 22 : * virtual override). The signature of computeQpResidual() expected to be defined in the derived 23 : * class is as follows: 24 : * 25 : * @tparam Derived The object type 26 : * @param i The element-local DOF index 27 : * @param qp The local quadrature point index 28 : * @param datum The AssemblyDatum object of the current thread 29 : * @returns The residual contribution 30 : * 31 : * template <typename Derived> 32 : * KOKKOS_FUNCTION Moose::Kokkos::ADReal computeQpResidual(const unsigned int i, 33 : * const unsigned int qp, 34 : * AssemblyDatum & datum) const; 35 : * 36 : * Note that computeQpJacobian() and computeQpOffDiagJacobian() are unused for AD kernels. 37 : */ 38 : class ADKernel : public KernelBase 39 : { 40 : public: 41 : static InputParameters validParams(); 42 : 43 : /** 44 : * Constructor 45 : */ 46 : ADKernel(const InputParameters & parameters); 47 : 48 : virtual void computeResidual() override; 49 : virtual void computeJacobian() override; 50 : virtual void computeResidualAndJacobian() override; 51 : 52 : /** 53 : * The parallel computation entry function called by Kokkos 54 : */ 55 : template <typename Derived> 56 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & kernel) const; 57 : 58 : /** 59 : * Compute residual 60 : * @param kernel The kernel object of the final derived type 61 : * @param datum The AssemblyDatum object of the current thread 62 : */ 63 : template <typename Derived> 64 : KOKKOS_FUNCTION void computeResidualInternal(const Derived & kernel, AssemblyDatum & datum) const; 65 : 66 : protected: 67 : /** 68 : * Dispatch parallel calculation 69 : */ 70 : virtual void dispatch(); 71 : 72 : /** 73 : * Current test function 74 : */ 75 : const ADVariableTestValue _test; 76 : /** 77 : * Gradient of the current test function 78 : */ 79 : const ADVariableTestGradient _grad_test; 80 : /** 81 : * Current shape function 82 : */ 83 : const ADVariablePhiValue _phi; 84 : /** 85 : * Gradient of the current shape function 86 : */ 87 : const ADVariablePhiGradient _grad_phi; 88 : /** 89 : * Current solution at quadrature points 90 : */ 91 : const ADVariableValue _u; 92 : /** 93 : * Gradient of the current solution at quadrature points 94 : */ 95 : const ADVariableGradient _grad_u; 96 : /** 97 : * Whether computing residual 98 : */ 99 : bool _computing_residual = false; 100 : /** 101 : * Whether computing Jacobian 102 : */ 103 : bool _computing_jacobian = false; 104 : }; 105 : 106 : template <typename Derived> 107 : KOKKOS_FUNCTION void 108 1214896 : ADKernel::operator()(ResidualLoop, const ThreadID tid, const Derived & kernel) const 109 : { 110 1214896 : auto elem = kokkosBlockElementID(_thread(tid, 1)); 111 : 112 2429792 : AssemblyDatum datum(elem, 113 : libMesh::invalid_uint, 114 : kokkosAssembly(), 115 : kokkosSystems(), 116 1214896 : _kokkos_var, 117 : _kokkos_var.var()); 118 : 119 1214896 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0)); 120 : 121 1214896 : datum.do_derivatives(_computing_jacobian); 122 : 123 1214896 : kernel.computeResidualInternal(kernel, datum); 124 1214896 : } 125 : 126 : template <typename Derived> 127 : KOKKOS_FUNCTION void 128 1214896 : ADKernel::computeResidualInternal(const Derived & kernel, AssemblyDatum & datum) const 129 : { 130 2393152 : for (unsigned int i = datum.local_thread_id(); i < datum.n_dofs(); i += datum.num_local_threads()) 131 : { 132 1178256 : ADReal local_re = 0; 133 : 134 5818000 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp) 135 4639744 : local_re += datum.JxW(qp) * kernel.template computeQpResidual<Derived>(i, qp, datum); 136 : 137 1178256 : if (_computing_residual) 138 1174056 : accumulateTaggedElementalResidual(local_re.value(), datum.elem().id, i); 139 1178256 : if (_computing_jacobian) 140 1101876 : accumulateTaggedElementalMatrix(local_re.derivatives(), datum, i); 141 : } 142 1214896 : } 143 : 144 : } // namespace Moose::Kokkos