9#ifndef GOOSEFEM_VECTOR_H
10#define GOOSEFEM_VECTOR_H
33 template <
class S,
class T>
113 T
Copy(
const T& nodevec_src,
const T& nodevec_dest)
const
115 T ret = T::from_shape(nodevec_dest.shape());
116 this->
copy(nodevec_src, ret);
127 void copy(
const T& nodevec_src, T& nodevec_dest)
const
132 xt::noalias(nodevec_dest) = nodevec_src;
145 this->asDofs_impl(arg, ret);
155 template <
class T,
class R>
158 this->asDofs_impl(arg, ret);
171 this->asNode_impl(arg, ret);
181 template <
class T,
class R>
184 this->asNode_impl(arg, ret);
197 this->asElement_impl(arg, ret);
207 template <
class T,
class R>
210 this->asElement_impl(arg, ret);
223 this->assembleDofs_impl(arg, ret);
233 template <
class T,
class R>
236 this->assembleDofs_impl(arg, ret);
249 this->assembleNode_impl(arg, ret);
259 template <
class T,
class R>
262 this->assembleNode_impl(arg, ret);
272 return std::array<size_t, 1>{
m_ndof};
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
408 if (arg.dimension() == 2) {
409 this->asDofs_impl_nodevec(arg, ret);
411 else if (arg.dimension() == 3) {
412 this->asDofs_impl_elemvec(arg, ret);
415 throw std::runtime_error(
"Vector::asDofs unknown dimension for conversion");
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
425 this->asDofs_impl_nodevec(arg, ret);
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
434 this->asDofs_impl_elemvec(arg, ret);
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
443 if (arg.dimension() == 1) {
444 this->asNode_impl_dofval(arg, ret);
446 else if (arg.dimension() == 3) {
447 this->asNode_impl_elemvec(arg, ret);
450 throw std::runtime_error(
"Vector::asNode unknown dimension for conversion");
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
460 this->asNode_impl_dofval(arg, ret);
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
469 this->asNode_impl_elemvec(arg, ret);
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
478 if (arg.dimension() == 1) {
479 this->asElement_impl_dofval(arg, ret);
481 else if (arg.dimension() == 2) {
482 this->asElement_impl_nodevec(arg, ret);
485 throw std::runtime_error(
"Vector::asElement unknown dimension for conversion");
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
495 this->asElement_impl_dofval(arg, ret);
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
504 this->asElement_impl_nodevec(arg, ret);
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
513 if (arg.dimension() == 2) {
514 this->assembleDofs_impl_nodevec(arg, ret);
516 else if (arg.dimension() == 3) {
517 this->assembleDofs_impl_elemvec(arg, ret);
520 throw std::runtime_error(
"Vector::assembleDofs unknown dimension for conversion");
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
530 this->assembleDofs_impl_nodevec(arg, ret);
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
539 this->assembleDofs_impl_elemvec(arg, ret);
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
548 if (arg.dimension() == 3) {
549 this->assembleNode_impl_elemvec(arg, ret);
552 throw std::runtime_error(
"Vector::assembleNode unknown dimension for conversion");
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
562 this->assembleNode_impl_elemvec(arg, ret);
568 template <
class T,
class R>
569 void asDofs_impl_nodevec(
const T& arg, R& ret)
const
572 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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);
589 template <
class T,
class R>
590 void asDofs_impl_elemvec(
const T& arg, R& ret)
const
593 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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) {
612 template <
class T,
class R>
613 void asNode_impl_dofval(
const T& arg, R& ret)
const
616 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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));
631 template <
class T,
class R>
632 void asNode_impl_elemvec(
const T& arg, R& ret)
const
635 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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);
654 template <
class T,
class R>
655 void asElement_impl_dofval(
const T& arg, R& ret)
const
658 xt::get_rank<R>::value == 3 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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) {
675 template <
class T,
class R>
676 void asElement_impl_nodevec(
const T& arg, R& ret)
const
679 xt::get_rank<R>::value == 3 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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);
696 template <
class T,
class R>
697 void assembleDofs_impl_nodevec(
const T& arg, R& ret)
const
700 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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);
716 template <
class T,
class R>
717 void assembleDofs_impl_elemvec(
const T& arg, R& ret)
const
720 xt::get_rank<R>::value == 1 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
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) {
738 template <
class T,
class R>
739 void assembleNode_impl_elemvec(
const T& arg, R& ret)
const
742 xt::get_rank<R>::value == 2 || !xt::has_fixed_rank_t<R>::value,
"Unknown rank 'ret'");
746 array_type::tensor<double, 1> dofval = this->
AssembleDofs(arg);
747 this->
asNode(dofval, ret);
Class to switch between storage types.
array_type::tensor< size_t, 2 > m_dofs
See dofs()
const array_type::tensor< size_t, 2 > & conn() const
void asElement(const T &arg, R &ret) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
std::array< size_t, 2 > shape_nodevec() const
Shape of "nodevec".
array_type::tensor< double, 2 > AsNode(const T &arg) const
Convert "dofval" or "elemvec" to "nodevec" (overwrite entries that occur more than once).
void assembleDofs(const T &arg, R &ret) const
Assemble "nodevec" or "elemvec" to "dofval" (adds entries that occur more that once).
array_type::tensor< double, 3 > allocate_elemmat(double val) const
Allocated and initialised "elemmat".
void assembleNode(const T &arg, R &ret) const
Assemble "elemvec" to "nodevec" (adds entries that occur more that once.
array_type::tensor< double, 1 > allocate_dofval() const
Allocated "dofval".
array_type::tensor< double, 2 > allocate_nodevec() const
Allocated "nodevec".
std::array< size_t, 3 > shape_elemvec() const
Shape of "elemvec".
std::array< size_t, 3 > shape_elemmat() const
Shape of "elemmat".
array_type::tensor< double, 3 > AsElement(const T &arg) const
Convert "dofval" or "nodevec" to "elemvec" (overwrite entries that occur more than once).
std::array< size_t, 1 > shape_dofval() const
Shape of "dofval".
array_type::tensor< double, 1 > AsDofs(const T &arg) const
Convert "nodevec" or "elemvec" to "dofval" (overwrite entries that occur more than once).
array_type::tensor< double, 3 > allocate_elemvec() const
Allocated "elemvec".
void copy(const T &nodevec_src, T &nodevec_dest) const
Copy "nodevec" to another "nodevec".
void asDofs(const T &arg, R &ret) const
Convert "nodevec" or "elemvec" to "dofval" (overwrite entries that occur more than once).
array_type::tensor< double, 3 > allocate_elemvec(double val) const
Allocated and initialised "elemvec".
array_type::tensor< double, 2 > allocate_nodevec(double val) const
Allocated and initialised "nodevec".
array_type::tensor< size_t, 2 > m_conn
See conn()
array_type::tensor< double, 2 > AssembleNode(const T &arg) const
Assemble "elemvec" to "nodevec" (adds entries that occur more that once.
array_type::tensor< double, 3 > allocate_elemmat() const
Allocated "elemmat".
Vector(const S &conn, const T &dofs)
Constructor.
const array_type::tensor< size_t, 2 > & dofs() const
array_type::tensor< double, 1 > AssembleDofs(const T &arg) const
Assemble "nodevec" or "elemvec" to "dofval" (adds entries that occur more that once).
T Copy(const T &nodevec_src, const T &nodevec_dest) const
Copy "nodevec" to another "nodevec".
void asNode(const T &arg, R &ret) const
Convert "dofval" or "elemvec" to "nodevec" (overwrite entries that occur more than once).
array_type::tensor< double, 1 > allocate_dofval(double val) const
Allocated and initialised "dofval".
#define GOOSEFEM_ASSERT(expr)
All assertions are implementation as::
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Toolbox to perform finite element computations.