libMesh
Loading...
Searching...
No Matches
kokkos_linalg_base.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18#ifndef LIBMESH_KOKKOS_LINALG_BASE_H
19#define LIBMESH_KOKKOS_LINALG_BASE_H
20
21// libMesh Kokkos compile-time linalg foundation.
22//
23// This header defines the small access/materialization layer that sits
24// underneath richer vector/tensor algebra. It is intentionally limited to
25// component access, storage-backed references, and conversion between
26// vector-like/tensor-like objects and libMesh semantic types.
27//
28// The key abstractions are:
29//
30// - "vector-like"/"tensor-like": the types registered with the
31// is_vector_like/is_tensor_like traits, whose components are read
32// through operator()(i) / operator()(i,j). libMesh's owning types
33// (TypeVector, TypeTensor, Point, ...) and the non-owning refs below
34// are registered, so the algorithms in kokkos_vector_ops.h and
35// kokkos_tensor_ops.h can be written once against either kind.
36//
37// - vector_ref/tensor_ref: lightweight non-owning handles addressing
38// one entry of a Kokkos storage view (see kokkos_storage_policy.h).
39// Reads and writes through a ref go directly to the underlying view,
40// so kernels can update storage in place without materializing
41// temporaries.
42//
43// - materialize_vector()/materialize_tensor(): copy any vector-like or
44// tensor-like object into an owning libMesh value type, for use in
45// register-resident arithmetic.
46
47#include "libmesh/libmesh_common.h"
48#include "libmesh/libmesh_device.h"
49#include "libmesh/point.h"
50#include "libmesh/tensor_value.h"
51#include "libmesh/type_tensor.h"
52#include "libmesh/type_vector.h"
53
54#include <type_traits>
55#include <utility>
56
58{
59
60namespace detail
61{
62
69template <typename T>
71 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
72
81template <typename ViewType>
84
90template <typename ViewType>
93
94} // namespace detail
95
102template <typename T>
104
110template <typename T>
112
122template <typename T>
123struct is_vector_like : std::false_type
124{
125};
126
133template <typename T>
134struct is_tensor_like : std::false_type
135{
136};
137
144template <typename T>
145struct is_vector_ref : std::false_type
146{
147};
148
153template <typename T>
154struct is_tensor_ref : std::false_type
155{
156};
157
166template <typename T>
168
169template <typename T>
171
172template <typename T>
174
175template <typename T>
177
192template <typename ViewType>
194{
195public:
196 // The underlying view type and the scalar type of its components.
197 using view_type = ViewType;
199
203 LIBMESH_DEVICE_INLINE
204 vector_ref(ViewType view, const unsigned int index) : _view(view), _index(index) {}
205
213 LIBMESH_DEVICE_INLINE
214 decltype(auto) operator()(const unsigned int component) const
215 {
216 return _view(_index, component);
217 }
218
219 LIBMESH_DEVICE_INLINE
220 decltype(auto) operator()(const unsigned int component)
221 {
222 return _view(_index, component);
223 }
224
228 template <typename RightVector>
229 LIBMESH_DEVICE_INLINE
230 void assign(const RightVector & right);
231
235 template <typename RightVector>
236 LIBMESH_DEVICE_INLINE
237 void add(const RightVector & right);
238
242 template <typename RightVector>
243 LIBMESH_DEVICE_INLINE
244 void add_scaled(const RightVector & right, const value_type & factor);
245
249 template <typename RightVector>
250 LIBMESH_DEVICE_INLINE
251 void subtract(const RightVector & right);
252
257 template <typename RightVector>
258 LIBMESH_DEVICE_INLINE
259 void subtract_scaled(const RightVector & right, const value_type & factor);
260
264 LIBMESH_DEVICE_INLINE
265 void zero();
266
270 template <typename RightVector>
271 LIBMESH_DEVICE_INLINE
272 auto contract(const RightVector & right) const;
273
278 LIBMESH_DEVICE_INLINE
279 auto norm() const;
280
284 LIBMESH_DEVICE_INLINE
285 auto norm_sq() const;
286
291 LIBMESH_DEVICE_INLINE
292 auto l1_norm() const;
293
298 LIBMESH_DEVICE_INLINE
299 bool is_zero() const;
300
305 LIBMESH_DEVICE_INLINE
306 auto unit() const;
307
312 template <typename RightVector>
313 LIBMESH_DEVICE_INLINE
314 auto cross(const RightVector & right) const;
315
319 LIBMESH_DEVICE_INLINE
320 unsigned int index() const
321 {
322 return _index;
323 }
324
325private:
326 ViewType _view;
327 unsigned int _index;
328};
329
339template <typename ViewType>
341{
342public:
343 // The underlying view type and the scalar type of its components.
344 using view_type = ViewType;
346
350 LIBMESH_DEVICE_INLINE
351 tensor_ref(ViewType view, const unsigned int index) : _view(view), _index(index) {}
352
358 LIBMESH_DEVICE_INLINE
359 decltype(auto) operator()(const unsigned int row, const unsigned int col) const
360 {
361 return _view(_index, row, col);
362 }
363
364 LIBMESH_DEVICE_INLINE
365 decltype(auto) operator()(const unsigned int row, const unsigned int col)
366 {
367 return _view(_index, row, col);
368 }
369
373 template <typename RightTensor>
374 LIBMESH_DEVICE_INLINE
375 void assign(const RightTensor & right);
376
380 template <typename RightTensor>
381 LIBMESH_DEVICE_INLINE
382 void add(const RightTensor & right);
383
387 template <typename RightTensor>
388 LIBMESH_DEVICE_INLINE
389 void add_scaled(const RightTensor & right, const value_type & factor);
390
394 template <typename RightTensor>
395 LIBMESH_DEVICE_INLINE
396 void subtract(const RightTensor & right);
397
402 template <typename RightTensor>
403 LIBMESH_DEVICE_INLINE
404 void subtract_scaled(const RightTensor & right, const value_type & factor);
405
409 LIBMESH_DEVICE_INLINE
410 void zero();
411
416 template <typename RightTensor>
417 LIBMESH_DEVICE_INLINE
418 auto contract(const RightTensor & right) const;
419
424 LIBMESH_DEVICE_INLINE
425 auto norm() const;
426
430 LIBMESH_DEVICE_INLINE
431 auto norm_sq() const;
432
437 LIBMESH_DEVICE_INLINE
438 bool is_zero() const;
439
444 LIBMESH_DEVICE_INLINE
445 auto transpose() const;
446
451 LIBMESH_DEVICE_INLINE
452 auto det(const unsigned int dim = LIBMESH_DIM) const;
453
457 LIBMESH_DEVICE_INLINE
458 auto tr() const;
459
464 LIBMESH_DEVICE_INLINE
465 auto inverse(const unsigned int dim = LIBMESH_DIM) const;
466
471 template <typename VectorLike, typename ResultVector>
472 LIBMESH_DEVICE_INLINE
473 void solve(const VectorLike & b, ResultVector & x) const;
474
478 LIBMESH_DEVICE_INLINE
479 auto row(const unsigned int i) const;
480
484 LIBMESH_DEVICE_INLINE
485 auto column(const unsigned int i) const;
486
491 template <typename VectorLike>
492 LIBMESH_DEVICE_INLINE
493 auto left_multiply(const VectorLike & v) const;
494
498 LIBMESH_DEVICE_INLINE
499 unsigned int index() const
500 {
501 return _index;
502 }
503
504private:
505 ViewType _view;
506 unsigned int _index;
507};
508
509// Owning vector types are their own semantic type; a vector_ref
510// materializes to the TypeVector of its component type.
511
512template <typename T>
517
518template <typename T>
523
524template <>
529
530template <typename ViewType>
536
537// The vector-like family: libMesh owning vector types plus vector_ref.
538
539template <typename T>
540struct is_vector_like<libMesh::TypeVector<T>> : std::true_type
541{
542};
543
544template <typename T>
545struct is_vector_like<libMesh::VectorValue<T>> : std::true_type
546{
547};
548
549template <>
550struct is_vector_like<libMesh::Point> : std::true_type
551{
552};
553
554template <typename ViewType>
555struct is_vector_like<vector_ref<ViewType>> : std::true_type
556{
557};
558
559template <typename ViewType>
560struct is_vector_ref<vector_ref<ViewType>> : std::true_type
561{
562};
563
564// Owning tensor types are their own semantic type; a tensor_ref
565// materializes to the TypeTensor of its component type.
566
567template <typename T>
572
573template <typename T>
578
579template <typename ViewType>
585
586// The tensor-like family: libMesh owning tensor types plus tensor_ref.
587
588template <typename T>
589struct is_tensor_like<libMesh::TypeTensor<T>> : std::true_type
590{
591};
592
593template <typename T>
594struct is_tensor_like<libMesh::TensorValue<T>> : std::true_type
595{
596};
597
598template <typename ViewType>
599struct is_tensor_like<tensor_ref<ViewType>> : std::true_type
600{
601};
602
603template <typename ViewType>
604struct is_tensor_ref<tensor_ref<ViewType>> : std::true_type
605{
606};
607
612template <typename T>
614
619template <typename T>
621
629template <typename ViewType>
630LIBMESH_DEVICE_INLINE
632make_vector_ref(ViewType && view, const unsigned int index)
633{
634 return vector_ref<typename std::remove_reference<ViewType>::type>(std::forward<ViewType>(view),
635 index);
636}
637
643template <typename ViewType>
644LIBMESH_DEVICE_INLINE
645tensor_ref<typename std::remove_reference<ViewType>::type>
646make_tensor_ref(ViewType && view, const unsigned int index)
647{
648 return tensor_ref<typename std::remove_reference<ViewType>::type>(std::forward<ViewType>(view),
649 index);
650}
651
659template <typename OutputVector, typename VectorLike>
660LIBMESH_DEVICE_INLINE
661OutputVector materialize_vector(const VectorLike & v)
662{
663 static_assert(is_vector_like_v<OutputVector>,
664 "materialize_vector() requires a vector-like output type");
665 static_assert(is_vector_like_v<VectorLike>,
666 "materialize_vector() requires a vector-like input type");
667
668 OutputVector out;
669 out.zero();
670
671 for (unsigned int component = 0; component < LIBMESH_DIM; ++component)
672 out(component) = v(component);
673
674 return out;
675}
676
681template <typename OutputTensor, typename TensorLike>
682LIBMESH_DEVICE_INLINE
683OutputTensor materialize_tensor(const TensorLike & T_in)
684{
685 static_assert(is_tensor_like_v<OutputTensor>,
686 "materialize_tensor() requires a tensor-like output type");
687 static_assert(is_tensor_like_v<TensorLike>,
688 "materialize_tensor() requires a tensor-like input type");
689
690 OutputTensor out;
691 out.zero();
692
693 for (unsigned int row = 0; row < LIBMESH_DIM; ++row)
694 for (unsigned int col = 0; col < LIBMESH_DIM; ++col)
695 out(row, col) = T_in(row, col);
696
697 return out;
698}
699
700} // namespace libMesh::Kokkos
701
702#endif // LIBMESH_KOKKOS_LINALG_BASE_H
unsigned int dim
Non-owning handle to one tensor entry of a Kokkos storage view.
LIBMESH_DEVICE_INLINE auto left_multiply(const VectorLike &v) const
LIBMESH_DEVICE_INLINE void add(const RightTensor &right)
Adds right to the referenced entry, in place.
LIBMESH_DEVICE_INLINE auto transpose() const
LIBMESH_DEVICE_INLINE tensor_ref(ViewType view, const unsigned int index)
Constructs a reference to entry index of view.
LIBMESH_DEVICE_INLINE unsigned int index() const
LIBMESH_DEVICE_INLINE void zero()
Sets every component of the referenced entry to zero.
LIBMESH_DEVICE_INLINE void subtract_scaled(const RightTensor &right, const value_type &factor)
Subtracts factor times right from the referenced entry, in place.
LIBMESH_DEVICE_INLINE void solve(const VectorLike &b, ResultVector &x) const
Solves the linear system (*this)x = b for x, via the explicit inverse.
LIBMESH_DEVICE_INLINE auto norm() const
LIBMESH_DEVICE_INLINE void add_scaled(const RightTensor &right, const value_type &factor)
Adds factor times right to the referenced entry, in place.
LIBMESH_DEVICE_INLINE auto norm_sq() const
LIBMESH_DEVICE_INLINE void subtract(const RightTensor &right)
Subtracts right from the referenced entry, in place.
LIBMESH_DEVICE_INLINE auto tr() const
LIBMESH_DEVICE_INLINE void assign(const RightTensor &right)
Assigns right 's components to the referenced entry.
LIBMESH_DEVICE_INLINE auto row(const unsigned int i) const
detail::tensor_view_value_t< ViewType > value_type
LIBMESH_DEVICE_INLINE auto contract(const RightTensor &right) const
LIBMESH_DEVICE_INLINE auto inverse(const unsigned int dim=LIBMESH_DIM) const
LIBMESH_DEVICE_INLINE auto det(const unsigned int dim=LIBMESH_DIM) const
LIBMESH_DEVICE_INLINE auto column(const unsigned int i) const
LIBMESH_DEVICE_INLINE bool is_zero() const
Non-owning handle to one vector entry of a Kokkos storage view.
LIBMESH_DEVICE_INLINE auto l1_norm() const
LIBMESH_DEVICE_INLINE auto norm() const
LIBMESH_DEVICE_INLINE vector_ref(ViewType view, const unsigned int index)
Constructs a reference to entry index of view.
LIBMESH_DEVICE_INLINE auto cross(const RightVector &right) const
LIBMESH_DEVICE_INLINE void zero()
Sets every component of the referenced entry to zero.
LIBMESH_DEVICE_INLINE void add_scaled(const RightVector &right, const value_type &factor)
Adds factor times right to the referenced entry, in place.
LIBMESH_DEVICE_INLINE void add(const RightVector &right)
Adds right to the referenced entry, in place.
detail::vector_view_value_t< ViewType > value_type
LIBMESH_DEVICE_INLINE void subtract(const RightVector &right)
Subtracts right from the referenced entry, in place.
LIBMESH_DEVICE_INLINE void subtract_scaled(const RightVector &right, const value_type &factor)
Subtracts factor times right from the referenced entry, in place.
LIBMESH_DEVICE_INLINE auto norm_sq() const
LIBMESH_DEVICE_INLINE auto contract(const RightVector &right) const
LIBMESH_DEVICE_INLINE void assign(const RightVector &right)
Assigns right 's components to the referenced entry.
LIBMESH_DEVICE_INLINE unsigned int index() const
LIBMESH_DEVICE_INLINE auto unit() const
LIBMESH_DEVICE_INLINE bool is_zero() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:41
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
Definition type_tensor.h:54
This class defines a vector in LIBMESH_DIM dimensional space of type T.
Definition type_vector.h:64
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
static const Real b
remove_cvref_t< decltype(std::declval< ViewType & >()(0, 0))> vector_view_value_t
The plain component type stored by a vector view.
typename std::remove_cv< typename std::remove_reference< T >::type >::type remove_cvref_t
Strips reference and const/volatile qualifiers from T, turning e.g.
remove_cvref_t< decltype(std::declval< ViewType & >()(0, 0, 0))> tensor_view_value_t
The plain component type stored by a tensor view, recovered from an (entry, row, column) indexing exp...
LIBMESH_DEVICE_INLINE OutputTensor materialize_tensor(const TensorLike &T_in)
LIBMESH_DEVICE_INLINE vector_ref< typename std::remove_reference< ViewType >::type > make_vector_ref(ViewType &&view, const unsigned int index)
constexpr bool is_tensor_like_v
typename tensor_traits< detail::remove_cvref_t< T > >::semantic_type tensor_semantic_type_t
The owning libMesh type a tensor-like T materializes to, with any cv/reference qualification on T str...
LIBMESH_DEVICE_INLINE OutputVector materialize_vector(const VectorLike &v)
constexpr bool is_vector_like_v
Variable template shorthands for the traits above.
typename vector_traits< detail::remove_cvref_t< T > >::semantic_type vector_semantic_type_t
The owning libMesh type a vector-like T materializes to, with any cv/reference qualification on T str...
constexpr bool is_vector_ref_v
LIBMESH_DEVICE_INLINE auto row(const TensorLike &T_in, const unsigned int i) -> std::enable_if_t< is_tensor_like_v< TensorLike >, std::conditional_t< std::is_void< ResultVector >::value, libMesh::TypeVector< typename TensorLike::value_type >, ResultVector > >
constexpr bool is_tensor_ref_v
LIBMESH_DEVICE_INLINE tensor_ref< typename std::remove_reference< ViewType >::type > make_tensor_ref(ViewType &&view, const unsigned int index)
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy out
Opt-in trait marking the types the generic tensor operations in kokkos_tensor_ops....
Type trait satisfied only by tensor_ref instantiations; the tensor-ref analogue of is_vector_ref.
Opt-in trait marking the types the generic vector operations in kokkos_vector_ops....
Type trait satisfied only by vector_ref instantiations.
typename tensor_ref< ViewType >::value_type value_type
Traits mapping each tensor-like type to its "semantic" owning libMesh type.
typename vector_ref< ViewType >::value_type value_type
Traits mapping each vector-like type to its "semantic" owning libMesh type - the type an algorithm sh...
static const bool value
Definition xdr_io.C:55