Quadrature schemes#

Objectives

This code snippet shows the location of the quadrature points for different degrees, cell types and quadrature rules both in 2D and 3D.

Download sources

2D Quadrature rule#

import matplotlib.pyplot as plt
import numpy as np
import basix
from basix import CellType, QuadratureType

all_cell_types = [CellType.triangle, CellType.quadrilateral]
degrees = range(5)
quad_rules = {
    QuadratureType.default: (degrees, all_cell_types),
    QuadratureType.gauss_jacobi: (degrees, all_cell_types),
    QuadratureType.gll: (degrees, [CellType.quadrilateral]),
    QuadratureType.xiao_gimbutas: (degrees[1:], [CellType.triangle]),
}

Hide code cell source

def plot_quad_points_2D(rule, cell_type, deg, color, ax):
    points, weights = basix.make_quadrature(cell_type, deg, rule=rule)

    vertices = basix.geometry(cell_type)
    facets = basix.cell.sub_entity_connectivity(cell_type)[1]

    for f in facets:
        vert = vertices[f[0], :]
        ax.plot(vert[:, 0], vert[:, 1], "k")

    ax.scatter(points[:, 0], points[:, 1], 500 * weights, color=color)
    ax.set_aspect("equal")


def plot_quadrature_rule_2D(rule, color="C0"):
    degs, cell_types = quad_rules[rule]
    for deg in degs:
        plt.figure()
        for i, cell_type in enumerate(cell_types):
            no_subplot = len(cell_types) < 2
            if no_subplot:
                ax = plt.gca()
            else:
                ax = plt.subplot(1, 2, i + 1)
            ax.margins(0.05)

            plot_quad_points_2D(rule, cell_type, deg, color, ax)
        if no_subplot:
            plt.title(f"{rule.name} rule, degree $d={deg}$")
        else:
            plt.suptitle(f"{rule.name} rule, degree $d={deg}$", y=0.8)
        plt.show()

Default quadrature rule#

plot_quadrature_rule_2D(QuadratureType.default, color="C3")
../../_images/9dfb39649049578eb282f3c773f39c0edbbcfa05bb6b19725b1ef4680a31b236.png ../../_images/90dc01f225727d711be417128397863ec61db7842d20742b0ff7f600490cc286.png ../../_images/914761134a036f7af5adc1d223ef91104effcab3ffc468b62898a6280a022ee7.png ../../_images/51bf6cc7833369ef060e1cc3232402b0d909fbcb9150228dd39adff669a179f4.png ../../_images/44239c7eae65aa09fcb8b03515762f15b27b23774127bf8b4db4155fe4d29d51.png

Gauss-Jacobi quadrature rule#

plot_quadrature_rule_2D(QuadratureType.gauss_jacobi, color="C2")
../../_images/9254e8ef22a0b1ce617e82210d50e951aab94ab95130c0dbcb0248e6ae0f4a5e.png ../../_images/e43fda017c5fd139f15f9120e3e1d4a27327ff4d13b38b6bb1c3d48a2e8abbc5.png ../../_images/a7bf57854453b0f895cde12816ccce85501da4d837a17d2fc67d84b109f44dca.png ../../_images/6ecf5eedfccca4c4a5892ef8f5926371ddc4bdbd5e25fc78651ca3ca362e72b1.png ../../_images/a6d69bd3811259deb2d46e370ff88ecd93713f43d63d2bdde70f639577b3edf6.png

Gauss-Legendre-Lobatto quadrature rule#

plot_quadrature_rule_2D(QuadratureType.gll, color="C1")
../../_images/fc20664e29df45b99a106fd6e85c2474a7bbd67242d9756ba4fbf091f747c10b.png ../../_images/68d4f6df4ea4bedfb730ff45cfcab327fc7c0887aef6bf568b3c5c8d4dc37ea8.png ../../_images/bfe8afa5c9747b34181b5de2084e7d5e94f80ada4a7482645857635ac1123bd7.png ../../_images/7c6765901b9e9e5aa952880be0da635b0f8d43ac1333ece5a0885e4ad1293b05.png ../../_images/6c3bad85a6db9026a69d7cc07bf325acc08c87ef95c246484f8ee77eb3cc90b9.png

Xiao-Gimbutas quadrature rule#

plot_quadrature_rule_2D(QuadratureType.xiao_gimbutas, color="C0")
../../_images/b81b2f17f24b8c090ec00c5cebf5712aea21b02dfce6248b696f1458bf15d9a8.png ../../_images/17204fa653bc9b2da2a879c6e894ff9242eef451cbab9fb4598fc6a70e2175ab.png ../../_images/916eb43949578793fb3e99ce67fded270796246c6c915a01100c62c17ab910c1.png ../../_images/666295fcff7e4df83d98a2bc4f9bee3e7453c1fcc1a4d85a78c74830cf722141.png

3D rules#

cell_type = CellType.hexahedron
dim = 3
deg = 2

from dolfinx import cpp, mesh
import pyvista as pv
from matplotlib.colors import to_hex

pv.set_jupyter_backend("static")

all_cell_types = [CellType.tetrahedron, CellType.hexahedron]
degrees = range(5)
quad_rules = {
    QuadratureType.default: (degrees, all_cell_types),
    QuadratureType.gauss_jacobi: (degrees, all_cell_types),
    QuadratureType.gll: (degrees, [CellType.hexahedron]),
    QuadratureType.xiao_gimbutas: (degrees[1:], [CellType.tetrahedron]),
}

Hide code cell source

def plot_quad_points_3D(rule, cell_type, deg, color, plotter):
    points, weights = basix.make_quadrature(cell_type, deg, rule=rule)

    vertices = basix.geometry(cell_type)
    facets = basix.cell.sub_entity_connectivity(cell_type)

    num_nodes_per_cell = len(facets[dim - 1][0][0])

    subentity_cell_type = {
        CellType.tetrahedron: mesh.CellType.triangle,
        CellType.hexahedron: mesh.CellType.quadrilateral,
    }
    map_vtk = np.argsort(
        cpp.io.perm_vtk(subentity_cell_type[cell_type], num_nodes_per_cell)
    )

    faces = [[f[0][m] for m in map_vtk] for f in facets[dim - 1]]

    cell = pv.PolyData.from_regular_faces(vertices, faces)

    # Add the mesh to the plotter
    plotter.add_mesh(cell, color="gray", opacity=0.4, show_edges=True)

    point_cloud = pv.PolyData(points)
    point_cloud["weights"] = np.abs(weights) ** 0.33 * 0.25
    glyphs = point_cloud.glyph(scale="weights", geom=pv.Sphere(), orient=False)
    plotter.add_mesh(glyphs, color=to_hex(color))
    plotter.camera.azimuth = 10.0
    plotter.camera.elevation = -30.0


def plot_quadrature_rule_3D(rule, color="C0"):
    degs, cell_types = quad_rules[rule]
    for deg in degs:
        for i, cell_type in enumerate(cell_types):
            no_subplot = len(cell_types) < 2
            # Create a PyVista plotter
            if no_subplot:
                plotter = pv.Plotter()
                plotter.window_size = (400, 400)
                plotter.add_title(rf"{rule.name} rule, degree d={deg}", font_size=10)
            else:
                if i == 0:
                    plotter = pv.Plotter(shape=(1, 2))
                    plotter.window_size = (800, 400)
                plotter.subplot(0, i)
                plotter.add_title(rf"{rule.name} rule, degree d={deg}", font_size=10)

            plot_quad_points_3D(rule, cell_type, deg, color, plotter)

        plotter.show()

Default quadrature rule#

plot_quadrature_rule_3D(QuadratureType.default, "C3")
../../_images/6e254dd2ddf2d1b3b8a74cc852fc298e447a9c581581646feb3317060261f243.png ../../_images/3ff82925668f2925966d0e46288f5eaeb3b821088e3d7512a10486503da3d967.png ../../_images/776717e75319ff197988e6df64a819e7ac0ac94f28b7c3d70bffc19aa86f67a9.png ../../_images/75bbc9e7c1c89fb83fccf8af997fd65880658bee7fa967afcedb8949fe5f7978.png ../../_images/1e8023dff437cb6e699dcca1ea78a76eb1fc3f14457cc18c59e88c02317f9288.png

Gauss-Jacobi quadrature rule#

plot_quadrature_rule_3D(QuadratureType.gauss_jacobi, "C2")
../../_images/e1a956aca65393e0731b79ca38f34948d54678e33c7ed090409332a52bc71acf.png ../../_images/f7eccc9eb92b5e15215b68d22acf1b750467f713f0a2ee42cb7c9414aa384e4d.png ../../_images/c23506aa2a679177c04aae98aa735dbdecf59e2e6f3f8c3d628004931112bd19.png ../../_images/fd71e4703929036c3218da4fec86878065c44fec9de1e3cdd9de3b4feaabca7b.png ../../_images/fda03decca041612318e83b238d045857ac7a8361f695b15dc29ca43d96cd745.png

Gauss-Legendre-Lobatto quadrature rule#

plot_quadrature_rule_3D(QuadratureType.gll, "C1")
../../_images/42bbe4e39ee32e587c3d78f9b68c3df98453a8754bc42b30bcdc56ffdee10292.png ../../_images/b0b5083879e3971b451ddbc125c4007fb871c459b6e8d19c476ba7ef46a1383e.png ../../_images/114dcffd0636200e4e7a47586b3eb272f81dff63f1f7a09f7200c0b70460ae9d.png ../../_images/90d47475d1b96700b8c27f09ba53f3ee13cb003c39d214924b492aed2c4d054d.png ../../_images/f3bfe425c27beb92b19de725fec946d7edf8884b98602157c419b31e1f6c97cf.png

Xiao-Gimbutas quadrature rule#

plot_quadrature_rule_3D(QuadratureType.xiao_gimbutas, "C0")
../../_images/b037f91b82e991c410a3075f847601c0a6286a20082907efe626d334560d4ff8.png ../../_images/5388531612afc8ae77c6be5611f3a0f7fb94a52e5999de3f652f5074336a6fd4.png ../../_images/c485302cd6897dac27f31e5cb799a4b3c7b482271e96faaec043fb836a523d28.png ../../_images/c99999b5a9a9146242cc6edcc7714569f15706df63b189e658215ace0f6e1b10.png