Coverage for pySDC/projects/Resilience/FDeigenvalues.py: 100%

10 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 14:51 +0000

1import numpy as np 

2 

3from pySDC.helpers.problem_helper import get_finite_difference_stencil 

4 

5 

6def get_finite_difference_eigenvalues(derivative, order, stencil_type=None, steps=None, dx=None, L=1.0): 

7 """ 

8 Compute the eigenvalues of the finite difference (FD) discretization using Fourier transform. 

9 

10 In Fourier space, the offsets in the FD discretizations manifest as multiplications by 

11 exp(2 * pi * j * n / N * offset). 

12 Then, all you need to do is sum up the contributions from all entries in the stencil and Bob's your uncle, 

13 you have computed the eigenvalues. 

14 

15 There are going to be as many eigenvalues as there are space elements. 

16 Please be aware that these are in general complex. 

17 

18 Args: 

19 derivative (int): The order of the derivative 

20 order (int): The order of accuracy of the derivative 

21 stencil_type (str): The type of stencil, i.e. 'forward', 'backward', or 'center' 

22 steps (list): If you want an exotic stencil like upwind, you can give the offsets here 

23 dx (float): The mesh spacing 

24 L (float): The length of the interval in space 

25 

26 Returns: 

27 numpy.ndarray: The complex (!) eigenvalues. 

28 """ 

29 # prepare variables 

30 N = int(L // dx) 

31 eigenvalues = np.zeros(N, dtype=complex) 

32 

33 # get the stencil 

34 weights, offsets = get_finite_difference_stencil( 

35 derivative=derivative, order=order, stencil_type=stencil_type, steps=steps 

36 ) 

37 

38 # get the impact of the stencil in Fourier space 

39 for n in range(N): 

40 for i in range(len(weights)): 

41 eigenvalues[n] += weights[i] * np.exp(2 * np.pi * 1j * n / N * offsets[i]) * 1.0 / (dx**derivative) 

42 

43 return eigenvalues