@@ -1609,6 +1609,76 @@ def compute_finite_difference(self, data, schema=1, mode="reflect", vertical=Fal
1609
1609
def compute_stencil (
1610
1610
self , data , stencil_halfwidth = 4 , mode = "reflect" , vertical = False
1611
1611
):
1612
+ r"""
1613
+ Apply stencil ponderation on field.
1614
+
1615
+ :param array data: array where apply stencil
1616
+ :param int stencil_halfwidth: from 1 t0 4, maximal stencil used
1617
+ :param str mode: convolution mode
1618
+ :param bool vertical: if True, method apply a vertical convolution
1619
+ :return: gradient array from stencil application
1620
+ :rtype: array
1621
+
1622
+ Short story, how to get stencil coefficient for stencil (3 points, 5 points and 7 points)
1623
+
1624
+ Taylor's theorem:
1625
+
1626
+ .. math::
1627
+ f(x \pm h) = f(x) \pm f'(x)h
1628
+ + \frac{f''(x)h^2}{2!} \pm \frac{f^{(3)}(x)h^3}{3!}
1629
+ + \frac{f^{(4)}(x)h^4}{4!} \pm \frac{f^{(5)}(x)h^5}{5!}
1630
+ + O(h^6)
1631
+
1632
+ If we stop at `O(h^2)`, we get classic differenciation (stencil 3 points):
1633
+
1634
+ .. math:: f(x+h) - f(x-h) = f(x) - f(x) + 2 f'(x)h + O(h^2)
1635
+
1636
+ .. math:: f'(x) = \frac{f(x+h) - f(x-h)}{2h} + O(h^2)
1637
+
1638
+ If we stop at `O(h^4)`, we will get stencil 5 points:
1639
+
1640
+ .. math::
1641
+ f(x+h) - f(x-h) = 2 f'(x)h + 2 \frac{f^{(3)}(x)h^3}{3!} + O(h^4)
1642
+ :label: E1
1643
+
1644
+ .. math::
1645
+ f(x+2h) - f(x-2h) = 4 f'(x)h + 16 \frac{f^{(3)}(x)h^3}{3!} + O(h^4)
1646
+ :label: E2
1647
+
1648
+ If we multiply equation :eq:`E1` by 8 and substract equation :eq:`E2`, we get:
1649
+
1650
+ .. math:: 8(f(x+h) - f(x-h)) - (f(x+2h) - f(x-2h)) = 16 f'(x)h - 4 f'(x)h + O(h^4)
1651
+
1652
+ .. math:: f'(x) = \frac{f(x-2h) - 8f(x-h) + 8f(x+h) - f(x+2h)}{12h} + O(h^4)
1653
+
1654
+ If we stop at `O(h^6)`, we will get stencil 7 points:
1655
+
1656
+ .. math::
1657
+ f(x+h) - f(x-h) = 2 f'(x)h + 2 \frac{f^{(3)}(x)h^3}{3!} + 2 \frac{f^{(5)}(x)h^5}{5!} + O(h^6)
1658
+ :label: E3
1659
+
1660
+ .. math::
1661
+ f(x+2h) - f(x-2h) = 4 f'(x)h + 16 \frac{f^{(3)}(x)h^3}{3!} + 64 \frac{f^{(5)}(x)h^5}{5!} + O(h^6)
1662
+ :label: E4
1663
+
1664
+ .. math::
1665
+ f(x+3h) - f(x-3h) = 6 f'(x)h + 54 \frac{f^{(3)}(x)h^3}{3!} + 486 \frac{f^{(5)}(x)h^5}{5!} + O(h^6)
1666
+ :label: E5
1667
+
1668
+ If we multiply equation :eq:`E3` by 45 and substract equation :eq:`E4` multiply by 9
1669
+ and add equation :eq:`E5`, we get:
1670
+
1671
+ .. math::
1672
+ 45(f(x+h) - f(x-h)) - 9(f(x+2h) - f(x-2h)) + (f(x+3h) - f(x-3h)) =
1673
+ 90 f'(x)h - 36 f'(x)h + 6 f'(x)h + O(h^6)
1674
+
1675
+ .. math::
1676
+ f'(x) = \frac{-f(x-3h) + 9f(x-2h) - 45f(x-h) + 45f(x+h) - 9f(x+2h) +f(x+3h)}{60h} + O(h^6)
1677
+
1678
+ ...
1679
+
1680
+
1681
+ """
1612
1682
stencil_halfwidth = max (min (int (stencil_halfwidth ), 4 ), 1 )
1613
1683
logger .debug ("Stencil half width apply : %d" , stencil_halfwidth )
1614
1684
# output
@@ -1739,7 +1809,7 @@ def add_uv(self, grid_height, uname="u", vname="v", stencil_halfwidth=4):
1739
1809
:param str grid_height: grid name where the funtion will apply stencil method
1740
1810
:param str uname: future name of u
1741
1811
:param str vname: future name of v
1742
- :param int stencil_halfwidth: largest stencil could be apply
1812
+ :param int stencil_halfwidth: largest stencil could be apply (max: 4)
1743
1813
1744
1814
.. minigallery:: py_eddy_tracker.RegularGridDataset.add_uv
1745
1815
"""
0 commit comments