diff --git a/docs/Mesh.rst b/docs/Mesh.rst index 85c3782..7cbbba0 100644 --- a/docs/Mesh.rst +++ b/docs/Mesh.rst @@ -1,106 +1,130 @@ ************** GooseFEM::Mesh ************** .. note:: Source: .. code-block:: cpp #include ``GooseFEM::Mesh::dofs`` ======================== -Get a sequential list of DOF-numbers for each vector-component of each node. - .. code-block:: cpp - MatS GooseFEM::Mesh::dofs ( size_t nnode , size_t ndim ) + GooseFEM::MatS GooseFEM::Mesh::dofs(size_t nnode, size_t ndim) -For example for 3 nodes in 2 dimensions the output is +Get a sequential list of DOF-numbers for each vector-component of each node. For example for 3 nodes in 2 dimensions the output is .. math:: \begin{bmatrix} 0 & 1 \\ 2 & 3 \\ 4 & 5 \end{bmatrix} ``GooseFEM::Mesh::renumber`` ============================ -* Renumber indices to lowest possible indices (returns a copy, input not modified). +.. code-block:: cpp - .. code-block:: cpp + GooseFEM::MatS GooseFEM::Mesh::renumber(const GooseFEM::MatS &dofs) - MatS GooseFEM::Mesh::renumber ( const MatS &in ) +Renumber (DOF) indices to lowest possible indices. For example: - For example: +.. math:: - .. math:: + \begin{bmatrix} + 0 & 1 \\ + 5 & 4 + \end{bmatrix} - \begin{bmatrix} - 0 & 1 \\ - 0 & 1 \\ - 5 & 4 - \end{bmatrix} +is renumbered to - is renumbered to +.. math:: - .. math:: + \begin{bmatrix} + 0 & 1 \\ + 3 & 2 + \end{bmatrix} + +Or, in pseudo-code, the result of this function is that: + +.. code-block:: python - \begin{bmatrix} - 0 & 1 \\ - 0 & 1 \\ - 3 & 2 - \end{bmatrix} + dofs = renumber(dofs) -* Reorder indices such that some items are at the beginning or the end (returns a copy, input not modified). + sort(unique(dofs[:])) == range(max(dofs+1)) + +.. note:: Generic interface .. code-block:: cpp - MatS GooseFEM::Mesh::renumber ( const MatS &in , const ColS &idx, std::string location="end" ); + template + void renumber(const InputIterator first, const InputIterator last, const OutputIterator result) + +``GooseFEM::Mesh::reorder`` +=========================== + +.. code-block:: cpp + + GooseFEM::MatS GooseFEM::Mesh::reorder(const GooseFEM::MatS &dofs, const ColS &idx, std::string location="end") + +Reorder (DOF) indices such to the lowest possible indices, such that some items are at the beginning or the end. For example: - For example: +.. math:: - .. math:: + \mathrm{dofs} = + \begin{bmatrix} + 0 & 1 \\ + 2 & 3 \\ + 4 & 5 + \end{bmatrix} - \mathrm{in} = - \begin{bmatrix} - 0 & 1 \\ - 0 & 1 \\ - 3 & 2 \\ - 4 & 5 - \end{bmatrix} +with - with +.. math:: - .. math:: + \mathrm{idx} = + \begin{bmatrix} + 0 & 1 + \end{bmatrix} - \mathrm{idx} = - \begin{bmatrix} - 6 & 4 - \end{bmatrix} +Implies that ``dofs`` is renumbered such that 0 becomes the one-before-last index (:math:`0 \rightarrow 4`), and the 1 becomes the last index (:math:`1 \rightarrow 5`). The remaining items are renumbered to the lowest index while keeping the same order. The result: - Implies that ``in`` is renumbered such that the 6th item becomes the one-before-last item (:math:`5 \rightarrow 4`), and the 4th item become the last (:math:`3 \rightarrow 5`). The remaining items are renumbered to the lowest index while keeping the same order. The result: +.. math:: - .. math:: + \begin{bmatrix} + 4 & 5 \\ + 0 & 1 \\ + 2 & 3 + \end{bmatrix} - \begin{bmatrix} - 0 & 1 \\ - 0 & 1 \\ - 5 & 2 \\ - 4 & 3 - \end{bmatrix} +Consider also [:download:`source: figures/Mesh/reorder.cpp `] - Consider also [:download:`source: figures/Mesh/renumber.cpp `] +.. note:: Generic interface + + .. code-block:: cpp + + template + void reorder(const InputIterator first, const InputIterator last, const OutputIterator result, const IndexIterator first_index, const IndexIterator last_index, std::string location) + +``GooseFEM::Mesh::elem2node`` +============================= + +.. code-block:: cpp + GooseFEM::SpMatS GooseFEM::Mesh::elem2node(const GooseFEM::MatS &conn) +Return a sparse matrix which contains the element numbers (columns) that are connected to each node (rows). +.. warning:: + One should not confuse the element ``0`` when this matrix is converted to a dense matrix. When this is done all the 'missing' items are filled in as zero, which does have a meaning here. diff --git a/docs/figures/Mesh/renumber.cpp b/docs/figures/Mesh/renumber.cpp deleted file mode 100644 index dfb8a7b..0000000 --- a/docs/figures/Mesh/renumber.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include - -using ColS = GooseFEM::ColS; -using MatS = GooseFEM::MatS; - -int main() -{ - // mesh definition - GooseFEM::Mesh::Quad4::Regular mesh = GooseFEM::Mesh::Quad4::Regular(2,2); - - // extract information - size_t ndim = mesh.ndim (); - ColS top = mesh.nodesTop (); - ColS bottom = mesh.nodesBottom(); - ColS left = mesh.nodesLeft (); - ColS right = mesh.nodesRight (); - size_t nleft = static_cast(left.size()); - size_t ntop = static_cast(top .size()); - - // default DOF-numbers: sequential numbering per element - MatS dofs = mesh.dofs(); - - std::cout << "dofs = " << std::endl; - std::cout << dofs << std::endl << std::endl; - - // periodicity in horizontal direction : eliminate 'dependent' DOFs - // N.B. the corner nodes are part of the fixed boundaries - for ( size_t i = 1 ; i < nleft-1 ; ++i ) - for ( size_t j = 0 ; j < ndim ; ++j ) - dofs(right(i),j) = dofs(left(i),j); - - // renumber "dofs" to be sequential - dofs = GooseFEM::Mesh::renumber(dofs); - - std::cout << "periodicity :" << std::endl << "dofs = " << std::endl; - std::cout << dofs << std::endl << std::endl; - - // construct list with prescribed DOFs - // - allocate - ColS fixedDofs(2*ntop*ndim); - // - read: bottom - for ( size_t i = 0 ; i < ntop ; ++i ) - for ( size_t j = 0 ; j < ndim ; ++j ) - fixedDofs(i*ndim+j) = dofs(bottom(i),j); - // - read: top - for ( size_t i = 0 ; i < ntop ; ++i ) - for ( size_t j = 0 ; j < ndim ; ++j ) - fixedDofs(i*ndim+j+ntop*ndim) = dofs(top(i),j); - - // renumber "dofs" to have the "fixedDofs" at the end - dofs = GooseFEM::Mesh::renumber(dofs,fixedDofs); - - std::cout << "fixedDofs to end :" << std::endl << "dofs = " << std::endl; - std::cout << dofs << std::endl << std::endl; - -} diff --git a/python/python_interface.cpp b/python/python_interface.cpp index a01ceea..58966e3 100644 --- a/python/python_interface.cpp +++ b/python/python_interface.cpp @@ -1,505 +1,509 @@ /* ================================================================================================= (c - GPLv3) T.W.J. de Geus (Tom) | tom@geus.me | www.geus.me | github.com/tdegeus/GooseFEM ================================================================================================= */ #include #include #include #include "../src/GooseFEM/GooseFEM.h" // alias for short-hand notation below namespace py = pybind11; PYBIND11_MODULE(GooseFEM, m) { // ================================================================================================= m.doc() = "Some simple finite element meshes and operations"; // define submodules "mXXX" py::module mMesh = m .def_submodule("Mesh" , "Generic mesh routines" ); py::module mMeshTri3 = mMesh.def_submodule("Tri3" , "Linear triangular elements (2D)" ); py::module mMeshQuad4 = mMesh.def_submodule("Quad4" , "Linear quadrilateral elements (2D)" ); py::module mMeshHex8 = mMesh.def_submodule("Hex8" , "Linear hexahedron (brick) elements (3D)"); // ======================================= GooseFEM/Mesh.h ======================================== mMesh.def("elem2node", &GooseFEM::Mesh::elem2node, "Elements connect to each node: [ number of elements , element numbers ]", py::arg("conn") ); mMesh.def("dofs", &GooseFEM::Mesh::dofs, "List with DOF-numbers (in sequential order)", py::arg("nnode"), py::arg("ndim") ); +using renumber = GooseFEM::MatS(const GooseFEM::MatS &); + mMesh.def("renumber", - py::overload_cast(&GooseFEM::Mesh::renumber), + py::overload_cast((renumber*)&GooseFEM::Mesh::renumber), "Renumber DOF-list to use the lowest possible index", py::arg("dofs") ); -mMesh.def("renumber", - py::overload_cast(&GooseFEM::Mesh::renumber), +using reorder = GooseFEM::MatS(const GooseFEM::MatS &, const GooseFEM::ColS&, std::string); + +mMesh.def("reorder", + py::overload_cast((reorder*)&GooseFEM::Mesh::reorder), "Renumber DOF-list to begin or end with 'idx'", py::arg("dofs"), py::arg("idx"), py::arg("location")="end" ); // ====================================== GooseFEM/MeshHex8.h ====================================== py::class_(mMeshHex8, "Regular") // constructor .def( py::init(), "mesh with nx*ny*nz 'pixels' and edge size h", py::arg("nx"), py::arg("ny"), py::arg("nz"), py::arg("h")=1. ) // sizes .def("nelem" , &GooseFEM::Mesh::Hex8::Regular::nelem ) .def("nnode" , &GooseFEM::Mesh::Hex8::Regular::nnode ) .def("nne" , &GooseFEM::Mesh::Hex8::Regular::nne ) .def("ndim" , &GooseFEM::Mesh::Hex8::Regular::ndim ) // mesh .def("coor" , &GooseFEM::Mesh::Hex8::Regular::coor ) .def("conn" , &GooseFEM::Mesh::Hex8::Regular::conn ) // boundary nodes: planes .def("nodesFront" , &GooseFEM::Mesh::Hex8::Regular::nodesFront ) .def("nodesBack" , &GooseFEM::Mesh::Hex8::Regular::nodesBack ) .def("nodesLeft" , &GooseFEM::Mesh::Hex8::Regular::nodesLeft ) .def("nodesRight" , &GooseFEM::Mesh::Hex8::Regular::nodesRight ) .def("nodesBottom" , &GooseFEM::Mesh::Hex8::Regular::nodesBottom ) .def("nodesTop" , &GooseFEM::Mesh::Hex8::Regular::nodesTop ) // boundary nodes: faces .def("nodesFrontFace" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontFace ) .def("nodesBackFace" , &GooseFEM::Mesh::Hex8::Regular::nodesBackFace ) .def("nodesLeftFace" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftFace ) .def("nodesRightFace" , &GooseFEM::Mesh::Hex8::Regular::nodesRightFace ) .def("nodesBottomFace" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomFace ) .def("nodesTopFace" , &GooseFEM::Mesh::Hex8::Regular::nodesTopFace ) // boundary nodes: edges .def("nodesFrontBottomEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontBottomEdge ) .def("nodesFrontTopEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontTopEdge ) .def("nodesFrontLeftEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontLeftEdge ) .def("nodesFrontRightEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontRightEdge ) .def("nodesBackBottomEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackBottomEdge ) .def("nodesBackTopEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackTopEdge ) .def("nodesBackLeftEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackLeftEdge ) .def("nodesBackRightEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackRightEdge ) .def("nodesBottomLeftEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomLeftEdge ) .def("nodesBottomRightEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomRightEdge ) .def("nodesTopLeftEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopLeftEdge ) .def("nodesTopRightEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopRightEdge ) // boundary nodes: faces (aliases) .def("nodesBottomFrontEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomFrontEdge ) .def("nodesBottomBackEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomBackEdge ) .def("nodesTopFrontEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopFrontEdge ) .def("nodesTopBackEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopBackEdge ) .def("nodesLeftBottomEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBottomEdge ) .def("nodesLeftFrontEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftFrontEdge ) .def("nodesLeftBackEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBackEdge ) .def("nodesLeftTopEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftTopEdge ) .def("nodesRightBottomEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBottomEdge ) .def("nodesRightTopEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightTopEdge ) .def("nodesRightFrontEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightFrontEdge ) .def("nodesRightBackEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBackEdge ) // boundary nodes: edges, without corners .def("nodesFrontBottomOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontBottomOpenEdge ) .def("nodesFrontTopOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontTopOpenEdge ) .def("nodesFrontLeftOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontLeftOpenEdge ) .def("nodesFrontRightOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontRightOpenEdge ) .def("nodesBackBottomOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackBottomOpenEdge ) .def("nodesBackTopOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackTopOpenEdge ) .def("nodesBackLeftOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackLeftOpenEdge ) .def("nodesBackRightOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBackRightOpenEdge ) .def("nodesBottomLeftOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomLeftOpenEdge ) .def("nodesBottomRightOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomRightOpenEdge ) .def("nodesTopLeftOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopLeftOpenEdge ) .def("nodesTopRightOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopRightOpenEdge ) // boundary nodes: edges, without corners (aliases) .def("nodesBottomFrontOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomFrontOpenEdge ) .def("nodesBottomBackOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomBackOpenEdge ) .def("nodesTopFrontOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopFrontOpenEdge ) .def("nodesTopBackOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesTopBackOpenEdge ) .def("nodesLeftBottomOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBottomOpenEdge ) .def("nodesLeftFrontOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftFrontOpenEdge ) .def("nodesLeftBackOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBackOpenEdge ) .def("nodesLeftTopOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftTopOpenEdge ) .def("nodesRightBottomOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBottomOpenEdge ) .def("nodesRightTopOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightTopOpenEdge ) .def("nodesRightFrontOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightFrontOpenEdge ) .def("nodesRightBackOpenEdge" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBackOpenEdge ) // boundary nodes: corners .def("nodesFrontBottomLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontBottomLeftCorner ) .def("nodesFrontBottomRightCorner", &GooseFEM::Mesh::Hex8::Regular::nodesFrontBottomRightCorner) .def("nodesFrontTopLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontTopLeftCorner ) .def("nodesFrontTopRightCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontTopRightCorner ) .def("nodesBackBottomLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackBottomLeftCorner ) .def("nodesBackBottomRightCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackBottomRightCorner ) .def("nodesBackTopLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackTopLeftCorner ) .def("nodesBackTopRightCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackTopRightCorner ) // boundary nodes: corners (aliases) .def("nodesFrontLeftBottomCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontLeftBottomCorner ) .def("nodesBottomFrontLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomFrontLeftCorner ) .def("nodesBottomLeftFrontCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomLeftFrontCorner ) .def("nodesLeftFrontBottomCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftFrontBottomCorner ) .def("nodesLeftBottomFrontCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBottomFrontCorner ) .def("nodesFrontRightBottomCorner", &GooseFEM::Mesh::Hex8::Regular::nodesFrontRightBottomCorner) .def("nodesBottomFrontRightCorner", &GooseFEM::Mesh::Hex8::Regular::nodesBottomFrontRightCorner) .def("nodesBottomRightFrontCorner", &GooseFEM::Mesh::Hex8::Regular::nodesBottomRightFrontCorner) .def("nodesRightFrontBottomCorner", &GooseFEM::Mesh::Hex8::Regular::nodesRightFrontBottomCorner) .def("nodesRightBottomFrontCorner", &GooseFEM::Mesh::Hex8::Regular::nodesRightBottomFrontCorner) .def("nodesFrontLeftTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontLeftTopCorner ) .def("nodesTopFrontLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopFrontLeftCorner ) .def("nodesTopLeftFrontCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopLeftFrontCorner ) .def("nodesLeftFrontTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftFrontTopCorner ) .def("nodesLeftTopFrontCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftTopFrontCorner ) .def("nodesFrontRightTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesFrontRightTopCorner ) .def("nodesTopFrontRightCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopFrontRightCorner ) .def("nodesTopRightFrontCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopRightFrontCorner ) .def("nodesRightFrontTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesRightFrontTopCorner ) .def("nodesRightTopFrontCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesRightTopFrontCorner ) .def("nodesBackLeftBottomCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackLeftBottomCorner ) .def("nodesBottomBackLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomBackLeftCorner ) .def("nodesBottomLeftBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomLeftBackCorner ) .def("nodesLeftBackBottomCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBackBottomCorner ) .def("nodesLeftBottomBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBottomBackCorner ) .def("nodesBackRightBottomCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackRightBottomCorner ) .def("nodesBottomBackRightCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomBackRightCorner ) .def("nodesBottomRightBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBottomRightBackCorner ) .def("nodesRightBackBottomCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBackBottomCorner ) .def("nodesRightBottomBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBottomBackCorner ) .def("nodesBackLeftTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackLeftTopCorner ) .def("nodesTopBackLeftCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopBackLeftCorner ) .def("nodesTopLeftBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopLeftBackCorner ) .def("nodesLeftBackTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftBackTopCorner ) .def("nodesLeftTopBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesLeftTopBackCorner ) .def("nodesBackRightTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesBackRightTopCorner ) .def("nodesTopBackRightCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopBackRightCorner ) .def("nodesTopRightBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesTopRightBackCorner ) .def("nodesRightBackTopCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesRightBackTopCorner ) .def("nodesRightTopBackCorner" , &GooseFEM::Mesh::Hex8::Regular::nodesRightTopBackCorner ) // periodicity .def("nodesPeriodic" , &GooseFEM::Mesh::Hex8::Regular::nodesPeriodic ) .def("nodesOrigin" , &GooseFEM::Mesh::Hex8::Regular::nodesOrigin ) .def("dofs" , &GooseFEM::Mesh::Hex8::Regular::dofs ) .def("dofsPeriodic" , &GooseFEM::Mesh::Hex8::Regular::dofsPeriodic ) // print to screen .def("__repr__", [](const GooseFEM::Mesh::Hex8::Regular &a){ return ""; } ); // ------------------------------------------------------------------------------------------------- py::class_(mMeshHex8, "FineLayer") // constructor .def( py::init(), "mesh with nx*ny*nz 'pixels' and edge size h", py::arg("nx"), py::arg("ny"), py::arg("nz"), py::arg("h")=1., py::arg("nfine")=1 ) // sizes .def("nelem" , &GooseFEM::Mesh::Hex8::FineLayer::nelem ) .def("nnode" , &GooseFEM::Mesh::Hex8::FineLayer::nnode ) .def("nne" , &GooseFEM::Mesh::Hex8::FineLayer::nne ) .def("ndim" , &GooseFEM::Mesh::Hex8::FineLayer::ndim ) .def("shape" , &GooseFEM::Mesh::Hex8::FineLayer::shape ) // mesh .def("coor" , &GooseFEM::Mesh::Hex8::FineLayer::coor ) .def("conn" , &GooseFEM::Mesh::Hex8::FineLayer::conn ) // element sets .def("elementsMiddleLayer" , &GooseFEM::Mesh::Hex8::FineLayer::elementsMiddleLayer ) // boundary nodes: planes .def("nodesFront" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFront ) .def("nodesBack" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBack ) .def("nodesLeft" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeft ) .def("nodesRight" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRight ) .def("nodesBottom" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottom ) .def("nodesTop" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTop ) // boundary nodes: faces .def("nodesFrontFace" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontFace ) .def("nodesBackFace" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackFace ) .def("nodesLeftFace" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftFace ) .def("nodesRightFace" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightFace ) .def("nodesBottomFace" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomFace ) .def("nodesTopFace" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopFace ) // boundary nodes: edges .def("nodesFrontBottomEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontBottomEdge ) .def("nodesFrontTopEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontTopEdge ) .def("nodesFrontLeftEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontLeftEdge ) .def("nodesFrontRightEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontRightEdge ) .def("nodesBackBottomEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackBottomEdge ) .def("nodesBackTopEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackTopEdge ) .def("nodesBackLeftEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackLeftEdge ) .def("nodesBackRightEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackRightEdge ) .def("nodesBottomLeftEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomLeftEdge ) .def("nodesBottomRightEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomRightEdge ) .def("nodesTopLeftEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopLeftEdge ) .def("nodesTopRightEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopRightEdge ) // boundary nodes: faces (aliases) .def("nodesBottomFrontEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomFrontEdge ) .def("nodesBottomBackEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomBackEdge ) .def("nodesTopFrontEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopFrontEdge ) .def("nodesTopBackEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopBackEdge ) .def("nodesLeftBottomEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBottomEdge ) .def("nodesLeftFrontEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftFrontEdge ) .def("nodesLeftBackEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBackEdge ) .def("nodesLeftTopEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftTopEdge ) .def("nodesRightBottomEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBottomEdge ) .def("nodesRightTopEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightTopEdge ) .def("nodesRightFrontEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightFrontEdge ) .def("nodesRightBackEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBackEdge ) // boundary nodes: edges, without corners .def("nodesFrontBottomOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontBottomOpenEdge ) .def("nodesFrontTopOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontTopOpenEdge ) .def("nodesFrontLeftOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontLeftOpenEdge ) .def("nodesFrontRightOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontRightOpenEdge ) .def("nodesBackBottomOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackBottomOpenEdge ) .def("nodesBackTopOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackTopOpenEdge ) .def("nodesBackLeftOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackLeftOpenEdge ) .def("nodesBackRightOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackRightOpenEdge ) .def("nodesBottomLeftOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomLeftOpenEdge ) .def("nodesBottomRightOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomRightOpenEdge ) .def("nodesTopLeftOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopLeftOpenEdge ) .def("nodesTopRightOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopRightOpenEdge ) // boundary nodes: edges, without corners (aliases) .def("nodesBottomFrontOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomFrontOpenEdge ) .def("nodesBottomBackOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomBackOpenEdge ) .def("nodesTopFrontOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopFrontOpenEdge ) .def("nodesTopBackOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopBackOpenEdge ) .def("nodesLeftBottomOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBottomOpenEdge ) .def("nodesLeftFrontOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftFrontOpenEdge ) .def("nodesLeftBackOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBackOpenEdge ) .def("nodesLeftTopOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftTopOpenEdge ) .def("nodesRightBottomOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBottomOpenEdge ) .def("nodesRightTopOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightTopOpenEdge ) .def("nodesRightFrontOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightFrontOpenEdge ) .def("nodesRightBackOpenEdge" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBackOpenEdge ) // boundary nodes: corners .def("nodesFrontBottomLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontBottomLeftCorner ) .def("nodesFrontBottomRightCorner", &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontBottomRightCorner) .def("nodesFrontTopLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontTopLeftCorner ) .def("nodesFrontTopRightCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontTopRightCorner ) .def("nodesBackBottomLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackBottomLeftCorner ) .def("nodesBackBottomRightCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackBottomRightCorner ) .def("nodesBackTopLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackTopLeftCorner ) .def("nodesBackTopRightCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackTopRightCorner ) // boundary nodes: corners (aliases) .def("nodesFrontLeftBottomCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontLeftBottomCorner ) .def("nodesBottomFrontLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomFrontLeftCorner ) .def("nodesBottomLeftFrontCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomLeftFrontCorner ) .def("nodesLeftFrontBottomCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftFrontBottomCorner ) .def("nodesLeftBottomFrontCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBottomFrontCorner ) .def("nodesFrontRightBottomCorner", &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontRightBottomCorner) .def("nodesBottomFrontRightCorner", &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomFrontRightCorner) .def("nodesBottomRightFrontCorner", &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomRightFrontCorner) .def("nodesRightFrontBottomCorner", &GooseFEM::Mesh::Hex8::FineLayer::nodesRightFrontBottomCorner) .def("nodesRightBottomFrontCorner", &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBottomFrontCorner) .def("nodesFrontLeftTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontLeftTopCorner ) .def("nodesTopFrontLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopFrontLeftCorner ) .def("nodesTopLeftFrontCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopLeftFrontCorner ) .def("nodesLeftFrontTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftFrontTopCorner ) .def("nodesLeftTopFrontCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftTopFrontCorner ) .def("nodesFrontRightTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesFrontRightTopCorner ) .def("nodesTopFrontRightCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopFrontRightCorner ) .def("nodesTopRightFrontCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopRightFrontCorner ) .def("nodesRightFrontTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightFrontTopCorner ) .def("nodesRightTopFrontCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightTopFrontCorner ) .def("nodesBackLeftBottomCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackLeftBottomCorner ) .def("nodesBottomBackLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomBackLeftCorner ) .def("nodesBottomLeftBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomLeftBackCorner ) .def("nodesLeftBackBottomCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBackBottomCorner ) .def("nodesLeftBottomBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBottomBackCorner ) .def("nodesBackRightBottomCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackRightBottomCorner ) .def("nodesBottomBackRightCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomBackRightCorner ) .def("nodesBottomRightBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBottomRightBackCorner ) .def("nodesRightBackBottomCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBackBottomCorner ) .def("nodesRightBottomBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBottomBackCorner ) .def("nodesBackLeftTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackLeftTopCorner ) .def("nodesTopBackLeftCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopBackLeftCorner ) .def("nodesTopLeftBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopLeftBackCorner ) .def("nodesLeftBackTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftBackTopCorner ) .def("nodesLeftTopBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesLeftTopBackCorner ) .def("nodesBackRightTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesBackRightTopCorner ) .def("nodesTopBackRightCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopBackRightCorner ) .def("nodesTopRightBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesTopRightBackCorner ) .def("nodesRightBackTopCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightBackTopCorner ) .def("nodesRightTopBackCorner" , &GooseFEM::Mesh::Hex8::FineLayer::nodesRightTopBackCorner ) // periodicity .def("nodesPeriodic" , &GooseFEM::Mesh::Hex8::FineLayer::nodesPeriodic ) .def("nodesOrigin" , &GooseFEM::Mesh::Hex8::FineLayer::nodesOrigin ) .def("dofs" , &GooseFEM::Mesh::Hex8::FineLayer::dofs ) .def("dofsPeriodic" , &GooseFEM::Mesh::Hex8::FineLayer::dofsPeriodic ) // print to screen .def("__repr__", [](const GooseFEM::Mesh::Hex8::FineLayer &a){ return ""; } ); // ===================================== GooseFEM/MeshQuad4.h ===================================== py::class_(mMeshQuad4, "Regular") .def( py::init(), "Regular mesh: 'nx' pixels in horizontal direction, 'ny' in vertical direction, edge size 'h'", py::arg("nx"), py::arg("ny"), py::arg("h")=1. ) .def("coor" , &GooseFEM::Mesh::Quad4::Regular::coor ) .def("conn" , &GooseFEM::Mesh::Quad4::Regular::conn ) .def("nelem" , &GooseFEM::Mesh::Quad4::Regular::nelem ) .def("nnode" , &GooseFEM::Mesh::Quad4::Regular::nnode ) .def("nne" , &GooseFEM::Mesh::Quad4::Regular::nne ) .def("ndim" , &GooseFEM::Mesh::Quad4::Regular::ndim ) .def("nodesBottomEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesBottomEdge ) .def("nodesTopEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesTopEdge ) .def("nodesLeftEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesLeftEdge ) .def("nodesRightEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesRightEdge ) .def("nodesBottomOpenEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesBottomOpenEdge ) .def("nodesTopOpenEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesTopOpenEdge ) .def("nodesLeftOpenEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesLeftOpenEdge ) .def("nodesRightOpenEdge" , &GooseFEM::Mesh::Quad4::Regular::nodesRightOpenEdge ) .def("nodesBottomLeftCorner" , &GooseFEM::Mesh::Quad4::Regular::nodesBottomLeftCorner ) .def("nodesBottomRightCorner", &GooseFEM::Mesh::Quad4::Regular::nodesBottomRightCorner) .def("nodesTopLeftCorner" , &GooseFEM::Mesh::Quad4::Regular::nodesTopLeftCorner ) .def("nodesTopRightCorner" , &GooseFEM::Mesh::Quad4::Regular::nodesTopRightCorner ) .def("nodesLeftBottomCorner" , &GooseFEM::Mesh::Quad4::Regular::nodesLeftBottomCorner ) .def("nodesLeftTopCorner" , &GooseFEM::Mesh::Quad4::Regular::nodesLeftTopCorner ) .def("nodesRightBottomCorner", &GooseFEM::Mesh::Quad4::Regular::nodesRightBottomCorner) .def("nodesRightTopCorner" , &GooseFEM::Mesh::Quad4::Regular::nodesRightTopCorner ) .def("nodesPeriodic" , &GooseFEM::Mesh::Quad4::Regular::nodesPeriodic ) .def("nodesOrigin" , &GooseFEM::Mesh::Quad4::Regular::nodesOrigin ) .def("dofs" , &GooseFEM::Mesh::Quad4::Regular::dofs ) .def("dofsPeriodic" , &GooseFEM::Mesh::Quad4::Regular::dofsPeriodic ) .def("__repr__", [](const GooseFEM::Mesh::Quad4::Regular &a){ return ""; } ); // ------------------------------------------------------------------------------------------------- py::class_(mMeshQuad4, "FineLayer") .def( py::init(), "FineLayer mesh: 'nx' pixels in horizontal direction (length 'Lx'), idem in vertical direction", py::arg("nx"), py::arg("ny"), py::arg("h")=1., py::arg("nfine")=1 ) .def("shape" , &GooseFEM::Mesh::Quad4::FineLayer::shape ) .def("coor" , &GooseFEM::Mesh::Quad4::FineLayer::coor ) .def("conn" , &GooseFEM::Mesh::Quad4::FineLayer::conn ) .def("nelem" , &GooseFEM::Mesh::Quad4::FineLayer::nelem ) .def("nnode" , &GooseFEM::Mesh::Quad4::FineLayer::nnode ) .def("nne" , &GooseFEM::Mesh::Quad4::FineLayer::nne ) .def("ndim" , &GooseFEM::Mesh::Quad4::FineLayer::ndim ) .def("elementsMiddleLayer" , &GooseFEM::Mesh::Quad4::FineLayer::elementsMiddleLayer ) .def("nodesBottomEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesBottomEdge ) .def("nodesTopEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesTopEdge ) .def("nodesLeftEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesLeftEdge ) .def("nodesRightEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesRightEdge ) .def("nodesBottomOpenEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesBottomOpenEdge ) .def("nodesTopOpenEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesTopOpenEdge ) .def("nodesLeftOpenEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesLeftOpenEdge ) .def("nodesRightOpenEdge" , &GooseFEM::Mesh::Quad4::FineLayer::nodesRightOpenEdge ) .def("nodesBottomLeftCorner" , &GooseFEM::Mesh::Quad4::FineLayer::nodesBottomLeftCorner ) .def("nodesBottomRightCorner", &GooseFEM::Mesh::Quad4::FineLayer::nodesBottomRightCorner) .def("nodesTopLeftCorner" , &GooseFEM::Mesh::Quad4::FineLayer::nodesTopLeftCorner ) .def("nodesTopRightCorner" , &GooseFEM::Mesh::Quad4::FineLayer::nodesTopRightCorner ) .def("nodesLeftBottomCorner" , &GooseFEM::Mesh::Quad4::FineLayer::nodesLeftBottomCorner ) .def("nodesLeftTopCorner" , &GooseFEM::Mesh::Quad4::FineLayer::nodesLeftTopCorner ) .def("nodesRightBottomCorner", &GooseFEM::Mesh::Quad4::FineLayer::nodesRightBottomCorner) .def("nodesRightTopCorner" , &GooseFEM::Mesh::Quad4::FineLayer::nodesRightTopCorner ) .def("nodesPeriodic" , &GooseFEM::Mesh::Quad4::FineLayer::nodesPeriodic ) .def("nodesOrigin" , &GooseFEM::Mesh::Quad4::FineLayer::nodesOrigin ) .def("dofs" , &GooseFEM::Mesh::Quad4::FineLayer::dofs ) .def("dofsPeriodic" , &GooseFEM::Mesh::Quad4::FineLayer::dofsPeriodic ) .def("__repr__", [](const GooseFEM::Mesh::Quad4::FineLayer &a){ return ""; } ); // ===================================== GooseFEM/MeshTri3.h ====================================== py::class_(mMeshTri3, "Regular") .def( py::init(), "Regular mesh: 'nx' pixels in horizontal direction, 'ny' in vertical direction, edge size 'h'", py::arg("nx"), py::arg("ny"), py::arg("h")=1. ) .def("coor" , &GooseFEM::Mesh::Tri3::Regular::coor ) .def("conn" , &GooseFEM::Mesh::Tri3::Regular::conn ) .def("nelem" , &GooseFEM::Mesh::Tri3::Regular::nelem ) .def("nnode" , &GooseFEM::Mesh::Tri3::Regular::nnode ) .def("nne" , &GooseFEM::Mesh::Tri3::Regular::nne ) .def("ndim" , &GooseFEM::Mesh::Tri3::Regular::ndim ) .def("nodesBottomEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesBottomEdge ) .def("nodesTopEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesTopEdge ) .def("nodesLeftEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesLeftEdge ) .def("nodesRightEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesRightEdge ) .def("nodesBottomOpenEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesBottomOpenEdge ) .def("nodesTopOpenEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesTopOpenEdge ) .def("nodesLeftOpenEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesLeftOpenEdge ) .def("nodesRightOpenEdge" , &GooseFEM::Mesh::Tri3::Regular::nodesRightOpenEdge ) .def("nodesBottomLeftCorner" , &GooseFEM::Mesh::Tri3::Regular::nodesBottomLeftCorner ) .def("nodesBottomRightCorner", &GooseFEM::Mesh::Tri3::Regular::nodesBottomRightCorner) .def("nodesTopLeftCorner" , &GooseFEM::Mesh::Tri3::Regular::nodesTopLeftCorner ) .def("nodesTopRightCorner" , &GooseFEM::Mesh::Tri3::Regular::nodesTopRightCorner ) .def("nodesLeftBottomCorner" , &GooseFEM::Mesh::Tri3::Regular::nodesLeftBottomCorner ) .def("nodesLeftTopCorner" , &GooseFEM::Mesh::Tri3::Regular::nodesLeftTopCorner ) .def("nodesRightBottomCorner", &GooseFEM::Mesh::Tri3::Regular::nodesRightBottomCorner) .def("nodesRightTopCorner" , &GooseFEM::Mesh::Tri3::Regular::nodesRightTopCorner ) .def("nodesPeriodic" , &GooseFEM::Mesh::Tri3::Regular::nodesPeriodic ) .def("nodesOrigin" , &GooseFEM::Mesh::Tri3::Regular::nodesOrigin ) .def("dofs" , &GooseFEM::Mesh::Tri3::Regular::dofs ) .def("dofsPeriodic" , &GooseFEM::Mesh::Tri3::Regular::dofsPeriodic ) .def("__repr__", [](const GooseFEM::Mesh::Tri3::Regular &a){ return ""; } ); // ------------------------------------------------------------------------------------------------- mMeshTri3.def("getOrientation",&GooseFEM::Mesh::Tri3::getOrientation, "Get the orientation of each element", py::arg("coor"), py::arg("conn") ); // ------------------------------------------------------------------------------------------------- mMeshTri3.def("retriangulate",&GooseFEM::Mesh::Tri3::retriangulate, "Re-triangulate existing mesh", py::arg("coor"), py::arg("conn"), py::arg("orientation")=-1 ); // ================================================================================================= } diff --git a/src/GooseFEM/GooseFEM.h b/src/GooseFEM/GooseFEM.h index 6dc76a2..aebc711 100644 --- a/src/GooseFEM/GooseFEM.h +++ b/src/GooseFEM/GooseFEM.h @@ -1,76 +1,80 @@ /* ================================================================================================= (c - GPLv3) T.W.J. de Geus (Tom) | tom@geus.me | www.geus.me | github.com/tdegeus/GooseFEM ================================================================================================= */ #ifndef GOOSEFEM_H #define GOOSEFEM_H // ================================================================================================= #define _USE_MATH_DEFINES // to use "M_PI" from "math.h" #include #include #include #include #include #include #include +#include #include #include #include // ================================================================================================= #define GOOSEFEM_WORLD_VERSION 0 #define GOOSEFEM_MAJOR_VERSION 0 -#define GOOSEFEM_MINOR_VERSION 7 +#define GOOSEFEM_MINOR_VERSION 8 #define GOOSEFEM_VERSION_AT_LEAST(x,y,z) \ (GOOSEFEM_WORLD_VERSION>x || (GOOSEFEM_WORLD_VERSION>=x && \ (GOOSEFEM_MAJOR_VERSION>y || (GOOSEFEM_MAJOR_VERSION>=y && \ GOOSEFEM_MINOR_VERSION>=z)))) #define GOOSEFEM_VERSION(x,y,z) \ (GOOSEFEM_WORLD_VERSION==x && \ GOOSEFEM_MAJOR_VERSION==y && \ GOOSEFEM_MINOR_VERSION==z) // ================================================================================================= // dummy operation that can be use to suppress the "unused parameter" warnings #define UNUSED(p) ( (void)(p) ) // ================================================================================================= // alias Eigen types namespace GooseFEM { typedef Eigen::Matrix MatD; typedef Eigen::Matrix MatS; typedef Eigen::Matrix ColD; typedef Eigen::Matrix ColS; typedef Eigen::Matrix ColI; + + typedef Eigen::SparseMatrix SpMatD; + typedef Eigen::SparseMatrix SpMatS; } // ================================================================================================= #include "Mesh.h" #include "MeshTri3.h" #include "MeshQuad4.h" #include "MeshHex8.h" #include "DynamicsDiagonal.h" #include "OverdampedDynamicsDiagonal.h" #include "Mesh.cpp" #include "MeshTri3.cpp" #include "MeshQuad4.cpp" #include "MeshHex8.cpp" #include "DynamicsDiagonal.cpp" #include "OverdampedDynamicsDiagonal.cpp" // ================================================================================================= #endif diff --git a/src/GooseFEM/Mesh.cpp b/src/GooseFEM/Mesh.cpp index 893fa12..a69c794 100644 --- a/src/GooseFEM/Mesh.cpp +++ b/src/GooseFEM/Mesh.cpp @@ -1,149 +1,175 @@ /* ================================================================================================= (c - GPLv3) T.W.J. de Geus (Tom) | tom@geus.me | www.geus.me | github.com/tdegeus/GooseFEM ================================================================================================= */ #ifndef GOOSEFEM_MESH_CPP #define GOOSEFEM_MESH_CPP // ------------------------------------------------------------------------------------------------- #include "Mesh.h" // ======================================== GooseFEM::Mesh ========================================= namespace GooseFEM { namespace Mesh { -// ============================ LIST OF ELEMENTS CONNECTED TO EACH NODE ============================ +// ========================================= LIST OF DOFS ========================================== -inline MatS elem2node ( const MatS &conn ) +inline MatS dofs(size_t nnode, size_t ndim) { - size_t nnode = conn.maxCoeff() + 1; - - ColS N( nnode ); - - N *= 0; + ColS dofs_vec = ColS::LinSpaced(nnode*ndim, 0, nnode*ndim); - for ( auto e = 0 ; e < conn.rows() ; ++e ) - for ( auto m = 0 ; m < conn.cols() ; ++m ) - N( conn(e,m) ) += 1; - - MatS out( nnode , N.maxCoeff()+1 ); - out *= 0; - - for ( auto e = 0 ; e < conn.rows() ; ++e ) { - for ( auto m = 0 ; m < conn.cols() ; ++m ) { - auto nd = conn(e,m); - out( nd, 0 ) += 1; - out( nd, out(nd,0) ) = e; - } - } + Eigen::Map dofs(dofs_vec.data(), nnode, ndim); - return out; + return dofs; } -// ========================================= LIST OF DOFS ========================================== +// ================================== RENUMBER TO LOWEST POSSIBLE ================================== + +// --------------------------------------------- core ---------------------------------------------- -inline MatS dofs ( size_t nnode , size_t ndim ) +template +inline void renumber( + const InputIterator first, const InputIterator last, const OutputIterator result +) { - ColS dofs_vec = ColS::LinSpaced( nnode*ndim , 0 , nnode*ndim ); + // size of input and the the renumber list + auto N = last - first; + auto M = (*std::max_element(first, last)) + 1; - Eigen::Map dofs( dofs_vec.data() , nnode , ndim ); + // allocate presence list and list of new indices + std::vector inList(M, 0); // initialize all items as 'excluded' (== 0) + std::vector index (M); - return dofs; -} + // selectively set items that are 'included' (== 1) + for ( auto it = first; it != last; ++it ) inList[*it] = 1; -// =========================================== RENUMBER ============================================ + // new indices: cumulative sum of presence list + std::partial_sum(inList.begin(), inList.end(), index.begin()); + // make index start at 0 + for ( auto &i: index ) i--; -// -------------------------------- renumber all to lowest possible -------------------------------- + // apply renumbering + for ( auto i = 0; i < N; ++i ) *(result+i) = index[*(first+i)]; +}; -inline MatS renumber ( const MatS &in ) +// ------------------------------------------- interface ------------------------------------------- + +inline MatS renumber(const MatS &in) { - // size parameters - size_t N = in.size(); // number of items in "in" (and in "out") - size_t M = in.maxCoeff() + 1; // size of renumber-list + MatS out(in.rows(), in.cols()); - // allocate output - MatS out ( in.rows() , in.cols() ); + renumber(in.data(), in.data()+in.size(), out.data()); - // allocate renumber-list - ColS renum ( M ); + return out; +} - // set all items as being 'excluded' ( == 0 ) - renum.setZero(); +// ============================================ REORDER ============================================ - // selectively set items that are 'included' ( == 1 ) - for ( size_t i = 0 ; i < N ; ++i ) renum ( in(i) ) = 1; +// --------------------------------------------- core ---------------------------------------------- - // convert to indices, step 1: correct such that first index will start at 0 - renum[0] -= 1; - // convert to indices, step 2: cumulative sum - for ( size_t i = 1 ; i < M ; ++i ) renum ( i ) += renum ( i-1 ); +template +inline void reorder( + const InputIterator first, const InputIterator last, const OutputIterator result, + const IndexIterator first_index, const IndexIterator last_index, std::string location +) +{ + // size of input and the the renumber list + auto N = last - first; + auto M = (*std::max_element(first, last)) + 1; + + // allocate presence list and list of new indices + std::vector inList(M, 0); // initialize all items as 'excluded' (== 0) + std::vector index (M); + + // selectively set items that are 'included' (== 1) + for ( auto it = first; it != last; ++it ) inList[*it] = 1; + // check that all indices are actually included + #ifndef NDEBUG + for ( auto it = first_index; it != last_index; ++it ) assert( inList[*it] == 1 ); + #endif + // remove indices whose new index will be fixed + for ( auto it = first_index; it != last_index; ++it ) inList[*it] = 0; + + // new indices: cumulative sum of presence list + std::partial_sum(inList.begin(), inList.end(), index.begin()); + // make index start at 0 + for ( auto &i: index ) i--; + // optionally move to end + if ( location == "begin" ) for ( auto &i: index ) i += (last_index - first_index); + + // manually set indices + // - allocate offset + size_t offset; + // - set offset + if ( location == "begin" ) offset = 0; + else offset = N - (last_index - first_index); + // - apply + for ( auto it = first_index; it != last_index; ++it ) { index[*it] = offset; ++offset; } + + // apply renumbering + for ( auto i = 0; i < N; ++i ) *(result+i) = index[*(first+i)]; +}; + +// ------------------------------------------- interface ------------------------------------------- + +inline MatS reorder(const MatS &in, const ColS &idx, std::string loc) +{ + MatS out(in.rows(), in.cols()); - // renumber DOFs - for ( size_t i = 0 ; i < N ; ++i ) out ( i ) = renum ( in(i) ); + reorder(in.data(), in.data()+in.size(), out.data(), idx.data(), idx.data()+idx.size(), loc); return out; } -// -------------------------- reorder and renumber to the lower possible --------------------------- +// ============================ LIST OF ELEMENTS CONNECTED TO EACH NODE ============================ -inline MatS renumber ( const MatS &in , const ColS &idx , std::string loc ) +inline SpMatS elem2node(const MatS &conn) { - // copy input to make modifications - ColS tmp = idx; - MatS out = in; - ColS dat = ColS::LinSpaced(in.maxCoeff()+1, 0, in.maxCoeff()+1); - - // store size - size_t ndx = static_cast( idx.size() ); - size_t N = static_cast( out.size() ); - - // sort input - std::sort ( tmp.data(), tmp.data()+tmp.size() ); + // get number of nodes + size_t nnode = conn.maxCoeff() + 1; - // find "jdx = setdiff ( dat , idx )" + // number of elements connected to each node // - allocate - ColS jdx ( dat.size() - ndx ); - // - compute - std::set_difference ( - dat.data() , dat.data()+dat.size() , - tmp.data() , tmp.data()+tmp.size() , - jdx.data() - ); - - // store size - size_t mdx = static_cast( jdx.size() ); - - // renumber-list + ColS N(nnode), idx(nnode); + // - initialize + N .setZero(); + idx.setZero(); + // - fill from connectivity + for ( auto it = conn.data(); it != conn.data()+conn.size(); ++it ) N(*it) += 1; + + // triplet list, with elements per node + // - type + typedef Eigen::Triplet T; // - allocate - ColS renum ( dat.size() ); + std::vector triplets; + // - predict size + triplets.reserve(N.sum()); // - fill - if ( loc == "end" ) - { - // -- order [ jdx , idx ] - for ( size_t i = 0 ; i < mdx ; ++i ) renum ( jdx(i) ) = i; - for ( size_t i = 0 ; i < ndx ; ++i ) renum ( idx(i) ) = i + mdx; - } - else if ( loc == "begin" ) - { - // -- order [ jdx, idx ] - for ( size_t i = 0 ; i < ndx ; ++i ) renum ( idx(i) ) = i; - for ( size_t i = 0 ; i < mdx ; ++i ) renum ( jdx(i) ) = i + ndx; + for ( auto e = 0 ; e < conn.rows() ; ++e ) { + for ( auto m = 0 ; m < conn.cols() ; ++m ) { + auto nd = conn(e,m); + triplets.push_back(T(nd, idx(nd), e)); + idx(nd)++; + } } - // renumber - for ( size_t i = 0 ; i < N ; ++i ) out ( i ) = renum ( out (i) ); + // spare matrix + // - allocate + SpMatS mat(nnode, N.maxCoeff()); + // - fill + mat.setFromTriplets(triplets.begin(), triplets.end()); - return out; + return mat; } // ================================================================================================= }} // namespace ... // ------------------------------------------------------------------------------------------------- #endif diff --git a/src/GooseFEM/Mesh.h b/src/GooseFEM/Mesh.h index 0d7a9e5..d4d33ac 100644 --- a/src/GooseFEM/Mesh.h +++ b/src/GooseFEM/Mesh.h @@ -1,41 +1,55 @@ /* ================================================================================================= (c - GPLv3) T.W.J. de Geus (Tom) | tom@geus.me | www.geus.me | github.com/tdegeus/GooseFEM ================================================================================================= */ #ifndef GOOSEFEM_MESH_H #define GOOSEFEM_MESH_H // ------------------------------------------------------------------------------------------------- #include "GooseFEM.h" // ======================================== GooseFEM::Mesh ========================================= namespace GooseFEM { namespace Mesh { -// ================================================================================================= - -// elements connected to each node: -// out[ : , 0 ] = number of elements connected to each node -// out[ j , i+1 ] = "i"th element connected to node "j" -inline MatS elem2node ( const MatS &conn ); +// ------------------------------------------------------------------------------------------------- // list with DOF-numbers in sequential order -inline MatS dofs ( size_t nnode , size_t ndim ); +inline MatS dofs(size_t nnode, size_t ndim); + +// renumber to lowest possible numbers (e.g. [0,3,4,2] -> [0,2,3,1]) +// - core +template +inline void renumber( + const InputIterator first, const InputIterator last, const OutputIterator result +); +// - interface +inline MatS renumber(const MatS &dofs); + +// reorder (and renumber) such that certain indices "idx" are moved to the beginning or the end +// - core +template +inline void reorder( + const InputIterator first, const InputIterator last, const OutputIterator result, + const IndexIterator first_index, const IndexIterator last_index, std::string location +); +// - interface +inline MatS reorder(const MatS &dofs, const ColS &idx, std::string location="end"); -// renumber list of indices -// - renumber to lowest possible numbers (e.g. [0,3,4,2] -> [0,2,3,1]) -inline MatS renumber ( const MatS &in ); -// - renumber to begin [ idx , ... ] or end [ ... , idx ] (e.g. [0,1,3,2] -> [3,0,2,1]; with idx=0) -inline MatS renumber ( const MatS &in , const ColS &idx , std::string location="end" ); +// elements connected to each node: +// out[: ,0 ] = number of elements connected to each node +// out[j ,i+1] = "i"th element connected to node "j" +inline SpMatS elem2node(const MatS &conn); -// ================================================================================================= + +// ------------------------------------------------------------------------------------------------- }} // namespace ... // ================================================================================================= #endif