{ "cells": [ { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. _SectionBoundaryConditionMode:\n", "\n", "Boundary Condition Mode\n", "=======================" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "This example will explain the basic usage of the boundary condition mode with saenopy.\n", "\n", "This mode solves a boundary condition situation, where the displacement (Dirichlet conditon, *fixed* nodes) or the force (von Neumann condition, *free* nodes) on each node is defined.\n", "\n", "In other words, the user can provide target displacements for some nodes (e.g. the borders of the mesh with 0 displacement) and target forces for all other nodes (e.g. nodes with 0 force in the bulk of the material).\n", "\n", "The input is:\n", " - the material parameters (see :ref:`SectionMaterial`)\n", " - the mesh (nodes and connectivity) (see :ref:`SectionMesh`)\n", " - the displacements :math:`U_i` for fixed nodes\n", " - the forces :math:`f_i` for free nodes\n", " \n", "The output is:\n", " - the forces :math:`f_i` for fixed nodes\n", " - the displacements :math:`U_i` for free nodes\n", "\n", "First the basic theoretical background is explained, followed by the code to use it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Theory" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Due to the high non-linearity of the material, the boundary condition problem has to be solved iteratively.\n", "\n", "First the stiffness matrix :math:`K_{ij}(U)`, the nodal forces :math:`f_i(U)` and the total energy :math:`E(U)` are calculated for all nodes (indices :math:`i`, :math:`j`) for the current displacements :math:`U`.\n", "\n", ".. math::\n", " K_{ij}(U) &= \\frac{\\partial E}{\\partial u_i\\partial u_j}\\\\\n", " f_{i}(U) &= \\frac{\\partial E}{\\partial u_i}\n", "\n", "Then the following linear equation (:math:`A_{ij}\\cdot x_j = b_i`) is solved with a constant displacement :math:`U`, for an infinitessimal displacement shift :math:`\\Delta u`.\n", "\n", ".. math::\n", " \\underbrace{K_{ij}(U)}_{A_{ij}} \\cdot \\underbrace{\\Delta u_j}_{x_j} = \\underbrace{f_i(U) - f^\\mathrm{ext}_i}_{b_i}\n", " \n", "Index :math:`i` runs over all free nodes, :math:`j` over all nodes. \n", "Where :math:`K_{ij}` is the stiffness matrix, :math:`\\Delta u_i` an infinitessimal displacement, :math:`f_i` the force on the node :math:`i` and :math:`f^\\mathrm{ext}_i` the external force on the node :math:`i` (boundary condition).\n", "\n", "This equation is solved using the conjugate gradient method to obtain a value for :math:`\\Delta u_i`. A tiny fraction ( `stepper`) of this is applied to the displacement :math:`U_i`:\n", "\n", ".. math::\n", " U^\\prime_i = U_i + \\mathrm{stepper} \\cdot \\Delta u_i.\n", "\n", "With the new displacement :math:`U^\\prime`, the stiffness matrix :math:`K_{ij}(U^\\prime)`, the nodal forces :math:`f_i(U^\\prime)`, and the total energy :math:`E(U^\\prime)` are updated.\n", "\n", "This procedure is iterated until the total energy :math:`E` of the system converges. The convergence criterion is:\n", "\n", ".. math::\n", " \\frac{\\mathrm{std}(\\{E^{t-6}, E^{t-5}, ..., E^{t-1}, E^t\\})}{\\mathrm{mean}(\\{E^{t-6}, E^{t-5}, ..., E^{t-1}, E^t\\})} \\leq \\mathrm{rel\\_conv\\_crit}\n", "\n", "So when the standard deviation of :math:`E` divided by the mean of :math:`E` for the last 6 iterations is lower than the threshold `rel_conv_crit`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The following code example (the code of all boxed joined in a single file) can be downloaded at `boundarycondition.py `_.\n", "\n", ".. warning::\n", " This example does not make use of the graphical user interface. It is only recomended to use if you just want to use the API functionality.\n", "\n", " There is currently no version of the boundary condition solver that is compatile the the graphical user interface." ] }, { "cell_type": "markdown", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "First, import the Solver class. This is the central class of saenopy." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "jupyter": { "is_executing": true } }, "outputs": [], "source": [ "from saenopy import Solver\n", "import saenopy\n", "# initialize the object\n", "M = Solver()" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Set the material model (see :ref:`SectionMaterial`):" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from saenopy.materials import SemiAffineFiberMaterial\n", "\n", "# provide a material model\n", "material = SemiAffineFiberMaterial(1645, 0.0008, 1.0075, 0.033)\n", "M.set_material_model(material)" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Define the mesh (see :ref:`SectionMesh`)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "# define the coordinates of the nodes of the mesh\n", "# the array has to have the shape N_n x 3\n", "R = np.array([[0., 0., 0.], # 0\n", " [0., 1., 0.], # 1\n", " [1., 1., 0.], # 2\n", " [1., 0., 0.], # 3\n", " [0., 0., 1.], # 4\n", " [0., 1., 1.], # 5\n", " [1., 1., 1.], # 6\n", " [1., 0., 1.]]) # 7\n", "\n", "# define the concetivity of the mesh (only tetrahedra are allowed)\n", "# the array has to have the shape N_t x 4\n", "# every entry is an index referencing a node in R (indices start with 0)\n", "T = np.array([[0, 1, 3, 5],\n", " [1, 2, 3, 5],\n", " [0, 5, 3, 4],\n", " [4, 5, 3, 7],\n", " [5, 2, 3, 6],\n", " [3, 5, 6, 7]])\n", "\n", "# provide the node data\n", "M.set_nodes(R)\n", "# the tetrahedron data\n", "M.set_tetrahedra(T)" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "And define the boundary conditions (see :ref:`SectionBoundaryConditions`)." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# the displacement boundary conditions of the nodes\n", "# if a displacement boundary condition is given, the node will be fixed\n", "U = np.array([[ 0. , 0. , 0. ], # 0\n", " [ 0. , 0. , 0. ], # 1\n", " [np.nan, np.nan, np.nan], # 2\n", " [np.nan, np.nan, np.nan], # 3\n", " [ 0. , 0. , 0. ], # 4\n", " [ 0. , 0. , 0. ], # 5\n", " [np.nan, np.nan, np.nan], # 6\n", " [np.nan, np.nan, np.nan]]) # 7\n", "\n", "# the force boundary conditions of the nodes\n", "# if a target force boundary condition is given, the node will be free\n", "# this is the force that the material applies after solving onto the nodes\n", "# therefore for a pull to the right (positive x-direction) we have to provide\n", "# a target force to the left (negative x-direction)\n", "F_ext = np.array([[np.nan, np.nan, np.nan], # 0\n", " [np.nan, np.nan, np.nan], # 1\n", " [-2.5 , 0. , 0. ], # 2\n", " [-2.5 , 0. , 0. ], # 3\n", " [np.nan, np.nan, np.nan], # 4\n", " [np.nan, np.nan, np.nan], # 5\n", " [-2.5 , 0. , 0. ], # 6\n", " [-2.5 , 0. , 0. ]]) # 7\n", "\n", "# and the boundary condition\n", "M.set_boundary_condition(U, F_ext)" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "After defining all input parameters, we can start with the solving process (for parameters see :py:meth:`~.Solver.solve_boundarycondition`)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# relax the mesh and move the \"varible\" nodes\n", "M.solve_boundarycondition();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "celltoolbar": "Raw Cell Format", "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" }, "pycharm": { "stem_cell": { "cell_type": "raw", "metadata": { "collapsed": false }, "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 }