GooseFEM 1.4.1.dev2+g78f16df
Loading...
Searching...
No Matches
Vector.h
Go to the documentation of this file.
1
9#ifndef GOOSEFEM_VECTOR_H
10#define GOOSEFEM_VECTOR_H
11
12#include "config.h"
13
14namespace GooseFEM {
15
23class Vector {
24public:
25 Vector() = default;
26
33 template <class S, class T>
34 Vector(const S& conn, const T& dofs) : m_conn(conn), m_dofs(dofs)
35 {
36 GOOSEFEM_ASSERT(conn.dimension() == 2);
37 GOOSEFEM_ASSERT(dofs.dimension() == 2);
38
39 m_nelem = m_conn.shape(0);
40 m_nne = m_conn.shape(1);
41 m_nnode = m_dofs.shape(0);
42 m_ndim = m_dofs.shape(1);
43 m_ndof = xt::amax(m_dofs)() + 1;
44
45 GOOSEFEM_ASSERT(xt::amax(m_conn)() + 1 <= m_nnode);
47 }
48
52 size_t nelem() const
53 {
54 return m_nelem;
55 }
56
60 size_t nne() const
61 {
62 return m_nne;
63 }
64
68 size_t nnode() const
69 {
70 return m_nnode;
71 }
72
76 size_t ndim() const
77 {
78 return m_ndim;
79 }
80
84 size_t ndof() const
85 {
86 return m_ndof;
87 }
88
93 {
94 return m_conn;
95 }
96
101 {
102 return m_dofs;
103 }
104
112 template <class T>
113 T Copy(const T& nodevec_src, const T& nodevec_dest) const
114 {
115 T ret = T::from_shape(nodevec_dest.shape());
116 this->copy(nodevec_src, ret);
117 return ret;
118 }
119
126 template <class T>
127 void copy(const T& nodevec_src, T& nodevec_dest) const
128 {
129 GOOSEFEM_ASSERT(xt::has_shape(nodevec_src, this->shape_nodevec()));
130 GOOSEFEM_ASSERT(xt::has_shape(nodevec_dest, this->shape_nodevec()));
131
132 xt::noalias(nodevec_dest) = nodevec_src;
133 }
134
141 template <class T>
143 {
144 array_type::tensor<double, 1> ret = xt::empty<double>(this->shape_dofval());
145 this->asDofs_impl(arg, ret);
146 return ret;
147 }
148
155 template <class T, class R>
156 void asDofs(const T& arg, R& ret) const
157 {
158 this->asDofs_impl(arg, ret);
159 }
160
167 template <class T>
169 {
170 array_type::tensor<double, 2> ret = xt::empty<double>(this->shape_nodevec());
171 this->asNode_impl(arg, ret);
172 return ret;
173 }
174
181 template <class T, class R>
182 void asNode(const T& arg, R& ret) const
183 {
184 this->asNode_impl(arg, ret);
185 }
186
193 template <class T>
195 {
196 array_type::tensor<double, 3> ret = xt::empty<double>(this->shape_elemvec());
197 this->asElement_impl(arg, ret);
198 return ret;
199 }
200
207 template <class T, class R>
208 void asElement(const T& arg, R& ret) const
209 {
210 this->asElement_impl(arg, ret);
211 }
212
219 template <class T>
221 {
222 array_type::tensor<double, 1> ret = xt::empty<double>(this->shape_dofval());
223 this->assembleDofs_impl(arg, ret);
224 return ret;
225 }
226
233 template <class T, class R>
234 void assembleDofs(const T& arg, R& ret) const
235 {
236 this->assembleDofs_impl(arg, ret);
237 }
238
245 template <class T>
247 {
248 array_type::tensor<double, 2> ret = xt::empty<double>(this->shape_nodevec());
249 this->assembleNode_impl(arg, ret);
250 return ret;
251 }
252
259 template <class T, class R>
260 void assembleNode(const T& arg, R& ret) const
261 {
262 this->assembleNode_impl(arg, ret);
263 }
264
270 std::array<size_t, 1> shape_dofval() const
271 {
272 return std::array<size_t, 1>{m_ndof};
273 }
274
280 std::array<size_t, 2> shape_nodevec() const
281 {
282 return std::array<size_t, 2>{m_nnode, m_ndim};
283 }
284
290 std::array<size_t, 3> shape_elemvec() const
291 {
292 return std::array<size_t, 3>{m_nelem, m_nne, m_ndim};
293 }
294
300 std::array<size_t, 3> shape_elemmat() const
301 {
302 return std::array<size_t, 3>{m_nelem, m_nne * m_ndim, m_nne * m_ndim};
303 }
304
311 {
312 array_type::tensor<double, 1> dofval = xt::empty<double>(this->shape_dofval());
313 return dofval;
314 }
315
323 {
324 array_type::tensor<double, 1> dofval = xt::empty<double>(this->shape_dofval());
325 dofval.fill(val);
326 return dofval;
327 }
328
335 {
336 array_type::tensor<double, 2> nodevec = xt::empty<double>(this->shape_nodevec());
337 return nodevec;
338 }
339
347 {
348 array_type::tensor<double, 2> nodevec = xt::empty<double>(this->shape_nodevec());
349 nodevec.fill(val);
350 return nodevec;
351 }
352
359 {
360 array_type::tensor<double, 3> elemvec = xt::empty<double>(this->shape_elemvec());
361 return elemvec;
362 }
363
371 {
372 array_type::tensor<double, 3> elemvec = xt::empty<double>(this->shape_elemvec());
373 elemvec.fill(val);
374 return elemvec;
375 }
376
383 {
384 array_type::tensor<double, 3> elemmat = xt::empty<double>(this->shape_elemmat());
385 return elemmat;
386 }
387
395 {
396 array_type::tensor<double, 3> elemmat = xt::empty<double>(this->shape_elemmat());
397 elemmat.fill(val);
398 return elemmat;
399 }
400
401private:
406 void asDofs_impl(const T& arg, R& ret) const
407 {
408 if (arg.dimension() == 2) {
409 this->asDofs_impl_nodevec(arg, ret);
410 }
411 else if (arg.dimension() == 3) {
412 this->asDofs_impl_elemvec(arg, ret);
413 }
414 else {
415 throw std::runtime_error("Vector::asDofs unknown dimension for conversion");
416 }
417 }
418
423 void asDofs_impl(const T& arg, R& ret) const
424 {
425 this->asDofs_impl_nodevec(arg, ret);
426 }
427
432 void asDofs_impl(const T& arg, R& ret) const
433 {
434 this->asDofs_impl_elemvec(arg, ret);
435 }
436
441 void asNode_impl(const T& arg, R& ret) const
442 {
443 if (arg.dimension() == 1) {
444 this->asNode_impl_dofval(arg, ret);
445 }
446 else if (arg.dimension() == 3) {
447 this->asNode_impl_elemvec(arg, ret);
448 }
449 else {
450 throw std::runtime_error("Vector::asNode unknown dimension for conversion");
451 }
452 }
453
458 void asNode_impl(const T& arg, R& ret) const
459 {
460 this->asNode_impl_dofval(arg, ret);
461 }
462
467 void asNode_impl(const T& arg, R& ret) const
468 {
469 this->asNode_impl_elemvec(arg, ret);
470 }
471
476 void asElement_impl(const T& arg, R& ret) const
477 {
478 if (arg.dimension() == 1) {
479 this->asElement_impl_dofval(arg, ret);
480 }
481 else if (arg.dimension() == 2) {
482 this->asElement_impl_nodevec(arg, ret);
483 }
484 else {
485 throw std::runtime_error("Vector::asElement unknown dimension for conversion");
486 }
487 }
488
493 void asElement_impl(const T& arg, R& ret) const
494 {
495 this->asElement_impl_dofval(arg, ret);
496 }
497
502 void asElement_impl(const T& arg, R& ret) const
503 {
504 this->asElement_impl_nodevec(arg, ret);
505 }
506
511 void assembleDofs_impl(const T& arg, R& ret) const
512 {
513 if (arg.dimension() == 2) {
514 this->assembleDofs_impl_nodevec(arg, ret);
515 }
516 else if (arg.dimension() == 3) {
517 this->assembleDofs_impl_elemvec(arg, ret);
518 }
519 else {
520 throw std::runtime_error("Vector::assembleDofs unknown dimension for conversion");
521 }
522 }
523
528 void assembleDofs_impl(const T& arg, R& ret) const
529 {
530 this->assembleDofs_impl_nodevec(arg, ret);
531 }
532
537 void assembleDofs_impl(const T& arg, R& ret) const
538 {
539 this->assembleDofs_impl_elemvec(arg, ret);
540 }
541
546 void assembleNode_impl(const T& arg, R& ret) const
547 {
548 if (arg.dimension() == 3) {
549 this->assembleNode_impl_elemvec(arg, ret);
550 }
551 else {
552 throw std::runtime_error("Vector::assembleNode unknown dimension for conversion");
553 }
554 }
555
560 void assembleNode_impl(const T& arg, R& ret) const
561 {
562 this->assembleNode_impl_elemvec(arg, ret);
563 }
564
568 template <class T, class R>
569 void asDofs_impl_nodevec(const T& arg, R& ret) const
570 {
571 static_assert(
572 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
573 );
574 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_nodevec()));
575 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
576
577 ret.fill(0.0);
578
579#pragma omp parallel for
580 for (size_t m = 0; m < m_nnode; ++m) {
581 for (size_t i = 0; i < m_ndim; ++i) {
582 ret(m_dofs(m, i)) = arg(m, i);
583 }
584 }
585 }
586
590 template <class T, class R>
591 void asDofs_impl_elemvec(const T& arg, R& ret) const
592 {
593 static_assert(
594 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
595 );
596 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
597 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
598
599 ret.fill(0.0);
600
601#pragma omp parallel for
602 for (size_t e = 0; e < m_nelem; ++e) {
603 for (size_t m = 0; m < m_nne; ++m) {
604 for (size_t i = 0; i < m_ndim; ++i) {
605 ret(m_dofs(m_conn(e, m), i)) = arg(e, m, i);
606 }
607 }
608 }
609 }
610
614 template <class T, class R>
615 void asNode_impl_dofval(const T& arg, R& ret) const
616 {
617 static_assert(
618 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
619 );
620 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_dofval()));
621 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_nodevec()));
622
623#pragma omp parallel for
624 for (size_t m = 0; m < m_nnode; ++m) {
625 for (size_t i = 0; i < m_ndim; ++i) {
626 ret(m, i) = arg(m_dofs(m, i));
627 }
628 }
629 }
630
634 template <class T, class R>
635 void asNode_impl_elemvec(const T& arg, R& ret) const
636 {
637 static_assert(
638 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
639 );
640 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
641 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_nodevec()));
642
643 ret.fill(0.0);
644
645#pragma omp parallel for
646 for (size_t e = 0; e < m_nelem; ++e) {
647 for (size_t m = 0; m < m_nne; ++m) {
648 for (size_t i = 0; i < m_ndim; ++i) {
649 ret(m_conn(e, m), i) = arg(e, m, i);
650 }
651 }
652 }
653 }
654
658 template <class T, class R>
659 void asElement_impl_dofval(const T& arg, R& ret) const
660 {
661 static_assert(
662 xt::get_rank<R>::value == 3 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
663 );
664 GOOSEFEM_ASSERT(arg.size() == m_ndof);
665 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_elemvec()));
666
667#pragma omp parallel for
668 for (size_t e = 0; e < m_nelem; ++e) {
669 for (size_t m = 0; m < m_nne; ++m) {
670 for (size_t i = 0; i < m_ndim; ++i) {
671 ret(e, m, i) = arg(m_dofs(m_conn(e, m), i));
672 }
673 }
674 }
675 }
676
680 template <class T, class R>
681 void asElement_impl_nodevec(const T& arg, R& ret) const
682 {
683 static_assert(
684 xt::get_rank<R>::value == 3 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
685 );
686 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_nodevec()));
687 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_elemvec()));
688
689#pragma omp parallel for
690 for (size_t e = 0; e < m_nelem; ++e) {
691 for (size_t m = 0; m < m_nne; ++m) {
692 for (size_t i = 0; i < m_ndim; ++i) {
693 ret(e, m, i) = arg(m_conn(e, m), i);
694 }
695 }
696 }
697 }
698
702 template <class T, class R>
703 void assembleDofs_impl_nodevec(const T& arg, R& ret) const
704 {
705 static_assert(
706 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
707 );
708 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_nodevec()));
709 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
710
711 ret.fill(0.0);
712
713 for (size_t m = 0; m < m_nnode; ++m) {
714 for (size_t i = 0; i < m_ndim; ++i) {
715 ret(m_dofs(m, i)) += arg(m, i);
716 }
717 }
718 }
719
723 template <class T, class R>
724 void assembleDofs_impl_elemvec(const T& arg, R& ret) const
725 {
726 static_assert(
727 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
728 );
729 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
730 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
731
732 ret.fill(0.0);
733
734 for (size_t e = 0; e < m_nelem; ++e) {
735 for (size_t m = 0; m < m_nne; ++m) {
736 for (size_t i = 0; i < m_ndim; ++i) {
737 ret(m_dofs(m_conn(e, m), i)) += arg(e, m, i);
738 }
739 }
740 }
741 }
742
746 template <class T, class R>
747 void assembleNode_impl_elemvec(const T& arg, R& ret) const
748 {
749 static_assert(
750 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'"
751 );
752 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
753 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_nodevec()));
754
755 array_type::tensor<double, 1> dofval = this->AssembleDofs(arg);
756 this->asNode(dofval, ret);
757 }
758
759protected:
762 size_t m_nelem;
763 size_t m_nne;
764 size_t m_nnode;
765 size_t m_ndim;
766 size_t m_ndof;
767};
768
769} // namespace GooseFEM
770
771#endif
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
void asElement(const T &arg, R &ret) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
Definition Vector.h:208
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
array_type::tensor< double, 2 > AsNode(const T &arg) const
Convert "dofval" or "elemvec" to "nodevec" (overwrite entries that occur more than once).
Definition Vector.h:168
size_t nelem() const
Definition Vector.h:52
void assembleDofs(const T &arg, R &ret) const
Assemble "nodevec" or "elemvec" to "dofval" (adds entries that occur more that once).
Definition Vector.h:234
array_type::tensor< double, 3 > allocate_elemmat(double val) const
Allocated and initialised "elemmat".
Definition Vector.h:394
void assembleNode(const T &arg, R &ret) const
Assemble "elemvec" to "nodevec" (adds entries that occur more that once.
Definition Vector.h:260
array_type::tensor< double, 1 > allocate_dofval() const
Allocated "dofval".
Definition Vector.h:310
array_type::tensor< double, 2 > allocate_nodevec() const
Allocated "nodevec".
Definition Vector.h:334
std::array< size_t, 3 > shape_elemvec() const
Shape of "elemvec".
Definition Vector.h:290
size_t nne() const
Definition Vector.h:60
size_t m_nelem
See nelem.
Definition Vector.h:762
size_t nnode() const
Definition Vector.h:68
std::array< size_t, 3 > shape_elemmat() const
Shape of "elemmat".
Definition Vector.h:300
size_t ndim() const
Definition Vector.h:76
array_type::tensor< double, 3 > AsElement(const T &arg) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
Definition Vector.h:194
std::array< size_t, 1 > shape_dofval() const
Shape of "dofval".
Definition Vector.h:270
array_type::tensor< double, 1 > AsDofs(const T &arg) const
Convert "nodevec" or "elemvec" to "dofval" (overwrite entries that occur more than once).
Definition Vector.h:142
array_type::tensor< double, 3 > allocate_elemvec() const
Allocated "elemvec".
Definition Vector.h:358
void copy(const T &nodevec_src, T &nodevec_dest) const
Copy "nodevec" to another "nodevec".
Definition Vector.h:127
void asDofs(const T &arg, R &ret) const
Convert "nodevec" or "elemvec" to "dofval" (overwrite entries that occur more than once).
Definition Vector.h:156
array_type::tensor< double, 3 > allocate_elemvec(double val) const
Allocated and initialised "elemvec".
Definition Vector.h:370
array_type::tensor< double, 2 > allocate_nodevec(double val) const
Allocated and initialised "nodevec".
Definition Vector.h:346
array_type::tensor< size_t, 2 > m_conn
See conn()
Definition Vector.h:760
array_type::tensor< double, 2 > AssembleNode(const T &arg) const
Assemble "elemvec" to "nodevec" (adds entries that occur more that once.
Definition Vector.h:246
size_t m_ndim
See ndim.
Definition Vector.h:765
size_t ndof() const
Definition Vector.h:84
array_type::tensor< double, 3 > allocate_elemmat() const
Allocated "elemmat".
Definition Vector.h:382
Vector(const S &conn, const T &dofs)
Constructor.
Definition Vector.h:34
const array_type::tensor< size_t, 2 > & dofs() const
Definition Vector.h:100
array_type::tensor< double, 1 > AssembleDofs(const T &arg) const
Assemble "nodevec" or "elemvec" to "dofval" (adds entries that occur more that once).
Definition Vector.h:220
size_t m_nne
See nne.
Definition Vector.h:763
T Copy(const T &nodevec_src, const T &nodevec_dest) const
Copy "nodevec" to another "nodevec".
Definition Vector.h:113
size_t m_nnode
See nnode.
Definition Vector.h:764
void asNode(const T &arg, R &ret) const
Convert "dofval" or "elemvec" to "nodevec" (overwrite entries that occur more than once).
Definition Vector.h:182
array_type::tensor< double, 1 > allocate_dofval(double val) const
Allocated and initialised "dofval".
Definition Vector.h:322
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
auto AsTensor(const T &arg, const S &shape)
"Broadcast" a scalar stored in an array (e.g.
Definition Allocate.h:167