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/4b63f344d1f6b06fc4ce87619c245c0d794367226b80566930bf96a2eb332972.png ../../_images/563e968d92d4b857daa11989b42244cc769c56feea7a45a311fc277f6c1a371e.png ../../_images/7710490499c070a7cb4e25c190919eeb218a31b88194636894a1a27d72fa9ea4.png ../../_images/96b41093cc6bc6b159dfa59ba5ba172f9275a77628628d71b20b5cec07578e4b.png ../../_images/b8cbff56d2c159f32e10a0e109d3bbabc75ec62ec53ddc3eca8aeb24d1f5c947.png

Gauss-Jacobi quadrature rule#

plot_quadrature_rule_2D(QuadratureType.gauss_jacobi, color="C2")
../../_images/4250e0f77d65e0eeadc0d3e849f562854de56abfa9afd12b0efa67f10e930252.png ../../_images/abcd94f9b1b3fbc9fc970452059fcddab4a4f57fc761bb42b5a08f09a64d6f79.png ../../_images/dbcfc58d7698e1a176015dd0a6dd3d18cb09b2c4d7e7696cf99116259a9d25e4.png ../../_images/f8253b434ec948ee1423d488e177edc3eceb6bf0999a9d968f7692785f2c0290.png ../../_images/d27f08eeb142598b14fae775b085b930354cad141275bd45f555279c7d3cad7e.png

Gauss-Legendre-Lobatto quadrature rule#

plot_quadrature_rule_2D(QuadratureType.gll, color="C1")
../../_images/ad3005dad51bdb1408faf3ddd40fc2da4fec68b289b7e71c7623d0318cac258d.png ../../_images/d279e0fde72f27d093ea7d23df3398d18a38c0c370fc717b0aec1bc5dbe3a24c.png ../../_images/81c2bc3d70b0c71243e22fc862de234252ef325d53fe76c049419720fc3d8a49.png ../../_images/2aa069b86e56058931ef364e5543c5b35aa6a96ffbca6a369288f9d1adc0aa44.png ../../_images/3583acb8b180a4da2e90705ff7ac3c3f444abe3344412c797053a56fda48b1fb.png

Xiao-Gimbutas quadrature rule#

plot_quadrature_rule_2D(QuadratureType.xiao_gimbutas, color="C0")
../../_images/0f706c4d570fb9a4f0e4f9e529fce1e32551071687bf9b42f845e82bb1e5a7c2.png ../../_images/54fc46b6479cd8b810935dd1a41de2d04785ad4be36a2fb32460b610529e1aca.png ../../_images/158a378440b90c6b9a5110233aa266dd56af9310a8955c8285a97bfd2b9c70ed.png ../../_images/e93655a28ce78d64b3c8eaa4d222d259f6eb69a871bf5a401329fb411224863e.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/6a23341c925457400f116558bf40f1484def05dc76476f29907e2ccbb19fd381.png ../../_images/1d939a9ea7a5443494485ad541d52be902a25c777ca3c2e57fb701877b6f505f.png ../../_images/daa2f884c2d26b797521d3d4914360d4c7bb6cbbcc9e1ac33bd5dc8603efeb2d.png ../../_images/8a0cecd2fd502073ee2d9029cc2f6bbf0b2c8c1c25a36d64c600b6cdd653d5d2.png ../../_images/57f4bb3a5fd3d6a90174754f48b7018ff8aaa0e156675b0f496655a70cbabe1c.png

Gauss-Jacobi quadrature rule#

plot_quadrature_rule_3D(QuadratureType.gauss_jacobi, "C2")
../../_images/3a77c786b706069d17dd08a60bea38ed1e788c86109cf5aead781ac68bc2d1fc.png ../../_images/0b8afc4476eab3a0d7dc90484597f3db946ff0a9e66affff1cfa0132d111bcb8.png ../../_images/d938027c88665b8879c05ce4b28eda3922eb28029633a98c07948949b3ea6ee6.png ../../_images/56620153c30de41fe92fc837d13fe031ae3b4e9505dd4605410511be5f742ce5.png ../../_images/64ef4d00999bc9f3912e9e798d7ecc415500f89fd851f8721106cbcfe0e6b5cf.png

Gauss-Legendre-Lobatto quadrature rule#

plot_quadrature_rule_3D(QuadratureType.gll, "C1")
../../_images/1642be917148615ee681c13f682c1fc202d64679c4c7dfa16bbad9576c771463.png ../../_images/97f0ae4f1ebf604687246cc95dfd206339068641a9a9919d4fffda1605bfecfa.png ../../_images/eb79a25d431da0810af06a329de663bb1026f8875144e1384c3ad819b465d44d.png ../../_images/ed18f0389088361af16d3b7634fd7684ad84d49e373f7552bda8f4896bc0bbce.png ../../_images/061746172f2dc05cfccbac43971929436e91220b63289786ce5bae3a27d6c98d.png

Xiao-Gimbutas quadrature rule#

plot_quadrature_rule_3D(QuadratureType.xiao_gimbutas, "C0")
../../_images/b7090f38ffed3d979d628c4de1b96f0327a7ef0005d239771c2591e2a40932bd.png ../../_images/97e749a8cfb82f17410f7cbb4a83c83ef2f003c8b60308982b6d8fb9803b35fd.png ../../_images/6b7f3dd7ff69a0c0e8813faaca880edfa24d1c607b1a1517384c7a6e2f54682b.png ../../_images/c835289d713d5eb02cfdcafa20a486e30b043be951783fc6e54519ef37370bb9.png