Coverage for pySDC/implementations/datatype_classes/firedrake_mesh.py: 0%
67 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 10:09 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 10:09 +0000
1import firedrake as fd
3from pySDC.core.errors import DataError
4from pySDC.helpers.firedrake_ensemble_communicator import FiredrakeEnsembleCommunicator
7class firedrake_mesh(object):
8 """
9 Wrapper for firedrake function data.
11 Attributes:
12 functionspace (firedrake.Function): firedrake data
13 """
15 def __init__(self, init, val=0.0):
16 if fd.functionspaceimpl.WithGeometry in type(init).__mro__:
17 self.functionspace = fd.Function(init)
18 self.functionspace.assign(val)
19 elif fd.Function in type(init).__mro__:
20 self.functionspace = fd.Function(init)
21 elif type(init) == firedrake_mesh:
22 self.functionspace = init.functionspace.copy(deepcopy=True)
23 else:
24 raise DataError('something went wrong during %s initialization' % type(init))
26 def __getattr__(self, key):
27 return getattr(self.functionspace, key)
29 @property
30 def asnumpy(self):
31 """
32 Get a numpy array of the values associated with this data
33 """
34 return self.functionspace.dat._numpy_data
36 def __add__(self, other):
37 if isinstance(other, type(self)):
38 me = firedrake_mesh(other)
39 me.functionspace.assign(self.functionspace + other.functionspace)
40 return me
41 else:
42 raise DataError("Type error: cannot add %s to %s" % (type(other), type(self)))
44 def __sub__(self, other):
45 if isinstance(other, type(self)):
46 me = firedrake_mesh(other)
47 me.functionspace.assign(self.functionspace - other.functionspace)
48 return me
49 else:
50 raise DataError("Type error: cannot add %s to %s" % (type(other), type(self)))
52 def __rmul__(self, other):
53 """
54 Overloading the right multiply by scalar factor
56 Args:
57 other (float): factor
58 Raises:
59 DataError: if other is not a float
60 Returns:
61 fenics_mesh: copy of original values scaled by factor
62 """
64 try:
65 me = firedrake_mesh(self)
66 me.functionspace.assign(other * self.functionspace)
67 return me
68 except TypeError as e:
69 raise DataError("Type error: cannot multiply %s to %s" % (type(other), type(self))) from e
71 def __abs__(self):
72 """
73 Overloading the abs operator for mesh types
75 Returns:
76 float: L2 norm
77 """
79 return fd.norm(self.functionspace, 'L2')
81 def isend(self, dest=None, tag=None, comm=None):
82 """
83 Routine for sending data forward in time (non-blocking)
85 Args:
86 dest (int): target rank
87 tag (int): communication tag
88 comm: communicator
90 Returns:
91 request handle
92 """
93 assert (
94 type(comm) == FiredrakeEnsembleCommunicator
95 ), f'Need to give a FiredrakeEnsembleCommunicator here, not {type(comm)}'
96 return comm.Isend(self.functionspace, dest=dest, tag=tag)
98 def irecv(self, source=None, tag=None, comm=None):
99 """
100 Routine for receiving in time
102 Args:
103 source (int): source rank
104 tag (int): communication tag
105 comm: communicator
107 Returns:
108 None
109 """
110 assert (
111 type(comm) == FiredrakeEnsembleCommunicator
112 ), f'Need to give a FiredrakeEnsembleCommunicator here, not {type(comm)}'
113 return comm.Irecv(self.functionspace, source=source, tag=tag)
115 def bcast(self, root=None, comm=None):
116 """
117 Routine for broadcasting values
119 Args:
120 root (int): process with value to broadcast
121 comm: communicator
123 Returns:
124 broadcasted values
125 """
126 assert (
127 type(comm) == FiredrakeEnsembleCommunicator
128 ), f'Need to give a FiredrakeEnsembleCommunicator here, not {type(comm)}'
129 comm.Bcast(self.functionspace, root=root)
130 return self
133class IMEX_firedrake_mesh(object):
134 """
135 Datatype for IMEX integration with firedrake data.
137 Attributes:
138 impl (firedrake_mesh): implicit part
139 expl (firedrake_mesh): explicit part
140 """
142 def __init__(self, init, val=0.0):
143 if type(init) == type(self):
144 self.impl = firedrake_mesh(init.impl)
145 self.expl = firedrake_mesh(init.expl)
146 else:
147 self.impl = firedrake_mesh(init, val=val)
148 self.expl = firedrake_mesh(init, val=val)
150 def __add__(self, other):
151 me = IMEX_firedrake_mesh(self)
152 me.impl = self.impl + other.impl
153 me.expl = self.expl + other.expl
154 return me
156 def __sub__(self, other):
157 me = IMEX_firedrake_mesh(self)
158 me.impl = self.impl - other.impl
159 me.expl = self.expl - other.expl
160 return me
162 def __rmul__(self, other):
163 me = IMEX_firedrake_mesh(self)
164 me.impl = other * self.impl
165 me.expl = other * self.expl
166 return me