Coverage for pySDC / projects / StroemungsRaum / run_Navier_Stokes_equations_FEniCS.py: 72%

60 statements  

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

1from pathlib import Path 

2import json 

3 

4from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI 

5from pySDC.projects.StroemungsRaum.problem_classes.NavierStokes_2D_FEniCS import fenics_NSE_2D_mass 

6from pySDC.projects.StroemungsRaum.sweepers.imex_1st_order_mass_NSE import imex_1st_order_mass_NSE 

7from pySDC.projects.StroemungsRaum.hooks.hooks_NSE_IMEX_FEniCS import LogLiftDrag 

8from pySDC.helpers.stats_helper import get_sorted 

9 

10 

11def setup(t0=0): 

12 """ 

13 Helper routine to set up parameters 

14 

15 Args: 

16 t0: float, 

17 initial time 

18 

19 Returns: 

20 description: dict, 

21 pySDC description dictionary containing problem and method parameters. 

22 controller_params: dict, 

23 Parameters for the pySDC controller. 

24 """ 

25 # time step size 

26 dt = 1 / 1600 

27 

28 # initialize level parameters 

29 level_params = dict() 

30 level_params['e_tol'] = 1e-9 

31 level_params['dt'] = dt 

32 

33 # initialize step parameters 

34 step_params = dict() 

35 step_params['maxiter'] = 10 

36 

37 # initialize sweeper parameters 

38 sweeper_params = dict() 

39 sweeper_params['quad_type'] = 'RADAU-RIGHT' 

40 sweeper_params['num_nodes'] = 2 

41 sweeper_params['QE'] = ['PIC'] 

42 sweeper_params['QI'] = ['LU'] 

43 

44 # initialize problem parameters 

45 problem_params = dict() 

46 problem_params['nu'] = 0.001 

47 problem_params['t0'] = t0 

48 problem_params['family'] = 'CG' 

49 problem_params['order'] = 2 

50 

51 # initialize controller parameters 

52 controller_params = dict() 

53 controller_params['logger_level'] = 20 

54 controller_params['hook_class'] = [LogLiftDrag] 

55 

56 # Fill description dictionary 

57 description = dict() 

58 description['problem_class'] = fenics_NSE_2D_mass 

59 description['sweeper_class'] = imex_1st_order_mass_NSE 

60 description['problem_params'] = problem_params 

61 description['sweeper_params'] = sweeper_params 

62 description['level_params'] = level_params 

63 description['step_params'] = step_params 

64 

65 return description, controller_params 

66 

67 

68def run_simulation(description, controller_params, Tend): 

69 """ 

70 Run the time integration for the 2D Navier-Stokes equations. 

71 

72 Args: 

73 description: dict, 

74 pySDC problem and method description. 

75 controller_params: dict, 

76 Parameters for the pySDC controller. 

77 Tend: float, 

78 Final simulation time. 

79 

80 Returns: 

81 P: problem instance, 

82 Problem instance containing the final solution and other problem-related information. 

83 stats: dict, 

84 collected runtime statistics, 

85 uend: FEniCS function, 

86 Final solution at time Tend. 

87 """ 

88 # get initial time from description 

89 t0 = description['problem_params']['t0'] 

90 

91 # quickly generate block of steps 

92 controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description) 

93 

94 # get initial values on finest level 

95 P = controller.MS[0].levels[0].prob 

96 uinit = P.u_exact(t0) 

97 

98 # call main function to get things done... 

99 uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend) 

100 

101 return P, stats, uend 

102 

103 

104def run_postprocessing(description, stats): 

105 """ 

106 Postprocess and store simulation results for visualization and analysis. 

107 

108 Args: 

109 description: dict, 

110 pySDC description containing problem parameters. 

111 problem: Problem instance, 

112 Problem instance containing the final solution and other problem-related information. 

113 stats: dict, 

114 collected runtime statistics, 

115 

116 Returns: None 

117 """ 

118 # get the data directory 

119 import os 

120 

121 # create directory for storing results 

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

123 Path(path).mkdir(parents=True, exist_ok=True) 

124 

125 # extract lift and drag coefficients from the collected statistics 

126 lift = get_sorted(stats, type='lift_post_step', sortby='time') 

127 drag = get_sorted(stats, type='drag_post_step', sortby='time') 

128 

129 # extract timing information 

130 timing = get_sorted(stats, type='timing_run', sortby='time') 

131 

132 # save parameters 

133 parameters = description['problem_params'] 

134 parameters.update(description['level_params']) 

135 parameters['Tend'] = lift[-1][0] 

136 parameters['timing'] = timing[0][1] 

137 with open(path + "Navier_Stokes_FEniCS_parameters.json", 'w') as f: 

138 json.dump(parameters, f) 

139 

140 # save lift and drag coefficients 

141 with open(path + "Lift_Drag_Coefficients.txt", 'w') as f: 

142 for i in range(len(lift)): 

143 out = '%1.16f %1.16f %1.16f' % (lift[i][0], drag[i][1], lift[i][1]) 

144 f.write(out + '\n') 

145 

146 return None 

147 

148 

149if __name__ == "__main__": 

150 

151 t0 = 3.125e-04 

152 Tend = 0.005 

153 

154 # run the setup to get description and controller parameters 

155 description, controller_params = setup(t0=t0) 

156 

157 # run the simulation and get the problem, stats and final solution 

158 problem, stats, uend = run_simulation(description, controller_params, Tend) 

159 

160 # run postprocessing to save parameters and solutions for visualization 

161 run_postprocessing(description, stats)