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

1from firedrake import assemble, prolong, inject 

2from firedrake.__future__ import interpolate 

3 

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 

7 

8 

9class MeshToMeshFiredrake(SpaceTransfer): 

10 """ 

11 This implementation can restrict and prolong between Firedrake meshes 

12 """ 

13 

14 def restrict(self, F): 

15 """ 

16 Restrict from fine to coarse grid 

17 

18 Args: 

19 F: the fine level data 

20 

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)) 

32 

33 return u_coarse 

34 

35 def prolong(self, G): 

36 """ 

37 Prolongate from coarse to fine grid 

38 

39 Args: 

40 G: the coarse level data 

41 

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)) 

53 

54 return u_fine 

55 

56 

57class MeshToMeshFiredrakeHierarchy(SpaceTransfer): 

58 """ 

59 This implementation can restrict and prolong between Firedrake meshes that are generated from a hierarchy. 

60 Example: 

61 

62 ``` 

63 from firedrake import * 

64 

65 mesh = UnitSquareMesh(8, 8) 

66 hierarchy = MeshHierarchy(mesh, 4) 

67 

68 mesh = hierarchy[-1] 

69 ``` 

70 """ 

71 

72 @staticmethod 

73 def _restrict(u_fine, u_coarse): 

74 """Perform restriction in Firedrake""" 

75 inject(u_fine.functionspace, u_coarse.functionspace) 

76 

77 @staticmethod 

78 def _prolong(u_coarse, u_fine): 

79 """Perform prolongation in Firedrake""" 

80 prolong(u_coarse.functionspace, u_fine.functionspace) 

81 

82 def restrict(self, F): 

83 """ 

84 Restrict from fine to coarse grid 

85 

86 Args: 

87 F: the fine level data 

88 

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)) 

101 

102 return G 

103 

104 def prolong(self, G): 

105 """ 

106 Prolongate from coarse to fine grid 

107 

108 Args: 

109 G: the coarse level data 

110 

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)) 

123 

124 return F