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
« 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
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 """
12 def post_step(self, step, level_number):
13 """
14 Record lift and drag forces on the cylinder at the end of each step
16 Args:
17 step (pySDC.Step.step): the current step
18 level_number (int): the current level number
20 Returns:
21 None
22 """
23 super().post_step(step, level_number)
25 L = step.levels[level_number]
26 L.sweep.compute_end_point()
27 P = L.prob
29 rho = 1
31 # normal pointing out of obstacle
32 n = -df.FacetNormal(P.V.mesh())
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)
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)
41 # assemble the scalar values
42 CD = df.assemble(drag)
43 CL = df.assemble(lift)
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 )
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 )
67class LogWriteSolutions(Hooks):
68 """
69 Hook class to log the velocity and prssure solutions and write them in XDMF files
70 """
72 def pre_run(self, step, level_number):
73 """
74 Default routine called before time-loop starts
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)
82 L = step.levels[level_number]
83 P = L.prob
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')
90 def post_step(self, step, level_number):
91 """
92 Write the solutions after each time step
94 Args:
95 step (pySDC.Step.step): the current step
96 level_number (int): the current level number
98 Returns:
99 None
100 """
102 super().post_step(step, level_number)
104 L = step.levels[level_number]
105 L.sweep.compute_end_point()
106 P = L.prob
107 t = L.time
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)
112 def post_run(self, step, level_number):
113 """
114 Default routine called after each run
116 Args:
117 step (pySDC.Step.step): the current step
118 level_number (int): the current level number
119 """
121 super().post_run(step, level_number)
123 L = step.levels[level_number]
124 P = L.prob
126 P.xdmffile_p.close()
127 P.xdmffile_u.close()