.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/elements/plane182/example_quad4_shape_functions.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_gallery_elements_plane182_example_quad4_shape_functions.py: QUAD4 bilinear shape functions on the reference square ====================================================== Renders the four bilinear (4-node) shape functions :math:`N_i(\xi, \eta)` on the reference quadrilateral :math:`\hat\Omega = [-1, +1]^2`: .. math:: N_i(\xi, \eta) = \tfrac{1}{4}(1 + \xi_i\xi)(1 + \eta_i\eta), \qquad i = 1, \dots, 4, with corner-node signs :math:`(\xi_i, \eta_i) \in \{-1, +1\}^2`. Each function equals 1 at its own node and 0 at every other node — the Kronecker-delta property at the heart of standard Lagrange interpolation. The four basis functions sum to 1 everywhere on the square (partition of unity), so any constant or linear field is reproduced exactly. References ---------- * Cook, R. D., Malkus, D. S., Plesha, M. E., Witt, R. J. (2002) *Concepts and Applications of Finite Element Analysis*, 4th ed., Wiley, §6.3 (4-node quad), Table 6.3-1. * Hughes, T. J. R. (2000) *The Finite Element Method — Linear Static and Dynamic Finite Element Analysis*, Dover, §3.5 + §3.6. * Zienkiewicz, O. C., Taylor, R. L. (2013) *The Finite Element Method: Its Basis and Fundamentals*, 7th ed., §6.4. Implementation: :class:`femorph_solver.elements.quad4_plane.Quad4Plane`. .. GENERATED FROM PYTHON SOURCE LINES 35-41 .. code-block:: Python from __future__ import annotations import matplotlib.pyplot as plt import numpy as np .. GENERATED FROM PYTHON SOURCE LINES 42-43 Corner signs in VTK_QUAD order: (-1,-1), (+1,-1), (+1,+1), (-1,+1). .. GENERATED FROM PYTHON SOURCE LINES 43-56 .. code-block:: Python corner_signs = np.array( [[-1, -1], [+1, -1], [+1, +1], [-1, +1]], dtype=float, ) def n_corner(xi, eta, signs): """Bilinear corner shape function for a given (xi_i, eta_i).""" xi_i, eta_i = signs return 0.25 * (1 + xi_i * xi) * (1 + eta_i * eta) .. GENERATED FROM PYTHON SOURCE LINES 57-58 Sample the reference square on a (xi, eta) grid .. GENERATED FROM PYTHON SOURCE LINES 58-62 .. code-block:: Python n = 81 xi_grid, eta_grid = np.meshgrid(np.linspace(-1, 1, n), np.linspace(-1, 1, n), indexing="ij") .. GENERATED FROM PYTHON SOURCE LINES 63-64 Render — 2×2 grid of contour plots, one per corner. .. GENERATED FROM PYTHON SOURCE LINES 64-95 .. code-block:: Python fig, axes = plt.subplots(2, 2, figsize=(9, 7), constrained_layout=True) fig.suptitle( "QUAD4 bilinear shape functions on $\\hat\\Omega = [-1, +1]^2$", fontsize=13, ) for idx, signs in enumerate(corner_signs): row, col = divmod(idx, 2) ax = axes[row, col] N = n_corner(xi_grid, eta_grid, signs) img = ax.contourf(xi_grid, eta_grid, N, levels=21, cmap="plasma") ax.contour( xi_grid, eta_grid, N, levels=[0.0, 0.25, 0.5, 0.75, 1.0], colors="black", linewidths=0.4, ) sx, sy = signs.astype(int) ax.scatter(corner_signs[:, 0], corner_signs[:, 1], s=30, color="black", zorder=5) ax.scatter([sx], [sy], s=110, edgecolor="black", facecolor="white", zorder=6) ax.set_aspect("equal") ax.set_title(f"$N_{{{idx + 1}}}$ $(\\xi_i, \\eta_i) = ({sx:+d}, {sy:+d})$", fontsize=11) ax.set_xlabel(r"$\xi$") ax.set_ylabel(r"$\eta$") fig.colorbar(img, ax=ax, shrink=0.85) fig.show() .. image-sg:: /gallery/elements/plane182/images/sphx_glr_example_quad4_shape_functions_001.png :alt: QUAD4 bilinear shape functions on $\hat\Omega = [-1, +1]^2$, $N_{1}$ $(\xi_i, \eta_i) = (-1, -1)$, $N_{2}$ $(\xi_i, \eta_i) = (+1, -1)$, $N_{3}$ $(\xi_i, \eta_i) = (+1, +1)$, $N_{4}$ $(\xi_i, \eta_i) = (-1, +1)$ :srcset: /gallery/elements/plane182/images/sphx_glr_example_quad4_shape_functions_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 96-97 Verify partition of unity at every reference-element node. .. GENERATED FROM PYTHON SOURCE LINES 97-102 .. code-block:: Python total = sum(n_corner(corner_signs[:, 0], corner_signs[:, 1], s) for s in corner_signs) np.testing.assert_allclose(total, 1.0, atol=1e-14) print("OK — QUAD4 partition-of-unity holds at every corner node.") .. rst-class:: sphx-glr-script-out .. code-block:: none OK — QUAD4 partition-of-unity holds at every corner node. .. GENERATED FROM PYTHON SOURCE LINES 103-104 Verify Kronecker-delta interpolation at every reference-element node. .. GENERATED FROM PYTHON SOURCE LINES 104-112 .. code-block:: Python basis = np.zeros((4, 4)) for k, (xi_k, eta_k) in enumerate(corner_signs): for i, signs in enumerate(corner_signs): basis[k, i] = n_corner(xi_k, eta_k, signs) np.testing.assert_allclose(basis, np.eye(4), atol=1e-14) print("OK — QUAD4 Kronecker-delta interpolation verified at every node.") .. rst-class:: sphx-glr-script-out .. code-block:: none OK — QUAD4 Kronecker-delta interpolation verified at every node. .. GENERATED FROM PYTHON SOURCE LINES 113-114 Verify partition of unity on a dense interior grid as well. .. GENERATED FROM PYTHON SOURCE LINES 114-118 .. code-block:: Python dense_total = sum(n_corner(xi_grid, eta_grid, s) for s in corner_signs) np.testing.assert_allclose(dense_total, 1.0, atol=1e-14) print("OK — QUAD4 partition-of-unity holds across the full reference square.") .. rst-class:: sphx-glr-script-out .. code-block:: none OK — QUAD4 partition-of-unity holds across the full reference square. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.651 seconds) .. _sphx_glr_download_gallery_elements_plane182_example_quad4_shape_functions.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_quad4_shape_functions.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_quad4_shape_functions.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_quad4_shape_functions.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_