Coverage for pySDC/projects/TOMS/AllenCahn_monitor.py: 100%
37 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
1import numpy as np
3from pySDC.core.hooks import Hooks
6class monitor(Hooks):
7 phase_thresh = 0.0 # count everything above this threshold to the high phase.
9 def __init__(self):
10 """
11 Initialization of Allen-Cahn monitoring
12 """
13 super().__init__()
15 self.init_radius = None
17 def get_exact_radius(self, t):
18 return np.sqrt(max(self.init_radius**2 - 2.0 * t, 0))
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
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)
31 return (rows2[0][-1] - rows1[0][0]) * L.prob.dx / L.prob.eps
33 def pre_run(self, step, level_number):
34 """
35 Record radius of the blob, exact radius and interface width.
37 Args:
38 step (pySDC.Step.step): the current step
39 level_number (int): the current level number
40 """
41 super().pre_run(step, level_number)
42 L = step.levels[0]
44 radius = self.get_radius(L.u[0], L.prob.dx)
45 interface_width = self.get_interface_width(L.u[0], L)
46 self.init_radius = L.prob.radius
48 if L.time == 0.0:
49 self.add_to_stats(
50 process=step.status.slot,
51 time=L.time,
52 level=-1,
53 iter=step.status.iter,
54 sweep=L.status.sweep,
55 type='computed_radius',
56 value=radius,
57 )
58 self.add_to_stats(
59 process=step.status.slot,
60 time=L.time,
61 level=-1,
62 iter=step.status.iter,
63 sweep=L.status.sweep,
64 type='exact_radius',
65 value=self.init_radius,
66 )
67 self.add_to_stats(
68 process=step.status.slot,
69 time=L.time,
70 level=-1,
71 iter=step.status.iter,
72 sweep=L.status.sweep,
73 type='interface_width',
74 value=interface_width,
75 )
77 def post_step(self, step, level_number):
78 """
79 Record radius of the blob, exact radius and interface width.
81 Args:
82 step (pySDC.Step.step): the current step
83 level_number (int): the current level number
84 """
85 super().post_step(step, level_number)
87 # some abbreviations
88 L = step.levels[0]
90 radius = self.get_radius(L.uend, L.prob.dx)
91 interface_width = self.get_interface_width(L.uend, L)
93 exact_radius = self.get_exact_radius(L.time + L.dt)
95 self.add_to_stats(
96 process=step.status.slot,
97 time=L.time + L.dt,
98 level=-1,
99 iter=step.status.iter,
100 sweep=L.status.sweep,
101 type='computed_radius',
102 value=radius,
103 )
104 self.add_to_stats(
105 process=step.status.slot,
106 time=L.time + L.dt,
107 level=-1,
108 iter=step.status.iter,
109 sweep=L.status.sweep,
110 type='exact_radius',
111 value=exact_radius,
112 )
113 self.add_to_stats(
114 process=step.status.slot,
115 time=L.time + L.dt,
116 level=-1,
117 iter=step.status.iter,
118 sweep=L.status.sweep,
119 type='interface_width',
120 value=interface_width,
121 )