Repository navigation
Add post-dealiasing to nonlinear functions via fft/ifft wrapping - #96
Merged
Merged
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #96 +/- ##
=======================================
Coverage 92.02% 92.03%
=======================================
Files 75 75
Lines 2697 2698 +1
=======================================
+ Hits 2482 2483 +1
Misses 215 215 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Previously, the nonlinear functions only applied dealiasing before evaluating the nonlinearity (pre-dealiasing): high Fourier modes were zeroed out before transforming to physical space. However, the nonlinear product in physical space creates new aliased modes in the upper spectral band. These aliased modes were returned as part of the nonlinear term and propagated into the ETDRK intermediate stages and the final solution.
With the 2/3 rule and quadratic nonlinearities, these aliases only land in the "expendable" modes (N/3 to N/2), so the scheme was technically stable. However:
Changes
Core change:
BaseNonlinearFun.fftandifftnow handle dealiasingInstead of requiring each subclass to manually call
self.dealias(), thefftandifftmethods onBaseNonlinearFunnow apply the dealiasing mask automatically:ifft(pre-dealiasing): Zeros out high modes before transforming to physical space. This was already done explicitly in all subclasses; it is now handled by the base class.fft(post-dealiasing): Zeros out high modes after transforming back to Fourier space. This is the new behavior that ensures the returned nonlinear term is spectrally clean.When no
dealiasing_fractionis set (i.e.,dealiasing_mask is None), both methods behave as plainfft/ifftwith no overhead.Subclass cleanup
All explicit
self.dealias()calls have been removed from the nonlinear function implementations:PolynomialNonlinearFunConvectionNonlinearFun(all 4 variants: multi/single-channel, conservative/non-conservative)GradientNormNonlinearFunVorticityConvection2dProjectedConvection3dThe
dealias()method still exists on the base class for standalone use, but is no longer needed in the standard__call__flow.Documentation updates
BaseNonlinearFun.__init__docstring: Added info admonition explaining the pre- and post-dealiasing strategy.BaseNonlinearFun.dealias()docstring: Added note thatfft/iffthandle dealiasing automatically.BaseNonlinearFunhandles this via itsfft/ifftmethods. Removed redundant inline remarks from ETDRK2-4 parameter descriptions.creating_your_own_solvers_1d.ipynb): Updated the customNonlinearSourceFunexample to useself.ifft(u_hat)instead ofself.ifft(self.dealias(u_hat)), with an updated comment explaining the automatic dealiasing.Test additions
test_fft_ifft_apply_dealiasing()to verify thatifftpre-dealiases its input andfftpost-dealiases its output.Files changed (12)
exponax/nonlin_fun/_base.pyfft/ifftnow apply dealiasing mask; updated docstringsexponax/nonlin_fun/_polynomial.pyself.dealias()exponax/nonlin_fun/_convection.pyself.dealias()from all 4 eval methodsexponax/nonlin_fun/_gradient_norm.pyself.dealias()exponax/nonlin_fun/_vorticity_convection.pyself.dealias()exponax/nonlin_fun/_projected_convection.pyself.dealias()exponax/etdrk/_etdrk_1.pyexponax/etdrk/_etdrk_2.pyexponax/etdrk/_etdrk_3.pyexponax/etdrk/_etdrk_4.pydocs/examples/creating_your_own_solvers_1d.ipynbtests/test_nonlinear_funs.pytest_fft_ifft_apply_dealiasingBreaking changes
Users who subclass
BaseNonlinearFunand callself.dealias()explicitly (as shown in the old tutorial) will now get double-dealiasing, which is harmless (idempotent) but redundant. They should update to just useself.ifft(u_hat)instead ofself.ifft(self.dealias(u_hat)).