https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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 "KokkosDispatcher.h"
13#include "KokkosFESystem.h"
14#include "KokkosVariableValue.h"
16
17#include "MooseVariableBase.h"
18#include "ResidualObject.h"
19
20namespace Moose::Kokkos
21{
22
27 public MeshHolder,
28 public AssemblyHolder,
29 public FESystemHolder
30{
31public:
33
35 static constexpr bool use_precompute_hooks = false;
36
43 Moose::VarFieldType field_type,
44 bool nodal = false);
49
55 {
56 };
58 {
59 };
61 {
62 };
64
65 virtual const MooseVariableBase & variable() const override { return _var; }
66
67 virtual void computeOffDiagJacobian(unsigned int) override final
68 {
69 mooseError("computeOffDiagJacobian() is not used for Kokkos residual objects.");
70 }
71 virtual void computeResidualAndJacobian() override
72 {
75 }
76
77protected:
94 std::unique_ptr<DispatcherBase> _residual_dispatcher;
95 std::unique_ptr<DispatcherBase> _jacobian_dispatcher;
96 std::unique_ptr<DispatcherBase> _offdiag_jacobian_dispatcher;
98
102 const unsigned int _dimension;
103
108
129
137 KOKKOS_FUNCTION void accumulateTaggedElementalResidual(const Real local_re,
138 const ContiguousElementID elem,
139 const unsigned int i,
140 const unsigned int comp = 0) const;
148 KOKKOS_FUNCTION void accumulateTaggedNodalResidual(const bool add,
149 const Real local_re,
150 const ContiguousNodeID node,
151 const unsigned int comp = 0) const;
159 KOKKOS_FUNCTION void accumulateTaggedVectorNodalResidual(const bool add,
160 const Real local_re,
161 const ContiguousNodeID node,
162 const unsigned int i) const;
172 KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const Real local_ke,
173 const ContiguousElementID elem,
174 const unsigned int i,
175 const unsigned int j,
176 const unsigned int jvar,
177 const unsigned int comp = 0) const;
186 KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const DNDerivativeType & local_ke,
187 const AssemblyDatum & datum,
188 const unsigned int i,
189 const unsigned int comp = 0) const;
198 KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
199 const Real local_ke,
200 const ContiguousNodeID node,
201 const unsigned int jvar,
202 const unsigned int comp = 0) const;
212 KOKKOS_FUNCTION void accumulateTaggedVectorNodalMatrix(const bool add,
213 const Real local_ke,
214 const ContiguousNodeID node,
215 const unsigned int i,
216 const unsigned int j,
217 const unsigned int jvar) const;
226 KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
227 const DNDerivativeType & local_ke,
228 const ContiguousNodeID node,
229 const unsigned int comp = 0) const;
230
236 template <typename function>
237 KOKKOS_FUNCTION void computeResidualInternal(AssemblyDatum & datum, function body) const;
243 template <typename function>
244 KOKKOS_FUNCTION void computeJacobianInternal(AssemblyDatum & datum, function body) const;
245
246private:
254};
255
256KOKKOS_FUNCTION inline void
258 const ContiguousElementID elem,
259 const unsigned int i,
260 const unsigned int comp) const
261{
262 if (!local_re)
263 return;
264
265 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
266 auto dof = sys.getElemLocalDofIndex(elem, i, _kokkos_var.var(comp));
267
268 for (unsigned int t = 0; t < _vector_tags.size(); ++t)
269 {
270 auto tag = _vector_tags[t];
271
272 if (sys.isResidualTagActive(tag))
273 ::Kokkos::atomic_add(&sys.getVectorDofValue(dof, tag), local_re);
274 }
275}
276
277KOKKOS_FUNCTION inline void
279 const Real local_re,
280 const ContiguousNodeID node,
281 const unsigned int comp) const
282{
283 if (!local_re && add)
284 return;
285
286 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
287 auto dof = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
288
289 for (unsigned int t = 0; t < _vector_tags.size(); ++t)
290 {
291 auto tag = _vector_tags[t];
292
293 if (sys.isResidualTagActive(tag))
294 {
295 if (add)
296 sys.getVectorDofValue(dof, tag) += local_re;
297 else
298 sys.getVectorDofValue(dof, tag) = local_re;
299 }
300 }
301}
302
303KOKKOS_FUNCTION inline void
305 const Real local_re,
306 const ContiguousNodeID node,
307 const unsigned int i) const
308{
309 if (!local_re && add)
310 return;
311
312 auto & sys = kokkosSystem(_kokkos_var.sys());
313 auto dof = sys.getNodeLocalDofIndex(node, i, _kokkos_var.var());
314
315 for (unsigned int t = 0; t < _vector_tags.size(); ++t)
316 {
317 auto tag = _vector_tags[t];
318
319 if (sys.isResidualTagActive(tag))
320 {
321 if (add)
322 sys.getVectorDofValue(dof, tag) += local_re;
323 else
324 sys.getVectorDofValue(dof, tag) = local_re;
325 }
326 }
327}
328
329KOKKOS_FUNCTION inline void
331 const ContiguousElementID elem,
332 const unsigned int i,
333 const unsigned int j,
334 const unsigned int jvar,
335 const unsigned int comp) const
336{
337 if (!local_ke)
338 return;
339
340 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
341 auto row = sys.getElemLocalDofIndex(elem, i, _kokkos_var.var(comp));
342 auto col = sys.getElemGlobalDofIndex(elem, j, jvar);
343
344 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
345 {
346 auto tag = _matrix_tags[t];
347
348 if (sys.isMatrixTagActive(tag) && !sys.hasNodalBCMatrixTag(row, tag))
349 ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag), local_ke);
350 }
351}
352
353KOKKOS_FUNCTION inline void
355 const AssemblyDatum & datum,
356 const unsigned int i,
357 const unsigned int comp) const
358{
359 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
360 auto row = sys.getElemLocalDofIndex(datum.elem().id, i, _kokkos_var.var(comp));
361
362 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
363 {
364 auto tag = _matrix_tags[t];
365
366 if (sys.isMatrixTagActive(tag) && !sys.hasNodalBCMatrixTag(row, tag))
367 for (unsigned int j = 0; j < local_ke.size(); ++j)
368 {
369 auto col = local_ke.raw_index(j);
370
371 ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag), local_ke.raw_at(j));
372 }
373 }
374}
375
376KOKKOS_FUNCTION inline void
378 const Real local_ke,
379 const ContiguousNodeID node,
380 const unsigned int jvar,
381 const unsigned int comp) const
382{
383 if (!local_ke && add)
384 return;
385
386 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
387 auto row = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
388 auto col = sys.getNodeGlobalDofIndex(node, 0, jvar);
389
390 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
391 {
392 auto tag = _matrix_tags[t];
393
394 if (sys.isMatrixTagActive(tag))
395 {
396 auto & matrix = sys.getMatrix(tag);
397
398 if (add)
399 matrix(row, col) += local_ke;
400 else
401 {
402 matrix.zero(row);
403 matrix(row, col) = local_ke;
404 }
405 }
406 }
407}
408
409KOKKOS_FUNCTION inline void
411 const Real local_ke,
412 const ContiguousNodeID node,
413 const unsigned int i,
414 const unsigned int j,
415 const unsigned int jvar) const
416{
417 if (!local_ke && add)
418 return;
419
420 auto & sys = kokkosSystem(_kokkos_var.sys());
421 auto row = sys.getNodeLocalDofIndex(node, i, _kokkos_var.var());
422 auto col = sys.getNodeGlobalDofIndex(node, j, jvar);
423
424 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
425 {
426 auto tag = _matrix_tags[t];
427
428 if (sys.isMatrixTagActive(tag))
429 {
430 auto & matrix = sys.getMatrix(tag);
431
432 if (add)
433 matrix(row, col) += local_ke;
434 else
435 {
436 matrix.zero(row);
437 matrix(row, col) = local_ke;
438 }
439 }
440 }
441}
442
443KOKKOS_FUNCTION inline void
445 const DNDerivativeType & local_ke,
446 const ContiguousNodeID node,
447 const unsigned int comp) const
448{
449 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
450 auto row = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
451
452 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
453 {
454 auto tag = _matrix_tags[t];
455 auto & matrix = sys.getMatrix(tag);
456
457 if (sys.isMatrixTagActive(tag))
458 {
459 if (!add)
460 matrix.zero(row);
461
462 for (unsigned int j = 0; j < local_ke.size(); ++j)
463 {
464 auto col = local_ke.raw_index(j);
465
466 if (add)
467 matrix(row, col) += local_ke.raw_at(j);
468 else
469 matrix(row, col) = local_ke.raw_at(j);
470 }
471 }
472 }
473}
474
475template <typename function>
476KOKKOS_FUNCTION void
478{
479 Real local_re[MAX_CACHED_DOF];
480
481 unsigned int stride = MAX_CACHED_DOF * datum.num_local_threads();
482 unsigned int num_batches = datum.n_dofs() / stride;
483
484 if (datum.n_dofs() % stride)
485 ++num_batches;
486
487 for (unsigned int batch = 0; batch < num_batches; ++batch)
488 {
489 unsigned int ib = batch * stride;
490 unsigned int ie = ::Kokkos::min(ib + stride, datum.n_dofs());
491
492 const unsigned int n = ie - ib;
493 const unsigned int d = n / datum.num_local_threads();
494 const unsigned int m = n % datum.num_local_threads();
495 const unsigned int t = datum.local_thread_id();
496
497 ib += t * d + (t < m ? t : m);
498 ie = ib + d + (t < m ? 1 : 0);
499
500 for (unsigned int i = ib; i < ie; ++i)
501 local_re[i - ib] = 0;
502
503 body(local_re - ib, ib, ie);
504
505 for (unsigned int i = ib; i < ie; ++i)
506 accumulateTaggedElementalResidual(local_re[i - ib], datum.elem().id, i);
507 }
508}
509
510template <typename function>
511KOKKOS_FUNCTION void
513{
514 Real local_ke[MAX_CACHED_DOF];
515
516 for (unsigned int j = datum.local_thread_id(); j < datum.n_jdofs();
517 j += datum.num_local_threads())
518 {
519 unsigned int num_batches = datum.n_idofs() / MAX_CACHED_DOF;
520
521 if (datum.n_idofs() % MAX_CACHED_DOF)
522 ++num_batches;
523
524 for (unsigned int batch = 0; batch < num_batches; ++batch)
525 {
526 unsigned int ib = batch * MAX_CACHED_DOF;
527 unsigned int ie = ::Kokkos::min(ib + MAX_CACHED_DOF, datum.n_idofs());
528
529 for (unsigned int i = ib; i < ie; ++i)
530 local_ke[i - ib] = 0;
531
532 body(local_ke - ib, ib, ie, j);
533
534 for (unsigned int i = ib; i < ie; ++i)
535 accumulateTaggedElementalMatrix(local_ke[i - ib], datum.elem().id, i, j, datum.jvar());
536 }
537 }
538}
539
540} // namespace Moose::Kokkos
dof_id_type ContiguousElementID
Definition KokkosMesh.h:20
dof_id_type ContiguousNodeID
Definition KokkosMesh.h:21
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
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
Base variable class.
This class provides an interface for common operations on field variables of both FE and FV types wit...
KOKKOS_FUNCTION index_type size() const
Get the total array size.
The Kokkos array class.
The Kokkos object that holds thread-private data in the parallel operations of Kokkos kernels.
KOKKOS_FUNCTION unsigned int n_dofs() const
Get the number of local DOFs.
KOKKOS_FUNCTION unsigned int jvar() const
Get the coupled variable number.
KOKKOS_FUNCTION unsigned int n_idofs() const
Get the number of local DOFs.
KOKKOS_FUNCTION unsigned int n_jdofs() const
Get the number of local DOFs for the coupled variable.
The Kokkos interface that holds the host reference of the Kokkos assembly and copies it to device dur...
KOKKOS_FUNCTION unsigned int num_local_threads() const
Get the number of local threads.
KOKKOS_FUNCTION unsigned int local_thread_id() const
Get the current local thread ID.
KOKKOS_FUNCTION const ElementInfo & elem() const
Get the element information object.
Definition KokkosDatum.h:46
The Kokkos interface that holds the host reference of the Kokkos mesh and copies it to device during ...
Definition KokkosMesh.h:630
The base class for Kokkos residual objects.
virtual void computeResidualAndJacobian() override
Compute this object's contribution to the residual and Jacobian simultaneously.
Scalar< const Real > _t_old
Old time.
ResidualObject(const InputParameters &parameters, Moose::VarFieldType field_type, bool nodal=false)
Constructor.
std::unique_ptr< DispatcherBase > _residual_dispatcher
Kokkos functor dispatchers.
Scalar< Real > _t
TODO: Move to TransientInterface.
Scalar< Real > _dt_old
Size of the old time step.
KOKKOS_FUNCTION void accumulateTaggedVectorNodalMatrix(const bool add, const Real local_ke, const ContiguousNodeID node, const unsigned int i, const unsigned int j, const unsigned int jvar) const
Accumulate or set local nodal Jacobian contribution to tagged matrices for vector FE variables.
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.
ResidualObject(const ResidualObject &object)
Copy constructor for parallel dispatch.
Variable _kokkos_var
Kokkos variable.
Thread _thread
Kokkos thread object.
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.
static constexpr bool use_precompute_hooks
Whether this object's hooks factor out the test function.
const unsigned int _dimension
Mesh dimension.
static InputParameters validParams()
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.
Array< TagID > _vector_tags
Tags this object operates on.
KOKKOS_FUNCTION void accumulateTaggedVectorNodalResidual(const bool add, const Real local_re, const ContiguousNodeID node, const unsigned int i) const
Accumulate or set local nodal residual contribution to tagged vectors for vector FE variables.
MooseVariableFieldBase & _var
Reference of the MOOSE variable.
virtual void computeOffDiagJacobian(unsigned int) override final
Computes this object's contribution to off-diagonal blocks of the system Jacobian matrix.
KOKKOS_FUNCTION void computeJacobianInternal(AssemblyDatum &datum, function body) const
The common loop structure template for computing elemental Jacobian.
Scalar< Real > _dt
Time step size.
std::unique_ptr< DispatcherBase > _offdiag_jacobian_dispatcher
virtual const MooseVariableBase & variable() const override
Returns the variable that this object operates on.
std::unique_ptr< DispatcherBase > _jacobian_dispatcher
Scalar< int > _t_step
The number of the time step.
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.
KOKKOS_FUNCTION void computeResidualInternal(AssemblyDatum &datum, function body) const
The common loop structure template for computing elemental residual.
The Kokkos wrapper class that can hold the reference of an arithmetic scalar variable.
The Kokkos thread object that aids in converting the one-dimensional thread index into multi-dimensio...
The Kokkos variable object that carries the coupled variable and tag information.
KOKKOS_FUNCTION unsigned int var(unsigned int comp=0) const
Get the variable number of a component.
KOKKOS_FUNCTION unsigned int sys(unsigned int comp=0) const
Get the system number of a component.
This is the common base class for objects that give residual contributions.
virtual void computeResidual()=0
Compute this object's contribution to the residual.
virtual void computeJacobian()=0
Compute this object's contribution to the diagonal Jacobian entries.
KokkosSemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< MOOSE_AD_MAX_DOFS_PER_ELEM > > DNDerivativeType
constexpr unsigned int MAX_CACHED_DOF
Maximum number of DOFs to cache during residual and Jacobian computation.
ContiguousElementID id
Contiguous element ID.
Definition KokkosMesh.h:42