https://mooseframework.inl.gov
KokkosResidualObject.h
Go to the documentation of this file.
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 "KokkosVariableValue.h"
14 
15 #include "MooseVariableBase.h"
16 #include "ResidualObject.h"
17 
18 namespace Moose
19 {
20 namespace Kokkos
21 {
22 
27  public MeshHolder,
28  public AssemblyHolder,
29  public SystemHolder
30 {
31 public:
33 
40  Moose::VarFieldType field_type,
41  bool nodal = false);
45  ResidualObject(const ResidualObject & object);
46 
50  struct ResidualLoop
52  {
53  };
54  struct JacobianLoop
55  {
56  };
58  {
59  };
61 
62  virtual const MooseVariableBase & variable() const override { return _var; }
63 
64  virtual void computeOffDiagJacobian(unsigned int) override final
65  {
66  mooseError("computeOffDiagJacobian() is not used for Kokkos residual objects.");
67  }
68  virtual void computeResidualAndJacobian() override final
69  {
72  }
73 
74 protected:
87 
91 
113 
121  KOKKOS_FUNCTION void accumulateTaggedElementalResidual(const Real local_re,
122  const ContiguousElementID elem,
123  const unsigned int i,
124  const unsigned int comp = 0) const;
132  KOKKOS_FUNCTION void accumulateTaggedNodalResidual(const bool add,
133  const Real local_re,
134  const ContiguousNodeID node,
135  const unsigned int comp = 0) const;
145  KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const Real local_ke,
146  const ContiguousElementID elem,
147  const unsigned int i,
148  const unsigned int j,
149  const unsigned int jvar,
150  const unsigned int comp = 0) const;
159  KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
160  const Real local_ke,
161  const ContiguousNodeID node,
162  const unsigned int jvar,
163  const unsigned int comp = 0) const;
164 
170  template <typename function>
171  KOKKOS_FUNCTION void computeResidualInternal(ResidualDatum & datum, function body) const;
177  template <typename function>
178  KOKKOS_FUNCTION void computeJacobianInternal(ResidualDatum & datum, function body) const;
179 
180 private:
188 
195 };
196 
197 KOKKOS_FUNCTION inline void
199  const ContiguousElementID elem,
200  const unsigned int i,
201  const unsigned int comp) const
202 {
203  if (!local_re)
204  return;
205 
206  auto & sys = kokkosSystem(_kokkos_var.sys());
207  auto dof = sys.getElemLocalDofIndex(elem, i, _kokkos_var.var(comp));
208 
209  for (dof_id_type t = 0; t < _vector_tags.size(); ++t)
210  {
211  auto tag = _vector_tags[t];
212 
213  if (sys.isResidualTagActive(tag))
214  {
215  bool has_nodal_bc =
216  _is_extra_vector_tag[t] ? sys.hasNodalBCResidualTag(dof, tag) : sys.hasNodalBC(dof);
217 
218  if (!has_nodal_bc)
219  ::Kokkos::atomic_add(&sys.getVectorDofValue(dof, tag), local_re);
220  }
221  }
222 }
223 
224 KOKKOS_FUNCTION inline void
226  const Real local_re,
227  const ContiguousNodeID node,
228  const unsigned int comp) const
229 {
230  if (!local_re)
231  return;
232 
233  auto & sys = kokkosSystem(_kokkos_var.sys());
234  auto dof = sys.getNodeLocalDofIndex(node, _kokkos_var.var(comp));
235 
236  for (dof_id_type t = 0; t < _vector_tags.size(); ++t)
237  {
238  auto tag = _vector_tags[t];
239 
240  if (sys.isResidualTagActive(tag))
241  {
242  if (add)
243  sys.getVectorDofValue(dof, tag) += local_re;
244  else
245  sys.getVectorDofValue(dof, tag) = local_re;
246  }
247  }
248 }
249 
250 KOKKOS_FUNCTION inline void
252  const ContiguousElementID elem,
253  const unsigned int i,
254  const unsigned int j,
255  const unsigned int jvar,
256  const unsigned int comp) const
257 {
258  if (!local_ke)
259  return;
260 
261  auto & sys = kokkosSystem(_kokkos_var.sys());
262  auto row = sys.getElemLocalDofIndex(elem, i, _kokkos_var.var(comp));
263  auto col = sys.getElemGlobalDofIndex(elem, j, jvar);
264 
265  for (dof_id_type t = 0; t < _matrix_tags.size(); ++t)
266  {
267  auto tag = _matrix_tags[t];
268 
269  if (sys.isMatrixTagActive(tag))
270  {
271  bool has_nodal_bc =
272  _is_extra_matrix_tag[t] ? sys.hasNodalBCMatrixTag(row, tag) : sys.hasNodalBC(row);
273 
274  if (!has_nodal_bc)
275  ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag), local_ke);
276  }
277  }
278 }
279 
280 KOKKOS_FUNCTION inline void
282  const Real local_ke,
283  const ContiguousNodeID node,
284  const unsigned int jvar,
285  const unsigned int comp) const
286 {
287  if (!local_ke)
288  return;
289 
290  auto & sys = kokkosSystem(_kokkos_var.sys());
291  auto row = sys.getNodeLocalDofIndex(node, _kokkos_var.var(comp));
292  auto col = sys.getNodeGlobalDofIndex(node, jvar);
293 
294  for (dof_id_type t = 0; t < _matrix_tags.size(); ++t)
295  {
296  auto tag = _matrix_tags[t];
297 
298  if (sys.isMatrixTagActive(tag))
299  {
300  auto & matrix = sys.getMatrix(tag);
301 
302  if (add)
303  matrix(row, col) += local_ke;
304  else
305  {
306  matrix.zero(row);
307  matrix(row, col) = local_ke;
308  }
309  }
310  }
311 }
312 
313 template <typename function>
314 KOKKOS_FUNCTION void
316 {
317  Real local_re[MAX_CACHED_DOF];
318 
319  unsigned int num_batches = datum.n_dofs() / MAX_CACHED_DOF;
320 
321  if (datum.n_dofs() % MAX_CACHED_DOF)
322  ++num_batches;
323 
324  for (unsigned int batch = 0; batch < num_batches; ++batch)
325  {
326  unsigned int ib = batch * MAX_CACHED_DOF;
327  unsigned int ie = ::Kokkos::min(ib + MAX_CACHED_DOF, datum.n_dofs());
328 
329  for (unsigned int i = ib; i < ie; ++i)
330  local_re[i - ib] = 0;
331 
332  body(local_re - ib, ib, ie);
333 
334  for (unsigned int i = ib; i < ie; ++i)
335  accumulateTaggedElementalResidual(local_re[i - ib], datum.elem().id, i);
336  }
337 }
338 
339 template <typename function>
340 KOKKOS_FUNCTION void
342 {
343  Real local_ke[MAX_CACHED_DOF];
344 
345  unsigned int num_batches = datum.n_idofs() * datum.n_jdofs() / MAX_CACHED_DOF;
346 
347  if ((datum.n_idofs() * datum.n_jdofs()) % MAX_CACHED_DOF)
348  ++num_batches;
349 
350  for (unsigned int batch = 0; batch < num_batches; ++batch)
351  {
352  unsigned int ijb = batch * MAX_CACHED_DOF;
353  unsigned int ije = ::Kokkos::min(ijb + MAX_CACHED_DOF, datum.n_idofs() * datum.n_jdofs());
354 
355  for (unsigned int ij = ijb; ij < ije; ++ij)
356  local_ke[ij - ijb] = 0;
357 
358  body(local_ke - ijb, ijb, ije);
359 
360  for (unsigned int ij = ijb; ij < ije; ++ij)
361  {
362  unsigned int i = ij % datum.n_jdofs();
363  unsigned int j = ij / datum.n_jdofs();
364 
365  accumulateTaggedElementalMatrix(local_ke[ij - ijb], datum.elem().id, i, j, datum.jvar());
366  }
367  }
368 }
369 
370 } // namespace Kokkos
371 } // namespace Moose
372 
373 #define usingKokkosResidualObjectMembers \
374 public: \
375  usingPostprocessorInterfaceMembers; \
376  \
377 protected: \
378  using Moose::Kokkos::ResidualObject::kokkosAssembly; \
379  using Moose::Kokkos::ResidualObject::kokkosSystems; \
380  using Moose::Kokkos::ResidualObject::kokkosSystem; \
381  using Moose::Kokkos::ResidualObject::accumulateTaggedElementalResidual; \
382  using Moose::Kokkos::ResidualObject::accumulateTaggedNodalResidual; \
383  using Moose::Kokkos::ResidualObject::accumulateTaggedElementalMatrix; \
384  using Moose::Kokkos::ResidualObject::accumulateTaggedNodalMatrix; \
385  using Moose::Kokkos::ResidualObject::_var; \
386  using Moose::Kokkos::ResidualObject::_kokkos_var; \
387  using Moose::Kokkos::ResidualObject::_thread; \
388  using Moose::Kokkos::ResidualObject::_t; \
389  using Moose::Kokkos::ResidualObject::_t_old; \
390  using Moose::Kokkos::ResidualObject::_t_step; \
391  using Moose::Kokkos::ResidualObject::_dt; \
392  using Moose::Kokkos::ResidualObject::_dt_old; \
393  \
394 public: \
395  using Moose::Kokkos::ResidualObject::ResidualLoop; \
396  using Moose::Kokkos::ResidualObject::JacobianLoop; \
397  using Moose::Kokkos::ResidualObject::OffDiagJacobianLoop
VarFieldType
Definition: MooseTypes.h:722
KOKKOS_FUNCTION unsigned int n_jdofs() const
Get the number of local DOFs for the coupled variable.
Definition: KokkosDatum.h:287
KOKKOS_FUNCTION dof_id_type getElemLocalDofIndex(ContiguousElementID elem, unsigned int i, unsigned int var) const
Get the local DOF index of a variable for an element.
Definition: KokkosSystem.h:225
Scalar< Real > _dt_old
Size of the old time step.
KOKKOS_FUNCTION unsigned int sys(unsigned int comp=0) const
Get the system number of a component.
Scalar< Real > _t
TODO: Move to TransientInterface.
dof_id_type ContiguousElementID
Definition: KokkosMesh.h:20
KOKKOS_FUNCTION void computeJacobianInternal(ResidualDatum &datum, function body) const
The common loop structure template for computing elemental Jacobian.
Array< bool > _is_extra_vector_tag
Flag whether each tag.
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
ResidualObject(const InputParameters &parameters, Moose::VarFieldType field_type, bool nodal=false)
Constructor.
KOKKOS_FUNCTION void accumulateTaggedNodalResidual(const bool add, const Real local_re, const ContiguousNodeID node, const unsigned int comp=0) const
Accumulate or set local nodal residual contribution to tagged vectors.
KOKKOS_FUNCTION dof_id_type getNodeLocalDofIndex(ContiguousNodeID node, unsigned int var) const
Get the local DOF index of a variable for a node.
Definition: KokkosSystem.h:237
virtual void computeOffDiagJacobian(unsigned int) override final
Computes this object&#39;s contribution to off-diagonal blocks of the system Jacobian matrix...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
The base class for Kokkos residual objects.
Thread _thread
Kokkos thread object.
MooseVariableFieldBase & _var
Reference of the MOOSE variable.
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual void computeResidualAndJacobian() override final
Compute this object&#39;s contribution to the residual and Jacobian simultaneously.
The Kokkos interface that holds the host reference of the Kokkos systems and copies it to device duri...
Definition: KokkosSystem.h:576
The Kokkos interface that holds the host reference of the Kokkos mesh and copies it to device during ...
Definition: KokkosMesh.h:338
KOKKOS_FUNCTION unsigned int n_dofs() const
Get the number of local DOFs.
Definition: KokkosDatum.h:277
KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const Real local_ke, const ContiguousElementID elem, const unsigned int i, const unsigned int j, const unsigned int jvar, const unsigned int comp=0) const
Accumulate local elemental Jacobian contribution to tagged matrices.
dof_id_type ContiguousNodeID
Definition: KokkosMesh.h:21
virtual void computeResidual()=0
Compute this object&#39;s contribution to the residual.
KOKKOS_FUNCTION const System & kokkosSystem(unsigned int sys) const
Get the const reference of a Kokkos system.
Definition: KokkosSystem.h:615
The Kokkos interface that holds the host reference of the Kokkos assembly and copies it to device dur...
virtual void computeJacobian()=0
Compute this object&#39;s contribution to the diagonal Jacobian entries.
Scalar< const Real > _t_old
Old time.
Scalar< int > _t_step
The number of the time step.
constexpr unsigned int MAX_CACHED_DOF
Maximum number of DOFs to cache during residual and Jacobian computation.
Definition: KokkosHeader.h:79
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
The Kokkos variable object that carries the coupled variable and tag information. ...
KOKKOS_FUNCTION void accumulateTaggedElementalResidual(const Real local_re, const ContiguousElementID elem, const unsigned int i, const unsigned int comp=0) const
Accumulate local elemental residual contribution to tagged vectors.
KOKKOS_FUNCTION const ElementInfo & elem() const
Get the element information object.
Definition: KokkosDatum.h:80
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:271
KOKKOS_FUNCTION void computeResidualInternal(ResidualDatum &datum, function body) const
The common loop structure template for computing elemental residual.
Scalar< Real > _dt
Time step size.
Variable _kokkos_var
Kokkos variable.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
KOKKOS_FUNCTION unsigned int var(unsigned int comp=0) const
Get the variable number of a component.
auto min(const L &left, const R &right)
static InputParameters validParams()
KOKKOS_FUNCTION unsigned int jvar() const
Get the coupled variable number.
Definition: KokkosDatum.h:302
Array< TagID > _vector_tags
Tags this object operates on.
The Kokkos object that holds thread-private data in the parallel operations of Kokkos residual object...
Definition: KokkosDatum.h:222
KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add, const Real local_ke, const ContiguousNodeID node, const unsigned int jvar, const unsigned int comp=0) const
Accumulate or set local nodal Jacobian contribution to tagged matrices.
The Kokkos thread object that aids in converting the one-dimensional thread index into multi-dimensio...
Definition: KokkosThread.h:29
KOKKOS_FUNCTION unsigned int n_idofs() const
Get the number of local DOFs.
Definition: KokkosDatum.h:282
virtual const MooseVariableBase & variable() const override
Returns the variable that this object operates on.
ContiguousElementID id
Contiguous element ID.
Definition: KokkosMesh.h:44
Base variable class.
uint8_t dof_id_type