diff --git a/include/GooseFEM/TyingsPeriodic.h b/include/GooseFEM/TyingsPeriodic.h index d12ae4a..a77d624 100644 --- a/include/GooseFEM/TyingsPeriodic.h +++ b/include/GooseFEM/TyingsPeriodic.h @@ -1,226 +1,258 @@ /** Tools to store and apply nodal/DOF tyings. \file TyingsPeriodic.h \copyright Copyright 2017. Tom de Geus. All rights reserved. \license This project is released under the GNU Public License (GPLv3). */ #ifndef GOOSEFEM_TYINGSPERIODIC_H #define GOOSEFEM_TYINGSPERIODIC_H #include "config.h" #include #include namespace GooseFEM { /** Tools to store and apply nodal/DOF tyings. */ namespace Tyings { /** Nodal tyings per periodic boundary conditions. The idea is that the displacement of all DOFs of a node are tied to another node and to the average displacement gradient. The latter is applied/measured using 'virtual' control nodes. Consider the DOF list \f$ u \f$ renumbered such that it is split up in independent and dependent DOFs as follows \f$ u = \begin{bmatrix} u_i \\ u_d \end{bmatrix}\f$ whereby the independent DOFs are furthermore split up in unknown and prescribed nodes as follows \f$ u_i = \begin{bmatrix} u_u \\ u_p \end{bmatrix}\f$ such that \f$ u = \begin{bmatrix} u_u \\ u_p \\ u_d \end{bmatrix}\f$ \todo Document how the DOFs are tied to the control nodes, and what the has to do with the mean. */ class Periodic { public: Periodic() = default; /** Constructor. \param coor Nodal coordinates [nnode, ndim]. \param dofs DOF-numbers per node [nnode, ndim]. \param control_dofs DOF-numbers per control node [ndim, ndim]. \param nodal_tyings List of nodal tyings, see nodal_tyings(). [ntyings, 2]. */ Periodic( const xt::xtensor& coor, const xt::xtensor& dofs, const xt::xtensor& control_dofs, const xt::xtensor& nodal_tyings); /** Constructor. \param coor Nodal coordinates [nnode, ndim]. \param dofs DOF-numbers per node [nnode, ndim]. \param control_dofs DOF-numbers per control node [ndim, ndim]. \param nodal_tyings List of nodal tyings, see nodal_tyings(). [ntyings, 2]. \param iip List of prescribed DOF-numbers. */ Periodic( const xt::xtensor& coor, const xt::xtensor& dofs, const xt::xtensor& control_dofs, const xt::xtensor& nodal_tyings, const xt::xtensor& iip); /** Number of dependent DOFs. \return unsigned int */ size_t nnd() const; /** Number of independent DOFs. \return unsigned int */ size_t nni() const; /** Number of independent unknown DOFs. \return unsigned int */ size_t nnu() const; /** Number of independent prescribed DOFs. \return unsigned int */ size_t nnp() const; /** Return the DOF-numbers per node, as used internally (after renumbering). \return [nnode, ndim]. */ xt::xtensor dofs() const; /** Return the DOF-numbers for each control node, as used internally (after renumbering). \return [ndim, ndim]. */ xt::xtensor control() const; /** Return the applied nodal tyings. Per tying (row) two node numbers are specified, according to the convention (independent, dependent). \return [ntyings, 2]. */ xt::xtensor nodal_tyings() const; /** Dependent DOFs. \return List of DOF numbers. */ xt::xtensor iid() const; /** Independent DOFs. \return List of DOF numbers. */ xt::xtensor iii() const; /** Independent unknown DOFs. \return List of DOF numbers. */ xt::xtensor iiu() const; /** Independent prescribed DOFs. \return List of DOF numbers. */ xt::xtensor iip() const; /** Return tying matrix such as to get the dependent DOFs \f$ u_d \f$ from the independent DOFs \f$ u_i \f$ as follows \f$ u_d = C_{di} u_i \f$ Note that this can be further partitioned in \f$ u_d = C_{du} u_u + C_{dp} u_p \f$ See Cdu() and Cdp(). \return Sparse matrix. */ Eigen::SparseMatrix Cdi() const; /** Unknown part of the partitioned tying matrix, see Cdi(). \return Sparse matrix. */ Eigen::SparseMatrix Cdu() const; /** Prescribed part of the partitioned tying matrix, see Cdi(). \return Sparse matrix. */ Eigen::SparseMatrix Cdp() const; private: size_t m_nnu; ///< See nnu(). size_t m_nnp; ///< See nnp(). size_t m_nni; ///< See nni(). size_t m_nnd; ///< See nnd(). size_t m_ndim; ///< Number of dimensions. size_t m_nties; ///< Number of nodal ties. xt::xtensor m_dofs; ///< See dofs(). xt::xtensor m_control; ///< See control(). xt::xtensor m_tyings; ///< See nodal_tyings(). xt::xtensor m_coor; ///< Nodal coordinates [nnode, ndim]. }; +/** +Add control nodes to an existing system. +*/ class Control { public: - // Constructors + Control() = default; + + /** + Constructor. + + \param coor Nodal coordinates [nnode, ndim]. + \param dofs DOF-numbers per node [nnode, ndim]. + */ Control(const xt::xtensor& coor, const xt::xtensor& dofs); - // Extract new lists + /** + Nodal coordinates, for the system with control nodes added to it. + + \param [nnode + ndim, ndim], with nnode the number of nodes of the original system. + */ xt::xtensor coor() const; + + /** + DOF-numbers per node, for the system with control nodes added to it. + + \param [nnode + ndim, ndim], with nnode the number of nodes of the original system. + */ xt::xtensor dofs() const; + + /** + DOF-numbers of each control node. + + \param [ndim, ndim]. + */ xt::xtensor controlDofs() const; + + /** + Node-numbers of the control nodes. + + \param [ndim]. + */ xt::xtensor controlNodes() const; private: - xt::xtensor m_coor; - xt::xtensor m_dofs; - xt::xtensor m_control_dofs; - xt::xtensor m_control_nodes; + xt::xtensor m_coor; ///< See coor(). + xt::xtensor m_dofs; ///< See dofs(). + xt::xtensor m_control_dofs; ///< See controlDofs(). + xt::xtensor m_control_nodes; ///< See controlNodes(). }; } // namespace Tyings } // namespace GooseFEM #include "TyingsPeriodic.hpp" #endif