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://mooseframework.inl.gov
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 uses_precompute_hooks = false;
36
38 static constexpr bool supports_scalar_jacobian = false;
39
46 Moose::VarFieldType field_type,
47 bool nodal = false);
52
58 {
59 };
61 {
62 };
64 {
65 };
67 {
68 };
70
71 virtual const MooseVariableBase & variable() const override { return _var; }
72
73 virtual void computeOffDiagJacobian(unsigned int) override final
74 {
75 mooseError("computeOffDiagJacobian() is not used for Kokkos residual objects.");
76 }
77 virtual void computeResidualAndJacobian() override
78 {
81 }
82
83protected:
100 std::unique_ptr<DispatcherBase> _residual_dispatcher;
101 std::unique_ptr<DispatcherBase> _jacobian_dispatcher;
102 std::unique_ptr<DispatcherBase> _offdiag_jacobian_dispatcher;
103 std::unique_ptr<DispatcherBase> _offdiag_jacobian_scalar_dispatcher;
105
109 const unsigned int _dimension;
110
115
136
144 KOKKOS_FUNCTION void accumulateTaggedElementalResidual(const Real local_re,
145 const ContiguousElementID elem,
146 const unsigned int i,
147 const unsigned int comp = 0) const;
155 KOKKOS_FUNCTION void accumulateTaggedNodalResidual(const bool add,
156 const Real local_re,
157 const ContiguousNodeID node,
158 const unsigned int comp = 0) const;
166 KOKKOS_FUNCTION void accumulateTaggedVectorNodalResidual(const bool add,
167 const Real local_re,
168 const ContiguousNodeID node,
169 const unsigned int i) const;
179 KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const Real local_ke,
180 const ContiguousElementID elem,
181 const unsigned int i,
182 const unsigned int j,
183 const unsigned int jvar,
184 const unsigned int comp = 0) const;
193 KOKKOS_FUNCTION void accumulateTaggedElementalMatrix(const DNDerivativeType & local_ke,
194 const AssemblyDatum & datum,
195 const unsigned int i,
196 const unsigned int comp = 0) const;
205 KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
206 const Real local_ke,
207 const ContiguousNodeID node,
208 const unsigned int jvar,
209 const unsigned int comp = 0) const;
219 KOKKOS_FUNCTION void accumulateTaggedVectorNodalMatrix(const bool add,
220 const Real local_ke,
221 const ContiguousNodeID node,
222 const unsigned int i,
223 const unsigned int j,
224 const unsigned int jvar) const;
233 KOKKOS_FUNCTION void accumulateTaggedNodalMatrix(const bool add,
234 const DNDerivativeType & local_ke,
235 const ContiguousNodeID node,
236 const unsigned int comp = 0) const;
237
243 template <typename function>
244 KOKKOS_FUNCTION void computeResidualInternal(AssemblyDatum & datum, function body) const;
250 template <typename function>
251 KOKKOS_FUNCTION void computeJacobianInternal(AssemblyDatum & datum, function body) const;
252
253private:
261};
262
263KOKKOS_FUNCTION inline void
265 const ContiguousElementID elem,
266 const unsigned int i,
267 const unsigned int comp) const
268{
269 if (!local_re)
270 return;
271
272 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
273 const auto var = _kokkos_var.var(comp);
274 auto dof = sys.getElemLocalDofIndex(elem, i, var);
275 const auto scaled_local_re = local_re * sys.getVariableScalingFactor(var);
276
277 for (unsigned int t = 0; t < _vector_tags.size(); ++t)
278 {
279 auto tag = _vector_tags[t];
280
281 if (sys.isResidualTagActive(tag))
282 ::Kokkos::atomic_add(&sys.getVectorDofValue(dof, tag), scaled_local_re);
283 }
284}
285
286KOKKOS_FUNCTION inline void
288 const Real local_re,
289 const ContiguousNodeID node,
290 const unsigned int comp) const
291{
292 if (!local_re && add)
293 return;
294
295 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
296 auto dof = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
297
298 for (unsigned int t = 0; t < _vector_tags.size(); ++t)
299 {
300 auto tag = _vector_tags[t];
301
302 if (sys.isResidualTagActive(tag))
303 {
304 if (add)
305 sys.getVectorDofValue(dof, tag) += local_re;
306 else
307 sys.getVectorDofValue(dof, tag) = local_re;
308 }
309 }
310}
311
312KOKKOS_FUNCTION inline void
314 const Real local_re,
315 const ContiguousNodeID node,
316 const unsigned int i) const
317{
318 if (!local_re && add)
319 return;
320
321 auto & sys = kokkosSystem(_kokkos_var.sys());
322 auto dof = sys.getNodeLocalDofIndex(node, i, _kokkos_var.var());
323
324 for (unsigned int t = 0; t < _vector_tags.size(); ++t)
325 {
326 auto tag = _vector_tags[t];
327
328 if (sys.isResidualTagActive(tag))
329 {
330 if (add)
331 sys.getVectorDofValue(dof, tag) += local_re;
332 else
333 sys.getVectorDofValue(dof, tag) = local_re;
334 }
335 }
336}
337
338KOKKOS_FUNCTION inline void
340 const ContiguousElementID elem,
341 const unsigned int i,
342 const unsigned int j,
343 const unsigned int jvar,
344 const unsigned int comp) const
345{
346 if (!local_ke)
347 return;
348
349 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
350 const auto ivar = _kokkos_var.var(comp);
351 auto row = sys.getElemLocalDofIndex(elem, i, ivar);
352 auto col = sys.isScalarVariable(jvar) ? sys.getScalarGlobalDofIndex(j, jvar)
353 : sys.getElemGlobalDofIndex(elem, j, jvar);
354 const auto scaled_local_ke = local_ke * sys.getVariableScalingFactor(ivar);
355
356 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
357 {
358 auto tag = _matrix_tags[t];
359
360 if (sys.isMatrixTagActive(tag) && !sys.hasNodalBCMatrixTag(row, tag))
361 ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag), scaled_local_ke);
362 }
363}
364
365KOKKOS_FUNCTION inline void
367 const AssemblyDatum & datum,
368 const unsigned int i,
369 const unsigned int comp) const
370{
371 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
372 const auto ivar = _kokkos_var.var(comp);
373 auto row = sys.getElemLocalDofIndex(datum.elem().id, i, ivar);
374 const auto scaling_factor = sys.getVariableScalingFactor(ivar);
375
376 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
377 {
378 auto tag = _matrix_tags[t];
379
380 if (sys.isMatrixTagActive(tag) && !sys.hasNodalBCMatrixTag(row, tag))
381 for (unsigned int j = 0; j < local_ke.size(); ++j)
382 {
383 auto col = local_ke.raw_index(j);
384
385 ::Kokkos::atomic_add(&sys.getMatrixValue(row, col, tag),
386 local_ke.raw_at(j) * scaling_factor);
387 }
388 }
389}
390
391KOKKOS_FUNCTION inline void
393 const Real local_ke,
394 const ContiguousNodeID node,
395 const unsigned int jvar,
396 const unsigned int comp) const
397{
398 if (!local_ke && add)
399 return;
400
401 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
402 auto row = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
403 auto col = sys.getNodeGlobalDofIndex(node, 0, jvar);
404
405 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
406 {
407 auto tag = _matrix_tags[t];
408
409 if (sys.isMatrixTagActive(tag))
410 {
411 auto & matrix = sys.getMatrix(tag);
412
413 if (add)
414 matrix(row, col) += local_ke;
415 else
416 {
417 matrix.zero(row);
418 matrix(row, col) = local_ke;
419 }
420 }
421 }
422}
423
424KOKKOS_FUNCTION inline void
426 const Real local_ke,
427 const ContiguousNodeID node,
428 const unsigned int i,
429 const unsigned int j,
430 const unsigned int jvar) const
431{
432 if (!local_ke && add)
433 return;
434
435 auto & sys = kokkosSystem(_kokkos_var.sys());
436 auto row = sys.getNodeLocalDofIndex(node, i, _kokkos_var.var());
437 auto col = sys.getNodeGlobalDofIndex(node, j, jvar);
438
439 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
440 {
441 auto tag = _matrix_tags[t];
442
443 if (sys.isMatrixTagActive(tag))
444 {
445 auto & matrix = sys.getMatrix(tag);
446
447 if (add)
448 matrix(row, col) += local_ke;
449 else
450 {
451 matrix.zero(row);
452 matrix(row, col) = local_ke;
453 }
454 }
455 }
456}
457
458KOKKOS_FUNCTION inline void
460 const DNDerivativeType & local_ke,
461 const ContiguousNodeID node,
462 const unsigned int comp) const
463{
464 auto & sys = kokkosSystem(_kokkos_var.sys(comp));
465 auto row = sys.getNodeLocalDofIndex(node, 0, _kokkos_var.var(comp));
466
467 for (unsigned int t = 0; t < _matrix_tags.size(); ++t)
468 {
469 auto tag = _matrix_tags[t];
470 auto & matrix = sys.getMatrix(tag);
471
472 if (sys.isMatrixTagActive(tag))
473 {
474 if (!add)
475 matrix.zero(row);
476
477 for (unsigned int j = 0; j < local_ke.size(); ++j)
478 {
479 auto col = local_ke.raw_index(j);
480
481 if (add)
482 matrix(row, col) += local_ke.raw_at(j);
483 else
484 matrix(row, col) = local_ke.raw_at(j);
485 }
486 }
487 }
488}
489
490template <typename function>
491KOKKOS_FUNCTION void
493{
494 Real local_re[MAX_CACHED_DOF];
495
496 unsigned int stride = MAX_CACHED_DOF * datum.num_local_threads();
497 unsigned int num_batches = datum.n_dofs() / stride;
498
499 if (datum.n_dofs() % stride)
500 ++num_batches;
501
502 for (unsigned int batch = 0; batch < num_batches; ++batch)
503 {
504 unsigned int ib = batch * stride;
505 unsigned int ie = ::Kokkos::min(ib + stride, datum.n_dofs());
506
507 const unsigned int n = ie - ib;
508 const unsigned int d = n / datum.num_local_threads();
509 const unsigned int m = n % datum.num_local_threads();
510 const unsigned int t = datum.local_thread_id();
511
512 ib += t * d + (t < m ? t : m);
513 ie = ib + d + (t < m ? 1 : 0);
514
515 for (unsigned int i = ib; i < ie; ++i)
516 local_re[i - ib] = 0;
517
518 body(local_re - ib, ib, ie);
519
520 for (unsigned int i = ib; i < ie; ++i)
521 accumulateTaggedElementalResidual(local_re[i - ib], datum.elem().id, i);
522 }
523}
524
525template <typename function>
526KOKKOS_FUNCTION void
528{
529 Real local_ke[MAX_CACHED_DOF];
530
531 for (unsigned int j = datum.local_thread_id(); j < datum.n_jdofs();
532 j += datum.num_local_threads())
533 {
534 unsigned int num_batches = datum.n_idofs() / MAX_CACHED_DOF;
535
536 if (datum.n_idofs() % MAX_CACHED_DOF)
537 ++num_batches;
538
539 for (unsigned int batch = 0; batch < num_batches; ++batch)
540 {
541 unsigned int ib = batch * MAX_CACHED_DOF;
542 unsigned int ie = ::Kokkos::min(ib + MAX_CACHED_DOF, datum.n_idofs());
543
544 for (unsigned int i = ib; i < ie; ++i)
545 local_ke[i - ib] = 0;
546
547 body(local_ke - ib, ib, ie, j);
548
549 for (unsigned int i = ib; i < ie; ++i)
550 accumulateTaggedElementalMatrix(local_ke[i - ib], datum.elem().id, i, j, datum.jvar());
551 }
552 }
553}
554
555} // 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:669
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.
const unsigned int _dimension
Mesh dimension.
static InputParameters validParams()
std::unique_ptr< DispatcherBase > _offdiag_jacobian_scalar_dispatcher
static constexpr bool uses_precompute_hooks
Whether this object's hooks factor out the test function.
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.
static constexpr bool supports_scalar_jacobian
Whether this object has computeQpOffDiagJacobianScalar() hook.
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