77from special_integrator import special_integrator
88from solution_linear import solution_linear
99import numpy as np
10- #from scipy.sparse import linalg
10+ import scipy .sparse as sparse
1111import math
1212
1313from pylab import rcParams
@@ -30,7 +30,7 @@ def findroots(R, n):
3030def normalise (R , T , target ):
3131 roots = findroots (R , T )
3232 for x in roots :
33- assert abs (x ** T - R )< 1e-10 , ("Element in roots not a proper root: err=%5.3e" % abs (x ** T - R ))
33+ assert abs (x ** T - R )< 1e-5 , ("Element in roots not a proper root: err=%5.3e" % abs (x ** T - R ))
3434 minind = np .argmin (abs (np .angle (roots ) - target ))
3535 return roots [minind ]
3636
@@ -46,7 +46,7 @@ def normalise(R, T, target):
4646 nfine = 10
4747 niter_v = [5 , 10 , 15 ]
4848 dx = 0.1
49- Nsamples = 30
49+ Nsamples = 60
5050
5151 k_vec = np .linspace (0.0 , np .pi , Nsamples + 1 , endpoint = False )
5252 k_vec = k_vec [1 :]
@@ -60,19 +60,19 @@ def normalise(R, T, target):
6060 for i in range (0 ,np .size (k_vec )):
6161
6262 symb = - (1j * U_speed * k_vec [i ] + nu * k_vec [i ]** 2 )
63- # symb_coarse = symb
64- symb_coarse = - (1.0 / dx )* (1.0 - np .exp (- 1j * k_vec [i ]* dx ))
63+ symb_coarse = symb
64+ # symb_coarse = -(1.0/dx)*(1.0 - np.exp(-1j*k_vec[i]*dx))
6565
6666 # Solution objects define the problem
6767 u0 = solution_linear (u0_val , np .array ([[symb ]],dtype = 'complex' ))
6868 ucoarse = solution_linear (u0_val , np .array ([[symb_coarse ]],dtype = 'complex' ))
69+
70+ # create Parareal object
71+ para = parareal (0.0 , Tend , nslices , intexact , impeuler , nfine , ncoarse , 0.0 , niter_v [0 ], u0 )
6972
7073 # get update matrix for imp Euler over one slice
71- stab_fine = para .timemesh .slices [0 ].get_fine_update_matrix (u0 )
72- stab_fine = stab_fine
73-
74- stab_coarse = para .timemesh .slices [0 ].get_coarse_update_matrix (u0 )
75- stab_coarse = stab_coarse
74+ stab_fine = para .timemesh .slices [0 ].get_fine_update_matrix (u0 )
75+ stab_coarse = para .timemesh .slices [0 ].get_coarse_update_matrix (ucoarse )
7676
7777 stab_ex = np .exp (symb )
7878
@@ -89,12 +89,29 @@ def normalise(R, T, target):
8989 phase [2 ,i ] = sol_coarse .real / k_vec [i ]
9090 amp_factor [2 ,i ] = np .exp (sol_coarse .imag )
9191
92- # Create the parareal object to be used in the remainder
93- para = parareal (0.0 , Tend , nslices , intexact , impeuler , nfine , ncoarse , 0.0 , niter_v [0 ], u0 )
92+ #
93+ # TESTS FOR SPECIALLY TAILORED COARSE METHOD
94+ #
95+
96+ # for stab = r*exp(i*theta), r defines the amplitude factor and theta the phase speed
97+ stab_tailor = abs (stab_coarse [0 ,0 ])* np .exp (1j * np .angle (stab_ex )) # exact phase speed
98+ # stab_tailor = abs(stab_ex)*np.exp(1j*np.angle(stab_coarse[0,0])) # exact amplification factor
99+
100+ # coarse method with exact phase but amplification factor corresponding to a single large backward Euler step
101+ stab_coarse_limit = 1.0 / (1.0 - Tend * symb_coarse )
102+ stab_tailor = abs (stab_coarse_limit )* np .exp (1j * np .angle (stab_ex )) # exact phase speed, massively diffusive amplification factor
103+
104+ # stab_tailor = abs(stab_ex)*np.exp(1j*np.angle(stab_ex)) ## for testing
105+ # stab_tailor = abs(stab_coarse[0,0])*np.exp(1j*np.angle(stab_coarse[0,0])) ## for testing
106+
107+ # Re-Create the parareal object to be used in the remainder
108+ stab_tailor = sparse .csc_matrix (np .array ([stab_tailor ], dtype = 'complex' ))
109+ para = parareal (0.0 , Tend , nslices , intexact , stab_tailor , nfine , ncoarse , 0.0 , niter_v [0 ], u0 )
110+
111+ #################################################
94112
95-
96113 # Compute Parareal phase velocity and amplification factor
97- svds [0 ,i ] = para .get_max_svd (ucoarse = ucoarse )
114+ # svds[0,i] = para.get_max_svd(ucoarse=ucoarse)
98115 for jj in range (0 ,3 ):
99116 stab_para = para .get_parareal_stab_function (k = niter_v [jj ], ucoarse = ucoarse )
100117
0 commit comments