diff --git a/include/GooseFEM/VectorPartitioned.h b/include/GooseFEM/VectorPartitioned.h index e670ed4..e90eee6 100644 --- a/include/GooseFEM/VectorPartitioned.h +++ b/include/GooseFEM/VectorPartitioned.h @@ -1,169 +1,404 @@ /** Methods to switch between storage types based on a mesh and DOFs that are partitioned in: - unknown DOFs - prescribed DOFs \file VectorPartitioned.h \copyright Copyright 2017. Tom de Geus. All rights reserved. \license This project is released under the GNU Public License (GPLv3). */ #ifndef GOOSEFEM_VECTORPARTITIONED_H #define GOOSEFEM_VECTORPARTITIONED_H #include "config.h" #include "Vector.h" namespace GooseFEM { /* "nodevec" - nodal vectors - [nnode, ndim] "elemvec" - nodal vectors stored per element - [nelem, nne, ndim] "dofval" - DOF values - [ndof] "dofval_u" - DOF values (Unknown) "== dofval[iiu]" - [nnu] "dofval_p" - DOF values (Prescribed) "== dofval[iiu]" - [nnp] */ +/** +Class to switch between: + +- "dofval": DOF values [#ndof]. +- "dofval_u": unknown DOF values [#nnu]. +- "dofval_p": prescribed DOF values [#nnp]. +- "nodevec": nodal vectors [#nnode, #ndim]. +- "elemvec": nodal vectors stored per element [#nelem, #nne, #ndim]. + +Based on a mesh and DOFs that are partitioned in: + +- unknown DOFs (iiu()), indicated with "u". +- prescribed DOFs (iip()), indicated with "p". +*/ class VectorPartitioned : public Vector { public: - // Constructor VectorPartitioned() = default; + /** + Constructor. + + \param conn connectivity [#nelem, #nne]. + \param dofs DOFs per node [#nnode, #ndim]. + \param iip prescribed DOFs [#nnp]. + */ VectorPartitioned( const xt::xtensor& conn, const xt::xtensor& dofs, const xt::xtensor& iip); - // Dimensions - size_t nnu() const; // number of unknown DOFs - size_t nnp() const; // number of prescribed DOFs + /** + Number of unknown DOFs. + + \return unsigned int + */ + size_t nnu() const; + + /** + Number of prescribed DOFs. + + \return unsigned int + */ + size_t nnp() const; + + /** + Unknown DOFs. - // DOF lists - xt::xtensor iiu() const; // unknown DOFs - xt::xtensor iip() const; // prescribed DOFs + \return [#nnu] + */ + xt::xtensor iiu() const; + + /** + Prescribed DOFs. + + \return [#nnp] + */ + xt::xtensor iip() const; /** Per DOF (see Vector::dofs()) list if unknown ("u"). \return Boolean "nodevec". */ xt::xtensor dofs_is_u() const; /** Per DOF (see Vector::dofs()) list if prescribed ("p"). \return Boolean "nodevec". */ xt::xtensor dofs_is_p() const; - // Copy (part of) nodevec/dofval to another nodevec/dofval + /** + Copy unknown DOFs from "nodevec" to another "nodvec": + + nodevec_dest[vector.dofs_is_u()] = nodevec_src + + the other DOFs are taken from ``nodevec_dest``: + + nodevec_dest[vector.dofs_is_p()] = nodevec_dest + + \param nodevec_src input [#nnode, #ndim] + \param nodevec_dest input [#nnode, #ndim] + \return nodevec output [#nnode, #ndim] + */ + xt::xtensor Copy_u( + const xt::xtensor& nodevec_src, + const xt::xtensor& nodevec_dest) const; + + /** + Copy unknown DOFs from "nodevec" to another "nodvec": + + nodevec_dest[vector.dofs_is_u()] = nodevec_src + + the other DOFs are taken from ``nodevec_dest``: + + nodevec_dest[vector.dofs_is_p()] = nodevec_dest + + \param nodevec_src input [#nnode, #ndim] + \param nodevec_dest input/output [#nnode, #ndim] + */ void copy_u( - const xt::xtensor& nodevec_src, xt::xtensor& nodevec_dest) const; // "iiu" updated + const xt::xtensor& nodevec_src, xt::xtensor& nodevec_dest) const; + /** + Copy prescribed DOFs from "nodevec" to another "nodvec": + + nodevec_dest[vector.dofs_is_p()] = nodevec_src + + the other DOFs are taken from ``nodevec_dest``: + + nodevec_dest[vector.dofs_is_u()] = nodevec_dest + + \param nodevec_src input [#nnode, #ndim] + \param nodevec_dest input [#nnode, #ndim] + \return nodevec output [#nnode, #ndim] + */ + xt::xtensor Copy_p( + const xt::xtensor& nodevec_src, + const xt::xtensor& nodevec_dest) const; + + /** + Copy prescribed DOFs from "nodevec" to another "nodvec": + + nodevec_dest[vector.dofs_is_p()] = nodevec_src + + the other DOFs are taken from ``nodevec_dest``: + + nodevec_dest[vector.dofs_is_u()] = nodevec_dest + + \param nodevec_src input [#nnode, #ndim] + \param nodevec_dest input/output [#nnode, #ndim] + */ void copy_p( - const xt::xtensor& nodevec_src, xt::xtensor& nodevec_dest) const; // "iip" updated + const xt::xtensor& nodevec_src, xt::xtensor& nodevec_dest) const; + + /** + Combine unknown and prescribed "dofval" into a single "dofval" list. + + \param dofval_u input [#nnu] + \param dofval_p input [#nnp] + \return dofval output [#ndof] + */ + xt::xtensor DofsFromParitioned( + const xt::xtensor& dofval_u, + const xt::xtensor& dofval_p) const; - // Convert to "dofval" (overwrite entries that occur more than once) + /** + Combine unknown and prescribed "dofval" into a single "dofval" list. + \param dofval_u input [#nnu] + \param dofval_p input [#nnp] + \param dofval output [#ndof] + */ void dofsFromParitioned( const xt::xtensor& dofval_u, const xt::xtensor& dofval_p, xt::xtensor& dofval) const; - void asDofs_u(const xt::xtensor& dofval, xt::xtensor& dofval_u) const; - void asDofs_u(const xt::xtensor& nodevec, xt::xtensor& dofval_u) const; - void asDofs_u(const xt::xtensor& elemvec, xt::xtensor& dofval_u) const; - void asDofs_p(const xt::xtensor& dofval, xt::xtensor& dofval_p) const; - void asDofs_p(const xt::xtensor& nodevec, xt::xtensor& dofval_p) const; - void asDofs_p(const xt::xtensor& elemvec, xt::xtensor& dofval_p) const; + /** + Combine unknown and prescribed "dofval" into a single "dofval" list + and directly convert to "nodeval" without a temporary + (overwrite entries that occur more than once). - // Convert to "nodevec" (overwrite entries that occur more than once) -- (auto allocation below) + \param dofval_u input [#nnu] + \param dofval_p input [#nnp] + \return nodevec output [#nnode, #ndim] + */ + xt::xtensor NodeFromPartitioned( + const xt::xtensor& dofval_u, + const xt::xtensor& dofval_p) const; + + /** + Combine unknown and prescribed "dofval" into a single "dofval" list + and directly convert to "nodeval" without a temporary + (overwrite entries that occur more than once). + + \param dofval_u input [#nnu] + \param dofval_p input [#nnp] + \param nodevec output [#nnode, #ndim] + */ void nodeFromPartitioned( const xt::xtensor& dofval_u, const xt::xtensor& dofval_p, xt::xtensor& nodevec) const; - // Convert to "elemvec" (overwrite entries that occur more than once) -- (auto allocation below) + /** + Combine unknown and prescribed "dofval" into a single "dofval" list + and directly convert to "elemvec" without a temporary + (overwrite entries that occur more than once). + + \param dofval_u input [#nnu] + \param dofval_p input [#nnp] + \return elemvec output [#nelem, #nne, #ndim] + */ + xt::xtensor ElementFromPartitioned( + const xt::xtensor& dofval_u, + const xt::xtensor& dofval_p) const; + + /** + Combine unknown and prescribed "dofval" into a single "dofval" list + and directly convert to "elemvec" without a temporary + (overwrite entries that occur more than once). + + \param dofval_u input [#nnu] + \param dofval_p input [#nnp] + \param elemvec output [#nelem, #nne, #ndim] + */ void elementFromPartitioned( const xt::xtensor& dofval_u, const xt::xtensor& dofval_p, xt::xtensor& elemvec) const; - // Assemble "dofval" (adds entries that occur more that once) -- (auto allocation below) + /** + Extract the unknown "dofval": - [[ deprecated ]] - void assembleDofs_u(const xt::xtensor& nodevec, xt::xtensor& dofval_u) const; + dofval[iiu()] - [[ deprecated ]] - void assembleDofs_u(const xt::xtensor& elemvec, xt::xtensor& dofval_u) const; + \param dofval input [#ndof] + \return dofval_u input [#nnu] + */ + xt::xtensor AsDofs_u(const xt::xtensor& dofval) const; - [[ deprecated ]] - void assembleDofs_p(const xt::xtensor& nodevec, xt::xtensor& dofval_p) const; + /** + Extract the unknown "dofval": - [[ deprecated ]] - void assembleDofs_p(const xt::xtensor& elemvec, xt::xtensor& dofval_p) const; + dofval[iiu()] - // Auto-allocation of the functions above - xt::xtensor DofsFromParitioned( - const xt::xtensor& dofval_u, const xt::xtensor& dofval_p) const; + \param dofval input [#ndof] + \param dofval_u input [#nnu] + */ + void asDofs_u(const xt::xtensor& dofval, xt::xtensor& dofval_u) const; - xt::xtensor AsDofs_u(const xt::xtensor& dofval) const; + /** + Convert "nodevec" to "dofval" (overwrite entries that occur more than once) + and extract the unknown "dofval" without a temporary. + + \param nodevec input [#nnode, #ndim] + \return dofval_u input [#nnu] + */ xt::xtensor AsDofs_u(const xt::xtensor& nodevec) const; + + /** + Convert "nodevec" to "dofval" (overwrite entries that occur more than once) + and extract the unknown "dofval" without a temporary. + + \param nodevec input [#nnode, #ndim] + \param dofval_u input [#nnu] + */ + void asDofs_u(const xt::xtensor& nodevec, xt::xtensor& dofval_u) const; + + /** + Convert "elemvec" to "dofval" (overwrite entries that occur more than once) + and extract the unknown "dofval" without a temporary. + + \param elemvec input [#nelem, #nne, #ndim] + \return dofval_u input [#nnu] + */ xt::xtensor AsDofs_u(const xt::xtensor& elemvec) const; + + /** + Convert "elemvec" to "dofval" (overwrite entries that occur more than once) + and extract the unknown "dofval" without a temporary. + + \param elemvec input [#nelem, #nne, #ndim] + \param dofval_u input [#nnu] + */ + void asDofs_u(const xt::xtensor& elemvec, xt::xtensor& dofval_u) const; + + /** + Extract the prescribed "dofval": + + dofval[iip()] + + \param dofval input [#ndof] + \return dofval_p input [#nnp] + */ xt::xtensor AsDofs_p(const xt::xtensor& dofval) const; + + /** + Extract the prescribed "dofval": + + dofval[iip()] + + \param dofval input [#ndof] + \param dofval_p input [#nnp] + */ + void asDofs_p(const xt::xtensor& dofval, xt::xtensor& dofval_p) const; + + /** + Convert "nodevec" to "dofval" (overwrite entries that occur more than once) + and extract the prescribed "dofval" without a temporary. + + \param nodevec input [#nnode, #ndim] + \return dofval_p input [#nnp] + */ xt::xtensor AsDofs_p(const xt::xtensor& nodevec) const; + + /** + Convert "nodevec" to "dofval" (overwrite entries that occur more than once) + and extract the prescribed "dofval" without a temporary. + + \param nodevec input [#nnode, #ndim] + \param dofval_p input [#nnp] + */ + void asDofs_p(const xt::xtensor& nodevec, xt::xtensor& dofval_p) const; + + /** + Convert "elemvec" to "dofval" (overwrite entries that occur more than once) + and extract the prescribed "dofval" without a temporary. + + \param elemvec input [#nelem, #nne, #ndim] + \return dofval_p input [#nnp] + */ xt::xtensor AsDofs_p(const xt::xtensor& elemvec) const; - xt::xtensor NodeFromPartitioned( - const xt::xtensor& dofval_u, const xt::xtensor& dofval_p) const; + /** + Convert "elemvec" to "dofval" (overwrite entries that occur more than once) + and extract the prescribed "dofval" without a temporary. - xt::xtensor ElementFromPartitioned( - const xt::xtensor& dofval_u, const xt::xtensor& dofval_p) const; + \param elemvec input [#nelem, #nne, #ndim] + \param dofval_p input [#nnp] + */ + void asDofs_p(const xt::xtensor& elemvec, xt::xtensor& dofval_p) const; + /** + \cond + */ + [[ deprecated ]] + void assembleDofs_u(const xt::xtensor& nodevec, xt::xtensor& dofval_u) const; + + [[ deprecated ]] + void assembleDofs_u(const xt::xtensor& elemvec, xt::xtensor& dofval_u) const; + + [[ deprecated ]] + void assembleDofs_p(const xt::xtensor& nodevec, xt::xtensor& dofval_p) const; + + [[ deprecated ]] + void assembleDofs_p(const xt::xtensor& elemvec, xt::xtensor& dofval_p) const; [[ deprecated ]] xt::xtensor AssembleDofs_u(const xt::xtensor& nodevec) const; [[ deprecated ]] xt::xtensor AssembleDofs_u(const xt::xtensor& elemvec) const; [[ deprecated ]] xt::xtensor AssembleDofs_p(const xt::xtensor& nodevec) const; [[ deprecated ]] xt::xtensor AssembleDofs_p(const xt::xtensor& elemvec) const; - - xt::xtensor Copy_u( - const xt::xtensor& nodevec_src, - const xt::xtensor& nodevec_dest) const; - /** - Copy prescribed DOFs from an "src" to "dest". - - \param nodevec_src The input, from which to copy the prescribed DOFs. - \param nodevec_dest The destination, to which to copy the prescribed DOFs. - \returns The result after copying. + \endcond */ - xt::xtensor Copy_p( - const xt::xtensor& nodevec_src, - const xt::xtensor& nodevec_dest) const; protected: - // Bookkeeping - xt::xtensor m_iiu; // DOF-numbers that are unknown [nnu] - xt::xtensor m_iip; // DOF-numbers that are prescribed [nnp] + xt::xtensor m_iiu; ///< See iiu() + xt::xtensor m_iip; ///< See iip() + size_t m_nnu; ///< See #nnu + size_t m_nnp; ///< See #nnp - // DOFs per node, such that iiu = arange(nnu), iip = nnu + arange(nnp) - xt::xtensor m_part; + /** + Renumbered DOFs per node, such that + + iiu = arange(nnu) + iip = nnu + arange(nnp) - // Dimensions - size_t m_nnu; // number of unknown DOFs - size_t m_nnp; // number of prescribed DOFs + making is much simpler to slice. + */ + xt::xtensor m_part; }; } // namespace GooseFEM #include "VectorPartitioned.hpp" #endif