diff --git a/src/CompositeSimpson.rst b/src/CompositeSimpson.rst index 4cf5647..f753979 100644 --- a/src/CompositeSimpson.rst +++ b/src/CompositeSimpson.rst @@ -4,13 +4,17 @@ CompositeSimpson ================== -.. function:: beamIntegration('CompositeSimpson',tag,secTag,N) +.. function:: beamIntegration('CompositeSimpson', tag, secTag, N) + beamIntegration('CompositeSimpson', tag, N, *secTags) :noindex: - Create a CompositeSimpson beamIntegration object. - - Arguments and examples see :ref:`Lobatto-BeamIntegration`. + Composite Simpson ``beamIntegration``. Two forms as in :ref:`Lobatto-BeamIntegration`. +.. admonition:: Example + .. code-block:: python + import openseespy.opensees as ops + ops.beamIntegration('CompositeSimpson', 2, 1, 6) + ops.beamIntegration('CompositeSimpson', 3, 4, 1, 2, 2, 1) diff --git a/src/Concrete02IS.rst b/src/Concrete02IS.rst new file mode 100644 index 0000000..bf867ee --- /dev/null +++ b/src/Concrete02IS.rst @@ -0,0 +1,42 @@ +.. include:: sub.txt + +============================================== + Concrete02IS material +============================================== + +This command constructs a uniaxial concrete material with the same compressive envelope and tension/cyclic behavior as :doc:`Concrete02`, but with **user-defined initial stiffness** :math:`E_0`. In Concrete02 the initial stiffness is fixed at :math:`E_c = 2 f'_c / \varepsilon_{c0}`; Concrete02IS allows any :math:`E_0` (for example :math:`57000\sqrt{f'_c}` in psi units, or a secant stiffness to peak). + +.. function:: uniaxialMaterial('Concrete02IS', matTag, E0, fpc, epsc0, fpcu, epsU, *optional) + + Optional trailing arguments (in order): ratio between unloading slope at ``epsU`` and initial slope, tensile strength ``ft``, tension softening stiffness ``Ets``. + + ================================ =========================================================================== + ``matTag`` |int| unique material tag + ``E0`` |float| initial (elastic) stiffness + ``fpc`` |float| concrete compressive strength at 28 days (compression negative) + ``epsc0`` |float| concrete strain at maximum strength (negative) + ``fpcu`` |float| concrete crushing strength (negative) + ``epsU`` |float| concrete strain at crushing strength (negative) + ================================ =========================================================================== + +.. note:: + + Compressive parameters are taken as negative; if given positive, they are converted internally. Input :math:`E_0` affects unloading/reloading stiffness in compression. The ascending branch uses the Popovics equation (Concrete02 uses the Hognestad parabola). + +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + fc, epsc0 = 4000.0, -0.002 + fcu, epscu = -1000.0, -0.006 + Ec = 2.0 * fc / (-epsc0) + ops.uniaxialMaterial('Concrete02IS', 1, Ec, fc, epsc0, fcu, epscu) + ops.uniaxialMaterial('Concrete02IS', 2, Ec, fc, epsc0, fcu, epscu, 0.1, 500.0, 1738.33) + +.. seealso:: + + :doc:`Concrete02`. + +Code developed by: Filip Filippou (Concrete02); Nasser Marafi (Concrete02IS). diff --git a/src/Damper.rst b/src/Damper.rst new file mode 100644 index 0000000..532d9a3 --- /dev/null +++ b/src/Damper.rst @@ -0,0 +1,27 @@ +.. include:: sub.txt + +======================== + Damper material wrapper +======================== + +Constructs a **Damper** uniaxial material wrapper. The wrapper uses the stress–strain response of any uniaxial material as a **stress versus strain-rate** relationship for damping: strain rate is passed as strain, and the material tangent provides the damping tangent. + +.. function:: uniaxialMaterial('Damper', matTag, otherTag, *args) + + ``*args`` may include ``'-factors'``, ``fact1``, ``fact2``, … for multiple materials. + + ================================ =========================================================================== + ``matTag`` |int| unique material tag + ``otherTag`` |int| tag of a previously defined uniaxial material + ================================ =========================================================================== + +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + ops.uniaxialMaterial('Elastic', 1, 100.0) + ops.uniaxialMaterial('Damper', 2, 1) + +Code developed by: **Michael H. Scott** diff --git a/src/Diagonal.rst b/src/Diagonal.rst new file mode 100644 index 0000000..d374512 --- /dev/null +++ b/src/Diagonal.rst @@ -0,0 +1,111 @@ +.. include:: sub.txt + +Diagonal System +----------------------------- + +This command is used to construct a Diagonal linear system of equation object. This system stores only the diagonal entries of the coefficient matrix, making it extremely memory efficient for problems where off-diagonal coupling can be neglected or lumped into the diagonal. The system is solved by direct inversion of the diagonal entries. The following command is used to construct such a system: + +.. function:: system ('Diagonal', <-'lumped'>) + + **Optional Parameter:** + + * **-lumped** - If specified, off-diagonal matrix entries are added (lumped) to the diagonal before solving. This is useful for mass matrix lumping or when converting a coupled system to a diagonal approximation. + +A diagonal system stores only the diagonal entries of an n×n matrix **A**, where: + +:math:`K = \begin{bmatrix} k_{11} & 0 & \cdots & 0 \\ 0 & k_{22} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & k_{nn} \end{bmatrix}` + +The solution for :math:`K u = f` is obtained directly as: + +:math:`u_i = \frac{f_i}{k_{ii}} \quad \text{for } i = 1, \ldots, n` + +.. note:: + + 1. This solver requires that all diagonal entries are non-zero. + 2. The system only stores n values instead of n² for a full matrix, providing significant memory savings + 3. When using the **-lumped** option, the solver accumulates all off-diagonal entries in each row/column into the corresponding diagonal entry + +Mass Lumping +^^^^^^^^^^^^ + +When the **-lumped** option is specified, the Diagonal system performs **mass lumping** (also called diagonal lumping or row-sum lumping). This technique converts a consistent (coupled) mass matrix into a diagonal form by summing all entries in each row and placing the total on the diagonal. + +**Mathematical Formulation:** + +For a consistent mass matrix **M** with entries :math:`m_{ij}`, the lumped diagonal entry is: + +:math:`\tilde{m}_{ii} = \sum_{j=1}^{n} m_{ij}` + +All off-diagonal entries are set to zero: :math:`\tilde{m}_{ij} = 0` for :math:`i \neq j` + + +.. warning:: + + 1. This system is only appropriate when the problem structure allows diagonal treatment + 2. Mass lumping is generally only recommended for the mass matrix in dynamic analysis (ExplicitDifference integrator or CentralDifference integrator if no damping matrix is used or only mass proportional Rayleigh damping is used) + 3. Lumping the stiffness matrix is rarely appropriate and can lead to poor results + 4. For static analysis or implicit dynamics use full sparse solvers. + 5. Ideally, lumping should be handled at the element level, especially for high-order elements (like the TenNodeTetrahedron or SixNodeTriangle) where this technique leads to negative mass values (!!). + +**Implementation Details:** + +When **-lumped** is specified: + +.. code-block:: none + + For each element matrix entry m(i,j) at DOF locations id(i), id(j): + A[id(i)] += m(i,i) // Add diagonal entry + if (lumped): + for all j ≠ i: + A[id(i)] += m(j,i) // Add all column entries to diagonal + +This ensures that the total contribution from each element is preserved while creating a diagonal system. + + +.. admonition:: Example + + The following examples show how to construct a Diagonal system + + **1. Python Code - Basic diagonal system** + + .. code-block:: python + + import openseespy.opensees as ops + + ops.system('Diagonal') + + **2. Python Code - Lumped mass for explicit analysis** + + .. code-block:: python + + import openseespy.opensees as ops + + # Setup for explicit central difference method + ops.system('Diagonal', '-lumped') + ops.constraints('Plain') + ops.numberer('Plain') + ops.integrator('CentralDifference') + ops.analysis('Transient') + + **3. Python Code - Complete explicit dynamics example** + + .. code-block:: python + + import openseespy.opensees as ops + + # ... model definition ... + + # Analysis setup for blast/impact with lumped mass + ops.system('Diagonal', '-lumped') + ops.constraints('Plain') + ops.numberer('Plain') + ops.test('NormDispIncr', 1.0e-6, 10, 0) + ops.algorithm('Linear') + ops.integrator('CentralDifference') + ops.analysis('Transient') + + # Time step (must satisfy CFL condition) + dt = 0.0001 + ops.analyze(1000, dt) + +Code Developed by: **Frank McKenna** diff --git a/src/Legendre.rst b/src/Legendre.rst index 9b1560d..2cccf6b 100644 --- a/src/Legendre.rst +++ b/src/Legendre.rst @@ -1,21 +1,26 @@ .. include:: sub.txt -============================================== - Legendre -============================================== +========== + Legendre +========== -.. function:: beamIntegration('Legendre',tag,secTag,N) +.. function:: beamIntegration('Legendre', tag, secTag, N) + beamIntegration('Legendre', tag, N, *secTags) :noindex: - Create a Gauss-Legendre beamIntegration object. - Gauss-Legendre integration is more accurate than Gauss-Lobatto; however, it is not common - in force-based elements because there are no integration points at the element ends. + Gauss–Legendre integration: more accurate than Lobatto but **no** points at the element ends by default, so less common in force-based elements. Order of accuracy: :math:`2N-1`. + **Prismatic:** ``beamIntegration('Legendre', tag, secTag, N)``. - Places ``N`` Gauss-Legendre integration points along the element. The location and weight - of each integration point are tabulated in references on numerical analysis. - The force deformation response at each integration point is defined by the section. - The order of accuracy for Gauss-Legendre integration is 2N-1. + **Non-prismatic:** ``beamIntegration('Legendre', tag, N, secTag1, …, secTagN)``. - Arguments and examples see :ref:`Lobatto-BeamIntegration`. + Arguments: see :ref:`Lobatto-BeamIntegration`. +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + ops.beamIntegration('Legendre', 2, 1, 6) + ops.beamIntegration('Legendre', 3, 4, 1, 2, 2, 1) diff --git a/src/Lobatto.rst b/src/Lobatto.rst index 0191dbe..18bae60 100644 --- a/src/Lobatto.rst +++ b/src/Lobatto.rst @@ -1,21 +1,40 @@ .. include:: sub.txt .. _Lobatto-BeamIntegration: - + ========= Lobatto ========= -.. function:: beamIntegration('Lobatto',tag,secTag,N) +.. function:: beamIntegration('Lobatto', tag, secTag, N) + beamIntegration('Lobatto', tag, N, *secTags) :noindex: - Create a Gauss-Lobatto beamIntegration object. - Gauss-Lobatto integration is the most common approach for evaluating the response of - :doc:`ForceBeamColumn` (`Neuenhofer and Filippou 1997`_) because it places an integration point at each end of the element, where bending moments are largest in the absence of interior element loads. + Create a Gauss–Lobatto ``beamIntegration`` object. Gauss–Lobatto is common for :doc:`ForceBeamColumn` (`Neuenhofer and Filippou 1997`_) because it places an integration point at each end of the element, where bending is largest if there are no interior element loads. + + **Prismatic** — one section for all points: ``(tag, secTag, N)``. + + **Non-prismatic** — one section tag per point, in order from node *I* to *J*: ``(tag, N, secTag1, secTag2, …, secTagN)``. + + ================================ =========================================================================== + ``tag`` |int| unique beam integration tag + ``secTag`` |int| (prismatic) one defined section for all points + ``N`` |int| number of integration points + ``secTags`` |listi| (non-prismatic) ``N`` section tags + ================================ =========================================================================== + +.. note:: + + The non-prismatic form assigns different sections along the length (e.g. tapering reinforcement) without relying on hinge-only schemes. The same two forms exist for :doc:`Legendre`, :doc:`Radau`, :doc:`NewtonCotes`, :doc:`Trapezoidal`, and :doc:`CompositeSimpson`. + +.. admonition:: Example + + Prismatic: 6 points, section tag 1. Non-prismatic: 3 sections ``[1, 2, 1]`` at 3 Lobatto points. + + .. code-block:: python - ======================== ============================================================= - ``tag`` |int| tag of the beam integration. - ``secTag`` |int| A previous-defined section object. - ``N`` |int| Number of integration points along the element. - ======================== ============================================================= + import openseespy.opensees as ops + ops.beamIntegration('Lobatto', 2, 1, 6) + sec_tag_list = [1, 2, 1] + ops.beamIntegration('Lobatto', 3, len(sec_tag_list), *sec_tag_list) diff --git a/src/MultiplierUni.rst b/src/MultiplierUni.rst new file mode 100644 index 0000000..8d0f62f --- /dev/null +++ b/src/MultiplierUni.rst @@ -0,0 +1,26 @@ +.. include:: sub.txt + +============================ + Multiplier material wrapper +============================ + +Constructs a **Multiplier** uniaxial material wrapper: stress and tangent of the wrapped material are multiplied by a factor. Typical uses include overstrength factors and p-y multipliers (e.g. pile group shadowing). + +.. function:: uniaxialMaterial('Multiplier', matTag, otherTag, multiplier) + + ================================ =========================================================================== + ``matTag`` |int| unique material tag + ``otherTag`` |int| tag of a previously defined uniaxial material + ``multiplier`` |float| factor applied to stress and tangent + ================================ =========================================================================== + +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + ops.uniaxialMaterial('Elastic', 1, 100.0) + ops.uniaxialMaterial('Multiplier', 2, 1, 0.8) + +Code developed by: **Michael H. Scott** diff --git a/src/NewtonCotes.rst b/src/NewtonCotes.rst index 7164f7a..df6dfbd 100644 --- a/src/NewtonCotes.rst +++ b/src/NewtonCotes.rst @@ -1,22 +1,26 @@ .. include:: sub.txt .. _NewtonCotes-BeamIntegration: - -============= + +============== NewtonCotes -============= +============== -.. function:: beamIntegration('NewtonCotes',tag,secTag,N) +.. function:: beamIntegration('NewtonCotes', tag, secTag, N) + beamIntegration('NewtonCotes', tag, N, *secTags) :noindex: - Create a Newton-Cotes beamIntegration object. - Newton-Cotes places integration points uniformly along the element, including a point at - each end of the element. + Newton–Cotes integration: points uniformly spaced along the element, **including** both ends. Order of accuracy: :math:`N-1`. + + **Prismatic:** ``('NewtonCotes', tag, secTag, N)``. + + **Non-prismatic:** ``('NewtonCotes', tag, N, *secTags)``. + +.. admonition:: Example - Places ``N`` Newton-Cotes integration points along the element. The weights for the uniformly - spaced integration points are tabulated in references on numerical analysis. The force deformation - response at each integration point is defined by the section. - The order of accuracy for Gauss-Radau integration is N-1. + .. code-block:: python - Arguments and examples see :ref:`Lobatto-BeamIntegration`. + import openseespy.opensees as ops + ops.beamIntegration('NewtonCotes', 2, 1, 6) + ops.beamIntegration('NewtonCotes', 3, 4, 1, 2, 2, 1) diff --git a/src/PenaltyUni.rst b/src/PenaltyUni.rst new file mode 100644 index 0000000..4149135 --- /dev/null +++ b/src/PenaltyUni.rst @@ -0,0 +1,34 @@ +.. include:: sub.txt + +========================== + Penalty material wrapper +========================== + +Constructs a **Penalty** uniaxial material wrapper that adds a small stiffness to the wrapped material. Helps avoid singular stiffness from perfect plasticity; lightweight alternative to placing the wrapped material in parallel with an elastic material. + +.. function:: uniaxialMaterial('Penalty', matTag, otherTag, penalty, *args) + + Optional ``'-noStress'``: penalty stiffness is added only to the tangent, not to stress. + + ================================ =========================================================================== + ``matTag`` |int| unique material tag + ``otherTag`` |int| tag of a previously defined uniaxial material + ``penalty`` |float| stiffness added to tangent (and optionally stress); same units as tangent + ================================ =========================================================================== + +.. note:: + + Use a small penalty value so the response stays dominated by the wrapped material. + +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + E = 29000.0 + penalty = 0.05 * E + ops.uniaxialMaterial('Elastic', 1, E) + ops.uniaxialMaterial('Penalty', 2, 1, penalty) + +Code developed by: **Michael H. Scott** diff --git a/src/Radau.rst b/src/Radau.rst index ed073fa..e3e7adb 100644 --- a/src/Radau.rst +++ b/src/Radau.rst @@ -4,15 +4,19 @@ Radau ======= -.. function:: beamIntegration('Radau',tag,secTag,N) +.. function:: beamIntegration('Radau', tag, secTag, N) + beamIntegration('Radau', tag, N, *secTags) :noindex: - Create a Gauss-Radau beamIntegration object. - Gauss-Radau integration is not common in force-based elements because it places an integration point at only one end of the element; however, it forms the basis for optimal plastic - hinge integration methods. + Gauss–Radau integration: uncommon in force-based elements because only **one** end holds an integration point; useful as building block for plastic-hinge schemes. Places ``N`` Gauss–Radau points with a point at node **I**. Order of accuracy: :math:`2N-2`. - Places ``N`` Gauss-Radau integration points along the element with a point constrained to be at ndI. The location and weight of each integration point are tabulated in references on - numerical analysis. The force-deformation response at each integration point is defined - by the section. The order of accuracy for Gauss-Radau integration is 2N-2. + **Prismatic / non-prismatic:** same pattern as :ref:`Lobatto-BeamIntegration`. - Arguments and examples see :ref:`Lobatto-BeamIntegration`. +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + ops.beamIntegration('Radau', 2, 1, 6) + ops.beamIntegration('Radau', 3, 4, 1, 2, 2, 1) diff --git a/src/SimpleFracture.rst b/src/SimpleFracture.rst new file mode 100644 index 0000000..53716aa --- /dev/null +++ b/src/SimpleFracture.rst @@ -0,0 +1,26 @@ +.. include:: sub.txt + +================================ + SimpleFracture material wrapper +================================ + +Constructs a **SimpleFracture** uniaxial material wrapper that imposes tensile fracture on the wrapped material: after strain exceeds a maximum tensile strain, the wrapper supplies compressive stress based on an estimate of the elastic strain. + +.. function:: uniaxialMaterial('SimpleFracture', matTag, otherTag, maxStrain) + + ================================ =========================================================================== + ``matTag`` |int| unique material tag + ``otherTag`` |int| tag of a previously defined uniaxial material + ``maxStrain`` |float| maximum tensile strain (fracture strain) + ================================ =========================================================================== + +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + ops.uniaxialMaterial('Hardening', 1, 3.0, 1.0, 0.1) + ops.uniaxialMaterial('SimpleFracture', 2, 1, 0.8) + +Code developed by: **Michael H. Scott** diff --git a/src/TensionOnly.rst b/src/TensionOnly.rst new file mode 100644 index 0000000..6ab312a --- /dev/null +++ b/src/TensionOnly.rst @@ -0,0 +1,27 @@ +.. include:: sub.txt + +=============================== + TensionOnly material wrapper +=============================== + +Constructs a **TensionOnly** uniaxial material wrapper: when the wrapped material would return negative stress, the wrapper returns zero stress and zero tangent and does **not** call ``commitState()`` on the wrapped material. Only tensile (positive) stress is returned. + +.. function:: uniaxialMaterial('TensionOnly', matTag, otherTag, *args) + + Optional: ``'-min'``, ``minStrain``, ``'-max'``, ``maxStrain``. + + ================================ =========================================================================== + ``matTag`` |int| unique material tag + ``otherTag`` |int| tag of a previously defined uniaxial material + ================================ =========================================================================== + +.. admonition:: Example + + .. code-block:: python + + import openseespy.opensees as ops + + ops.uniaxialMaterial('Elastic', 1, 100.0) + ops.uniaxialMaterial('TensionOnly', 2, 1) + +Code developed by: **Michael H. Scott** diff --git a/src/Trapezoidal.rst b/src/Trapezoidal.rst index a7a149b..ac00d4b 100644 --- a/src/Trapezoidal.rst +++ b/src/Trapezoidal.rst @@ -1,13 +1,20 @@ .. include:: sub.txt -============= +============== Trapezoidal -============= +============== -.. function:: beamIntegration('Trapezoidal',tag,secTag,N) +.. function:: beamIntegration('Trapezoidal', tag, secTag, N) + beamIntegration('Trapezoidal', tag, N, *secTags) :noindex: - Create a Trapezoidal beamIntegration object. + Trapezoidal rule ``beamIntegration``. Two forms as in :ref:`Lobatto-BeamIntegration`. - Arguments and examples see :ref:`Lobatto-BeamIntegration`. +.. admonition:: Example + .. code-block:: python + + import openseespy.opensees as ops + + ops.beamIntegration('Trapezoidal', 2, 1, 6) + ops.beamIntegration('Trapezoidal', 3, 4, 1, 2, 2, 1) diff --git a/src/UmfPack.rst b/src/UmfPack.rst index 0235c0b..856690e 100644 --- a/src/UmfPack.rst +++ b/src/UmfPack.rst @@ -8,3 +8,10 @@ :noindex: This command is used to construct a sparse system of equations which uses the `UmfPack`_ solver. + +.. function:: system('UmfPack', '-useLongIndices') + :noindex: + + Pass ``'-useLongIndices'`` to use 64-bit indices in UMFPACK instead of the default 32-bit indices. + + If symbolic or numeric factorization returns **-1**, try adding this option. diff --git a/src/beamIntegration.rst b/src/beamIntegration.rst index 8551ac9..e1a55c7 100644 --- a/src/beamIntegration.rst +++ b/src/beamIntegration.rst @@ -6,8 +6,9 @@ .. function:: beamIntegration(type, tag, *args) - A wide range of numerical integration options are available in OpenSees to represent distributed plasticity or non-prismatic section details in Beam-Column Elements, i.e., across the entire element domain [0, L]. + A wide range of numerical integration options are available in OpenSees to represent distributed plasticity or non-prismatic section details in beam–column elements, i.e. along the element domain :math:`[0, L]`. + For **distributed** rules such as :doc:`Lobatto`, :doc:`Legendre`, :doc:`Radau`, :doc:`NewtonCotes`, :doc:`Trapezoidal`, and :doc:`CompositeSimpson`, two forms are supported: **prismatic** (one ``secTag`` and point count ``N``) and **non-prismatic** (``N`` then ``N`` section tags, node *I* to *J*). See :ref:`Lobatto-BeamIntegration`. Following are beamIntegration types available in the OpenSees: diff --git a/src/eleload.rst b/src/eleload.rst index 82a7db0..f12a9ad 100644 --- a/src/eleload.rst +++ b/src/eleload.rst @@ -32,6 +32,58 @@ temperature points. ======================== ============================================================= +**Uniform (full span)** — ``NDM`` = 2: + +.. code-block:: python + + ops.eleLoad('-ele', eleTag, '-type', '-beamUniform', Wy, Wx) + +**Trapezoidal (partial span, 2D)** — intensity varies linearly between normalized positions ``aOverL`` and ``bOverL`` (fraction of length, 0 to 1). Give transverse and axial intensities at start (:math:`W_{ya}`, :math:`W_{xa}`) and end (:math:`W_{yb}`, :math:`W_{xb}`). Supported by 2D ``elasticBeamColumn`` and ``forceBeamColumn``: + +.. code-block:: python + + ops.eleLoad('-ele', eleTag, '-type', '-beamUniform', + Wya, Wxa, aOverL, bOverL, Wyb, Wxb) + +**Uniform** — ``NDM`` = 3: + +.. code-block:: python + + ops.eleLoad('-ele', eleTag, '-type', '-beamUniform', Wy, Wz, Wx) + +For **trapezoidal** loads in 3D, pass ``Wy``, ``Wz``, ``Wx``, ``aOverL``, ``bOverL``, then end values ``Wyb``, ``Wzb``, ``Wxb``. Some 3D ``elasticBeamColumn`` paths may approximate a segment as triangular; combine loads if you need an exact trapezoid. + +**Point load** — ``NDM`` = 2: + +.. code-block:: python + + ops.eleLoad('-range', eleTag1, eleTag2, '-type', '-beamPoint', Py, xL, Px) + +``NDM`` = 3: + +.. code-block:: python + + ops.eleLoad('-range', eleTag1, eleTag2, '-type', '-beamPoint', Py, Pz, xL, Px) + +.. admonition:: Example + + Uniform span load and a 2D trapezoidal segment from :math:`0.2L` to :math:`0.8L`. + + .. code-block:: python + + import openseespy.opensees as ops + + width = 20.0 + W = 4000.0 + wya, wxa = -0.5, 0.0 + a_over_l, b_over_l = 0.2, 0.8 + wyb, wxb = -1.0, 0.0 + ops.timeSeries('Linear', 1) + ops.pattern('Plain', 1, 1) + ops.eleLoad('-ele', 3, '-type', '-beamUniform', -W / width) + ops.eleLoad('-ele', 4, '-type', '-beamUniform', + wya, wxa, a_over_l, b_over_l, wyb, wxb) + .. note:: diff --git a/src/element.rst b/src/element.rst index be57a19..0b5a748 100644 --- a/src/element.rst +++ b/src/element.rst @@ -36,6 +36,7 @@ Zero-Length Element #. :doc:`zeroLengthND` #. :doc:`zeroLengthSection` #. :doc:`CoupledZeroLength` +#. :doc:`zeroLengthContact` #. :doc:`zeroLengthContact2D` #. :doc:`zeroLengthContactNTS2D` #. :doc:`zeroLengthInterface2D` @@ -50,6 +51,7 @@ Zero-Length Element zeroLengthND zeroLengthSection CoupledZeroLength + zeroLengthContact zeroLengthContact2D zeroLengthContactNTS2D zeroLengthInterface2D diff --git a/src/elementRecorder.rst b/src/elementRecorder.rst index f61c316..47d3d73 100644 --- a/src/elementRecorder.rst +++ b/src/elementRecorder.rst @@ -1,6 +1,7 @@ .. include:: sub.txt - +.. _elementRecorder: + ======================== element recorder command ======================== @@ -30,4 +31,45 @@ element recorder command .. note:: - The setResponse() element method is dependent on the element type, and is described with the :meth:`element` Command. + The ``setResponse()`` behavior depends on the element type; see the :doc:`element` command. + +Recording fiber response +------------------------- + +For elements with fiber sections (e.g. **zeroLengthSection**, **forceBeamColumn**, **dispBeamColumn**, **mixedBeamColumn**), you can record a single fiber. Options depend on the uniaxial material’s ``setResponse()`` (common: ``stressStrain``). + +Choose the fiber by: + +1. **Index** — ``fiber``, index (0 … :math:`N_f-1`), response type. +2. **Location** — ``fiber``, *y*, *z*, response type (closest fiber to section coordinates; 2D bending about *z* still uses *y* and *z*, e.g. ``z = 0``). +3. **Material tag at location** — ``fiber``, *y*, *z*, ``matTag``, response type (disambiguate overlapping fibers). + +Prefix with ``section`` for **zeroLengthSection** (one section). For beam–columns use ``section`` *secNum* (integration point 1 … :math:`N_p` from node *I* to *J*), or :ref:`elementRecorderSectionX` with coordinate *x* along the element. + +.. code-block:: python + + # zeroLengthSection: fiber near (y, z) + ops.recorder('Element', '-ele', 1, '-file', 'fiber.out', 'section', 'fiber', 0.1, 0.0, 'stressStrain') + + # Beam-column: section 1, steel fiber at tension face (h = depth) + h = 0.5 + ops.recorder('Element', '-ele', 1, '-file', 'steelFiber.out', 'section', 1, 'fiber', -h / 2, 0, 2, 'stressStrain') + +.. _elementRecorderSectionX: + +Recording section response by location (``sectionX``) +----------------------------------------------------- + +For beam–columns you can record section quantities by index (``section`` *i*) or by **physical position**: ``sectionX``, *x* with :math:`x \in [0, L]` from node *I* to *J*. OpenSees picks the integration section **closest** to *x*. Remaining tokens match the usual section recorder (e.g. ``deformation``, ``force``, or ``fiber`` …). + +.. code-block:: python + + ops.recorder('Element', '-ele', 1, '-file', 'sec25.out', 'sectionX', 25.0, 'deformation') + +.. note:: + + One *x* per recorder; use multiple recorders for multiple locations. + +.. seealso:: + + :doc:`Fatigue` (damage recorders). diff --git a/src/section.rst b/src/section.rst index 40c65bf..6b45906 100644 --- a/src/section.rst +++ b/src/section.rst @@ -23,7 +23,9 @@ For example, secArgs = [E, A, Iz] section(secType, secTag, *secArgs) +.. note:: + Valid queries for many sections when using an element recorder include ``force`` and ``deformation``; some sections support more (see each section’s notes). For fiber output (e.g. ``stressStrain``) and ``sectionX`` recorders, see :ref:`elementRecorder`. The following contain information about available ``secType``: diff --git a/src/system.rst b/src/system.rst index cc7061f..5fe2e9c 100644 --- a/src/system.rst +++ b/src/system.rst @@ -23,6 +23,7 @@ The following contain information about available ``systemType``: #. :doc:`UmfPack` #. :doc:`FullGeneral` #. :doc:`SparseSYM` +#. :doc:`Diagonal` #. :ref:`PFEM-System` #. :doc:`Mumps` @@ -38,6 +39,7 @@ The following contain information about available ``systemType``: UmfPack FullGeneral SparseSYM + Diagonal Mumps diff --git a/src/uniaxialMaterial.rst b/src/uniaxialMaterial.rst index 9facfc2..216189e 100644 --- a/src/uniaxialMaterial.rst +++ b/src/uniaxialMaterial.rst @@ -62,6 +62,7 @@ Concrete Materials #. :doc:`Concrete01` #. :doc:`Concrete02` +#. :doc:`Concrete02IS` #. :doc:`Concrete04` #. :doc:`Concrete06` #. :doc:`Concrete07` @@ -83,6 +84,7 @@ Concrete Materials Concrete01 Concrete02 + Concrete02IS Concrete04 Concrete06 Concrete07 @@ -151,6 +153,7 @@ Other Uniaxial Materials #. :doc:`Hardening` #. :doc:`Cast` +#. :doc:`Damper` #. :doc:`ViscousDamper` #. :doc:`BilinearOilDamper` #. :doc:`Bilin` @@ -160,6 +163,7 @@ Other Uniaxial Materials #. :doc:`BarSlip` #. :doc:`Bond_SP01` #. :doc:`Fatigue` +#. :doc:`MultiplierUni` #. :doc:`ImpactMaterial` #. :doc:`HyperbolicGapMaterial` #. :doc:`LimitState` @@ -169,7 +173,10 @@ Other Uniaxial Materials #. :doc:`MultiLinear` #. :doc:`InitStrainMaterial` #. :doc:`InitStressMaterial` +#. :doc:`PenaltyUni` #. :doc:`PathIndependent` +#. :doc:`SimpleFracture` +#. :doc:`TensionOnly` #. :doc:`Pinching4` #. :doc:`ECC01` #. :doc:`SelfCentering` @@ -194,6 +201,7 @@ Other Uniaxial Materials Hardening Cast + Damper ViscousDamper BilinearOilDamper Bilin @@ -203,6 +211,7 @@ Other Uniaxial Materials BarSlip Bond_SP01 Fatigue + MultiplierUni ImpactMaterial HyperbolicGapMaterial LimitState @@ -212,7 +221,10 @@ Other Uniaxial Materials MultiLinear InitStrainMaterial InitStressMaterial + PenaltyUni PathIndependent + SimpleFracture + TensionOnly Pinching4 ECC01 SelfCentering diff --git a/src/zeroLengthContact.rst b/src/zeroLengthContact.rst new file mode 100644 index 0000000..e4e6612 --- /dev/null +++ b/src/zeroLengthContact.rst @@ -0,0 +1,53 @@ +.. include:: sub.txt + +=========================== + zeroLengthContact elements +=========================== + +Node-to-node frictional contact (**2D** or **3D**): constrained node vs retained node. Mohr–Coulomb: :math:`T = \mu N + c` (:math:`T` tangential, :math:`N` normal, :math:`\mu` friction, :math:`c` cohesion). + +**2D** + +.. function:: element('zeroLengthContact2D', eleTag, cNode, rNode, Kn, Kt, mu, '-normal', Nx, Ny) + +**3D** + +.. function:: element('zeroLengthContact3D', eleTag, cNode, rNode, Kn, Kt, mu, c, dir) + + ================================ =========================================================================== + ``eleTag`` |int| element tag + ``cNode``, ``rNode`` |int| constrained and retained node tags + ``Kn``, ``Kt`` |float| penalty stiffness (normal, tangential) + ``mu`` |float| friction coefficient + ``Nx``, ``Ny`` |float| (2D) unit normal components + ``c`` |float| (3D) cohesion (not used in 2D) + ``dir`` |int| (3D) out-normal of retained plane: 1 = +X, 2 = +Y, 3 = +Z + ================================ =========================================================================== + +.. note:: + + #. Element tangent is non-symmetric; use a non-symmetric linear system solver. + #. 2D contact: nodes with 2 DOF; 3D contact: nodes with 3 DOF. + #. Out-normal of the master (retained) plane is taken fixed during analysis. + +.. seealso:: + + `Notes (OpenSees wiki) `_ + +.. admonition:: Example + + **2D:** contact between nodes **2** and **4**, normal ``(0, -1)``. + + .. code-block:: python + + import openseespy.opensees as ops + + ops.element('zeroLengthContact2D', 1, 2, 4, 1e8, 1e8, 0.3, '-normal', 0, -1) + + **3D:** cohesion ``0``, out-normal **+Z** (``dir`` = 3). + + .. code-block:: python + + ops.element('zeroLengthContact3D', 1, 2, 4, 1e8, 1e8, 0.3, 0.0, 3) + +Code developed by: **Gang Wang**, Geomatrix