FrictionQPotFEM 0.23.3
Loading...
Searching...
No Matches
MatrixPartitionedTyings.h
Go to the documentation of this file.
1
12#ifndef GOOSEFEM_MATRIXPARTITIONEDTYINGS_H
13#define GOOSEFEM_MATRIXPARTITIONEDTYINGS_H
14
15#include "Matrix.h"
16#include "config.h"
17
18#include <Eigen/Eigen>
19#include <Eigen/Sparse>
20#include <Eigen/SparseCholesky>
21
22namespace GooseFEM {
23
24// forward declaration
25template <class>
26class MatrixPartitionedTyingsSolver;
27
37class MatrixPartitionedTyings : public MatrixPartitionedTyingsBase<MatrixPartitionedTyings> {
38private:
42
43protected:
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;
53 Eigen::SparseMatrix<double> m_ACuu;
54 Eigen::SparseMatrix<double> m_ACup;
55 Eigen::SparseMatrix<double> m_ACpu;
56 Eigen::SparseMatrix<double> m_ACpp;
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;
70
71 // grant access to solver class
72 template <class>
74
75public:
76 MatrixPartitionedTyings() = default;
77
89 const Eigen::SparseMatrix<double>& Cdu,
90 const Eigen::SparseMatrix<double>& Cdp)
91 {
92 GOOSEFEM_ASSERT(Cdu.rows() == Cdp.rows());
93
94 m_conn = conn;
95 m_dofs = dofs;
96 m_Cdu = Cdu;
97 m_Cdp = Cdp;
98 m_nnu = static_cast<size_t>(m_Cdu.cols());
99 m_nnp = static_cast<size_t>(m_Cdp.cols());
100 m_nnd = static_cast<size_t>(m_Cdp.rows());
101 m_nni = m_nnu + m_nnp;
102 m_ndof = m_nni + m_nnd;
103 m_iiu = xt::arange<size_t>(m_nnu);
104 m_iip = xt::arange<size_t>(m_nnu, m_nnu + m_nnp);
105 m_iii = xt::arange<size_t>(m_nni);
106 m_iid = xt::arange<size_t>(m_nni, m_nni + m_nnd);
107 m_nelem = m_conn.shape(0);
108 m_nne = m_conn.shape(1);
109 m_nnode = m_dofs.shape(0);
110 m_ndim = m_dofs.shape(1);
111 m_Cud = m_Cdu.transpose();
112 m_Cpd = m_Cdp.transpose();
113 m_Tuu.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
114 m_Tup.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
115 m_Tpu.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
116 m_Tpp.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
117 m_Tud.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
118 m_Tpd.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
119 m_Tdu.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
120 m_Tdp.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
121 m_Tdd.reserve(m_nelem * m_nne * m_ndim * m_nne * m_ndim);
122 m_Auu.resize(m_nnu, m_nnu);
123 m_Aup.resize(m_nnu, m_nnp);
124 m_Apu.resize(m_nnp, m_nnu);
125 m_App.resize(m_nnp, m_nnp);
126 m_Aud.resize(m_nnu, m_nnd);
127 m_Apd.resize(m_nnp, m_nnd);
128 m_Adu.resize(m_nnd, m_nnu);
129 m_Adp.resize(m_nnd, m_nnp);
130 m_Add.resize(m_nnd, m_nnd);
131
133 GOOSEFEM_ASSERT(m_ndof == xt::amax(m_dofs)() + 1);
134 }
135
139 const Eigen::SparseMatrix<double>& data_uu() const
140 {
141 return m_Auu;
142 }
143
147 const Eigen::SparseMatrix<double>& data_up() const
148 {
149 return m_Aup;
150 }
151
155 const Eigen::SparseMatrix<double>& data_pu() const
156 {
157 return m_Apu;
158 }
159
163 const Eigen::SparseMatrix<double>& data_pp() const
164 {
165 return m_App;
166 }
167
171 const Eigen::SparseMatrix<double>& data_ud() const
172 {
173 return m_Aud;
174 }
175
179 const Eigen::SparseMatrix<double>& data_pd() const
180 {
181 return m_Apd;
182 }
183
187 const Eigen::SparseMatrix<double>& data_du() const
188 {
189 return m_Adu;
190 }
191
195 const Eigen::SparseMatrix<double>& data_dp() const
196 {
197 return m_Adp;
198 }
199
203 const Eigen::SparseMatrix<double>& data_dd() const
204 {
205 return m_Add;
206 }
207
208private:
209 template <class T>
210 void assemble_impl(const T& elemmat)
211 {
212 GOOSEFEM_ASSERT(xt::has_shape(elemmat, {m_nelem, m_nne * m_ndim, m_nne * m_ndim}));
213
214 m_Tuu.clear();
215 m_Tup.clear();
216 m_Tpu.clear();
217 m_Tpp.clear();
218 m_Tud.clear();
219 m_Tpd.clear();
220 m_Tdu.clear();
221 m_Tdp.clear();
222 m_Tdd.clear();
223
224 for (size_t e = 0; e < m_nelem; ++e) {
225 for (size_t m = 0; m < m_nne; ++m) {
226 for (size_t i = 0; i < m_ndim; ++i) {
227
228 size_t di = m_dofs(m_conn(e, m), i);
229
230 for (size_t n = 0; n < m_nne; ++n) {
231 for (size_t j = 0; j < m_ndim; ++j) {
232
233 size_t dj = m_dofs(m_conn(e, n), j);
234
235 if (di < m_nnu && dj < m_nnu) {
236 m_Tuu.push_back(Eigen::Triplet<double>(
237 di, dj, elemmat(e, m * m_ndim + i, n * m_ndim + j)));
238 }
239 else if (di < m_nnu && dj < m_nni) {
240 m_Tup.push_back(Eigen::Triplet<double>(
241 di, dj - m_nnu, elemmat(e, m * m_ndim + i, n * m_ndim + j)));
242 }
243 else if (di < m_nnu) {
244 m_Tud.push_back(Eigen::Triplet<double>(
245 di, dj - m_nni, elemmat(e, m * m_ndim + i, n * m_ndim + j)));
246 }
247 else if (di < m_nni && dj < m_nnu) {
248 m_Tpu.push_back(Eigen::Triplet<double>(
249 di - m_nnu, dj, elemmat(e, m * m_ndim + i, n * m_ndim + j)));
250 }
251 else if (di < m_nni && dj < m_nni) {
252 m_Tpp.push_back(Eigen::Triplet<double>(
253 di - m_nnu,
254 dj - m_nnu,
255 elemmat(e, m * m_ndim + i, n * m_ndim + j)));
256 }
257 else if (di < m_nni) {
258 m_Tpd.push_back(Eigen::Triplet<double>(
259 di - m_nnu,
260 dj - m_nni,
261 elemmat(e, m * m_ndim + i, n * m_ndim + j)));
262 }
263 else if (dj < m_nnu) {
264 m_Tdu.push_back(Eigen::Triplet<double>(
265 di - m_nni, dj, elemmat(e, m * m_ndim + i, n * m_ndim + j)));
266 }
267 else if (dj < m_nni) {
268 m_Tdp.push_back(Eigen::Triplet<double>(
269 di - m_nni,
270 dj - m_nnu,
271 elemmat(e, m * m_ndim + i, n * m_ndim + j)));
272 }
273 else {
274 m_Tdd.push_back(Eigen::Triplet<double>(
275 di - m_nni,
276 dj - m_nni,
277 elemmat(e, m * m_ndim + i, n * m_ndim + j)));
278 }
279 }
280 }
281 }
282 }
283 }
284
285 m_Auu.setFromTriplets(m_Tuu.begin(), m_Tuu.end());
286 m_Aup.setFromTriplets(m_Tup.begin(), m_Tup.end());
287 m_Apu.setFromTriplets(m_Tpu.begin(), m_Tpu.end());
288 m_App.setFromTriplets(m_Tpp.begin(), m_Tpp.end());
289 m_Aud.setFromTriplets(m_Tud.begin(), m_Tud.end());
290 m_Apd.setFromTriplets(m_Tpd.begin(), m_Tpd.end());
291 m_Adu.setFromTriplets(m_Tdu.begin(), m_Tdu.end());
292 m_Adp.setFromTriplets(m_Tdp.begin(), m_Tdp.end());
293 m_Add.setFromTriplets(m_Tdd.begin(), m_Tdd.end());
294 m_changed = true;
295 }
296
297 // todo: test
298 template <class T>
299 void todense_impl(T& ret) const
300 {
301 ret.fill(0.0);
302
303 for (int k = 0; k < m_Auu.outerSize(); ++k) {
304 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Auu, k); it; ++it) {
305 ret(m_iiu(it.row()), m_iiu(it.col())) = it.value();
306 }
307 }
308
309 for (int k = 0; k < m_Aup.outerSize(); ++k) {
310 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Aup, k); it; ++it) {
311 ret(m_iiu(it.row()), m_iip(it.col())) = it.value();
312 }
313 }
314
315 for (int k = 0; k < m_Apu.outerSize(); ++k) {
316 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Apu, k); it; ++it) {
317 ret(m_iip(it.row()), m_iiu(it.col())) = it.value();
318 }
319 }
320
321 for (int k = 0; k < m_App.outerSize(); ++k) {
322 for (Eigen::SparseMatrix<double>::InnerIterator it(m_App, k); it; ++it) {
323 ret(m_iip(it.row()), m_iip(it.col())) = it.value();
324 }
325 }
326
327 for (int k = 0; k < m_Adu.outerSize(); ++k) {
328 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Adu, k); it; ++it) {
329 ret(m_iid(it.row()), m_iiu(it.col())) = it.value();
330 }
331 }
332
333 for (int k = 0; k < m_Adp.outerSize(); ++k) {
334 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Adp, k); it; ++it) {
335 ret(m_iid(it.row()), m_iip(it.col())) = it.value();
336 }
337 }
338
339 for (int k = 0; k < m_Aud.outerSize(); ++k) {
340 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Aud, k); it; ++it) {
341 ret(m_iiu(it.row()), m_iid(it.col())) = it.value();
342 }
343 }
344
345 for (int k = 0; k < m_Apd.outerSize(); ++k) {
346 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Apd, k); it; ++it) {
347 ret(m_iip(it.row()), m_iid(it.col())) = it.value();
348 }
349 }
350
351 for (int k = 0; k < m_Add.outerSize(); ++k) {
352 for (Eigen::SparseMatrix<double>::InnerIterator it(m_Add, k); it; ++it) {
353 ret(m_iid(it.row()), m_iid(it.col())) = it.value();
354 }
355 }
356 }
357
358 template <class T>
359 void dot_nodevec_impl(const T& x, T& b) const
360 {
361 UNUSED(x);
362 UNUSED(b);
363 throw std::runtime_error("Not yet implemented");
364 }
365
366 template <class T>
367 void dot_dofval_impl(const T& x, T& b) const
368 {
369 UNUSED(x);
370 UNUSED(b);
371 throw std::runtime_error("Not yet implemented");
372 }
373
374 template <class T>
375 void reaction_nodevec_impl(const T& x, T& b) const
376 {
377 UNUSED(x);
378 UNUSED(b);
379 throw std::runtime_error("Not yet implemented");
380 }
381
382 template <class T>
383 void reaction_dofval_impl(const T& x, T& b) const
384 {
385 UNUSED(x);
386 UNUSED(b);
387 throw std::runtime_error("Not yet implemented");
388 }
389
390 void reaction_p_impl(
391 const array_type::tensor<double, 1>& x_u,
392 const array_type::tensor<double, 1>& x_p,
393 array_type::tensor<double, 1>& b_p) const
394 {
395 UNUSED(x_u);
396 UNUSED(x_p);
397 UNUSED(b_p);
398 throw std::runtime_error("Not yet implemented");
399 }
400
401private:
402 // Convert arrays (Eigen version of VectorPartitioned, which contains public functions)
403 Eigen::VectorXd AsDofs_u(const array_type::tensor<double, 1>& dofval) const
404 {
405 GOOSEFEM_ASSERT(dofval.size() == m_ndof);
406
407 Eigen::VectorXd dofval_u(m_nnu, 1);
408
409#pragma omp parallel for
410 for (size_t d = 0; d < m_nnu; ++d) {
411 dofval_u(d) = dofval(m_iiu(d));
412 }
413
414 return dofval_u;
415 }
416
417 Eigen::VectorXd AsDofs_u(const array_type::tensor<double, 2>& nodevec) const
418 {
419 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
420
421 Eigen::VectorXd dofval_u = Eigen::VectorXd::Zero(m_nnu, 1);
422
423#pragma omp parallel for
424 for (size_t m = 0; m < m_nnode; ++m) {
425 for (size_t i = 0; i < m_ndim; ++i) {
426 if (m_dofs(m, i) < m_nnu) {
427 dofval_u(m_dofs(m, i)) = nodevec(m, i);
428 }
429 }
430 }
431
432 return dofval_u;
433 }
434
435 Eigen::VectorXd AsDofs_p(const array_type::tensor<double, 1>& dofval) const
436 {
437 GOOSEFEM_ASSERT(dofval.size() == m_ndof);
438
439 Eigen::VectorXd dofval_p(m_nnp, 1);
440
441#pragma omp parallel for
442 for (size_t d = 0; d < m_nnp; ++d) {
443 dofval_p(d) = dofval(m_iip(d));
444 }
445
446 return dofval_p;
447 }
448
449 Eigen::VectorXd AsDofs_p(const array_type::tensor<double, 2>& nodevec) const
450 {
451 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
452
453 Eigen::VectorXd dofval_p = Eigen::VectorXd::Zero(m_nnp, 1);
454
455#pragma omp parallel for
456 for (size_t m = 0; m < m_nnode; ++m) {
457 for (size_t i = 0; i < m_ndim; ++i) {
458 if (m_dofs(m, i) >= m_nnu && m_dofs(m, i) < m_nni) {
459 dofval_p(m_dofs(m, i) - m_nnu) = nodevec(m, i);
460 }
461 }
462 }
463
464 return dofval_p;
465 }
466
467 Eigen::VectorXd AsDofs_d(const array_type::tensor<double, 1>& dofval) const
468 {
469 GOOSEFEM_ASSERT(dofval.size() == m_ndof);
470
471 Eigen::VectorXd dofval_d(m_nnd, 1);
472
473#pragma omp parallel for
474 for (size_t d = 0; d < m_nnd; ++d) {
475 dofval_d(d) = dofval(m_iip(d));
476 }
477
478 return dofval_d;
479 }
480
481 Eigen::VectorXd AsDofs_d(const array_type::tensor<double, 2>& nodevec) const
482 {
483 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
484
485 Eigen::VectorXd dofval_d = Eigen::VectorXd::Zero(m_nnd, 1);
486
487#pragma omp parallel for
488 for (size_t m = 0; m < m_nnode; ++m) {
489 for (size_t i = 0; i < m_ndim; ++i) {
490 if (m_dofs(m, i) >= m_nni) {
491 dofval_d(m_dofs(m, i) - m_nni) = nodevec(m, i);
492 }
493 }
494 }
495
496 return dofval_d;
497 }
498};
499
516template <class Solver = Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>>>
518 : public MatrixSolverBase<MatrixPartitionedTyingsSolver<Solver>>,
519 public MatrixSolverPartitionedBase<MatrixPartitionedTyingsSolver<Solver>> {
520private:
523
524public:
526
527private:
528 template <class T>
529 void solve_nodevec_impl(MatrixPartitionedTyings& A, const T& b, T& x)
530 {
531 this->factorize(A);
532
533 Eigen::VectorXd B_u = A.AsDofs_u(b);
534 Eigen::VectorXd B_d = A.AsDofs_d(b);
535 Eigen::VectorXd X_p = A.AsDofs_p(x);
536
537 B_u += A.m_Cud * B_d;
538
539 Eigen::VectorXd X_u = m_solver.solve(Eigen::VectorXd(B_u - A.m_ACup * X_p));
540 Eigen::VectorXd X_d = A.m_Cdu * X_u + A.m_Cdp * X_p;
541
542#pragma omp parallel for
543 for (size_t m = 0; m < A.m_nnode; ++m) {
544 for (size_t i = 0; i < A.m_ndim; ++i) {
545 if (A.m_dofs(m, i) < A.m_nnu) {
546 x(m, i) = X_u(A.m_dofs(m, i));
547 }
548 else if (A.m_dofs(m, i) >= A.m_nni) {
549 x(m, i) = X_d(A.m_dofs(m, i) - A.m_nni);
550 }
551 }
552 }
553 }
554
555 template <class T>
556 void solve_dofval_impl(MatrixPartitionedTyings& A, const T& b, T& x)
557 {
558 this->factorize(A);
559
560 Eigen::VectorXd B_u = A.AsDofs_u(b);
561 Eigen::VectorXd B_d = A.AsDofs_d(b);
562 Eigen::VectorXd X_p = A.AsDofs_p(x);
563
564 Eigen::VectorXd X_u = m_solver.solve(Eigen::VectorXd(B_u - A.m_ACup * X_p));
565 Eigen::VectorXd X_d = A.m_Cdu * X_u + A.m_Cdp * X_p;
566
567#pragma omp parallel for
568 for (size_t d = 0; d < A.m_nnu; ++d) {
569 x(A.m_iiu(d)) = X_u(d);
570 }
571
572#pragma omp parallel for
573 for (size_t d = 0; d < A.m_nnd; ++d) {
574 x(A.m_iid(d)) = X_d(d);
575 }
576 }
577
578public:
595 {
596 array_type::tensor<double, 1> x_u = xt::empty<double>({A.m_nnu});
597 this->solve_u(A, b_u, b_d, x_p, x_u);
598 return x_u;
599 }
600
619 {
620 UNUSED(b_d);
621 GOOSEFEM_ASSERT(b_u.size() == A.m_nnu);
622 GOOSEFEM_ASSERT(b_d.size() == A.m_nnd);
623 GOOSEFEM_ASSERT(x_p.size() == A.m_nnp);
624 GOOSEFEM_ASSERT(x_u.size() == A.m_nnu);
625
626 this->factorize(A);
627
628 Eigen::Map<Eigen::VectorXd>(x_u.data(), x_u.size()).noalias() =
629 m_solver.solve(Eigen::VectorXd(
630 Eigen::Map<const Eigen::VectorXd>(b_u.data(), b_u.size()) -
631 A.m_ACup * Eigen::Map<const Eigen::VectorXd>(x_p.data(), x_p.size())));
632 }
633
634private:
635 Solver m_solver;
636 bool m_factor = true;
637
641 void factorize(MatrixPartitionedTyings& A)
642 {
643 if (!A.m_changed && !m_factor) {
644 return;
645 }
646
647 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;
648
649 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;
650
651 // A.m_ACpu = A.m_Apu + A.m_Apd * A.m_Cdu + A.m_Cpd * A.m_Adu
652 // + A.m_Cpd * A.m_Add * A.m_Cdu;
653
654 // A.m_ACpp = A.m_App + A.m_Apd * A.m_Cdp + A.m_Cpd * A.m_Adp
655 // + A.m_Cpd * A.m_Add * A.m_Cdp;
656
657 m_solver.compute(A.m_ACuu);
658 m_factor = false;
659 A.m_changed = false;
660 }
661};
662
663} // namespace GooseFEM
664
665#endif
CRTP base class for a matrix.
Definition: Matrix.h:198
const array_type::tensor< size_t, 2 > & dofs() const
DOFs per node.
Definition: Matrix.h:278
const array_type::tensor< size_t, 2 > & conn() const
Connectivity.
Definition: Matrix.h:287
array_type::tensor< size_t, 2 > m_dofs
DOF-numbers per node [nnode, ndim].
Definition: Matrix.h:201
array_type::tensor< size_t, 2 > m_conn
Connectivity [nelem, nne].
Definition: Matrix.h:200
size_t m_nelem
See nelem().
Definition: Matrix.h:203
size_t m_nne
See nne().
Definition: Matrix.h:204
bool m_changed
Signal changes to data.
Definition: Matrix.h:209
size_t m_nnode
See nnode().
Definition: Matrix.h:205
size_t m_ndim
See ndim().
Definition: Matrix.h:206
size_t m_ndof
See ndof().
Definition: Matrix.h:207
CRTP base class for a partitioned matrix.
Definition: Matrix.h:415
array_type::tensor< size_t, 1 > m_iiu
See iiu()
Definition: Matrix.h:417
array_type::tensor< size_t, 1 > m_iip
See iip()
Definition: Matrix.h:418
CRTP base class for a partitioned matrix with tying.
Definition: Matrix.h:582
array_type::tensor< size_t, 1 > m_iii
See iii()
Definition: Matrix.h:584
array_type::tensor< size_t, 1 > m_iid
See iid()
Definition: Matrix.h:585
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.
Definition: Matrix.h:26
CRTP base class for a extra functions for a partitioned solver class.
Definition: Matrix.h:136
#define GOOSEFEM_ASSERT(expr)
All assertions are implementation as::
Definition: config.h:96
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Definition: config.h:176
Toolbox to perform finite element computations.
Definition: Allocate.h:14