class _fft: try: import psutil nproc = psutil.cpu_count(logical=False) except ImportError: try: import os nproc = os.cpu_count() except AttributeError: import multiprocessing nproc = multiprocessing.cpu_count() try: # pyfftw is, in most situations, faster than numpys fft, # although pyfftw will benefit from multithreading only on very large arrays # on a 720x240x240 3D transform multithreading still doesn't give a large benefit # benchmarks of a 720x240x240 transform of real data on a Intel(R) Xeon(R) CPU # E5-1620 v4 @ 3.50GHz: # numpy.fft: 3.6 seconds # pyfftw, nproc=4: first transform 2.2s, further transforms 1.8s # pyfftw, nproc=1: first transform 3.4s, further transforms 2.8s # Try to import pyFFTW's numpy_fft interface import pyfftw.interfaces.cache as fftw_cache import pyfftw.interfaces.numpy_fft as fftw fftw_cache.enable() fft_module = fftw # workaround for # https://github.com/pyFFTW/pyFFTW/issues/135 # also, scaling is bad, so 1 process wont hurt too much nproc = 1 fft_kwargs = dict(planner_effort='FFTW_ESTIMATE', threads=nproc) except ImportError: # pyFFTW is not available, just import numpys fft import numpy.fft as fft_module fft_kwargs = dict() _fft_functions = [ 'fft', 'ifft', 'fft2', 'ifft2', 'fftn', 'ifftn', 'rfft', 'irfft', 'rfft2', 'irfft2', 'irfftn', 'hfft', 'ihfft' ] @classmethod def _get_defaultkwargf(cls, name): wrapped = getattr(cls.fft_module, name) @functools.wraps(wrapped) def ret(*args, **kwargs): kws = cls.fft_kwargs.copy() kws.update(kwargs) return wrapped(*args, **kws) return ret def __getattr__(self, attr): return getattr(self.fft_module, attr) def __init__(self): for fftf in self._fft_functions: setattr(self, fftf, self._get_defaultkwargf(fftf))
import numpy as np import pyfftw.interfaces.numpy_fft as fft # from numpy import fft from pyfftw.interfaces import cache import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt cache.enable() def N_boyd(M): """ Boyd's rule of thumb. M is the number of wave lengths given by M = L/l where L is the box size and l is the smallest scale to be resolved """ return int(2**np.ceil(np.log2(4 * (M - 1) + 6))) class ScalarTool(object): """ Description: ScalarTool contains a collection of functions necessary to compute basic operations such as gradients and norms on scalars defined on a 2D periodic square domain of length L and discretized in each dimension into N intervals. Inputs: N - number of discretized points in each dimension L - length of side """ def __init__(self, N, L): self.N = N