Coverage for pySDC/implementations/datatype_classes/fenics_mesh.py: 100%

55 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2024-11-16 14:51 +0000

1import dolfin as df 

2 

3from pySDC.core.errors import DataError 

4 

5 

6class fenics_mesh(object): 

7 """ 

8 FEniCS Function data type with arbitrary dimensions 

9 

10 Attributes: 

11 values (np.ndarray): contains the ndarray of the values 

12 """ 

13 

14 def __init__(self, init=None, val=0.0): 

15 """ 

16 Initialization routine 

17 

18 Args: 

19 init: can either be a FunctionSpace or another fenics_mesh object 

20 val: initial value (default: 0.0) 

21 Raises: 

22 DataError: if init is none of the types above 

23 """ 

24 # if init is another fenic_mesh, do a deepcopy (init by copy) 

25 if isinstance(init, type(self)): 

26 self.values = init.values.copy(deepcopy=True) 

27 # if init is FunctionSpace, create mesh object with val as initial value 

28 elif isinstance(init, df.Function): 

29 self.values = init.copy(deepcopy=True) 

30 elif isinstance(init, df.FunctionSpace): 

31 self.values = df.Function(init) 

32 self.values.vector()[:] = val 

33 else: 

34 raise DataError('something went wrong during %s initialization' % type(init)) 

35 

36 def __add__(self, other): 

37 """ 

38 Overloading the addition operator for mesh types 

39 

40 Args: 

41 other (fenics_mesh): mesh object to be added 

42 Raises: 

43 DataError: if other is not a mesh object 

44 Returns: 

45 fenics_mesh: sum of caller and other values (self+other) 

46 """ 

47 

48 if isinstance(other, type(self)): 

49 # always create new mesh, since otherwise c = a + b changes a as well! 

50 me = fenics_mesh(other) 

51 me.values.vector()[:] = self.values.vector()[:] + other.values.vector()[:] 

52 return me 

53 else: 

54 raise DataError("Type error: cannot add %s to %s" % (type(other), type(self))) 

55 

56 def __sub__(self, other): 

57 """ 

58 Overloading the subtraction operator for mesh types 

59 

60 Args: 

61 other (fenics_mesh): mesh object to be subtracted 

62 Raises: 

63 DataError: if other is not a mesh object 

64 Returns: 

65 fenics_mesh: differences between caller and other values (self-other) 

66 """ 

67 

68 if isinstance(other, type(self)): 

69 # always create new mesh, since otherwise c = a - b changes a as well! 

70 me = fenics_mesh(other) 

71 me.values.vector()[:] = self.values.vector()[:] - other.values.vector()[:] 

72 return me 

73 else: 

74 raise DataError("Type error: cannot subtract %s from %s" % (type(other), type(self))) 

75 

76 def __rmul__(self, other): 

77 """ 

78 Overloading the right multiply by factor operator for mesh types 

79 

80 Args: 

81 other (float): factor 

82 Raises: 

83 DataError: is other is not a float 

84 Returns: 

85 fenics_mesh: copy of original values scaled by factor 

86 """ 

87 

88 if isinstance(other, float): 

89 # always create new mesh, since otherwise c = f*a changes a as well! 

90 me = fenics_mesh(self) 

91 me.values.vector()[:] = other * self.values.vector()[:] 

92 return me 

93 else: 

94 raise DataError("Type error: cannot multiply %s to %s" % (type(other), type(self))) 

95 

96 def __abs__(self): 

97 """ 

98 Overloading the abs operator for mesh types 

99 

100 Returns: 

101 float: absolute maximum of all mesh values 

102 """ 

103 

104 # take absolute values of the mesh values 

105 

106 absval = df.norm(self.values, 'L2') 

107 

108 # return maximum 

109 return absval 

110 

111 

112class rhs_fenics_mesh(object): 

113 """ 

114 RHS data type for fenics_meshes with implicit and explicit components 

115 

116 This data type can be used to have RHS with 2 components (here implicit and explicit) 

117 

118 Attributes: 

119 impl (fenics_mesh): implicit part 

120 expl (fenics_mesh): explicit part 

121 """ 

122 

123 def __init__(self, init, val=0.0): 

124 """ 

125 Initialization routine 

126 

127 Args: 

128 init: can either be a tuple (one int per dimension) or a number (if only one dimension is requested) 

129 or another rhs_imex_mesh object 

130 val (float): an initial number (default: 0.0) 

131 Raises: 

132 DataError: if init is none of the types above 

133 """ 

134 # if init is another rhs_imex_mesh, do a deepcopy (init by copy) 

135 if isinstance(init, type(self)): 

136 self.impl = fenics_mesh(init.impl) 

137 self.expl = fenics_mesh(init.expl) 

138 # if init is a number or a tuple of numbers, create mesh object with None as initial value 

139 elif isinstance(init, df.FunctionSpace): 

140 self.impl = fenics_mesh(init, val=val) 

141 self.expl = fenics_mesh(init, val=val) 

142 # something is wrong, if none of the ones above hit 

143 else: 

144 raise DataError('something went wrong during %s initialization' % type(self)) 

145 

146 def __sub__(self, other): 

147 """ 

148 Overloading the subtraction operator for rhs types 

149 

150 Args: 

151 other (rhs_fenics_mesh): rhs object to be subtracted 

152 Raises: 

153 DataError: if other is not a rhs object 

154 Returns: 

155 rhs_fenics_mesh: differences between caller and other values (self-other) 

156 """ 

157 

158 if isinstance(other, rhs_fenics_mesh): 

159 # always create new rhs_imex_mesh, since otherwise c = a - b changes a as well! 

160 me = rhs_fenics_mesh(self) 

161 me.impl = self.impl - other.impl 

162 me.expl = self.expl - other.expl 

163 return me 

164 else: 

165 raise DataError("Type error: cannot subtract %s from %s" % (type(other), type(self))) 

166 

167 def __add__(self, other): 

168 """ 

169 Overloading the addition operator for rhs types 

170 

171 Args: 

172 other (rhs_fenics_mesh): rhs object to be added 

173 Raises: 

174 DataError: if other is not a rhs object 

175 Returns: 

176 rhs_fenics_mesh: sum of caller and other values (self-other) 

177 """ 

178 

179 if isinstance(other, rhs_fenics_mesh): 

180 # always create new rhs_imex_mesh, since otherwise c = a + b changes a as well! 

181 me = rhs_fenics_mesh(self) 

182 me.impl = self.impl + other.impl 

183 me.expl = self.expl + other.expl 

184 return me 

185 else: 

186 raise DataError("Type error: cannot add %s to %s" % (type(other), type(self))) 

187 

188 def __rmul__(self, other): 

189 """ 

190 Overloading the right multiply by factor operator for mesh types 

191 

192 Args: 

193 other (float): factor 

194 Raises: 

195 DataError: is other is not a float 

196 Returns: 

197 rhs_fenics_mesh: copy of original values scaled by factor 

198 """ 

199 

200 if isinstance(other, float): 

201 # always create new mesh, since otherwise c = f*a changes a as well! 

202 me = rhs_fenics_mesh(self) 

203 me.impl = other * self.impl 

204 me.expl = other * self.expl 

205 return me 

206 else: 

207 raise DataError("Type error: cannot multiply %s to %s" % (type(other), type(self)))