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
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-01 10:24 +0000
1import logging
2import shutil
4from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.utils.openfoam_utils import \
5 OpenFOAMUtils
6from bim2sim.tasks.base import ITask
7import sys
8import os
9import pathlib
11from butterfly import foamfile
13logger = logging.getLogger(__name__)
16class RunOpenFOAMSimulation(ITask):
17 """This ITask runs the openfoam simulation on linux systems.
18 """
20 reads = ('openfoam_case', )
21 touches = ()
23 def __init__(self, playground):
24 super().__init__(playground)
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.')
33 if not sys.platform == 'linux':
34 logger.warning('Execution on non-Linux systems is not '
35 'recommended. Simulation aborted.')
36 return
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')
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)
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)
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)