Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internally deriving from Vector #165

Merged
merged 3 commits into from
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions include/GooseFEM/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ namespace GooseFEM {

class Vector {
public:
// Constructor

Vector() = default;

/**
Constructor.

\param conn Connectivity, shape ``[nelem, nne]``.
\param dofs DOFs per node, shape ``[nnode, ndim]``.
*/
Vector(const xt::xtensor<size_t, 2>& conn, const xt::xtensor<size_t, 2>& dofs);

// Dimensions
Expand Down Expand Up @@ -66,6 +73,10 @@ class Vector {
xt::xtensor<double, 1> AssembleDofs(const xt::xtensor<double, 3>& elemvec) const;
xt::xtensor<double, 2> AssembleNode(const xt::xtensor<double, 3>& elemvec) const;

xt::xtensor<double, 2> Copy(
const xt::xtensor<double, 2>& nodevec_src,
const xt::xtensor<double, 2>& nodevec_dest) const;

// Get shape of dofval, nodevec, elemvec
std::array<size_t, 1> ShapeDofval() const;
std::array<size_t, 2> ShapeNodevec() const;
Expand All @@ -82,17 +93,14 @@ class Vector {
xt::xtensor<double, 3> AllocateElemvec(double val) const;
xt::xtensor<double, 3> AllocateElemmat(double val) const;

private:
// Bookkeeping
xt::xtensor<size_t, 2> m_conn; // connectivity [nelem, nne ]
xt::xtensor<size_t, 2> m_dofs; // DOF-numbers per node [nnode, ndim]

// Dimensions
size_t m_nelem; // number of elements
size_t m_nne; // number of nodes per element
size_t m_nnode; // number of nodes
size_t m_ndim; // number of dimensions
size_t m_ndof; // number of DOFs
protected:
xt::xtensor<size_t, 2> m_conn; ///< Connectivity ``[nelem, nne]``
xt::xtensor<size_t, 2> m_dofs; ///< DOF-numbers per node ``[nnode, ndim]``
size_t m_nelem; ///< Number of elements
size_t m_nne; ///< Number of nodes per element
size_t m_nnode; ///< Number of nodes
size_t m_ndim; ///< Number of dimensions
size_t m_ndof; ///< Number of DOFs
};

} // namespace GooseFEM
Expand Down
143 changes: 92 additions & 51 deletions include/GooseFEM/Vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ inline xt::xtensor<size_t, 2> Vector::dofs() const
return m_dofs;
}

inline void
Vector::copy(const xt::xtensor<double, 2>& nodevec_src, xt::xtensor<double, 2>& nodevec_dest) const
inline void Vector::copy(
const xt::xtensor<double, 2>& nodevec_src, xt::xtensor<double, 2>& nodevec_dest) const
{
GOOSEFEM_ASSERT(xt::has_shape(nodevec_src, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec_dest, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec_src, this->ShapeNodevec()));
GOOSEFEM_ASSERT(xt::has_shape(nodevec_dest, this->ShapeNodevec()));

xt::noalias(nodevec_dest) = nodevec_src;
}

inline void
Vector::asDofs(const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 1>& dofval) const
inline void Vector::asDofs(
const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 1>& dofval) const
{
GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, this->ShapeNodevec()));
GOOSEFEM_ASSERT(dofval.size() == m_ndof);

dofval.fill(0.0);
Expand All @@ -79,10 +79,10 @@ Vector::asDofs(const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 1>& do
}
}

inline void
Vector::asDofs(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 1>& dofval) const
inline void Vector::asDofs(
const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 1>& dofval) const
{
GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, this->ShapeElemvec()));
GOOSEFEM_ASSERT(dofval.size() == m_ndof);

dofval.fill(0.0);
Expand All @@ -97,11 +97,11 @@ Vector::asDofs(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 1>& do
}
}

inline void
Vector::asNode(const xt::xtensor<double, 1>& dofval, xt::xtensor<double, 2>& nodevec) const
inline void Vector::asNode(
const xt::xtensor<double, 1>& dofval, xt::xtensor<double, 2>& nodevec) const
{
GOOSEFEM_ASSERT(dofval.size() == m_ndof);
GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, this->ShapeNodevec()));

#pragma omp parallel for
for (size_t m = 0; m < m_nnode; ++m) {
Expand All @@ -111,11 +111,11 @@ Vector::asNode(const xt::xtensor<double, 1>& dofval, xt::xtensor<double, 2>& nod
}
}

inline void
Vector::asNode(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 2>& nodevec) const
inline void Vector::asNode(
const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 2>& nodevec) const
{
GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, this->ShapeElemvec()));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, this->ShapeNodevec()));

nodevec.fill(0.0);

Expand All @@ -129,11 +129,11 @@ Vector::asNode(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 2>& no
}
}

inline void
Vector::asElement(const xt::xtensor<double, 1>& dofval, xt::xtensor<double, 3>& elemvec) const
inline void Vector::asElement(
const xt::xtensor<double, 1>& dofval, xt::xtensor<double, 3>& elemvec) const
{
GOOSEFEM_ASSERT(dofval.size() == m_ndof);
GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, this->ShapeElemvec()));

#pragma omp parallel for
for (size_t e = 0; e < m_nelem; ++e) {
Expand All @@ -145,11 +145,11 @@ Vector::asElement(const xt::xtensor<double, 1>& dofval, xt::xtensor<double, 3>&
}
}

inline void
Vector::asElement(const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 3>& elemvec) const
inline void Vector::asElement(
const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 3>& elemvec) const
{
GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, this->ShapeNodevec()));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, this->ShapeElemvec()));

#pragma omp parallel for
for (size_t e = 0; e < m_nelem; ++e) {
Expand All @@ -161,10 +161,10 @@ Vector::asElement(const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 3>&
}
}

inline void
Vector::assembleDofs(const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 1>& dofval) const
inline void Vector::assembleDofs(
const xt::xtensor<double, 2>& nodevec, xt::xtensor<double, 1>& dofval) const
{
GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, this->ShapeNodevec()));
GOOSEFEM_ASSERT(dofval.size() == m_ndof);

dofval.fill(0.0);
Expand All @@ -176,10 +176,10 @@ Vector::assembleDofs(const xt::xtensor<double, 2>& nodevec, xt::xtensor<double,
}
}

inline void
Vector::assembleDofs(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 1>& dofval) const
inline void Vector::assembleDofs(
const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 1>& dofval) const
{
GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, this->ShapeElemvec()));
GOOSEFEM_ASSERT(dofval.size() == m_ndof);

dofval.fill(0.0);
Expand All @@ -193,127 +193,168 @@ Vector::assembleDofs(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double,
}
}

inline void
Vector::assembleNode(const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 2>& nodevec) const
inline void Vector::assembleNode(
const xt::xtensor<double, 3>& elemvec, xt::xtensor<double, 2>& nodevec) const
{
GOOSEFEM_ASSERT(xt::has_shape(elemvec, {m_nelem, m_nne, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, {m_nnode, m_ndim}));
GOOSEFEM_ASSERT(xt::has_shape(elemvec, this->ShapeElemvec()));
GOOSEFEM_ASSERT(xt::has_shape(nodevec, this->ShapeNodevec()));

xt::xtensor<double, 1> dofval = this->AssembleDofs(elemvec);
this->asNode(dofval, nodevec);
}

inline xt::xtensor<double, 1> Vector::AsDofs(const xt::xtensor<double, 2>& nodevec) const
{
xt::xtensor<double, 1> dofval = xt::empty<double>({m_ndof});
xt::xtensor<double, 1> dofval = xt::empty<double>(this->ShapeDofval());
this->asDofs(nodevec, dofval);
return dofval;
}

inline xt::xtensor<double, 1> Vector::AsDofs(const xt::xtensor<double, 3>& elemvec) const
{
xt::xtensor<double, 1> dofval = xt::empty<double>({m_ndof});
xt::xtensor<double, 1> dofval = xt::empty<double>(this->ShapeDofval());
this->asDofs(elemvec, dofval);
return dofval;
}

inline xt::xtensor<double, 2> Vector::AsNode(const xt::xtensor<double, 1>& dofval) const
{
xt::xtensor<double, 2> nodevec = xt::empty<double>({m_nnode, m_ndim});
xt::xtensor<double, 2> nodevec = xt::empty<double>(this->ShapeNodevec());
this->asNode(dofval, nodevec);
return nodevec;
}

inline xt::xtensor<double, 2> Vector::AsNode(const xt::xtensor<double, 3>& elemvec) const
{
xt::xtensor<double, 2> nodevec = xt::empty<double>({m_nnode, m_ndim});
xt::xtensor<double, 2> nodevec = xt::empty<double>(this->ShapeNodevec());
this->asNode(elemvec, nodevec);
return nodevec;
}

inline xt::xtensor<double, 3> Vector::AsElement(const xt::xtensor<double, 1>& dofval) const
{
xt::xtensor<double, 3> elemvec = xt::empty<double>({m_nelem, m_nne, m_ndim});
xt::xtensor<double, 3> elemvec = xt::empty<double>(this->ShapeElemvec());
this->asElement(dofval, elemvec);
return elemvec;
}

inline xt::xtensor<double, 3> Vector::AsElement(const xt::xtensor<double, 2>& nodevec) const
{
xt::xtensor<double, 3> elemvec = xt::empty<double>({m_nelem, m_nne, m_ndim});
xt::xtensor<double, 3> elemvec = xt::empty<double>(this->ShapeElemvec());
this->asElement(nodevec, elemvec);
return elemvec;
}

inline xt::xtensor<double, 1> Vector::AssembleDofs(const xt::xtensor<double, 2>& nodevec) const
{
xt::xtensor<double, 1> dofval = xt::empty<double>({m_ndof});
xt::xtensor<double, 1> dofval = xt::empty<double>(this->ShapeDofval());
this->assembleDofs(nodevec, dofval);
return dofval;
}

inline xt::xtensor<double, 1> Vector::AssembleDofs(const xt::xtensor<double, 3>& elemvec) const
{
xt::xtensor<double, 1> dofval = xt::empty<double>({m_ndof});
xt::xtensor<double, 1> dofval = xt::empty<double>(this->ShapeDofval());
this->assembleDofs(elemvec, dofval);
return dofval;
}

inline xt::xtensor<double, 2> Vector::AssembleNode(const xt::xtensor<double, 3>& elemvec) const
{
xt::xtensor<double, 2> nodevec = xt::empty<double>({m_nnode, m_ndim});
xt::xtensor<double, 2> nodevec = xt::empty<double>(this->ShapeNodevec());
this->assembleNode(elemvec, nodevec);
return nodevec;
}

inline xt::xtensor<double, 2> Vector::Copy(
const xt::xtensor<double, 2>& nodevec_src, const xt::xtensor<double, 2>& nodevec_dest) const
{
xt::xtensor<double, 2> ret = nodevec_dest;
this->copy(nodevec_src, ret);
return ret;
}

inline std::array<size_t, 1> Vector::ShapeDofval() const
{
std::array<size_t, 1> shape;
shape[0] = m_ndof;
return shape;
}

inline std::array<size_t, 2> Vector::ShapeNodevec() const
{
std::array<size_t, 2> shape;
shape[0] = m_nnode;
shape[1] = m_ndim;
return shape;
}

inline std::array<size_t, 3> Vector::ShapeElemvec() const
{
std::array<size_t, 3> shape;
shape[0] = m_nelem;
shape[1] = m_nne;
shape[2] = m_ndim;
return shape;
}

inline std::array<size_t, 3> Vector::ShapeElemmat() const
{
std::array<size_t, 3> shape;
shape[0] = m_nelem;
shape[1] = m_nne * m_ndim;
shape[2] = m_nne * m_ndim;
return shape;
}

inline xt::xtensor<double, 1> Vector::AllocateDofval() const
{
xt::xtensor<double, 1> dofval = xt::empty<double>({m_ndof});
xt::xtensor<double, 1> dofval = xt::empty<double>(this->ShapeDofval());
return dofval;
}

inline xt::xtensor<double, 2> Vector::AllocateNodevec() const
{
xt::xtensor<double, 2> nodevec = xt::empty<double>({m_nnode, m_ndim});
xt::xtensor<double, 2> nodevec = xt::empty<double>(this->ShapeNodevec());
return nodevec;
}

inline xt::xtensor<double, 3> Vector::AllocateElemvec() const
{
xt::xtensor<double, 3> elemvec = xt::empty<double>({m_nelem, m_nne, m_ndim});
xt::xtensor<double, 3> elemvec = xt::empty<double>(this->ShapeElemvec());
return elemvec;
}

inline xt::xtensor<double, 3> Vector::AllocateElemmat() const
{
xt::xtensor<double, 3> elemmat = xt::empty<double>({m_nelem, m_nne * m_ndim, m_nne * m_ndim});
xt::xtensor<double, 3> elemmat = xt::empty<double>(this->ShapeElemmat());
return elemmat;
}

inline xt::xtensor<double, 1> Vector::AllocateDofval(double val) const
{
xt::xtensor<double, 1> dofval = xt::empty<double>({m_ndof});
xt::xtensor<double, 1> dofval = xt::empty<double>(this->ShapeDofval());
dofval.fill(val);
return dofval;
}

inline xt::xtensor<double, 2> Vector::AllocateNodevec(double val) const
{
xt::xtensor<double, 2> nodevec = xt::empty<double>({m_nnode, m_ndim});
xt::xtensor<double, 2> nodevec = xt::empty<double>(this->ShapeNodevec());
nodevec.fill(val);
return nodevec;
}

inline xt::xtensor<double, 3> Vector::AllocateElemvec(double val) const
{
xt::xtensor<double, 3> elemvec = xt::empty<double>({m_nelem, m_nne, m_ndim});
xt::xtensor<double, 3> elemvec = xt::empty<double>(this->ShapeElemvec());
elemvec.fill(val);
return elemvec;
}

inline xt::xtensor<double, 3> Vector::AllocateElemmat(double val) const
{
xt::xtensor<double, 3> elemmat = xt::empty<double>({m_nelem, m_nne * m_ndim, m_nne * m_ndim});
xt::xtensor<double, 3> elemmat = xt::empty<double>(this->ShapeElemmat());
elemmat.fill(val);
return elemmat;
}
Expand Down
Loading