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

42 statements  

« prev     ^ index     » next       coverage.py v7.17.0, created at 2026-11-02 12:30 +0000

1import dolfin as df 

2 

3from pySDC.core.errors import DataError 

4from pySDC.implementations.datatype_classes.container import MultiComponentContainer 

5 

6 

7class fenics_mesh(object): 

8 """ 

9 FEniCS Function data type with arbitrary dimensions 

10 

11 Attributes: 

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

13 """ 

14 

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

16 """ 

17 Initialization routine 

18 

19 Args: 

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

21 val: initial value (default: 0.0) 

22 Raises: 

23 DataError: if init is none of the types above 

24 """ 

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

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

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

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

29 elif isinstance(init, df.Function): 

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

31 elif isinstance(init, df.FunctionSpace): 

32 self.values = df.Function(init) 

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

34 else: 

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

36 

37 def __add__(self, other): 

38 """ 

39 Overloading the addition operator for mesh types 

40 

41 Args: 

42 other (fenics_mesh): mesh object to be added 

43 Raises: 

44 DataError: if other is not a mesh object 

45 Returns: 

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

47 """ 

48 

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

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

51 me = fenics_mesh(self) 

52 me += other 

53 return me 

54 else: 

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

56 

57 def __sub__(self, other): 

58 """ 

59 Overloading the subtraction operator for mesh types 

60 

61 Args: 

62 other (fenics_mesh): mesh object to be subtracted 

63 Raises: 

64 DataError: if other is not a mesh object 

65 Returns: 

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

67 """ 

68 

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

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

71 me = fenics_mesh(self) 

72 me -= other 

73 return me 

74 else: 

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

76 

77 def __iadd__(self, other): 

78 """ 

79 Add another mesh in place, on the vector underneath, without copying through NumPy 

80 

81 Args: 

82 other (fenics_mesh): mesh object to be added 

83 Raises: 

84 DataError: if other is not a mesh object 

85 Returns: 

86 fenics_mesh: the caller, now holding self+other 

87 """ 

88 

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

90 self.values.vector().axpy(1.0, other.values.vector()) 

91 return self 

92 else: 

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

94 

95 def __isub__(self, other): 

96 """ 

97 Subtract another mesh in place, on the vector underneath, without copying through NumPy 

98 

99 Args: 

100 other (fenics_mesh): mesh object to be subtracted 

101 Raises: 

102 DataError: if other is not a mesh object 

103 Returns: 

104 fenics_mesh: the caller, now holding self-other 

105 """ 

106 

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

108 self.values.vector().axpy(-1.0, other.values.vector()) 

109 return self 

110 else: 

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

112 

113 def __rmul__(self, other): 

114 """ 

115 Overloading the right multiply by factor operator for mesh types 

116 

117 Args: 

118 other (float): factor 

119 Raises: 

120 DataError: if other is not a float 

121 Returns: 

122 fenics_mesh: copy of original values scaled by factor 

123 """ 

124 

125 if isinstance(other, float): 

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

127 me = fenics_mesh(self) 

128 vector = me.values.vector() 

129 vector *= other 

130 return me 

131 else: 

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

133 

134 def __abs__(self): 

135 """ 

136 Overloading the abs operator for mesh types 

137 

138 Returns: 

139 float: absolute maximum of all mesh values 

140 """ 

141 

142 # take absolute values of the mesh values 

143 

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

145 

146 # return maximum 

147 return absval 

148 

149 

150class rhs_fenics_mesh(MultiComponentContainer): 

151 """ 

152 RHS data type for fenics_meshes with implicit and explicit components 

153 

154 Attributes: 

155 impl (fenics_mesh): implicit part 

156 expl (fenics_mesh): explicit part 

157 """ 

158 

159 components = ['impl', 'expl'] 

160 component_type = fenics_mesh