Coverage for pySDC/implementations/transfer_classes/TransferFiredrakeMesh.py: 0%
47 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
1from firedrake import assemble, prolong, inject
2from firedrake.__future__ import interpolate
4from pySDC.core.errors import TransferError
5from pySDC.core.space_transfer import SpaceTransfer
6from pySDC.implementations.datatype_classes.firedrake_mesh import firedrake_mesh, IMEX_firedrake_mesh
9class MeshToMeshFiredrake(SpaceTransfer):
10 """
11 This implementation can restrict and prolong between Firedrake meshes
12 """
14 def restrict(self, F):
15 """
16 Restrict from fine to coarse grid
18 Args:
19 F: the fine level data
21 Returns:
22 Coarse level data
23 """
24 if isinstance(F, firedrake_mesh):
25 u_coarse = self.coarse_prob.dtype_u(assemble(interpolate(F.functionspace, self.coarse_prob.init)))
26 elif isinstance(F, IMEX_firedrake_mesh):
27 u_coarse = IMEX_firedrake_mesh(self.coarse_prob.init)
28 u_coarse.impl.functionspace.assign(assemble(interpolate(F.impl.functionspace, self.coarse_prob.init)))
29 u_coarse.expl.functionspace.assign(assemble(interpolate(F.expl.functionspace, self.coarse_prob.init)))
30 else:
31 raise TransferError('Unknown type of fine data, got %s' % type(F))
33 return u_coarse
35 def prolong(self, G):
36 """
37 Prolongate from coarse to fine grid
39 Args:
40 G: the coarse level data
42 Returns:
43 fine level data
44 """
45 if isinstance(G, firedrake_mesh):
46 u_fine = self.fine_prob.dtype_u(assemble(interpolate(G.functionspace, self.fine_prob.init)))
47 elif isinstance(G, IMEX_firedrake_mesh):
48 u_fine = IMEX_firedrake_mesh(self.fine_prob.init)
49 u_fine.impl.functionspace.assign(assemble(interpolate(G.impl.functionspace, self.fine_prob.init)))
50 u_fine.expl.functionspace.assign(assemble(interpolate(G.expl.functionspace, self.fine_prob.init)))
51 else:
52 raise TransferError('Unknown type of coarse data, got %s' % type(G))
54 return u_fine
57class MeshToMeshFiredrakeHierarchy(SpaceTransfer):
58 """
59 This implementation can restrict and prolong between Firedrake meshes that are generated from a hierarchy.
60 Example:
62 ```
63 from firedrake import *
65 mesh = UnitSquareMesh(8, 8)
66 hierarchy = MeshHierarchy(mesh, 4)
68 mesh = hierarchy[-1]
69 ```
70 """
72 @staticmethod
73 def _restrict(u_fine, u_coarse):
74 """Perform restriction in Firedrake"""
75 inject(u_fine.functionspace, u_coarse.functionspace)
77 @staticmethod
78 def _prolong(u_coarse, u_fine):
79 """Perform prolongation in Firedrake"""
80 prolong(u_coarse.functionspace, u_fine.functionspace)
82 def restrict(self, F):
83 """
84 Restrict from fine to coarse grid
86 Args:
87 F: the fine level data
89 Returns:
90 Coarse level data
91 """
92 if isinstance(F, firedrake_mesh):
93 G = self.coarse_prob.u_init
94 self._restrict(u_fine=F, u_coarse=G)
95 elif isinstance(F, IMEX_firedrake_mesh):
96 G = IMEX_firedrake_mesh(self.coarse_prob.init)
97 self._restrict(u_fine=F.impl, u_coarse=G.impl)
98 self._restrict(u_fine=F.expl, u_coarse=G.expl)
99 else:
100 raise TransferError('Unknown type of fine data, got %s' % type(F))
102 return G
104 def prolong(self, G):
105 """
106 Prolongate from coarse to fine grid
108 Args:
109 G: the coarse level data
111 Returns:
112 fine level data
113 """
114 if isinstance(G, firedrake_mesh):
115 F = self.fine_prob.u_init
116 self._prolong(u_coarse=G, u_fine=F)
117 elif isinstance(G, IMEX_firedrake_mesh):
118 F = self.fine_prob.f_init
119 self._prolong(u_coarse=G.impl, u_fine=F.impl)
120 self._prolong(u_coarse=G.expl, u_fine=F.expl)
121 else:
122 raise TransferError('Unknown type of coarse data, got %s' % type(G))
124 return F