Source code for felupe.quadrature._sphere

# -*- 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/>.
"""

import numpy as np

from ._scheme import Scheme


[docs] class BazantOh(Scheme): r"""Quadrature scheme for a numeric integration of the surface of a unit sphere [1]_. Parameters ---------- n : int, optional The number of quadrature points (default is 21). Notes ----- The approximation is given by .. math:: \int_{\partial V} f(x) dA \approx \sum f(x_q) w_q with quadrature points :math:`x_q` and corresponding weights :math:`w_q`. Examples -------- .. pyvista-plot:: :force_static: >>> import felupe as fem >>> import pyvista as pv >>> >>> quadrature = fem.BazantOh(n=21) >>> >>> plotter = quadrature.plot(weighted=True) >>> sphere = pv.Sphere(radius=1).clip(normal="z", invert=False) >>> actor = plotter.add_mesh(sphere, opacity=0.3, color="white") >>> plotter.show() References ---------- .. [1] Bazant, Z. P., & Oh, B. H. (1986). Efficient Numerical Integration on the Surface of a Sphere. ZAMM ‐ Journal of Applied Mathematics and Mechanics / Zeitschrift für Angewandte Mathematik und Mechanik, 66(1), 37-49. https://doi.org/10.1002/zamm.19860660108 """ def __init__(self, n: int = 21): schemes = { 21: self._scheme_21, } points, weights = schemes[n]() super().__init__(points=points, weights=weights) def _scheme_21(self): "2x21-point scheme (degree 9, orthogonal symmetries)." a = np.sqrt(2) / 2 b = 0.836095596749 c = 0.387907304067 points = np.array( [ [0, 0, 1], [0, 1, 0], [1, 0, 0], [0, a, a], [0, -a, a], [a, 0, a], [-a, 0, a], [a, a, 0], [-a, a, 0], [b, c, c], [-b, c, c], [b, -c, c], [-b, -c, c], [c, b, c], [-c, b, c], [c, -b, c], [-c, -b, c], [c, c, b], [-c, c, b], [c, -c, b], [-c, -c, b], ] ) w1 = 0.0265214244093 w2 = 0.0199301476312 w3 = 0.0250712367487 weights = 2 * np.concatenate( [np.repeat(w1, 3), np.repeat(w2, 6), np.repeat(w3, 12)] ) return points, weights