12#ifndef GOOSEFEM_MATRIXPARTITIONEDTYINGS_H
13#define GOOSEFEM_MATRIXPARTITIONEDTYINGS_H
19#include <Eigen/Sparse>
20#include <Eigen/SparseCholesky>
26class MatrixPartitionedTyingsSolver;
44 Eigen::SparseMatrix<double>
m_Auu;
45 Eigen::SparseMatrix<double>
m_Aup;
46 Eigen::SparseMatrix<double>
m_Apu;
47 Eigen::SparseMatrix<double>
m_App;
48 Eigen::SparseMatrix<double>
m_Aud;
49 Eigen::SparseMatrix<double>
m_Apd;
50 Eigen::SparseMatrix<double>
m_Adu;
51 Eigen::SparseMatrix<double>
m_Adp;
52 Eigen::SparseMatrix<double>
m_Add;
57 std::vector<Eigen::Triplet<double>>
m_Tuu;
58 std::vector<Eigen::Triplet<double>>
m_Tup;
59 std::vector<Eigen::Triplet<double>>
m_Tpu;
60 std::vector<Eigen::Triplet<double>>
m_Tpp;
61 std::vector<Eigen::Triplet<double>>
m_Tud;
62 std::vector<Eigen::Triplet<double>>
m_Tpd;
63 std::vector<Eigen::Triplet<double>>
m_Tdu;
64 std::vector<Eigen::Triplet<double>>
m_Tdp;
65 std::vector<Eigen::Triplet<double>>
m_Tdd;
66 Eigen::SparseMatrix<double>
m_Cdu;
67 Eigen::SparseMatrix<double>
m_Cdp;
68 Eigen::SparseMatrix<double>
m_Cud;
69 Eigen::SparseMatrix<double>
m_Cpd;
89 const Eigen::SparseMatrix<double>& Cdu,
90 const Eigen::SparseMatrix<double>& Cdp
140 const Eigen::SparseMatrix<double>&
data_uu()
const
148 const Eigen::SparseMatrix<double>&
data_up()
const
156 const Eigen::SparseMatrix<double>&
data_pu()
const
164 const Eigen::SparseMatrix<double>&
data_pp()
const
172 const Eigen::SparseMatrix<double>&
data_ud()
const
180 const Eigen::SparseMatrix<double>&
data_pd()
const
188 const Eigen::SparseMatrix<double>&
data_du()
const
196 const Eigen::SparseMatrix<double>&
data_dp()
const
204 const Eigen::SparseMatrix<double>&
data_dd()
const
211 void assemble_impl(
const T&
elemmat)
226 for (
size_t m = 0;
m <
m_nne; ++
m) {
231 for (
size_t n = 0;
n <
m_nne; ++
n) {
237 m_Tuu.push_back(Eigen::Triplet<double>(
242 m_Tup.push_back(Eigen::Triplet<double>(
247 m_Tud.push_back(Eigen::Triplet<double>(
252 m_Tpu.push_back(Eigen::Triplet<double>(
257 m_Tpp.push_back(Eigen::Triplet<double>(
264 m_Tpd.push_back(Eigen::Triplet<double>(
271 m_Tdu.push_back(Eigen::Triplet<double>(
276 m_Tdp.push_back(Eigen::Triplet<double>(
283 m_Tdd.push_back(Eigen::Triplet<double>(
309 void todense_impl(
T&
ret)
const
313 for (
int k = 0;
k <
m_Auu.outerSize(); ++
k) {
314 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Auu,
k);
it; ++
it) {
319 for (
int k = 0;
k <
m_Aup.outerSize(); ++
k) {
320 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Aup,
k);
it; ++
it) {
325 for (
int k = 0;
k <
m_Apu.outerSize(); ++
k) {
326 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Apu,
k);
it; ++
it) {
331 for (
int k = 0;
k <
m_App.outerSize(); ++
k) {
332 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_App,
k);
it; ++
it) {
337 for (
int k = 0;
k <
m_Adu.outerSize(); ++
k) {
338 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Adu,
k);
it; ++
it) {
343 for (
int k = 0;
k <
m_Adp.outerSize(); ++
k) {
344 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Adp,
k);
it; ++
it) {
349 for (
int k = 0;
k <
m_Aud.outerSize(); ++
k) {
350 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Aud,
k);
it; ++
it) {
355 for (
int k = 0;
k <
m_Apd.outerSize(); ++
k) {
356 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Apd,
k);
it; ++
it) {
361 for (
int k = 0;
k <
m_Add.outerSize(); ++
k) {
362 for (Eigen::SparseMatrix<double>::InnerIterator
it(
m_Add,
k);
it; ++
it) {
369 void dot_nodevec_impl(
const T&
x,
T&
b)
const
373 throw std::runtime_error(
"Not yet implemented");
377 void dot_dofval_impl(
const T&
x,
T&
b)
const
381 throw std::runtime_error(
"Not yet implemented");
385 void reaction_nodevec_impl(
const T&
x,
T&
b)
const
389 throw std::runtime_error(
"Not yet implemented");
393 void reaction_dofval_impl(
const T&
x,
T&
b)
const
397 throw std::runtime_error(
"Not yet implemented");
400 void reaction_p_impl(
401 const array_type::tensor<double, 1>&
x_u,
402 const array_type::tensor<double, 1>&
x_p,
403 array_type::tensor<double, 1>&
b_p
409 throw std::runtime_error(
"Not yet implemented");
414 Eigen::VectorXd AsDofs_u(
const array_type::tensor<double, 1>&
dofval)
const
420#pragma omp parallel for
421 for (
size_t d = 0;
d <
m_nnu; ++
d) {
428 Eigen::VectorXd AsDofs_u(
const array_type::tensor<double, 2>&
nodevec)
const
434#pragma omp parallel for
446 Eigen::VectorXd AsDofs_p(
const array_type::tensor<double, 1>&
dofval)
const
452#pragma omp parallel for
453 for (
size_t d = 0;
d <
m_nnp; ++
d) {
460 Eigen::VectorXd AsDofs_p(
const array_type::tensor<double, 2>&
nodevec)
const
466#pragma omp parallel for
478 Eigen::VectorXd AsDofs_d(
const array_type::tensor<double, 1>&
dofval)
const
484#pragma omp parallel for
485 for (
size_t d = 0;
d <
m_nnd; ++
d) {
492 Eigen::VectorXd AsDofs_d(
const array_type::tensor<double, 2>&
nodevec)
const
498#pragma omp parallel for
527template <
class Solver = Eigen::SimplicialLDLT<Eigen::SparseMatrix<
double>>>
544 Eigen::VectorXd
B_u =
A.AsDofs_u(
b);
545 Eigen::VectorXd
B_d =
A.AsDofs_d(
b);
546 Eigen::VectorXd
X_p =
A.AsDofs_p(
x);
550 Eigen::VectorXd
X_u = m_solver.solve(Eigen::VectorXd(
B_u -
A.m_ACup *
X_p));
551 Eigen::VectorXd
X_d =
A.m_Cdu *
X_u +
A.m_Cdp *
X_p;
553#pragma omp parallel for
554 for (
size_t m = 0;
m <
A.m_nnode; ++
m) {
555 for (
size_t i = 0;
i <
A.m_ndim; ++
i) {
556 if (
A.m_dofs(
m,
i) <
A.m_nnu) {
559 else if (
A.m_dofs(
m,
i) >=
A.m_nni) {
571 Eigen::VectorXd
B_u =
A.AsDofs_u(
b);
572 Eigen::VectorXd
B_d =
A.AsDofs_d(
b);
573 Eigen::VectorXd
X_p =
A.AsDofs_p(
x);
575 Eigen::VectorXd
X_u = m_solver.solve(Eigen::VectorXd(
B_u -
A.m_ACup *
X_p));
576 Eigen::VectorXd
X_d =
A.m_Cdu *
X_u +
A.m_Cdp *
X_p;
578#pragma omp parallel for
579 for (
size_t d = 0;
d <
A.m_nnu; ++
d) {
583#pragma omp parallel for
584 for (
size_t d = 0;
d <
A.m_nnd; ++
d) {
641 Eigen::Map<Eigen::VectorXd>(
x_u.data(),
x_u.size()).noalias() =
642 m_solver.solve(Eigen::VectorXd(
643 Eigen::Map<const Eigen::VectorXd>(
b_u.data(),
b_u.size()) -
644 A.m_ACup * Eigen::Map<const Eigen::VectorXd>(
x_p.data(),
x_p.size())
650 bool m_factor =
true;
657 if (!
A.m_changed && !m_factor) {
661 A.m_ACuu =
A.m_Auu +
A.m_Aud *
A.m_Cdu +
A.m_Cud *
A.m_Adu +
A.m_Cud *
A.m_Add *
A.m_Cdu;
663 A.m_ACup =
A.m_Aup +
A.m_Aud *
A.m_Cdp +
A.m_Cud *
A.m_Adp +
A.m_Cud *
A.m_Add *
A.m_Cdp;
671 m_solver.compute(
A.m_ACuu);
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.
array_type::tensor< size_t, 1 > m_iiu
See iiu()
array_type::tensor< size_t, 1 > m_iip
See iip()
CRTP base class for a partitioned matrix with tying.
array_type::tensor< size_t, 1 > m_iii
See iii()
array_type::tensor< size_t, 1 > m_iid
See iid()
Solver for MatrixPartitionedTyings().
array_type::tensor< double, 1 > Solve_u(MatrixPartitionedTyings &A, const array_type::tensor< double, 1 > &b_u, const array_type::tensor< double, 1 > &b_d, const array_type::tensor< double, 1 > &x_p)
Same as Solve(MatrixPartitionedTyings&, const array_type::tensor<double, 2>&, const array_type::tenso...
void solve_u(MatrixPartitionedTyings &A, const array_type::tensor< double, 1 > &b_u, const array_type::tensor< double, 1 > &b_d, const array_type::tensor< double, 1 > &x_p, array_type::tensor< double, 1 > &x_u)
Same as Solve_u(MatrixPartitionedTyings&, const array_type::tensor<double, 1>&, const array_type::ten...
Sparse matrix from with dependent DOFs are eliminated, and the remaining (small) independent system i...
std::vector< Eigen::Triplet< double > > m_Tpp
Matrix entries.
Eigen::SparseMatrix< double > m_Auu
The matrix.
const Eigen::SparseMatrix< double > & data_pd() const
Pointer to data.
std::vector< Eigen::Triplet< double > > m_Tup
Matrix entries.
Eigen::SparseMatrix< double > m_Cdu
Tying matrix, see Tyings::Periodic::Cdu().
Eigen::SparseMatrix< double > m_App
The matrix.
Eigen::SparseMatrix< double > m_ACup
// The matrix for which the tyings have been applied.
Eigen::SparseMatrix< double > m_Aup
The matrix.
Eigen::SparseMatrix< double > m_Adp
The matrix.
Eigen::SparseMatrix< double > m_Apd
The matrix.
std::vector< Eigen::Triplet< double > > m_Tdu
Matrix entries.
std::vector< Eigen::Triplet< double > > m_Tdd
Matrix entries.
const Eigen::SparseMatrix< double > & data_uu() const
Pointer to data.
Eigen::SparseMatrix< double > m_Apu
The matrix.
const Eigen::SparseMatrix< double > & data_dd() const
Pointer to data.
const Eigen::SparseMatrix< double > & data_pu() const
Pointer to data.
const Eigen::SparseMatrix< double > & data_ud() const
Pointer to data.
Eigen::SparseMatrix< double > m_ACpp
// The matrix for which the tyings have been applied.
std::vector< Eigen::Triplet< double > > m_Tpd
Matrix entries.
Eigen::SparseMatrix< double > m_Add
The matrix.
Eigen::SparseMatrix< double > m_Aud
The matrix.
Eigen::SparseMatrix< double > m_ACpu
// The matrix for which the tyings have been applied.
const Eigen::SparseMatrix< double > & data_pp() const
Pointer to data.
const Eigen::SparseMatrix< double > & data_up() const
Pointer to data.
Eigen::SparseMatrix< double > m_Adu
The matrix.
MatrixPartitionedTyings(const array_type::tensor< size_t, 2 > &conn, const array_type::tensor< size_t, 2 > &dofs, const Eigen::SparseMatrix< double > &Cdu, const Eigen::SparseMatrix< double > &Cdp)
Constructor.
const Eigen::SparseMatrix< double > & data_du() const
Pointer to data.
std::vector< Eigen::Triplet< double > > m_Tud
Matrix entries.
Eigen::SparseMatrix< double > m_Cpd
Transpose of "m_Cdp".
Eigen::SparseMatrix< double > m_ACuu
// The matrix for which the tyings have been applied.
std::vector< Eigen::Triplet< double > > m_Tuu
Matrix entries.
const Eigen::SparseMatrix< double > & data_dp() const
Pointer to data.
Eigen::SparseMatrix< double > m_Cdp
Tying matrix, see Tyings::Periodic::Cdp().
std::vector< Eigen::Triplet< double > > m_Tpu
Matrix entries.
std::vector< Eigen::Triplet< double > > m_Tdp
Matrix entries.
Eigen::SparseMatrix< double > m_Cud
Transpose of "m_Cdu".
CRTP base class for a solver class.
CRTP base class for a extra functions for a partitioned solver class.
#define GOOSEFEM_ASSERT(expr)
All assertions are implementation as::
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Toolbox to perform finite element computations.
auto AsTensor(const T &arg, const S &shape)
"Broadcast" a scalar stored in an array (e.g.