11#ifndef GOOSEFEM_MATRIXDIAGONALPARTITIONED_H
12#define GOOSEFEM_MATRIXDIAGONALPARTITIONED_H
62 m_iiu = xt::setdiff1d(
dofs,
iip);
66 m_Auu = xt::empty<double>({m_nnu});
67 m_App = xt::empty<double>({m_nnp});
68 m_inv_uu = xt::empty<double>({m_nnu});
101 void todense_impl(
T&
ret)
const
105#pragma omp parallel for
106 for (
size_t d = 0;
d < m_nnu; ++
d) {
107 ret(m_iiu(
d), m_iiu(
d)) = m_Auu(
d);
110#pragma omp parallel for
111 for (
size_t d = 0;
d < m_nnp; ++
d) {
112 ret(m_iip(
d), m_iip(
d)) = m_App(
d);
125#pragma omp parallel for
126 for (
size_t d = 0;
d < m_nnu; ++
d) {
127 m_Auu(
d) =
A(m_iiu(
d));
130#pragma omp parallel for
131 for (
size_t d = 0;
d < m_nnp; ++
d) {
132 m_App(
d) =
A(m_iip(
d));
146#pragma omp parallel for
147 for (
size_t d = 0;
d < m_nnu; ++
d) {
148 ret(m_iiu(
d)) = m_Auu(
d);
151#pragma omp parallel for
152 for (
size_t d = 0;
d < m_nnp; ++
d) {
153 ret(m_iip(
d)) = m_App(
d);
189 void dot_nodevec_impl(
const T&
x,
T&
b)
const
194#pragma omp parallel for
198 size_t d = m_part(
m,
i);
204 b(
m,
i) = m_App(
d - m_nnu) *
x(
m,
i);
211 void dot_dofval_impl(
const T&
x,
T&
b)
const
216#pragma omp parallel for
217 for (
size_t d = 0;
d < m_nnu; ++
d) {
218 b(m_iiu(
d)) = m_Auu(
d) *
x(m_iiu(
d));
221#pragma omp parallel for
222 for (
size_t d = 0;
d < m_nnp; ++
d) {
223 b(m_iip(
d)) = m_App(
d) *
x(m_iip(
d));
234 array_type::tensor<double, 1>
260#pragma omp parallel for
261 for (
size_t d = 0;
d < m_nnu; ++
d) {
298#pragma omp parallel for
299 for (
size_t d = 0;
d < m_nnp; ++
d) {
306 void solve_nodevec_impl(
const T&
b,
T&
x)
313#pragma omp parallel for
316 if (m_part(
m,
i) < m_nnu) {
317 x(
m,
i) = m_inv_uu(m_part(
m,
i)) *
b(
m,
i);
324 void solve_dofval_impl(
const T&
b,
T&
x)
331#pragma omp parallel for
332 for (
size_t d = 0;
d < m_nnu; ++
d) {
333 x(m_iiu(
d)) = m_inv_uu(
d) *
b(m_iiu(
d));
343 array_type::tensor<double, 1>
370#pragma omp parallel for
371 for (
size_t d = 0;
d < m_nnu; ++
d) {
378 void reaction_nodevec_impl(
const T&
x,
T&
b)
const
383#pragma omp parallel for
386 if (m_part(
m,
i) >= m_nnu) {
387 b(
m,
i) = m_App(m_part(
m,
i) - m_nnu) *
x(
m,
i);
394 void reaction_dofval_impl(
const T&
x,
T&
b)
const
399#pragma omp parallel for
400 for (
size_t d = 0;
d < m_nnp; ++
d) {
401 b(m_iip(
d)) = m_App(
d) *
x(m_iip(
d));
405 void reaction_p_impl(
406 const array_type::tensor<double, 1>&
x_u,
407 const array_type::tensor<double, 1>&
x_p,
408 array_type::tensor<double, 1>&
b_p
417#pragma omp parallel for
418 for (
size_t d = 0;
d < m_nnp; ++
d) {
425 array_type::tensor<double, 1> m_Auu;
426 array_type::tensor<double, 1> m_App;
427 array_type::tensor<double, 1> m_inv_uu;
430 array_type::tensor<size_t, 2> m_part;
431 array_type::tensor<size_t, 1> m_iiu;
432 array_type::tensor<size_t, 1> m_iip;
445#pragma omp parallel for
446 for (
size_t d = 0;
d < m_nnu; ++
d) {
447 m_inv_uu(
d) = 1.0 / m_Auu(
d);
CRTP base class for a matrix.
const array_type::tensor< size_t, 2 > & dofs() const
DOFs per node.
const array_type::tensor< size_t, 2 > & conn() const
Connectivity.
array_type::tensor< size_t, 2 > m_dofs
DOF-numbers per node [nnode, ndim].
array_type::tensor< size_t, 2 > m_conn
Connectivity [nelem, nne].
size_t m_nelem
See nelem().
bool m_changed
Signal changes to data.
size_t m_nnode
See nnode().
CRTP base class for a partitioned matrix with tying.
Diagonal and partitioned matrix.
array_type::tensor< double, 1 > Solve_u(const array_type::tensor< double, 1 > &b_u, const array_type::tensor< double, 1 > &x_p)
MatrixDiagonalPartitioned(const array_type::tensor< size_t, 2 > &conn, const array_type::tensor< size_t, 2 > &dofs, const array_type::tensor< size_t, 1 > &iip)
Constructor.
void dot_u(const array_type::tensor< double, 1 > &x_u, const array_type::tensor< double, 1 > &x_p, array_type::tensor< double, 1 > &b_u) const
const array_type::tensor< double, 1 > & data_uu() const
Pointer to data.
array_type::tensor< double, 1 > Dot_p(const array_type::tensor< double, 1 > &x_u, const array_type::tensor< double, 1 > &x_p) const
array_type::tensor< double, 1 > data() const
Assemble to diagonal matrix (involves copies).
array_type::tensor< double, 1 > Todiagonal() const
Pointer to data.
array_type::tensor< double, 1 > Dot_u(const array_type::tensor< double, 1 > &x_u, const array_type::tensor< double, 1 > &x_p) const
void solve_u(const array_type::tensor< double, 1 > &b_u, const array_type::tensor< double, 1 > &x_p, array_type::tensor< double, 1 > &x_u)
void set(const array_type::tensor< double, 1 > &A)
Set all (diagonal) matrix components.
const array_type::tensor< double, 1 > & data_pp() const
Pointer to data.
void dot_p(const array_type::tensor< double, 1 > &x_u, const array_type::tensor< double, 1 > &x_p, array_type::tensor< double, 1 > &b_p) const
CRTP base class for a partitioned matrix.
const array_type::tensor< size_t, 1 > & iip() const
Prescribed DOFs.
Reorder to lowest possible index, in specific order.
#define GOOSEFEM_ASSERT(expr)
All assertions are implementation as::
bool isDiagonal(const array_type::tensor< double, 3 > &elemmat)
Check that all of the matrices stored per elemmat (shape: [nelem, nne * ndim, nne * ndim]) are diagon...
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Toolbox to perform finite element computations.
bool is_unique(const T &arg)
Returns true is a list is unique (has not duplicate items).
auto AsTensor(const T &arg, const S &shape)
"Broadcast" a scalar stored in an array (e.g.