Coverage for pySDC/core/level.py: 100%

68 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-04 15:08 +0000

1from pySDC.core.sweeper import Sweeper 

2from pySDC.core.problem import Problem 

3 

4from pySDC.helpers.pysdc_helper import FrozenClass 

5 

6 

7# short helper class to add params as attributes 

8class _Pars(FrozenClass): 

9 def __init__(self, params): 

10 self.dt = None 

11 self.dt_initial = None 

12 self.restol = -1.0 

13 self.nsweeps = 1 

14 self.residual_type = 'full_abs' 

15 for k, v in params.items(): 

16 setattr(self, k, v) 

17 # freeze class, no further attributes allowed from this point 

18 self._freeze() 

19 

20 self.dt_initial = self.dt * 1.0 if self.dt is not None else None 

21 

22 

23# short helper class to bundle all status variables 

24class _Status(FrozenClass): 

25 """ 

26 This class carries the status of the level. All variables that the core SDC / PFASST functionality depend on are 

27 initialized here. 

28 """ 

29 

30 def __init__(self): 

31 self.residual = None 

32 self.unlocked = False 

33 self.updated = False 

34 self.time = None 

35 self.dt_new = None 

36 self.sweep = None 

37 # freeze class, no further attributes allowed from this point 

38 self._freeze() 

39 

40 

41class Level(FrozenClass): 

42 """ 

43 Level class containing all management functionality for a single level 

44 

45 A level contains all data structures, types and objects to perform sweeps on this particular level. It does not 

46 know about other levels. 

47 

48 Attributes: 

49 params (__Pars): parameter object containing the custom parameters passed by the user 

50 status (__Status): status object 

51 level_index (int): custom string naming this level 

52 uend: dof values at the right end point of the interval 

53 u (list of dtype_u): dof values at the nodes 

54 uold (list of dtype_u): copy of dof values for saving data during restriction) 

55 f (list of dtype_f): RHS values at the nodes 

56 fold (list of dtype_f): copy of RHS values for saving data during restriction 

57 tau (list of dtype_u): FAS correction, allocated via step class if necessary 

58 """ 

59 

60 def __init__(self, problem_class, problem_params, sweeper_class, sweeper_params, level_params, level_index): 

61 """ 

62 Initialization routine 

63 

64 Args: 

65 problem_class: problem class 

66 problem_params (dict): parameters for the problem to be initialized 

67 sweeper_class: sweeper class 

68 sweeper_params (dict): parameters for the sweeper (contains collocation) 

69 level_params (dict): parameters given by the user, will be added as attributes 

70 level_index (int): custom name for this level 

71 """ 

72 

73 # set level parameters and status 

74 self.params = _Pars(level_params) 

75 self.status = _Status() 

76 

77 # instantiate sweeper, problem and hooks 

78 self.__sweep: Sweeper = sweeper_class(sweeper_params, self) 

79 self.__prob: Problem = problem_class(**problem_params) 

80 

81 # set name 

82 self.level_index = level_index 

83 

84 # empty data at the nodes, the right end point and tau 

85 self.uend = None 

86 self.u = [None] * (self.sweep.coll.num_nodes + 1) 

87 self.uold = [None] * (self.sweep.coll.num_nodes + 1) 

88 self.u_avg = [None] * self.sweep.coll.num_nodes 

89 self.residual = [None] * self.sweep.coll.num_nodes 

90 self.increment = [None] * self.sweep.coll.num_nodes 

91 self.f = [None] * (self.sweep.coll.num_nodes + 1) 

92 self.fold = [None] * (self.sweep.coll.num_nodes + 1) 

93 

94 self.tau = [None] * self.sweep.coll.num_nodes 

95 

96 self.__tag = None 

97 

98 # freeze class, no further attributes allowed from this point 

99 self._freeze() 

100 

101 def reset_level(self, reset_status=True): 

102 """ 

103 Routine to clean-up the level for the next time step 

104 

105 Args: 

106 reset_status (bool): Reset the status or only the solution 

107 

108 Returns: 

109 None 

110 """ 

111 

112 # reset status 

113 if reset_status: 

114 self.status = _Status() 

115 

116 # all data back to None 

117 self.uend = None 

118 self.u = [None] * (self.sweep.coll.num_nodes + 1) 

119 self.uold = [None] * (self.sweep.coll.num_nodes + 1) 

120 self.f = [None] * (self.sweep.coll.num_nodes + 1) 

121 self.fold = [None] * (self.sweep.coll.num_nodes + 1) 

122 self.tau = [None] * self.sweep.coll.num_nodes 

123 

124 @property 

125 def sweep(self) -> Sweeper: 

126 """ 

127 Getter for the sweeper 

128 

129 Returns: 

130 pySDC.Sweeper.sweeper: the sweeper associated to this level 

131 """ 

132 return self.__sweep 

133 

134 @property 

135 def prob(self) -> Problem: 

136 """ 

137 Getter for the problem 

138 

139 Returns: 

140 pySDC.Problem.ptype: the problem associated to this level 

141 """ 

142 return self.__prob 

143 

144 @property 

145 def time(self): 

146 """ 

147 Meta-getter for the current time 

148 

149 Returns: 

150 float: referencing status time for convenience 

151 """ 

152 return self.status.time 

153 

154 @property 

155 def dt(self): 

156 """ 

157 Meta-getter for the time-step size 

158 

159 Returns: 

160 float: referencing dt from parameters for convenience 

161 """ 

162 return self.params.dt 

163 

164 @property 

165 def tag(self): 

166 """ 

167 Getter for tag 

168 

169 Returns: 

170 tag for sending/receiving 

171 """ 

172 return self.__tag 

173 

174 @tag.setter 

175 def tag(self, t): 

176 """ 

177 Setter for tag 

178 

179 Args: 

180 t: new tag for sending/receiving 

181 """ 

182 self.__tag = t