Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: add support for 45 degree FD approx #2326

Merged
merged 9 commits into from
Mar 12, 2024
Merged

api: add support for 45 degree FD approx #2326

merged 9 commits into from
Mar 12, 2024

Conversation

mloubout
Copy link
Contributor

@mloubout mloubout commented Mar 5, 2024

Add suppport for 45 degree derivatives (usually called RSFD). This only supports cases where the diagonal (45 degree axis) aligns with points at which the fields is defined.

@mloubout mloubout added the API api (symbolics, types, ...) label Mar 5, 2024
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@mloubout mloubout force-pushed the stagg-fd-custom branch 2 times, most recently from 9d81997 to 3ed3e19 Compare March 5, 2024 03:29
Copy link

codecov bot commented Mar 5, 2024

Codecov Report

Attention: Patch coverage is 92.85714% with 16 lines in your changes are missing coverage. Please review.

Project coverage is 86.67%. Comparing base (f29cb35) to head (47be3e1).

Files Patch % Lines
devito/finite_differences/tools.py 69.23% 7 Missing and 1 partial ⚠️
devito/finite_differences/operators.py 71.42% 4 Missing ⚠️
devito/finite_differences/differentiable.py 81.81% 1 Missing and 1 partial ⚠️
devito/finite_differences/rsfd.py 96.22% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2326      +/-   ##
==========================================
+ Coverage   86.66%   86.67%   +0.01%     
==========================================
  Files         231      232       +1     
  Lines       43260    43409     +149     
  Branches     8022     8057      +35     
==========================================
+ Hits        37490    37626     +136     
- Misses       5068     5079      +11     
- Partials      702      704       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@FabioLuporini FabioLuporini self-requested a review March 5, 2024 03:35
devito/finite_differences/derivative.py Outdated Show resolved Hide resolved
@@ -210,7 +215,7 @@ def _new_from_self(self, **kwargs):
expr = kwargs.pop('expr', self.expr)
_kwargs = {'deriv_order': self.deriv_order, 'fd_order': self.fd_order,
'side': self.side, 'transpose': self.transpose, 'subs': self._ppsubs,
'x0': self.x0, 'preprocessed': True}
'x0': self.x0, 'preprocessed': True, 'method': self.method}
_kwargs.update(**kwargs)
return Derivative(expr, *self.dims, **_kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one day... we should just make use of .rebuild(...). Perhaps worth adding an issue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memo (add issue?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devito/finite_differences/derivative.py Show resolved Hide resolved
devito/finite_differences/derivative.py Show resolved Hide resolved
devito/finite_differences/derivative.py Outdated Show resolved Hide resolved
devito/types/dense.py Show resolved Hide resolved
devito/types/dense.py Outdated Show resolved Hide resolved
devito/types/dense.py Outdated Show resolved Hide resolved
devito/finite_differences/rsfd.py Outdated Show resolved Hide resolved
devito/finite_differences/rsfd.py Outdated Show resolved Hide resolved
@mloubout mloubout force-pushed the stagg-fd-custom branch 4 times, most recently from 351d79d to ae85ddf Compare March 6, 2024 03:55
devito/finite_differences/derivative.py Show resolved Hide resolved
@@ -318,16 +329,17 @@ def div(self, shift=None, order=None):
order: int, optional, default=None
Discretization order for the finite differences.
Uses `func.space_order` when not specified

method: str, optional, default='FD'
Discretization method. Options are 'FD' (default) and 'RSFD'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be worth adding a '(rotated-staggered finite-difference)' to the docstrings where this option is exposed to the user

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also (nitpicking) full stop at the end (lacked by several entries)

@@ -114,8 +117,8 @@ def cross_derivative(expr, dims, fd_order, deriv_order, x0=None, **kwargs):
finite difference. Defaults to `direct`.
x0 : dict, optional
Origin of the finite-difference scheme as a map dim: origin_dim.
symbolic : bool, optional
Use default or custom coefficients (weights). Defaults to False.
coefficients : strong, optional
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: string

@@ -186,8 +189,8 @@ def generic_derivative(expr, dim, fd_order, deriv_order, matvec=direct, x0=None,
finite difference. Defaults to `direct`.
x0 : dict, optional
Origin of the finite-difference scheme as a map dim: origin_dim.
symbolic : bool, optional
Use default or custom coefficients (weights). Defaults to False.
coefficients : strong, optional
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@@ -200,30 +203,33 @@ def generic_derivative(expr, dim, fd_order, deriv_order, matvec=direct, x0=None,
side = None
# First order derivative with 2nd order FD is highly non-recommended so taking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're changing this file, then you might as well change this line to "strongly discouraged"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"strongly discouraged. Taking the..."


def div45(func, shift=None, order=None, method='FD'):
"""
Divergence of the input Function, using the 45 degrees rotated derivative.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Using 45 degree rotated derivatives"


Rotated finite differences based on:
https://www.sciencedirect.com/science/article/pii/S0165212599000232
The rotated axis (the four diagonals of a cube) are:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Axes"

Expand the expression. Defaults to True.
"""
# Make sure the grid supports RSFD
if expr.grid.dim == 1:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if expr.grid.dim not in (2, 3): would be safer

devito/finite_differences/tools.py Show resolved Hide resolved
@pytest.mark.parametrize('staggered', [(True, True), (False, False),
(True, False), (False, True)])
@pytest.mark.parametrize('space_order', [2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
def test_fd_space_45(self, staggered, space_order):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test this in 3D as well to make sure everything is implemented as intended

@mloubout mloubout force-pushed the stagg-fd-custom branch 8 times, most recently from 5f4bc51 to a7f3be3 Compare March 10, 2024 03:28
@@ -328,6 +337,8 @@ def _eval_at(self, func):
"""
# If an x0 already exists do not overwrite it
x0 = self.x0 or dict(func.indices_ref._getters)
# expr_x0 = self.expr.indices_ref._getters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover

@@ -210,7 +215,7 @@ def _new_from_self(self, **kwargs):
expr = kwargs.pop('expr', self.expr)
_kwargs = {'deriv_order': self.deriv_order, 'fd_order': self.fd_order,
'side': self.side, 'transpose': self.transpose, 'subs': self._ppsubs,
'x0': self.x0, 'preprocessed': True}
'x0': self.x0, 'preprocessed': True, 'method': self.method}
_kwargs.update(**kwargs)
return Derivative(expr, *self.dims, **_kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memo (add issue?)

@@ -318,16 +329,17 @@ def div(self, shift=None, order=None):
order: int, optional, default=None
Discretization order for the finite differences.
Uses `func.space_order` when not specified

method: str, optional, default='FD'
Discretization method. Options are 'FD' (default) and 'RSFD'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also (nitpicking) full stop at the end (lacked by several entries)

@@ -659,7 +672,7 @@ def _evaluate(self, **kwargs):
expr = self.expr._evaluate(**kwargs)

if not kwargs.get('expand', True):
return self.func(expr, self.dimensions)
return self._rebuild(expr)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nitpicking) func is fine, it defaults to _rebuild underneath, maybe we should just use func wherever we can

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func is not fine it leads to some weird error I didn't have time to look into why I switched back to rebuild

symbolic : bool, optional
Use default or custom coefficients (weights). Defaults to False.
coefficients : string, optional
Use taylor or custom coefficients (weights). Defaults to taylor.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nitpicking)

As pointed out in Zoe's latest PR, the "Defaults ..." goes in the line above. We should start changing them all, obv incrementally

@@ -55,12 +120,12 @@ def curl(func, shift=None, order=None):
Uses `func.space_order` when not specified
"""
try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could maybe just call curl(func, shift=shift, order=order, method='RSFD')?

@@ -360,11 +374,20 @@ def generate_indices_staggered(expr, dim, order, side=None, x0=None):
indices = [start, start - diff]
indices = IndexSet(dim, indices)
else:
o_min = -order//2
o_max = order//2
if x0 is None or order % 2 == 0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use a comment down here

if self._coefficients not in fd_weights_registry:
if self._coefficients == 'standard':
self._coefficients = 'taylor'
warnings.warn("The `standard` mode is deprecated and will be removed in "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so just to be sure: nobody will ever see this deprecation warning unless they were explicitly doing Function(..., coefficients='standard', ...) right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another option is to simply just add standard to fd_weights_registry and make it point to taylor without the need to deprecate and change any code here

@@ -277,31 +275,31 @@ def kernel_staggered_2d(model, u, v, **kwargs):

if forward:
# Stencils
phdx = costheta * u.dx - sintheta * u.dy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need the extra 'c' now?

is this affecting use side anyhow? looks like a critical change at first glance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you check the 3d below you'll see the c was supposed to be there but was luckily working in 2D without it. t's mostly because this is a twisted PDE with a missing field so need some tweaks for the FD>

dims = self.model.space_dimensions
stagg_u = (-dims[-1])
stagg_v = (-dims[0], -dims[1]) if self.model.grid.dim == 3 else (-dims[0])
stagg_u = stagg_v = NODE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lovely clean up

@@ -198,32 +201,34 @@ def generic_derivative(expr, dim, fd_order, deriv_order, matvec=direct, x0=None,
``deriv-order`` derivative of ``expr``.
"""
side = None
# First order derivative with 2nd order FD is highly non-recommended so taking
# First order derivative with 2nd order FD is strongly discouraged so taking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment still a little garbled. "strongly discouraged. Taking first order FD is recommended in this case."

Rotated derivatives require at least 2D to get access to diagonal points.
We create a simple 1D gradient over a 2D grid to check against a polynomial
"""
# dummy axis dimension
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalise

Copy link
Contributor

@FabioLuporini FabioLuporini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, GTG now

@mloubout mloubout merged commit 8f6b6a8 into master Mar 12, 2024
31 checks passed
@mloubout mloubout deleted the stagg-fd-custom branch March 12, 2024 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API api (symbolics, types, ...)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants