Coverage for kwave/recorder.py: 42%

65 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-03-24 12:06 -0700

1from dataclasses import dataclass 

2from typing import List 

3 

4from kwave.data import Vector 

5from kwave.kgrid import kWaveGrid 

6 

7 

8@dataclass 

9class Recorder(object): 

10 def __init__(self): 

11 # flags which control which parameters are recorded 

12 self.p = True #: time-varying acoustic pressure 

13 self.p_max = False #: maximum pressure over simulation 

14 self.p_min = False #: minimum pressure over simulation 

15 self.p_rms = False #: root-mean-squared pressure over simulation 

16 self.p_max_all = False #: maximum pressure over simulation at all grid points 

17 self.p_min_all = False #: minimum pressure over simulation at all grid points 

18 self.p_final = False #: final pressure field at all grid points 

19 self.u = False #: time-varying particle velocity 

20 self.u_split_field = False #: compressional and shear components of time-varying particle velocity 

21 self.u_non_staggered = False #: time-varying particle velocity on non-staggered grid 

22 self.u_max = False #: maximum particle velocity over simulation 

23 self.u_min = False #: minimum particle velocity over simulation 

24 self.u_rms = False #: root-mean-squared particle velocity over simulation 

25 self.u_max_all = False #: maximum particle velocity over simulation at all grid points 

26 self.u_min_all = False #: minimum particle velocity over simulation at all grid points 

27 self.u_final = False #: final particle velocity field at all grid points 

28 self.I = False #: time-varying acoustic intensity 

29 self.I_avg = False #: time-averaged acoustic intensity 

30 

31 self.cuboid_corners_list = None 

32 

33 self.x1_inside, self.x2_inside = None, None 

34 self.y1_inside, self.y2_inside = None, None 

35 self.z1_inside, self.z2_inside = None, None 

36 

37 def set_flags_from_list(self, flags_list: List[str], is_elastic_code: bool) -> None: 

38 """ 

39 Set Recorder flags that are present in the string list to True 

40 

41 Args: 

42 flags_list: String list of flags that should be set to True 

43 is_elastic_code: Is the simulation elastic 

44 

45 Returns: 

46 None 

47 """ 

48 # check the contents of the cell array are valid inputs 

49 allowed_flags = self.get_allowed_flags(is_elastic_code) 

50 for record_element in flags_list: 

51 assert record_element in allowed_flags, f"{record_element} is not a valid input for sensor.record" 

52 

53 if record_element == "p": # custom logic for 'p' 

54 continue 

55 else: 

56 setattr(self, record_element, True) 

57 

58 # set self.record_p to false if a user input for sensor.record 

59 # is given and 'p' is not set (default is true) 

60 self.p = "p" in flags_list 

61 

62 def set_index_variables(self, kgrid: kWaveGrid, pml_size: Vector, is_pml_inside: bool, is_axisymmetric: bool) -> None: 

63 """ 

64 Assign the index variables 

65 

66 Args: 

67 kgrid: kWaveGrid instance 

68 pml_size: Size of the PML 

69 is_pml_inside: Whether the PML is inside the grid defined by the user 

70 is_axisymmetric: Whether the simulation is axisymmetric 

71 

72 Returns: 

73 None 

74 """ 

75 if not is_pml_inside: 

76 self.x1_inside = pml_size.x + 1.0 

77 self.x2_inside = kgrid.Nx - pml_size.x 

78 if kgrid.dim == 2: 

79 if is_axisymmetric: 

80 self.y1_inside = 1 

81 else: 

82 self.y1_inside = pml_size.y + 1.0 

83 self.y2_inside = kgrid.Ny - pml_size.y 

84 elif kgrid.dim == 3: 

85 self.y1_inside = pml_size.y + 1.0 

86 self.y2_inside = kgrid.Ny - pml_size.y 

87 self.z1_inside = pml_size.z + 1.0 

88 self.z2_inside = kgrid.Nz - pml_size.z 

89 else: 

90 self.x1_inside = 1.0 

91 self.x2_inside = kgrid.Nx 

92 if kgrid.dim == 2: 

93 self.y1_inside = 1.0 

94 self.y2_inside = kgrid.Ny 

95 if kgrid.dim == 3: 

96 self.z1_inside = 1.0 

97 self.z2_inside = kgrid.Nz 

98 

99 @staticmethod 

100 def get_allowed_flags(is_elastic_code): 

101 """ 

102 Get the list of allowed flags for a given simulation type 

103 

104 Args: 

105 is_elastic_code: Whether the simulation is axisymmetric 

106 

107 Returns: 

108 List of allowed flags for a given simulation type 

109 """ 

110 allowed_flags = [ 

111 "p", 

112 "p_max", 

113 "p_min", 

114 "p_rms", 

115 "p_max_all", 

116 "p_min_all", 

117 "p_final", 

118 "u", 

119 "u_max", 

120 "u_min", 

121 "u_rms", 

122 "u_max_all", 

123 "u_min_all", 

124 "u_final", 

125 "u_non_staggered", 

126 "I", 

127 "I_avg", 

128 ] 

129 if is_elastic_code: # pragma: no cover 

130 allowed_flags += ["u_split_field"] 

131 return allowed_flags 

132 

133 def is_set(self, attrs: List[str]) -> List[bool]: 

134 """ 

135 Check if the attributes are set 

136 

137 Args: 

138 attrs: Attributes to check 

139 

140 Returns: 

141 List of individual boolean results 

142 """ 

143 return [getattr(self, a) for a in attrs]