Coverage for pySDC / projects / StroemungsRaum / hooks / hooks_NSE_IMEX_FEniCS.py: 100%

40 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-27 07:06 +0000

1from pySDC.core.hooks import Hooks 

2import dolfin as df 

3import os 

4 

5 

6class LogLiftDrag(Hooks): 

7 """ 

8 Hook class to compute lift and drag forces on the cylinder at the end of each step, 

9 and add them to the statistics 

10 """ 

11 

12 def post_step(self, step, level_number): 

13 """ 

14 Record lift and drag forces on the cylinder at the end of each step 

15 

16 Args: 

17 step (pySDC.Step.step): the current step 

18 level_number (int): the current level number 

19 

20 Returns: 

21 None 

22 """ 

23 super().post_step(step, level_number) 

24 

25 L = step.levels[level_number] 

26 L.sweep.compute_end_point() 

27 P = L.prob 

28 

29 rho = 1 

30 

31 # normal pointing out of obstacle 

32 n = -df.FacetNormal(P.V.mesh()) 

33 

34 # tangential velocity component at the interface of the obstacle 

35 u_t = df.inner(df.as_vector((n[1], -n[0])), L.uend.values) 

36 

37 # compute the drag and lift coefficients 

38 drag = df.Form(2 / 0.1 * (P.nu / rho * df.inner(df.grad(u_t), n) * n[1] - P.pn * n[0]) * P.dsc) 

39 lift = df.Form(-2 / 0.1 * (P.nu / rho * df.inner(df.grad(u_t), n) * n[0] + P.pn * n[1]) * P.dsc) 

40 

41 # assemble the scalar values 

42 CD = df.assemble(drag) 

43 CL = df.assemble(lift) 

44 

45 # add to statistics 

46 self.add_to_stats( 

47 process=step.status.slot, 

48 time=L.time, 

49 level=L.level_index, 

50 iter=step.status.iter, 

51 sweep=L.status.sweep, 

52 type='lift_post_step', 

53 value=CL, 

54 ) 

55 

56 self.add_to_stats( 

57 process=step.status.slot, 

58 time=L.time, 

59 level=L.level_index, 

60 iter=step.status.iter, 

61 sweep=L.status.sweep, 

62 type='drag_post_step', 

63 value=CD, 

64 ) 

65 

66 

67class LogWriteSolutions(Hooks): 

68 """ 

69 Hook class to log the velocity and prssure solutions and write them in XDMF files 

70 """ 

71 

72 def pre_run(self, step, level_number): 

73 """ 

74 Default routine called before time-loop starts 

75 

76 Args: 

77 step (pySDC.Step.step): the current step 

78 level_number (int): the current level number 

79 """ 

80 super().pre_run(step, level_number) 

81 

82 L = step.levels[level_number] 

83 P = L.prob 

84 

85 # create XDMF file for visualization output 

86 path = f"{os.path.dirname(__file__)}/../data/navier_stokes/" 

87 P.xdmffile_p = df.XDMFFile(path + 'Cylinder_pressure.xdmf') 

88 P.xdmffile_u = df.XDMFFile(path + 'Cylinder_velocity.xdmf') 

89 

90 def post_step(self, step, level_number): 

91 """ 

92 Write the solutions after each time step 

93 

94 Args: 

95 step (pySDC.Step.step): the current step 

96 level_number (int): the current level number 

97 

98 Returns: 

99 None 

100 """ 

101 

102 super().post_step(step, level_number) 

103 

104 L = step.levels[level_number] 

105 L.sweep.compute_end_point() 

106 P = L.prob 

107 t = L.time 

108 

109 P.xdmffile_p.write_checkpoint(P.pn, "pn", t, df.XDMFFile.Encoding.HDF5, True) 

110 P.xdmffile_u.write_checkpoint(L.uend.values, "un", t, df.XDMFFile.Encoding.HDF5, True) 

111 

112 def post_run(self, step, level_number): 

113 """ 

114 Default routine called after each run 

115 

116 Args: 

117 step (pySDC.Step.step): the current step 

118 level_number (int): the current level number 

119 """ 

120 

121 super().post_run(step, level_number) 

122 

123 L = step.levels[level_number] 

124 P = L.prob 

125 

126 P.xdmffile_p.close() 

127 P.xdmffile_u.close()