.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/ex21_nonlinear-truss-analysis.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_ex21_nonlinear-truss-analysis.py: Nonlinear Truss Analysis ------------------------ .. topic:: Numeric continuation of a 3d truss system. * use FElupe with contique * view the normal forces of the deformed truss system * plot load-proportionality-factor (LPF) - displacement curves .. admonition:: This example requires external packages. :class: hint .. code-block:: pip install contique This example describes a three-dimensional system of trusses with 5 points and 6 cells (in total 5 active degrees of freedom). Given to its geometry, strong geometric nonlinearities are to be expected when the given reference load is applied. First, we create a mesh, where points are defined by their coordinates and cells by pairs of point connectivities. .. GENERATED FROM PYTHON SOURCE LINES 27-49 .. code-block:: Python import contique import matplotlib.pyplot as plt import numpy as np import felupe as fem mesh = fem.Mesh( points=[ [2.5, 0, 0], [-1.25, 1.25, 0], [1, 2, 0], [-0.5, 1.5, 1.5], [-2.5, 4.5, 2.5], ], cells=[[0, 3], [1, 3], [2, 3], [2, 4], [1, 4], [3, 4]], cell_type="line", ) region = fem.RegionTruss(mesh) field = fem.FieldContainer([fem.Field(region, dim=3)]) .. GENERATED FROM PYTHON SOURCE LINES 51-53 Beside points and cells we have to define displacement boundary conditions, external forces and the constitutive material formulation for the trusses. .. GENERATED FROM PYTHON SOURCE LINES 53-71 .. code-block:: Python boundaries = fem.BoundaryDict( fixed_xyz=fem.Boundary(field[0], mask=[1, 1, 1, 0, 0]), fixed_y=fem.Boundary(field[0], mask=[0, 0, 0, 0, 1], skip=(1, 0, 1)), ) dof0, dof1 = fem.dof.partition(field, boundaries) solid = fem.TrussBody( umat=fem.LinearElastic1D(E=1), field=field, area=[0.75, 1, 0.5, 0.75, 1, 1], ) force_3 = np.array([1, 1, -1]) force_4 = np.array([-2, 0, -2]) load_3 = fem.PointLoad(field, [3], force_3) load_4 = fem.PointLoad(field, [4], force_4) .. GENERATED FROM PYTHON SOURCE LINES 72-73 The undeformed configuration is plotted in a 3d-view. .. GENERATED FROM PYTHON SOURCE LINES 73-91 .. code-block:: Python plotter = mesh.plot( line_width=10, render_lines_as_tubes=True, show_edges=False, ) plotter.add_points( mesh.points, color="black", point_size=20, render_points_as_spheres=True, ) plotter = boundaries.plot(plotter=plotter) plotter = load_3.plot(plotter=plotter, color="green", deformed=False) plotter = load_4.plot(plotter=plotter, color="green", deformed=False) plotter.show() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_001.png :alt: ex21 nonlinear truss analysis :srcset: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_001.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/docs/checkouts/readthedocs.org/user_builds/felupe/checkouts/stable/docs/examples/images/sphx_glr_ex21_nonlinear-truss-analysis_001.vtksz .. GENERATED FROM PYTHON SOURCE LINES 92-96 For the numeric continuation, the equilibrium function ``fun`` and its derivatives w.r.t. the displacement field ``dfun_du`` and the load-proportionality-factor ``dfun_dlpf`` have to be defined. Here, we're only interested in the active degrees of freedom. .. GENERATED FROM PYTHON SOURCE LINES 96-115 .. code-block:: Python def fun(x, lpf, *args): field[0].values.ravel()[dof1] = x load_3.update(force_3 * lpf) load_4.update(force_4 * lpf) return fem.tools.fun([solid, load_3, load_4], field)[dof1] def dfun_du(x, lpf, *args): field[0].values.ravel()[dof1] = x K = fem.tools.jac([solid, load_3, load_4], field) return fem.solve.partition(field, K, dof1, dof0)[2] def dfun_dlpf(x, lpf, *args): load_3.update(force_3) load_4.update(force_4) return fem.tools.fun([load_3, load_4], field)[dof1] .. GENERATED FROM PYTHON SOURCE LINES 116-123 Now that the model is finished, some additional settings have to be chosen. Initial allowed incremental system vector components for both the displacement vector and the load-proportionality-factor (LPF) have to be specified. We use ``dlpf = 0.005`` and ``du = 0.05`` (figured out after some trial and error). Both parameters can't be specified automatically, as they depend on the model configuration. The job will be limited to a total amount of 163 increments (again, the total number has been figured out after some job runs to get good looking plots). .. GENERATED FROM PYTHON SOURCE LINES 123-140 .. code-block:: Python res = contique.solve( fun=fun, jac=[dfun_du, dfun_dlpf], x0=field[0][dof1], lpf0=0, dxmax=0.05, dlpfmax=0.005, maxsteps=163, rebalance=True, overshoot=1.25, tol=1e-8, low=1e-2, high=4, maxiter=8, ) X = np.array([r.x for r in res]) .. rst-class:: sphx-glr-script-out .. code-block:: none |Step,C.| Control Component | Norm (Iter.#) | Message | |-------|-------------------|---------------|-------------| | 1,1 | 5+ => 4- | 8.8e-09 ( 6#) | => re-Cycle | | 2 | 4- => 3- | 1.7e-14 ( 3#) |tol.Overshoot| | 2,1 | 3- => 3- | 1.6e-14 ( 3#) | | | 3,1 | 3- => 4- | 2.3e-14 ( 3#) |tol.Overshoot| | 4,1 | 4- => 4- | 6.7e-14 ( 3#) | | | 5,1 | 4- => 4- | 4.2e-13 ( 3#) | | | 6,1 | 4- => 4- | 2.5e-12 ( 3#) | | | 7,1 | 4- => 4- | 1.4e-11 ( 3#) | | | 8,1 | 4- => 4- | 7.1e-11 ( 3#) | | | 9,1 | 4- => 4- | 5.4e-11 ( 3#) | | | 10,1 | 4- => 4- | 3.8e-11 ( 3#) | | | 11,1 | 4- => 4- | 3.0e-11 ( 3#) | | | 12,1 | 4- => 4- | 2.7e-11 ( 3#) | | | 13,1 | 4- => 4- | 2.7e-11 ( 3#) | | | 14,1 | 4- => 4- | 3.1e-11 ( 3#) | | | 15,1 | 4- => 4- | 4.0e-11 ( 3#) | | | 16,1 | 4- => 4- | 5.4e-11 ( 3#) | | | 17,1 | 4- => 4- | 7.6e-11 ( 3#) | | | 18,1 | 4- => 4- | 1.1e-10 ( 3#) | | | 19,1 | 4- => 4- | 1.6e-10 ( 3#) | | | 20,1 | 4- => 4- | 2.3e-10 ( 3#) | | | 21,1 | 4- => 4- | 3.3e-10 ( 3#) | | | 22,1 | 4- => 4- | 4.6e-10 ( 3#) | | | 23,1 | 4- => 4- | 6.1e-10 ( 3#) | | | 24,1 | 4- => 4- | 6.5e-10 ( 3#) | | | 25,1 | 4- => 4- | 3.4e-10 ( 3#) | | | 26,1 | 4- => 4- | 4.1e-10 ( 3#) | | | 27,1 | 4- => 4- | 1.9e-15 ( 4#) | | | 28,1 | 4- => 4- | 2.5e-13 ( 4#) | | | 29,1 | 4- => 2- | 4.7e-11 ( 4#) |tol.Overshoot| | 30,1 | 2- => 2- | 9.4e-13 ( 4#) | | | 31,1 | 2- => 2- | 1.9e-12 ( 4#) | | | 32,1 | 2- => 2- | 3.9e-09 ( 4#) | | | 33,1 | 2- => 2- | 7.3e-03 ( 8#) |Failed | | 34,1 | 2- => 4+ | 5.4e-02 ( 8#) |Failed | | 35,1 | 2- => 4+ | 4.0e-11 ( 4#) |tol.Overshoot| | 36,1 | 4+ => 4+ | 2.2e-09 ( 3#) | | | 37,1 | 4+ => 4+ | 2.4e-10 ( 3#) | | | 38,1 | 4+ => 4+ | 2.5e-10 ( 3#) | | | 39,1 | 4+ => 4+ | 1.6e-10 ( 3#) | | | 40,1 | 4+ => 4+ | 3.5e-11 ( 3#) | | | 41,1 | 4+ => 4+ | 1.8e-10 ( 3#) | | | 42,1 | 4+ => 4+ | 1.3e-09 ( 3#) | | | 43,1 | 4+ => 4+ | 7.3e-10 ( 3#) | | | 44,1 | 4+ => 4+ | 2.9e-10 ( 3#) | | | 45,1 | 4+ => 4+ | 1.0e-10 ( 3#) | | | 46,1 | 4+ => 4+ | 3.5e-11 ( 3#) | | | 47,1 | 4+ => 4+ | 1.5e-11 ( 3#) | | | 48,1 | 4+ => 4+ | 1.5e-11 ( 3#) | | | 49,1 | 4+ => 4+ | 1.8e-11 ( 3#) | | | 50,1 | 4+ => 4+ | 2.1e-11 ( 3#) | | | 51,1 | 4+ => 4+ | 2.3e-11 ( 3#) | | | 52,1 | 4+ => 4+ | 2.5e-11 ( 3#) | | | 53,1 | 4+ => 4+ | 2.8e-11 ( 3#) | | | 54,1 | 4+ => 4+ | 3.2e-11 ( 3#) | | | 55,1 | 4+ => 4+ | 3.8e-11 ( 3#) | | | 56,1 | 4+ => 4+ | 4.7e-11 ( 3#) | | | 57,1 | 4+ => 4+ | 6.2e-11 ( 3#) | | | 58,1 | 4+ => 4+ | 8.9e-11 ( 3#) | | | 59,1 | 4+ => 4+ | 1.4e-10 ( 3#) | | | 60,1 | 4+ => 4+ | 2.3e-10 ( 3#) | | | 61,1 | 4+ => 4+ | 4.3e-10 ( 3#) | | | 62,1 | 4+ => 4+ | 9.0e-10 ( 3#) | | | 63,1 | 4+ => 4+ | 2.1e-09 ( 3#) | | | 64,1 | 4+ => 4+ | 5.4e-09 ( 3#) | | | 65,1 | 4+ => 3+ | 2.3e-15 ( 4#) |tol.Overshoot| | 66,1 | 3+ => 3+ | 1.9e-09 ( 3#) | | | 67,1 | 3+ => 3+ | 1.5e-09 ( 3#) | | | 68,1 | 3+ => 3+ | 3.4e-09 ( 3#) | | | 69,1 | 3+ => 3+ | 2.4e-15 ( 4#) | | | 70,1 | 3+ => 3+ | 6.5e-04 ( 8#) |Failed | | 71,1 | 3+ => 3+ | 1.4e-15 ( 4#) | | | 72,1 | 3+ => 3+ | 7.0e-04 ( 8#) |Failed | | 73,1 | 3+ => 3+ | 3.1e-15 ( 4#) | | | 74,1 | 3+ => 2- | 4.2e-03 ( 8#) |Failed | | 75,1 | 3+ => 2- | 1.5e-14 ( 4#) |tol.Overshoot| | 76,1 | 2- => 2- | 3.6e-11 ( 3#) | | | 77,1 | 2- => 2- | 1.2e-11 ( 3#) | | | 78,1 | 2- => 2- | 4.1e-11 ( 3#) | | | 79,1 | 2- => 2- | 1.4e-10 ( 3#) | | | 80,1 | 2- => 2- | 5.4e-10 ( 3#) | | | 81,1 | 2- => 3- | 2.5e-09 ( 3#) |tol.Overshoot| | 82,1 | 3- => 3- | 4.2e-14 ( 4#) | | | 83,1 | 3- => 3- | 4.3e-15 ( 4#) | | | 84,1 | 3- => 3- | 7.9e-09 ( 3#) | | | 85,1 | 3- => 3- | 7.5e-09 ( 3#) | | | 86,1 | 3- => 3- | 3.7e-10 ( 3#) | | | 87,1 | 3- => 4- | 1.7e-09 ( 3#) |tol.Overshoot| | 88,1 | 4- => 4- | 3.0e-10 ( 3#) | | | 89,1 | 4- => 4- | 3.0e-10 ( 3#) | | | 90,1 | 4- => 4- | 2.5e-10 ( 3#) | | | 91,1 | 4- => 4- | 1.9e-10 ( 3#) | | | 92,1 | 4- => 4- | 1.3e-10 ( 3#) | | | 93,1 | 4- => 4- | 9.3e-11 ( 3#) | | | 94,1 | 4- => 4- | 6.5e-11 ( 3#) | | | 95,1 | 4- => 4- | 4.8e-11 ( 3#) | | | 96,1 | 4- => 4- | 3.9e-11 ( 3#) | | | 97,1 | 4- => 4- | 3.7e-11 ( 3#) | | | 98,1 | 4- => 4- | 4.3e-11 ( 3#) | | | 99,1 | 4- => 4- | 5.9e-11 ( 3#) | | | 100,1 | 4- => 4- | 9.7e-11 ( 3#) | | | 101,1 | 4- => 4- | 1.8e-10 ( 3#) | | | 102,1 | 4- => 4- | 3.9e-10 ( 3#) | | | 103,1 | 4- => 4- | 9.8e-10 ( 3#) | | | 104,1 | 4- => 4- | 3.0e-09 ( 3#) | | | 105,1 | 4- => 4- | 9.0e-16 ( 4#) | | | 106,1 | 4- => 4- | 2.9e-13 ( 4#) | | | 107,1 | 4- => 3+ | 2.5e-11 ( 5#) | => re-Cycle | | 2 | 3+ => 3+ | 1.5e-10 ( 4#) | | | 108,1 | 3+ => 3+ | 1.9e-10 ( 4#) | | | 109,1 | 3+ => 3+ | 4.3e-12 ( 4#) | | | 110,1 | 3+ => 3+ | 6.1e-15 ( 4#) | | | 111,1 | 3+ => 3+ | 9.7e-09 ( 3#) | | | 112,1 | 3+ => 3+ | 5.6e-09 ( 3#) | | | 113,1 | 3+ => 3+ | 3.2e-09 ( 3#) | | | 114,1 | 3+ => 3+ | 2.0e-09 ( 3#) | | | 115,1 | 3+ => 3+ | 6.7e-09 ( 3#) | | | 116,1 | 3+ => 3+ | 3.8e-15 ( 4#) | | | 117,1 | 3+ => 3+ | 6.1e-15 ( 4#) | | | 118,1 | 3+ => 3+ | 8.0e-09 ( 3#) | | | 119,1 | 3+ => 3+ | 4.2e-10 ( 3#) | | | 120,1 | 3+ => 3+ | 7.0e-10 ( 3#) | | | 121,1 | 3+ => 3+ | 5.9e-10 ( 3#) | | | 122,1 | 3+ => 3+ | 3.0e-10 ( 3#) | | | 123,1 | 3+ => 3+ | 1.3e-10 ( 3#) | | | 124,1 | 3+ => 3+ | 1.1e-10 ( 3#) | | | 125,1 | 3+ => 3+ | 2.6e-10 ( 3#) | | | 126,1 | 3+ => 3+ | 4.5e-10 ( 3#) | | | 127,1 | 3+ => 3+ | 5.5e-10 ( 3#) | | | 128,1 | 3+ => 3+ | 5.1e-10 ( 3#) | | | 129,1 | 3+ => 3+ | 7.0e-10 ( 3#) | | | 130,1 | 3+ => 3+ | 2.3e-09 ( 3#) | | | 131,1 | 3+ => 3+ | 7.3e-09 ( 3#) | | | 132,1 | 3+ => 3+ | 5.0e-15 ( 4#) | | | 133,1 | 3+ => 4- | 3.1e-13 ( 4#) |tol.Overshoot| | 134,1 | 4- => 4- | 3.5e-14 ( 4#) | | | 135,1 | 4- => 4- | 5.1e-09 ( 3#) | | | 136,1 | 4- => 4- | 1.9e-09 ( 3#) | | | 137,1 | 4- => 4- | 1.7e-09 ( 3#) | | | 138,1 | 4- => 4- | 1.6e-09 ( 3#) | | | 139,1 | 4- => 4- | 1.2e-09 ( 3#) | | | 140,1 | 4- => 4- | 8.9e-10 ( 3#) | | | 141,1 | 4- => 4- | 8.2e-10 ( 3#) | | | 142,1 | 4- => 4- | 1.0e-09 ( 3#) | | | 143,1 | 4- => 4- | 1.5e-09 ( 3#) | | | 144,1 | 4- => 4- | 2.8e-09 ( 3#) | | | 145,1 | 4- => 4- | 6.1e-09 ( 3#) | | | 146,1 | 4- => 3- | 6.8e-16 ( 4#) |tol.Overshoot| | 147,1 | 3- => 3- | 2.3e-10 ( 3#) | | | 148,1 | 3- => 3- | 8.2e-11 ( 3#) | | | 149,1 | 3- => 3- | 3.9e-11 ( 3#) | | | 150,1 | 3- => 3- | 2.7e-11 ( 3#) | | | 151,1 | 3- => 3- | 2.3e-11 ( 3#) | | | 152,1 | 3- => 3- | 2.1e-11 ( 3#) | | | 153,1 | 3- => 3- | 2.0e-11 ( 3#) | | | 154,1 | 3- => 3- | 2.1e-11 ( 3#) | | | 155,1 | 3- => 3- | 2.3e-11 ( 3#) | | | 156,1 | 3- => 3- | 2.8e-11 ( 3#) | | | 157,1 | 3- => 3- | 3.6e-11 ( 3#) | | | 158,1 | 3- => 3- | 4.8e-11 ( 3#) | | | 159,1 | 3- => 3- | 6.7e-11 ( 3#) | | | 160,1 | 3- => 3- | 9.4e-11 ( 3#) | | | 161,1 | 3- => 3- | 1.4e-10 ( 3#) | | | 162,1 | 3- => 3- | 1.9e-10 ( 3#) | | | 163,1 | 3- => 3- | 2.5e-10 ( 3#) | | .. GENERATED FROM PYTHON SOURCE LINES 141-143 To visualize the deformed state of the model for increment 40 the deformed model plot is generated. .. GENERATED FROM PYTHON SOURCE LINES 143-163 .. code-block:: Python field[0].values.ravel()[dof1] = X[40, :-1] force = solid.evaluate.gradient(field) * solid.area plotter = field.view(cell_data={"Force": force}).plot( "Force", line_width=10, show_undeformed=False, view="xy", cmap="coolwarm", clim=[-abs(force).max(), abs(force).max()], render_lines_as_tubes=True, show_edges=False, ) plotter.add_points( mesh.points + field[0].values, color="black", point_size=20, render_points_as_spheres=True, ) plotter.show() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_002.png :alt: ex21 nonlinear truss analysis :srcset: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_002.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: /home/docs/checkouts/readthedocs.org/user_builds/felupe/checkouts/stable/docs/examples/images/sphx_glr_ex21_nonlinear-truss-analysis_002.vtksz .. GENERATED FROM PYTHON SOURCE LINES 164-169 Path-tracing of the displacement-LPF curves ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The path-tracing of the deformation process is shown as a History Plot of Displacement-LPF curves for all active DOF. Strong geometrical nonlinearities are observed for all active DOF. .. GENERATED FROM PYTHON SOURCE LINES 169-176 .. code-block:: Python fig, ax = plt.subplots() ax.plot(*X[:, [0, -1]].T, ".-", label="Point 3") ax.plot(*X[:, [3, -1]].T, ".-", label="Point 4") ax.set_xlabel("Displacement X") ax.set_ylabel("LPF") ax.legend() .. image-sg:: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_003.png :alt: ex21 nonlinear truss analysis :srcset: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 177-183 .. code-block:: Python fig, ax = plt.subplots() ax.plot(*X[:, [1, -1]].T, ".-", label="Point 3") ax.set_xlabel("Displacement Y") ax.set_ylabel("LPF") ax.legend() .. image-sg:: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_004.png :alt: ex21 nonlinear truss analysis :srcset: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 184-190 .. code-block:: Python fig, ax = plt.subplots() ax.plot(*X[:, [2, -1]].T, ".-", label="Point 3") ax.plot(*X[:, [4, -1]].T, ".-", label="Point 4") ax.set_xlabel("Displacement Z") ax.set_ylabel("LPF") ax.legend() .. image-sg:: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_005.png :alt: ex21 nonlinear truss analysis :srcset: /examples/images/sphx_glr_ex21_nonlinear-truss-analysis_005.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 3.543 seconds) .. _sphx_glr_download_examples_ex21_nonlinear-truss-analysis.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: ex21_nonlinear-truss-analysis.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: ex21_nonlinear-truss-analysis.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: ex21_nonlinear-truss-analysis.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_