-
Notifications
You must be signed in to change notification settings - Fork 0
/
06_eigenSpeedup.py
113 lines (93 loc) · 2.85 KB
/
06_eigenSpeedup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed May 17 10:14:22 2023
@author: telu
"""
import numpy as np
import matplotlib.pyplot as plt
from blockops import BlockProblem
nBlocks = 10
nPoints = 1
schemeF = 'RK4'
nStepsF = 20
schemeG = 'FE'
nStepsG = 4
algoName = 'Parareal'
alpha = 1 # From 0 (fully parabolic) to 1 (fully hyperbolic)
rhoMax = 2
nLam = 200
suffix = rf'r={nStepsF/nStepsG}, G={schemeG}, $\alpha$={alpha}'
plotFineDiscrError = False
plotApproxError = False
plotNumIter = False
rho = np.linspace(0, rhoMax, nLam)
lam = rho*np.exp(1j*np.pi*(1-alpha*0.5))
prob = BlockProblem(
lam.ravel(), tEnd=nBlocks, nBlocks=nBlocks, nPoints=nPoints,
scheme='RungeKutta', rkScheme=schemeF,
nStepsPerPoint=nStepsF, ptsType='LEGENDRE', quadType='LOBATTO')
prob.setApprox(scheme='RungeKutta', rkScheme=schemeG, nStepsPerPoint=nStepsG)
algo = prob.getBlockIteration(algoName)
# Compute fine solution
uNum = prob.getSolution('fine')
# Compute exact solution and discretization error
uExact = prob.getSolution('exact')
errDiscr = np.abs(uExact - uNum)
errDiscrMax = np.max(errDiscr, axis=(0, -1))
if plotFineDiscrError:
plt.figure('Discr. Error')
plt.semilogy(rho, errDiscrMax, label=suffix)
plt.xlabel(r'$|\lambda|$')
plt.ylabel('Max. Error')
plt.legend()
plt.tight_layout()
# Compute approximate solution and error
uApprox = prob.getSolution('approx')
errApprox = np.abs(uNum - uApprox)
errApproxMax = np.max(errApprox, axis=(0, -1)).reshape(lam.shape)
if plotApproxError:
plt.figure('Approx. Error')
plt.semilogy(rho, errApproxMax, label=suffix)
plt.xlabel(r'$|\lambda|$')
plt.ylabel('Max. Error')
plt.legend()
plt.tight_layout()
# Compute PinT solution and error
nIterMax = nBlocks
uPar = algo(nIter=nIterMax)
errPinT = np.abs(uNum - uPar)
errPinTMax = np.max(errPinT, axis=(1, -1)).reshape(
(errPinT.shape[0],) + (lam.shape))
# Compute required number of iterations to discretization error
nIter = np.zeros_like(errDiscrMax, dtype=int)
k = errPinT.shape[0] - 1
for err in errPinTMax[-1::-1]:
nIter[err < errDiscrMax] = k
k -= 1
if plotNumIter:
# Plot number of iteration until discretization error
plt.figure('nIter')
plt.plot(rho, nIter, label=suffix)
plt.xlabel(r'$|\lambda|$')
plt.ylabel('nIter')
plt.legend()
plt.tight_layout()
reqIters = np.unique(nIter).tolist()
if 0 in reqIters:
reqIters.remove(0)
# %% Block-by-Block scheduling
speedupBbB = np.zeros(nBlocks + 1)
efficiencyBbB = np.zeros(nBlocks + 1)
for k in reqIters:
speedupBbB[k], efficiencyBbB[k], _ = algo.getPerformances(
N=nBlocks, K=k, schedulerType='BbB')
nSpeedup = speedupBbB[nIter]
nEfficiency = efficiencyBbB[nIter]
# Plotting
plt.figure('Block-by-Block Schedule')
plt.plot(rho, nSpeedup, label=suffix)
plt.xlabel(r'$|\lambda|$')
plt.ylabel('Speedup')
plt.legend()
plt.tight_layout()