|
4 | 4 |
|
5 | 5 |
|
6 | 6 | class monitor(hooks): |
| 7 | + phase_thresh = 0.0 # count everything above this threshold to the high phase. |
| 8 | + |
7 | 9 | def __init__(self): |
8 | 10 | """ |
9 | 11 | Initialization of Allen-Cahn monitoring |
10 | 12 | """ |
11 | | - super(monitor, self).__init__() |
| 13 | + super().__init__() |
12 | 14 |
|
13 | 15 | self.init_radius = None |
14 | 16 |
|
| 17 | + def get_exact_radius(self, t): |
| 18 | + return np.sqrt(max(self.init_radius**2 - 2.0 * t, 0)) |
| 19 | + |
| 20 | + @classmethod |
| 21 | + def get_radius(cls, u, dx): |
| 22 | + c = np.count_nonzero(u > cls.phase_thresh) |
| 23 | + return np.sqrt(c / np.pi) * dx |
| 24 | + |
| 25 | + @staticmethod |
| 26 | + def get_interface_width(u, L): |
| 27 | + # TODO: How does this generalize to different phase transitions? |
| 28 | + rows1 = np.where(u[L.prob.init[0][0] // 2, : L.prob.init[0][0] // 2] > -0.99) |
| 29 | + rows2 = np.where(u[L.prob.init[0][0] // 2, : L.prob.init[0][0] // 2] < 0.99) |
| 30 | + |
| 31 | + return (rows2[0][-1] - rows1[0][0]) * L.prob.dx / L.prob.eps |
| 32 | + |
15 | 33 | def pre_run(self, step, level_number): |
16 | 34 | """ |
17 | | - Overwrite standard pre run hook |
| 35 | + Record radius of the blob, exact radius and interface width. |
18 | 36 |
|
19 | 37 | Args: |
20 | 38 | step (pySDC.Step.step): the current step |
21 | 39 | level_number (int): the current level number |
22 | 40 | """ |
23 | | - super(monitor, self).pre_run(step, level_number) |
| 41 | + super().pre_run(step, level_number) |
24 | 42 | L = step.levels[0] |
25 | 43 |
|
26 | | - c = np.count_nonzero(L.u[0] > 0.0) |
27 | | - radius = np.sqrt(c / np.pi) * L.prob.dx |
28 | | - |
29 | | - radius1 = 0 |
30 | | - rows, cols = np.where(L.u[0] > 0.0) |
31 | | - for r in rows: |
32 | | - radius1 = max(radius1, abs(L.prob.xvalues[r])) |
33 | | - |
34 | | - rows1 = np.where(L.u[0][int((L.prob.init[0][0]) / 2), : int((L.prob.init[0][0]) / 2)] > -0.99) |
35 | | - rows2 = np.where(L.u[0][int((L.prob.init[0][0]) / 2), : int((L.prob.init[0][0]) / 2)] < 0.99) |
36 | | - interface_width = (rows2[0][-1] - rows1[0][0]) * L.prob.dx / L.prob.eps |
37 | | - |
| 44 | + radius = self.get_radius(L.u[0], L.prob.dx) |
| 45 | + interface_width = self.get_interface_width(L.u[0], L) |
38 | 46 | self.init_radius = L.prob.radius |
39 | 47 |
|
40 | 48 | if L.time == 0.0: |
@@ -68,24 +76,21 @@ def pre_run(self, step, level_number): |
68 | 76 |
|
69 | 77 | def post_step(self, step, level_number): |
70 | 78 | """ |
71 | | - Overwrite standard post step hook |
| 79 | + Record radius of the blob, exact radius and interface width. |
72 | 80 |
|
73 | 81 | Args: |
74 | 82 | step (pySDC.Step.step): the current step |
75 | 83 | level_number (int): the current level number |
76 | 84 | """ |
77 | | - super(monitor, self).post_step(step, level_number) |
| 85 | + super().post_step(step, level_number) |
78 | 86 |
|
79 | 87 | # some abbreviations |
80 | 88 | L = step.levels[0] |
81 | 89 |
|
82 | | - c = np.count_nonzero(L.uend >= 0.0) |
83 | | - radius = np.sqrt(c / np.pi) * L.prob.dx |
| 90 | + radius = self.get_radius(L.uend, L.prob.dx) |
| 91 | + interface_width = self.get_interface_width(L.uend, L) |
84 | 92 |
|
85 | | - exact_radius = np.sqrt(max(self.init_radius**2 - 2.0 * (L.time + L.dt), 0)) |
86 | | - rows1 = np.where(L.uend[int((L.prob.init[0][0]) / 2), : int((L.prob.init[0][0]) / 2)] > -0.99) |
87 | | - rows2 = np.where(L.uend[int((L.prob.init[0][0]) / 2), : int((L.prob.init[0][0]) / 2)] < 0.99) |
88 | | - interface_width = (rows2[0][-1] - rows1[0][0]) * L.prob.dx / L.prob.eps |
| 93 | + exact_radius = self.get_exact_radius(L.time + L.dt) |
89 | 94 |
|
90 | 95 | self.add_to_stats( |
91 | 96 | process=step.status.slot, |
|
0 commit comments