FrictionQPotFEM 0.23.3
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:
405 template <class T, class R, typename std::enable_if_t<!xt::has_fixed_rank_t<T>::value, int> = 0>
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
422 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 2, int> = 0>
423 void asDofs_impl(const T& arg, R& ret) const
424 {
425 this->asDofs_impl_nodevec(arg, ret);
426 }
427
431 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 3, int> = 0>
432 void asDofs_impl(const T& arg, R& ret) const
433 {
434 this->asDofs_impl_elemvec(arg, ret);
435 }
436
440 template <class T, class R, typename std::enable_if_t<!xt::has_fixed_rank_t<T>::value, int> = 0>
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
457 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 1, int> = 0>
458 void asNode_impl(const T& arg, R& ret) const
459 {
460 this->asNode_impl_dofval(arg, ret);
461 }
462
466 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 3, int> = 0>
467 void asNode_impl(const T& arg, R& ret) const
468 {
469 this->asNode_impl_elemvec(arg, ret);
470 }
471
475 template <class T, class R, typename std::enable_if_t<!xt::has_fixed_rank_t<T>::value, int> = 0>
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
492 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 1, int> = 0>
493 void asElement_impl(const T& arg, R& ret) const
494 {
495 this->asElement_impl_dofval(arg, ret);
496 }
497
501 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 2, int> = 0>
502 void asElement_impl(const T& arg, R& ret) const
503 {
504 this->asElement_impl_nodevec(arg, ret);
505 }
506
510 template <class T, class R, typename std::enable_if_t<!xt::has_fixed_rank_t<T>::value, int> = 0>
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
527 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 2, int> = 0>
528 void assembleDofs_impl(const T& arg, R& ret) const
529 {
530 this->assembleDofs_impl_nodevec(arg, ret);
531 }
532
536 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 3, int> = 0>
537 void assembleDofs_impl(const T& arg, R& ret) const
538 {
539 this->assembleDofs_impl_elemvec(arg, ret);
540 }
541
545 template <class T, class R, typename std::enable_if_t<!xt::has_fixed_rank_t<T>::value, int> = 0>
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
559 template <class T, class R, typename std::enable_if_t<xt::get_rank<T>::value == 3, int> = 0>
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 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_nodevec()));
574 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
575
576 ret.fill(0.0);
577
578#pragma omp parallel for
579 for (size_t m = 0; m < m_nnode; ++m) {
580 for (size_t i = 0; i < m_ndim; ++i) {
581 ret(m_dofs(m, i)) = arg(m, i);
582 }
583 }
584 }
585
589 template <class T, class R>
590 void asDofs_impl_elemvec(const T& arg, R& ret) const
591 {
592 static_assert(
593 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
594 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
595 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
596
597 ret.fill(0.0);
598
599#pragma omp parallel for
600 for (size_t e = 0; e < m_nelem; ++e) {
601 for (size_t m = 0; m < m_nne; ++m) {
602 for (size_t i = 0; i < m_ndim; ++i) {
603 ret(m_dofs(m_conn(e, m), i)) = arg(e, m, i);
604 }
605 }
606 }
607 }
608
612 template <class T, class R>
613 void asNode_impl_dofval(const T& arg, R& ret) const
614 {
615 static_assert(
616 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
617 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_dofval()));
618 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_nodevec()));
619
620#pragma omp parallel for
621 for (size_t m = 0; m < m_nnode; ++m) {
622 for (size_t i = 0; i < m_ndim; ++i) {
623 ret(m, i) = arg(m_dofs(m, i));
624 }
625 }
626 }
627
631 template <class T, class R>
632 void asNode_impl_elemvec(const T& arg, R& ret) const
633 {
634 static_assert(
635 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
636 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
637 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_nodevec()));
638
639 ret.fill(0.0);
640
641#pragma omp parallel for
642 for (size_t e = 0; e < m_nelem; ++e) {
643 for (size_t m = 0; m < m_nne; ++m) {
644 for (size_t i = 0; i < m_ndim; ++i) {
645 ret(m_conn(e, m), i) = arg(e, m, i);
646 }
647 }
648 }
649 }
650
654 template <class T, class R>
655 void asElement_impl_dofval(const T& arg, R& ret) const
656 {
657 static_assert(
658 xt::get_rank<R>::value == 3 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
659 GOOSEFEM_ASSERT(arg.size() == m_ndof);
660 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_elemvec()));
661
662#pragma omp parallel for
663 for (size_t e = 0; e < m_nelem; ++e) {
664 for (size_t m = 0; m < m_nne; ++m) {
665 for (size_t i = 0; i < m_ndim; ++i) {
666 ret(e, m, i) = arg(m_dofs(m_conn(e, m), i));
667 }
668 }
669 }
670 }
671
675 template <class T, class R>
676 void asElement_impl_nodevec(const T& arg, R& ret) const
677 {
678 static_assert(
679 xt::get_rank<R>::value == 3 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
680 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_nodevec()));
681 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_elemvec()));
682
683#pragma omp parallel for
684 for (size_t e = 0; e < m_nelem; ++e) {
685 for (size_t m = 0; m < m_nne; ++m) {
686 for (size_t i = 0; i < m_ndim; ++i) {
687 ret(e, m, i) = arg(m_conn(e, m), i);
688 }
689 }
690 }
691 }
692
696 template <class T, class R>
697 void assembleDofs_impl_nodevec(const T& arg, R& ret) const
698 {
699 static_assert(
700 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
701 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_nodevec()));
702 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
703
704 ret.fill(0.0);
705
706 for (size_t m = 0; m < m_nnode; ++m) {
707 for (size_t i = 0; i < m_ndim; ++i) {
708 ret(m_dofs(m, i)) += arg(m, i);
709 }
710 }
711 }
712
716 template <class T, class R>
717 void assembleDofs_impl_elemvec(const T& arg, R& ret) const
718 {
719 static_assert(
720 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
721 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
722 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_dofval()));
723
724 ret.fill(0.0);
725
726 for (size_t e = 0; e < m_nelem; ++e) {
727 for (size_t m = 0; m < m_nne; ++m) {
728 for (size_t i = 0; i < m_ndim; ++i) {
729 ret(m_dofs(m_conn(e, m), i)) += arg(e, m, i);
730 }
731 }
732 }
733 }
734
738 template <class T, class R>
739 void assembleNode_impl_elemvec(const T& arg, R& ret) const
740 {
741 static_assert(
742 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value, "Unknown rank 'ret'");
743 GOOSEFEM_ASSERT(xt::has_shape(arg, this->shape_elemvec()));
744 GOOSEFEM_ASSERT(xt::has_shape(ret, this->shape_nodevec()));
745
746 array_type::tensor<double, 1> dofval = this->AssembleDofs(arg);
747 this->asNode(dofval, ret);
748 }
749
750protected:
753 size_t m_nelem;
754 size_t m_nne;
755 size_t m_nnode;
756 size_t m_ndim;
757 size_t m_ndof;
758};
759
760} // namespace GooseFEM
761
762#endif
Class to switch between storage types.
Definition: Vector.h:23
array_type::tensor< size_t, 2 > m_dofs
See dofs()
Definition: Vector.h:752
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:757
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:753
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:751
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:756
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:754
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:755
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
#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