Coverage for pySDC/implementations/datatype_classes/fenics_mesh.py: 100%
55 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
1import dolfin as df
3from pySDC.core.errors import DataError
6class fenics_mesh(object):
7 """
8 FEniCS Function data type with arbitrary dimensions
10 Attributes:
11 values (np.ndarray): contains the ndarray of the values
12 """
14 def __init__(self, init=None, val=0.0):
15 """
16 Initialization routine
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))
36 def __add__(self, other):
37 """
38 Overloading the addition operator for mesh types
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 """
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)))
56 def __sub__(self, other):
57 """
58 Overloading the subtraction operator for mesh types
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 """
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)))
76 def __rmul__(self, other):
77 """
78 Overloading the right multiply by factor operator for mesh types
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 """
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)))
96 def __abs__(self):
97 """
98 Overloading the abs operator for mesh types
100 Returns:
101 float: absolute maximum of all mesh values
102 """
104 # take absolute values of the mesh values
106 absval = df.norm(self.values, 'L2')
108 # return maximum
109 return absval
112class rhs_fenics_mesh(object):
113 """
114 RHS data type for fenics_meshes with implicit and explicit components
116 This data type can be used to have RHS with 2 components (here implicit and explicit)
118 Attributes:
119 impl (fenics_mesh): implicit part
120 expl (fenics_mesh): explicit part
121 """
123 def __init__(self, init, val=0.0):
124 """
125 Initialization routine
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))
146 def __sub__(self, other):
147 """
148 Overloading the subtraction operator for rhs types
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 """
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)))
167 def __add__(self, other):
168 """
169 Overloading the addition operator for rhs types
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 """
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)))
188 def __rmul__(self, other):
189 """
190 Overloading the right multiply by factor operator for mesh types
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 """
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)))