GooseFEM 1.4.1.dev2+g78f16df
Loading...
Searching...
No Matches
VectorPartitioned.h
Go to the documentation of this file.
1
11#ifndef GOOSEFEM_VECTORPARTITIONED_H
12#define GOOSEFEM_VECTORPARTITIONED_H
13
14#include "Mesh.h"
15#include "Vector.h"
16#include "assertions.h"
17#include "config.h"
18
19namespace GooseFEM {
20
45class VectorPartitioned : public Vector {
46protected:
49 size_t m_nnu;
50 size_t m_nnp;
51
61
62public:
63 VectorPartitioned() = default;
64
76 )
78 {
80
81 m_iiu = xt::setdiff1d(m_dofs, m_iip);
82 m_nnp = m_iip.size();
83 m_nnu = m_iiu.size();
85
86 GOOSEFEM_ASSERT(xt::amax(m_iip)() <= xt::amax(m_dofs)());
87 }
88
92 size_t nnu() const
93 {
94 return m_nnu;
95 }
96
100 size_t nnp() const
101 {
102 return m_nnp;
103 }
104
109 {
110 return m_iiu;
111 }
112
117 {
118 return m_iip;
119 }
120
127 {
128 array_type::tensor<bool, 2> ret = xt::zeros<bool>(this->shape_nodevec());
129
130#pragma omp parallel for
131 for (size_t m = 0; m < m_nnode; ++m) {
132 for (size_t i = 0; i < m_ndim; ++i) {
133 if (m_part(m, i) < m_nnu) {
134 ret(m, i) = true;
135 }
136 }
137 }
138
139 return ret;
140 }
141
148 {
149 array_type::tensor<bool, 2> ret = xt::zeros<bool>(this->shape_nodevec());
150
151#pragma omp parallel for
152 for (size_t m = 0; m < m_nnode; ++m) {
153 for (size_t i = 0; i < m_ndim; ++i) {
154 if (m_part(m, i) >= m_nnu) {
155 ret(m, i) = true;
156 }
157 }
158 }
159
160 return ret;
161 }
162
185
198 void copy_u(
201 ) const
202 {
203 GOOSEFEM_ASSERT(xt::has_shape(nodevec_src, {m_nnode, m_ndim}));
204 GOOSEFEM_ASSERT(xt::has_shape(nodevec_dest, {m_nnode, m_ndim}));
205
206#pragma omp parallel for
207 for (size_t m = 0; m < m_nnode; ++m) {
208 for (size_t i = 0; i < m_ndim; ++i) {
209 if (m_part(m, i) < m_nnu) {
211 }
212 }
213 }
214 }
215
238
251 void copy_p(
254 ) const
255 {
256 GOOSEFEM_ASSERT(xt::has_shape(nodevec_src, {m_nnode, m_ndim}));
257 GOOSEFEM_ASSERT(xt::has_shape(nodevec_dest, {m_nnode, m_ndim}));
258
259#pragma omp parallel for
260 for (size_t m = 0; m < m_nnode; ++m) {
261 for (size_t i = 0; i < m_ndim; ++i) {
262 if (m_part(m, i) >= m_nnu) {
264 }
265 }
266 }
267 }
268
285
297 ) const
298 {
299 GOOSEFEM_ASSERT(dofval_u.size() == m_nnu);
300 GOOSEFEM_ASSERT(dofval_p.size() == m_nnp);
301 GOOSEFEM_ASSERT(dofval.size() == m_ndof);
302
303 dofval.fill(0.0);
304
305#pragma omp parallel for
306 for (size_t d = 0; d < m_nnu; ++d) {
307 dofval(m_iiu(d)) = dofval_u(d);
308 }
309
310#pragma omp parallel for
311 for (size_t d = 0; d < m_nnp; ++d) {
312 dofval(m_iip(d)) = dofval_p(d);
313 }
314 }
315
334
348 ) const
349 {
350 GOOSEFEM_ASSERT(dofval_u.size() == m_nnu);
351 GOOSEFEM_ASSERT(dofval_p.size() == m_nnp);
352 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
353
354#pragma omp parallel for
355 for (size_t m = 0; m < m_nnode; ++m) {
356 for (size_t i = 0; i < m_ndim; ++i) {
357 if (m_part(m, i) < m_nnu) {
358 nodevec(m, i) = dofval_u(m_part(m, i));
359 }
360 else {
361 nodevec(m, i) = dofval_p(m_part(m, i) - m_nnu);
362 }
363 }
364 }
365 }
366
385
399 ) const
400 {
401 GOOSEFEM_ASSERT(dofval_u.size() == m_nnu);
402 GOOSEFEM_ASSERT(dofval_p.size() == m_nnp);
403 GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
404
405#pragma omp parallel for
406 for (size_t e = 0; e < m_nelem; ++e) {
407 for (size_t m = 0; m < m_nne; ++m) {
408 for (size_t i = 0; i < m_ndim; ++i) {
409 if (m_part(m_conn(e, m), i) < m_nnu) {
410 elemvec(e, m, i) = dofval_u(m_part(m_conn(e, m), i));
411 }
412 else {
413 elemvec(e, m, i) = dofval_p(m_part(m_conn(e, m), i) - m_nnu);
414 }
415 }
416 }
417 }
418 }
419
429 {
430 array_type::tensor<double, 1> dofval_u = xt::empty<double>({m_nnu});
431 this->asDofs_u(dofval, dofval_u);
432 return dofval_u;
433 }
434
446 ) const
447 {
448 GOOSEFEM_ASSERT(dofval.size() == m_ndof);
449 GOOSEFEM_ASSERT(dofval_u.size() == m_nnu);
450
451#pragma omp parallel for
452 for (size_t d = 0; d < m_nnu; ++d) {
453 dofval_u(d) = dofval(m_iiu(d));
454 }
455 }
456
465 {
466 array_type::tensor<double, 1> dofval_u = xt::empty<double>({m_nnu});
467 this->asDofs_u(nodevec, dofval_u);
468 return dofval_u;
469 }
470
481 ) const
482 {
483 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
484 GOOSEFEM_ASSERT(dofval_u.size() == m_nnu);
485
486 dofval_u.fill(0.0);
487
488#pragma omp parallel for
489 for (size_t m = 0; m < m_nnode; ++m) {
490 for (size_t i = 0; i < m_ndim; ++i) {
491 if (m_part(m, i) < m_nnu) {
492 dofval_u(m_part(m, i)) = nodevec(m, i);
493 }
494 }
495 }
496 }
497
506 {
507 array_type::tensor<double, 1> dofval_u = xt::empty<double>({m_nnu});
508 this->asDofs_u(elemvec, dofval_u);
509 return dofval_u;
510 }
511
522 ) const
523 {
524 GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
525 GOOSEFEM_ASSERT(dofval_u.size() == m_nnu);
526
527 dofval_u.fill(0.0);
528
529#pragma omp parallel for
530 for (size_t e = 0; e < m_nelem; ++e) {
531 for (size_t m = 0; m < m_nne; ++m) {
532 for (size_t i = 0; i < m_ndim; ++i) {
533 if (m_part(m_conn(e, m), i) < m_nnu) {
534 dofval_u(m_part(m_conn(e, m), i)) = elemvec(e, m, i);
535 }
536 }
537 }
538 }
539 }
540
550 {
551 array_type::tensor<double, 1> dofval_p = xt::empty<double>({m_nnp});
552 this->asDofs_p(dofval, dofval_p);
553 return dofval_p;
554 }
555
567 ) const
568 {
569 GOOSEFEM_ASSERT(dofval.size() == m_ndof);
570 GOOSEFEM_ASSERT(dofval_p.size() == m_nnp);
571
572#pragma omp parallel for
573 for (size_t d = 0; d < m_nnp; ++d) {
574 dofval_p(d) = dofval(m_iip(d));
575 }
576 }
577
586 {
587 array_type::tensor<double, 1> dofval_p = xt::empty<double>({m_nnp});
588 this->asDofs_p(nodevec, dofval_p);
589 return dofval_p;
590 }
591
602 ) const
603 {
604 GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
605 GOOSEFEM_ASSERT(dofval_p.size() == m_nnp);
606
607 dofval_p.fill(0.0);
608
609#pragma omp parallel for
610 for (size_t m = 0; m < m_nnode; ++m) {
611 for (size_t i = 0; i < m_ndim; ++i) {
612 if (m_part(m, i) >= m_nnu) {
613 dofval_p(m_part(m, i) - m_nnu) = nodevec(m, i);
614 }
615 }
616 }
617 }
618
627 {
628 array_type::tensor<double, 1> dofval_p = xt::empty<double>({m_nnp});
629 this->asDofs_p(elemvec, dofval_p);
630 return dofval_p;
631 }
632
643 ) const
644 {
645 GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
646 GOOSEFEM_ASSERT(dofval_p.size() == m_nnp);
647
648 dofval_p.fill(0.0);
649
650#pragma omp parallel for
651 for (size_t e = 0; e < m_nelem; ++e) {
652 for (size_t m = 0; m < m_nne; ++m) {
653 for (size_t i = 0; i < m_ndim; ++i) {
654 if (m_part(m_conn(e, m), i) >= m_nnu) {
655 dofval_p(m_part(m_conn(e, m), i) - m_nnu) = elemvec(e, m, i);
656 }
657 }
658 }
659 }
660 }
661};
662
663} // namespace GooseFEM
664
665#endif
Generic mesh operations.
Methods to switch between storage types based on a mesh.
Reorder to lowest possible index, in specific order.
Definition Mesh.h:2384
Class to switch between storage types, based on a mesh and DOFs that are partitioned in:
const array_type::tensor< size_t, 1 > & iip() const
array_type::tensor< double, 1 > AsDofs_u(const array_type::tensor< double, 3 > &elemvec) const
Convert "elemvec" to "dofval" (overwrite entries that occur more than once) and extract the unknown "...
void asDofs_u(const array_type::tensor< double, 1 > &dofval, array_type::tensor< double, 1 > &dofval_u) const
Extract the unknown "dofval":
void asDofs_p(const array_type::tensor< double, 3 > &elemvec, array_type::tensor< double, 1 > &dofval_p) const
Convert "elemvec" to "dofval" (overwrite entries that occur more than once) and extract the prescribe...
array_type::tensor< double, 1 > AsDofs_u(const array_type::tensor< double, 1 > &dofval) const
Extract the unknown "dofval":
void asDofs_p(const array_type::tensor< double, 1 > &dofval, array_type::tensor< double, 1 > &dofval_p) const
Extract the prescribed "dofval":
array_type::tensor< double, 1 > DofsFromParitioned(const array_type::tensor< double, 1 > &dofval_u, const array_type::tensor< double, 1 > &dofval_p) const
Combine unknown and prescribed "dofval" into a single "dofval" list.
void elementFromPartitioned(const array_type::tensor< double, 1 > &dofval_u, const array_type::tensor< double, 1 > &dofval_p, array_type::tensor< double, 3 > &elemvec) const
Combine unknown and prescribed "dofval" into a single "dofval" list and directly convert to "elemvec"...
array_type::tensor< bool, 2 > dofs_is_u() const
Per DOF (see Vector::dofs()) list if unknown ("u").
void asDofs_p(const array_type::tensor< double, 2 > &nodevec, array_type::tensor< double, 1 > &dofval_p) const
Convert "nodevec" to "dofval" (overwrite entries that occur more than once) and extract the prescribe...
array_type::tensor< double, 1 > AsDofs_p(const array_type::tensor< double, 3 > &elemvec) const
Convert "elemvec" to "dofval" (overwrite entries that occur more than once) and extract the prescribe...
VectorPartitioned(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 copy_p(const array_type::tensor< double, 2 > &nodevec_src, array_type::tensor< double, 2 > &nodevec_dest) const
Copy prescribed DOFs from "nodevec" to another "nodvec":
void dofsFromParitioned(const array_type::tensor< double, 1 > &dofval_u, const array_type::tensor< double, 1 > &dofval_p, array_type::tensor< double, 1 > &dofval) const
Combine unknown and prescribed "dofval" into a single "dofval" list.
void copy_u(const array_type::tensor< double, 2 > &nodevec_src, array_type::tensor< double, 2 > &nodevec_dest) const
Copy unknown DOFs from "nodevec" to another "nodvec":
const array_type::tensor< size_t, 1 > & iiu() const
array_type::tensor< size_t, 1 > m_iiu
See iiu()
array_type::tensor< size_t, 2 > m_part
Renumbered DOFs per node, such that.
array_type::tensor< double, 2 > Copy_u(const array_type::tensor< double, 2 > &nodevec_src, const array_type::tensor< double, 2 > &nodevec_dest) const
Copy unknown DOFs from "nodevec" to another "nodvec":
array_type::tensor< double, 2 > NodeFromPartitioned(const array_type::tensor< double, 1 > &dofval_u, const array_type::tensor< double, 1 > &dofval_p) const
Combine unknown and prescribed "dofval" into a single "dofval" list and directly convert to "nodeval"...
array_type::tensor< size_t, 1 > m_iip
See iip()
void asDofs_u(const array_type::tensor< double, 3 > &elemvec, array_type::tensor< double, 1 > &dofval_u) const
Convert "elemvec" to "dofval" (overwrite entries that occur more than once) and extract the unknown "...
array_type::tensor< double, 1 > AsDofs_p(const array_type::tensor< double, 1 > &dofval) const
Extract the prescribed "dofval":
void asDofs_u(const array_type::tensor< double, 2 > &nodevec, array_type::tensor< double, 1 > &dofval_u) const
Convert "nodevec" to "dofval" (overwrite entries that occur more than once) and extract the unknown "...
array_type::tensor< double, 2 > Copy_p(const array_type::tensor< double, 2 > &nodevec_src, const array_type::tensor< double, 2 > &nodevec_dest) const
Copy prescribed DOFs from "nodevec" to another "nodvec":
void nodeFromPartitioned(const array_type::tensor< double, 1 > &dofval_u, const array_type::tensor< double, 1 > &dofval_p, array_type::tensor< double, 2 > &nodevec) const
Combine unknown and prescribed "dofval" into a single "dofval" list and directly convert to "nodeval"...
array_type::tensor< bool, 2 > dofs_is_p() const
Per DOF (see Vector::dofs()) list if prescribed ("p").
array_type::tensor< double, 3 > ElementFromPartitioned(const array_type::tensor< double, 1 > &dofval_u, const array_type::tensor< double, 1 > &dofval_p) const
Combine unknown and prescribed "dofval" into a single "dofval" list and directly convert to "elemvec"...
array_type::tensor< double, 1 > AsDofs_u(const array_type::tensor< double, 2 > &nodevec) const
Convert "nodevec" to "dofval" (overwrite entries that occur more than once) and extract the unknown "...
array_type::tensor< double, 1 > AsDofs_p(const array_type::tensor< double, 2 > &nodevec) const
Convert "nodevec" to "dofval" (overwrite entries that occur more than once) and extract the prescribe...
Class to switch between storage types.
Definition Vector.h:23
array_type::tensor< size_t, 2 > m_dofs
See dofs()
Definition Vector.h:761
const array_type::tensor< size_t, 2 > & conn() const
Definition Vector.h:92
std::array< size_t, 2 > shape_nodevec() const
Shape of "nodevec".
Definition Vector.h:280
size_t m_ndof
See ndof.
Definition Vector.h:766
size_t m_nelem
See nelem.
Definition Vector.h:762
array_type::tensor< size_t, 2 > m_conn
See conn()
Definition Vector.h:760
size_t m_ndim
See ndim.
Definition Vector.h:765
const array_type::tensor< size_t, 2 > & dofs() const
Definition Vector.h:100
size_t m_nne
See nne.
Definition Vector.h:763
size_t m_nnode
See nnode.
Definition Vector.h:764
Basic configuration:
#define GOOSEFEM_ASSERT(expr)
All assertions are implementation as::
Definition config.h:97
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Definition config.h:177
Toolbox to perform finite element computations.
Definition Allocate.h:14
bool is_unique(const T &arg)
Returns true is a list is unique (has not duplicate items).
Definition assertions.h:20
auto AsTensor(const T &arg, const S &shape)
"Broadcast" a scalar stored in an array (e.g.
Definition Allocate.h:167