Coverage for bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/task/run_openfoam_simulation.py: 0%

79 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-01 10:24 +0000

1import logging 

2import shutil 

3 

4from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.utils.openfoam_utils import \ 

5 OpenFOAMUtils 

6from bim2sim.tasks.base import ITask 

7import sys 

8import os 

9import pathlib 

10 

11from butterfly import foamfile 

12 

13logger = logging.getLogger(__name__) 

14 

15 

16class RunOpenFOAMSimulation(ITask): 

17 """This ITask runs the openfoam simulation on linux systems. 

18 """ 

19 

20 reads = ('openfoam_case', ) 

21 touches = () 

22 

23 def __init__(self, playground): 

24 super().__init__(playground) 

25 

26 def run(self, openfoam_case): 

27 if not self.playground.sim_settings.run_cfd_simulation: 

28 return 

29 elif not self.playground.sim_settings.run_meshing: 

30 logger.warning('Meshing must be done in advance. Simulation ' 

31 'aborted.') 

32 

33 if not sys.platform == 'linux': 

34 logger.warning('Execution on non-Linux systems is not ' 

35 'recommended. Simulation aborted.') 

36 return 

37 

38 of_path = openfoam_case.openfoam_dir 

39 logger.warning("Simulation in progress. This will take " 

40 "a while.") 

41 # Use half of the available processes 

42 procs = os.cpu_count() 

43 # procs = round(procs / 4) * 2 

44 steady_iterations = self.playground.sim_settings.steady_iterations 

45 radiation_precondition_time = self.playground.sim_settings.radiation_precondition_time 

46 if (self.playground.sim_settings.simulation_type == 'combined' or 

47 self.playground.sim_settings.radiation_model == 'preconditioned_fvDOM'): 

48 new_end_time = 0 

49 if self.playground.sim_settings.simulation_type == 'combined': 

50 new_end_time = steady_iterations 

51 elif self.playground.sim_settings.radiation_model == 'preconditioned_fvDOM': 

52 new_end_time = radiation_precondition_time 

53 openfoam_case.controlDict.update_values({'startTime': 0}) 

54 openfoam_case.controlDict.update_values({ 

55 'endTime': new_end_time}) 

56 write_interval = float(openfoam_case.controlDict.values['writeInterval']) 

57 if write_interval > (new_end_time/2): 

58 openfoam_case.controlDict.update_values({'writeInterval': 

59 new_end_time / 2}) 

60 openfoam_case.controlDict.save(of_path) 

61 # Execution 

62 cwd = os.getcwd() 

63 os.chdir(of_path) 

64 os.system('pwd') 

65 os.system('decomposePar -force') 

66 logger.info( 

67 'Writing buoyantSimpleFoam output to file \'logSimulation\'.') 

68 os.system('mpiexec --oversubscribe -np ' + str(procs) + ' buoyantSimpleFoam ' 

69 '-parallel > logSimulation') 

70 if self.playground.sim_settings.radiation_model == 'preconditioned_fvDOM': 

71 os.system('reconstructPar -latestTime') 

72 # add IDefault for transient simulation 

73 shutil.copy2(openfoam_case.openfoam_0_dir / 'IDefault', 

74 openfoam_case.openfoam_dir / str(new_end_time) / 'IDefault') 

75 

76 openfoam_case.controlDict.update_values({ 

77 'startFrom': 'latestTime'}) 

78 openfoam_case.controlDict.update_values({ 

79 'startTime': new_end_time}) 

80 openfoam_case.controlDict.update_values({'endTime': 

81 new_end_time + 5000}) 

82 openfoam_case.controlDict.save(of_path) 

83 eq = openfoam_case.fvSolution.relaxationFactors.values['equations'] 

84 new_eq = OpenFOAMUtils.duplicate_table_for_restart(eq, new_end_time) 

85 openfoam_case.fvSolution.relaxationFactors.values['equations'] = \ 

86 (new_eq) 

87 openfoam_case.fvSolution.save(of_path) 

88 

89 thispath = (openfoam_case.default_templates_dir / 'constant' / 

90 'radiation' / 'fvDOM' / 

91 'radiationProperties') 

92 posixpath = thispath.as_posix() 

93 openfoam_case.radiationProperties = foamfile.FoamFile.from_file(posixpath) 

94 openfoam_case.radiationProperties.save(openfoam_case.openfoam_dir) 

95 os.system('decomposePar -fields') 

96 logger.info( 

97 'Writing buoyantSimpleFoam output to file \'logSimulationfvDOM\'.') 

98 os.system('mpiexec --oversubscribe -np ' + str(procs) + ' buoyantSimpleFoam ' 

99 '-parallel > logSimulationfvDOM') 

100 if self.playground.sim_settings.simulation_type == 'combined': 

101 # update control dict for transient simulations 

102 openfoam_case.controlDict = openfoam_case.controlDict.from_file( 

103 openfoam_case.default_templates_dir / 

104 'system' / 'transient' / 

105 'controlDict') 

106 openfoam_case.controlDict.update_values({ 

107 'startFrom': 'latestTime'}) 

108 openfoam_case.controlDict.update_values({ 

109 'startTime': steady_iterations}) 

110 openfoam_case.controlDict.update_values({'endTime': 

111 steady_iterations + 10}) 

112 # get comfort settings from previous control_dict if applicable: 

113 if self.playground.sim_settings.add_comfort: 

114 openfoam_case.controlDict.values['functions'].update(openfoam_case.comfortDict) 

115 

116 openfoam_case.controlDict.save(of_path) 

117 # update fvSchemes for transient simulation 

118 openfoam_case.fvSchemes = openfoam_case.fvSchemes.from_file( 

119 openfoam_case.default_templates_dir / 

120 'system' / 'transient' / 

121 'fvSchemes') 

122 openfoam_case.fvSchemes.save(of_path) 

123 # update fvSolution for transient simulation 

124 shutil.copy2(openfoam_case.default_templates_dir / 'system' / 

125 'transient' / 'fvSolution', 

126 openfoam_case.openfoam_systems_dir) 

127 # todo: currently, fvSolution cannot be accessed using butterfly 

128 openfoam_case.fvSolution = None 

129 logger.info( 

130 'Writing buoyantPimpleFoam output to file ' 

131 '\'logSimulationPimple\'.') 

132 os.system('mpiexec --oversubscribe -np ' + str( 

133 procs) + ' buoyantPimpleFoam ' 

134 '-parallel > logSimulationPimple') 

135 os.system('reconstructPar -latestTime') 

136 os.chdir(cwd) 

137