Source code for felupe.quadrature._tetra

# -*- coding: utf-8 -*-
"""
This file is part of FElupe.

FElupe is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

FElupe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with FElupe.  If not, see <http://www.gnu.org/licenses/>.
"""

from types import SimpleNamespace

import numpy as np

from ._scheme import Scheme


[docs] class Tetrahedron(Scheme): r"""A quadrature scheme suitable for Tetrahedrons of order 1, 2 or 3 on the interval :math:`[0, 1]`. Parameters ---------- order : int The order of the quadrature scheme. Notes ----- The approximation is given by .. math:: \int_V f(x) dV \approx \sum f(x_q) w_q with quadrature points :math:`x_q` and corresponding weights :math:`w_q` [1]_. Examples -------- .. pyvista-plot:: :force_static: >>> import felupe as fem >>> >>> element = fem.Tetra() >>> quadrature = fem.TetrahedronQuadrature(order=1) >>> quadrature.plot( ... plotter=element.plot(add_point_labels=False, show_points=False), ... weighted=True, ... ).show() .. pyvista-plot:: :force_static: >>> import felupe as fem >>> >>> element = fem.QuadraticTetra() >>> quadrature = fem.TetrahedronQuadrature(order=2) >>> quadrature.plot( ... plotter=element.plot(add_point_labels=False, show_points=False), ... weighted=True, ... ).show() .. pyvista-plot:: :force_static: >>> import felupe as fem >>> >>> element = fem.QuadraticTetra() >>> quadrature = fem.TetrahedronQuadrature(order=5) >>> quadrature.plot( ... plotter=element.plot(add_point_labels=False, show_points=False), ... weighted=True, ... ).show() References ---------- .. [1] O. C. Zienkiewicz, R. L. Taylor and J. Z. Zhu, The Finite Element Method: Its Basis and Fundamentals, 7th ed., Elsevier, 2013. """ def __init__(self, order: int): scheme = SimpleNamespace() if order == 1: scheme.points = np.ones((1, 3)) / 4 scheme.weights = np.ones(1) / 6 elif order == 2: a = 0.13819660 b = 0.58541020 scheme.points = np.array([[a, a, a], [b, a, a], [a, b, a], [a, a, b]]) scheme.weights = np.ones(4) / 24 elif order == 3: a = 1 / 6 b = 1 / 2 c = 1 / 4 d = 9 / 120 scheme.points = np.array( [[a, a, a], [b, a, a], [a, b, a], [b, b, a], [c, c, c]] ) scheme.weights = np.array([d, d, d, d, -4 / 30]) elif order == 5: a = 1 / 2 b = 0.6984197043243866 c = 0.1005267652252045 d = 0.0568813795204234 e = 0.31437287349319221 f = 0.019047619047619 g = 0.0885898247429807 h = 0.1328387466855907 scheme.points = np.array( [ [0, a, a, a, 0, 0, b, c, c, c, d, e, e, e], [a, 0, a, 0, a, 0, c, c, c, b, e, e, e, d], [a, a, 0, 0, 0, a, c, c, b, c, e, e, d, e], ] ).T scheme.weights = np.array([f, f, f, f, f, f, g, g, g, g, h, h, h, h]) / 6 else: raise NotImplementedError("order must be either 1, 2, 3 or 5.") super().__init__(scheme.points, scheme.weights)