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

1import numpy as np 

2 

3from pySDC.core.hooks import Hooks 

4 

5 

6class monitor(Hooks): 

7 phase_thresh = 0.0 # count everything above this threshold to the high phase. 

8 

9 def __init__(self): 

10 """ 

11 Initialization of Allen-Cahn monitoring 

12 """ 

13 super().__init__() 

14 

15 self.init_radius = None 

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 

33 def pre_run(self, step, level_number): 

34 """ 

35 Record radius of the blob, exact radius and interface width. 

36 

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] 

43 

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 

47 

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 ) 

76 

77 def post_step(self, step, level_number): 

78 """ 

79 Record radius of the blob, exact radius and interface width. 

80 

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) 

86 

87 # some abbreviations 

88 L = step.levels[0] 

89 

90 radius = self.get_radius(L.uend, L.prob.dx) 

91 interface_width = self.get_interface_width(L.uend, L) 

92 

93 exact_radius = self.get_exact_radius(L.time + L.dt) 

94 

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 )