deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
tensor.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2020 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
17#include <deal.II/base/tensor.h>
18
22
23#include <Kokkos_Macros.hpp>
24
25#include <array>
26#include <cstddef>
27#include <string>
28
30
31namespace
32{
33 template <int dim, typename Number>
34 void
35 calculate_svd_in_place(Tensor<2, dim, Number> &A_in_VT_out,
37 {
38 // inputs: A
39 // outputs: V^T, U
40 // SVD: A = U S V^T
41 // Since Tensor stores data in row major order and lapack expects column
42 // major ordering, we take the SVD of A^T by running the gesvd command.
43 // The results (V^T)^T and U^T are provided in column major that we use
44 // as row major results V^T and U.
45 // It essentially computes A^T = (V^T)^T S U^T and gives us V^T and U.
46 // This trick gives what we originally wanted (A = U S V^T) but the order
47 // of U and V^T is reversed.
48 std::array<Number, dim> S;
49 const types::blas_int N = dim;
50 // lwork must be >= max(1, 3*min(m,n)+max(m,n), 5*min(m,n))
51 const types::blas_int lwork = 5 * dim;
52 std::array<Number, lwork> work;
53 types::blas_int info;
54 constexpr std::size_t size =
56 std::array<Number, size> A_array;
57 A_in_VT_out.unroll(A_array.begin(), A_array.end());
58 std::array<Number, size> U_array;
59 U.unroll(U_array.begin(), U_array.end());
60 gesvd(&LAPACKSupport::O, // replace VT in place
62 &N,
63 &N,
64 A_array.data(),
65 &N,
66 S.data(),
67 A_array.data(),
68 &N,
69 U_array.data(),
70 &N,
71 work.data(),
72 &lwork,
73 &info);
74 Assert(info == 0, LAPACKSupport::ExcErrorCode("gesvd", info));
75 Assert(S.back() / S.front() > 1.e-10, LACExceptions::ExcSingular());
76
77 A_in_VT_out =
78 Tensor<2, dim, Number>(make_array_view(A_array.begin(), A_array.end()));
79 U = Tensor<2, dim, Number>(make_array_view(U_array.begin(), U_array.end()));
80 }
81} // namespace
82
83
84
85template <int dim, typename Number>
88{
90 calculate_svd_in_place(VT, U);
91 return U * VT;
92}
93
94
95
100template Tensor<2, 3, float>
108
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
void unroll(const Iterator begin, const Iterator end) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcErrorCode(std::string arg1, types::blas_int arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcSingular()
void gesvd(const char *, const char *, const ::types::blas_int *, const ::types::blas_int *, number1 *, const ::types::blas_int *, number2 *, number3 *, const ::types::blas_int *, number4 *, const ::types::blas_int *, number5 *, const ::types::blas_int *, ::types::blas_int *)
std::size_t size
Definition mpi.cc:733
constexpr char O
constexpr char N
constexpr char U
constexpr char A
Tensor< 2, dim, Number > project_onto_orthogonal_tensors(const Tensor< 2, dim, Number > &A)
Definition tensor.cc:87