-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparareal.py
112 lines (103 loc) · 5.64 KB
/
parareal.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
from pint_task_graph import PintGraph
class Parareal(PintGraph):
def __init__(self, cost_fine: float, cost_coarse: float, cost_copy: float = 0, cost_correction: float = 0,
*args: object, **kwargs: object) -> None:
"""
Constructor
:param cost_fine: Cost of the fine propagator
:param cost_coarse: Cost of the coarse propagator
:param cost_copy: Cost of a copy operation
:param cost_correction: Cost of a correction
:param args:
:param kwargs:
"""
super().__init__(*args, **kwargs)
self.cost_coarse = cost_coarse
self.cost_fine = cost_fine
self.cost_correction = cost_correction
self.cost_copy = cost_copy
def parareal_iteration(self, k: int) -> None:
"""
Parareal iteration
:param k: Iteration number
"""
# Foreach loop, starting with the highest index to simplify standard schedule
for i in range(self.nt - 1, k - 1, -1):
self.add_node(name="F",
predecessors=self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=i - 1,
iteration=k - 1)),
set_values=self.create_node_name(var_name='hatu', var_dict=self.cr_dict(level=0, time_point=i,
iteration=k - 1)),
cost=self.cost_fine,
point=i,
description='parareal_fine_operator')
for i in range(k, self.nt):
# Coarse Propagator
self.add_node(name="G",
predecessors=self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=i - 1,
iteration=min(k, i - 1))),
set_values=self.create_node_name(var_name='tildeu',
var_dict=self.cr_dict(level=0, time_point=i, iteration=k)),
cost=self.cost_coarse,
point=i,
description='parareal_coarse_operator')
# add/sub
pred = self.create_node_name(var_name='tildeu', var_dict=self.cr_dict(level=0, time_point=i, iteration=k))
pred += self.create_node_name(var_name='hatu',
var_dict=self.cr_dict(level=0, time_point=i, iteration=k - 1))
pred += self.create_node_name(var_name='tildeu',
var_dict=self.cr_dict(level=0, time_point=i, iteration=k - 1))
self.add_node(name="+",
predecessors=pred,
set_values=self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=i, iteration=k)),
cost=self.cost_correction,
point=i,
description='parareal_correction')
def compute_initial_guess(self) -> None:
"""
Initial guess
"""
for i in range(1, self.nt):
# Coarse propagator
self.add_node(name="G",
predecessors=self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=i - 1,
iteration=0)),
set_values=self.create_node_name(var_name='tildeu',
var_dict=self.cr_dict(level=0, time_point=i, iteration=0)),
cost=self.cost_coarse,
point=i,
description='parareal_coarse_operator')
# Copy
self.add_node(name="C",
predecessors=self.create_node_name(var_name='tildeu',
var_dict=self.cr_dict(level=0, time_point=i, iteration=0)),
set_values=self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=i, iteration=0)),
cost=self.cost_copy,
point=i,
description='parareal_copy')
def compute(self) -> None:
"""
Computes the graph
"""
# Copy initial value
self.add_node(name="C",
predecessors=['u_0'],
set_values=self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=0, iteration=0)),
cost=self.cost_copy,
point=0)
self.compute_initial_guess()
for k in range(1, self.iterations + 1):
self.parareal_iteration(k=k)
cc = {}
for i in range(k, self.nt):
tmp = self.create_node_name(var_name='u', var_dict=self.cr_dict(level=0, time_point=i, iteration=k))
tmp += self.create_node_name(var_name='u',
var_dict=self.cr_dict(level=0, time_point=i, iteration=k - 1))
cc[i] = tmp
self.convergence_criterion(poins_with_dependencies=cc)