pycphy 0.1.0__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pycphy/__init__.py +11 -0
- pycphy/cli.py +145 -0
- pycphy/config_manager.py +373 -0
- pycphy/foamCaseDeveloper/__init__.py +60 -41
- pycphy/foamCaseDeveloper/config/__init__.py +69 -26
- pycphy/foamCaseDeveloper/config/cad_mesh_config.py +62 -0
- pycphy/foamCaseDeveloper/config/config_hfdibdem.py +193 -0
- pycphy/foamCaseDeveloper/config/constant/__init__.py +23 -0
- pycphy/foamCaseDeveloper/config/constant/dynamic_mesh_config.py +208 -0
- pycphy/foamCaseDeveloper/config/constant/gravity_field_config.py +379 -0
- pycphy/foamCaseDeveloper/config/constant/transport_properties_config.py +225 -0
- pycphy/foamCaseDeveloper/config/constant/turbulence_config.py +617 -0
- pycphy/foamCaseDeveloper/config/csv_boundary_reader.py +219 -0
- pycphy/foamCaseDeveloper/config/system/__init__.py +31 -0
- pycphy/foamCaseDeveloper/config/system/block_mesh_config.py +184 -0
- pycphy/foamCaseDeveloper/config/{control_config.py → system/control_config.py} +113 -1
- pycphy/foamCaseDeveloper/config/system/decompose_par_config.py +525 -0
- pycphy/foamCaseDeveloper/config/system/fv_options_config.py +575 -0
- pycphy/foamCaseDeveloper/config/system/fv_schemes_config.py +363 -0
- pycphy/foamCaseDeveloper/config/system/set_fields_config.py +640 -0
- pycphy/foamCaseDeveloper/config/system/snappy_hex_mesh_config.py +241 -0
- pycphy/foamCaseDeveloper/config/zero/U_config.py +135 -0
- pycphy/foamCaseDeveloper/config/zero/__init__.py +22 -0
- pycphy/foamCaseDeveloper/config/zero/f_config.py +140 -0
- pycphy/foamCaseDeveloper/config/zero/lambda_config.py +157 -0
- pycphy/foamCaseDeveloper/config/zero/p_config.py +97 -0
- pycphy/foamCaseDeveloper/core/__init__.py +30 -18
- pycphy/foamCaseDeveloper/core/block_mesh_developer.py +1 -1
- pycphy/foamCaseDeveloper/core/cad_block_mesh_developer.py +463 -0
- pycphy/foamCaseDeveloper/core/case_builder.py +1217 -0
- pycphy/foamCaseDeveloper/core/foam_case_manager.py +370 -111
- pycphy/foamCaseDeveloper/develop_case.py +640 -0
- pycphy/foamCaseDeveloper/main.py +260 -260
- pycphy/foamCaseDeveloper/utils/myAutoCAD.py +418 -0
- pycphy/foamCaseDeveloper/writers/__init__.py +37 -4
- pycphy/foamCaseDeveloper/writers/constant/__init__.py +25 -0
- pycphy/foamCaseDeveloper/writers/constant/dynamic_mesh_dict_writer.py +75 -0
- pycphy/foamCaseDeveloper/writers/constant/gravity_field_writer.py +88 -0
- pycphy/foamCaseDeveloper/writers/constant/hfdibdem_dict_writer.py +81 -0
- pycphy/foamCaseDeveloper/writers/constant/transport_properties_writer.py +202 -0
- pycphy/foamCaseDeveloper/writers/{turbulence_properties_writer.py → constant/turbulence_properties_writer.py} +49 -1
- pycphy/foamCaseDeveloper/writers/system/__init__.py +31 -0
- pycphy/foamCaseDeveloper/writers/{block_mesh_writer.py → system/block_mesh_writer.py} +1 -1
- pycphy/foamCaseDeveloper/writers/{control_dict_writer.py → system/control_dict_writer.py} +37 -1
- pycphy/foamCaseDeveloper/writers/system/decompose_par_writer.py +228 -0
- pycphy/foamCaseDeveloper/writers/system/fv_options_writer.py +188 -0
- pycphy/foamCaseDeveloper/writers/system/fv_schemes_writer.py +155 -0
- pycphy/foamCaseDeveloper/writers/system/set_fields_writer.py +191 -0
- pycphy/foamCaseDeveloper/writers/system/snappy_hex_mesh_writer.py +123 -0
- pycphy/foamCaseDeveloper/writers/zero/__init__.py +24 -0
- pycphy/foamCaseDeveloper/writers/zero/f_field_writer.py +89 -0
- pycphy/foamCaseDeveloper/writers/zero/lambda_field_writer.py +84 -0
- pycphy/foamCaseDeveloper/writers/zero/p_field_writer.py +89 -0
- pycphy/foamCaseDeveloper/writers/zero/u_field_writer.py +96 -0
- pycphy/foamCaseDeveloper/writers/zero/zero_field_factory.py +388 -0
- {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/METADATA +154 -6
- pycphy-0.2.0.dist-info/RECORD +63 -0
- pycphy-0.2.0.dist-info/entry_points.txt +3 -0
- pycphy/foamCaseDeveloper/config/block_mesh_config.py +0 -90
- pycphy/foamCaseDeveloper/config/turbulence_config.py +0 -187
- pycphy/foamCaseDeveloper/core/control_dict_writer.py +0 -55
- pycphy/foamCaseDeveloper/core/turbulence_properties_writer.py +0 -68
- pycphy-0.1.0.dist-info/RECORD +0 -24
- pycphy-0.1.0.dist-info/entry_points.txt +0 -2
- {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/WHEEL +0 -0
- {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,640 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Main script to run OpenFOAM case setup using the pycphy package with config files.
|
4
|
+
|
5
|
+
This script demonstrates how to use the pycphy.foamCaseDeveloper module
|
6
|
+
with the new configuration file structure.
|
7
|
+
|
8
|
+
Author: Sanjeev Bashyal
|
9
|
+
Location: https://github.com/SanjeevBashyal/pycphy
|
10
|
+
"""
|
11
|
+
|
12
|
+
import os
|
13
|
+
import sys
|
14
|
+
import argparse
|
15
|
+
|
16
|
+
# Add the current directory to Python path to import pycphy
|
17
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
18
|
+
|
19
|
+
from pycphy.foamCaseDeveloper import FoamCaseManager, CADBlockMeshDeveloper, cad_mesh_config
|
20
|
+
from pycphy.config_manager import ConfigManager
|
21
|
+
|
22
|
+
def parse_args(argv=None):
|
23
|
+
parser = argparse.ArgumentParser(description="Run pycphy OpenFOAM case builder")
|
24
|
+
parser.add_argument("--config-dir", dest="config_dir", default=None, help="Directory containing user config .py files")
|
25
|
+
parser.add_argument("--case-name", dest="case_name", default=None, help="Override case name from configs")
|
26
|
+
|
27
|
+
# CAD-based generation options
|
28
|
+
parser.add_argument("--cad-mode", action="store_true", default=True, help="Enable CAD-based blockMeshDict generation (default)")
|
29
|
+
parser.add_argument("--config-mode", action="store_true", help="Use traditional config-based geometry generation instead of CAD")
|
30
|
+
parser.add_argument("--blocks-csv", dest="blocks_csv", default="Inputs/blocks.csv", help="Path to blocks CSV file")
|
31
|
+
parser.add_argument("--patches-csv", dest="patches_csv", default="Inputs/patches.csv", help="Path to patches CSV file")
|
32
|
+
parser.add_argument("--cad-debug", action="store_true", help="Enable debug output for CAD processing")
|
33
|
+
parser.add_argument("--cad-tolerance", dest="cad_tolerance", type=float, default=1e-6, help="Tolerance for CAD face matching")
|
34
|
+
parser.add_argument("--block-xdata-app", dest="block_xdata_app", default="BLOCKDATA", help="XData app name for blocks")
|
35
|
+
parser.add_argument("--region-xdata-app", dest="region_xdata_app", default="REGIONDATA", help="XData app name for regions")
|
36
|
+
|
37
|
+
return parser.parse_args(argv)
|
38
|
+
|
39
|
+
def setup_cad_based_mesh(case_manager, args, global_config):
|
40
|
+
"""
|
41
|
+
Set up CAD-based mesh generation using AutoCAD and CSV files.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
case_manager: FoamCaseManager instance
|
45
|
+
args: Parsed command line arguments
|
46
|
+
global_config: Global configuration object
|
47
|
+
|
48
|
+
Returns:
|
49
|
+
bool: True if successful, False otherwise
|
50
|
+
"""
|
51
|
+
print("\nSetting up CAD-based mesh generation...")
|
52
|
+
|
53
|
+
if global_config.verbose_output:
|
54
|
+
print(f" - Blocks CSV: {args.blocks_csv}")
|
55
|
+
print(f" - Patches CSV: {args.patches_csv}")
|
56
|
+
print(f" - Tolerance: {args.cad_tolerance}")
|
57
|
+
print(f" - Block XData app: {args.block_xdata_app}")
|
58
|
+
print(f" - Region XData app: {args.region_xdata_app}")
|
59
|
+
print(f" - Debug mode: {args.cad_debug}")
|
60
|
+
|
61
|
+
# Create CAD Block Mesh Developer
|
62
|
+
cad_developer = CADBlockMeshDeveloper(
|
63
|
+
blocks_csv_file=args.blocks_csv,
|
64
|
+
patches_csv_file=args.patches_csv,
|
65
|
+
tolerance=args.cad_tolerance,
|
66
|
+
block_xdata_app_name=args.block_xdata_app,
|
67
|
+
region_xdata_app_name=args.region_xdata_app
|
68
|
+
)
|
69
|
+
|
70
|
+
# Process CAD file and generate blockMeshDict + zero fields
|
71
|
+
print(" Processing CAD file and generating mesh...")
|
72
|
+
success = cad_developer.process_cad_file(
|
73
|
+
output_path=os.path.join(case_manager.case_name, "system", "blockMeshDict"),
|
74
|
+
debug=args.cad_debug
|
75
|
+
)
|
76
|
+
|
77
|
+
if success:
|
78
|
+
summary = cad_developer.get_summary()
|
79
|
+
print(f" ✓ CAD mesh generation successful!")
|
80
|
+
print(f" - {summary['total_vertices']} vertices")
|
81
|
+
print(f" - {summary['total_blocks']} blocks")
|
82
|
+
print(f" - {summary['total_patches']} patches")
|
83
|
+
print(f" - Zero field files generated with CSV boundary conditions")
|
84
|
+
|
85
|
+
# Mark geometry as ready for case creation
|
86
|
+
case_manager.mark_geometry_ready(summary)
|
87
|
+
case_manager.cad_mesh_summary = summary
|
88
|
+
return True
|
89
|
+
else:
|
90
|
+
print(f" ✗ CAD mesh generation failed!")
|
91
|
+
print(" Please check:")
|
92
|
+
print(" - AutoCAD is running with your CAD file open")
|
93
|
+
print(" - CSV files exist and have correct format")
|
94
|
+
print(" - XData is properly set on entities")
|
95
|
+
return False
|
96
|
+
|
97
|
+
def main(argv=None):
|
98
|
+
"""
|
99
|
+
Main function to demonstrate pycphy usage with config files.
|
100
|
+
"""
|
101
|
+
args = parse_args(argv)
|
102
|
+
|
103
|
+
# Handle mode selection: config-mode overrides default CAD mode
|
104
|
+
if args.config_mode:
|
105
|
+
use_cad_mode = False
|
106
|
+
else:
|
107
|
+
use_cad_mode = args.cad_mode # Default is True
|
108
|
+
|
109
|
+
print("=== pycphy: Python Computational Physics ===")
|
110
|
+
if use_cad_mode:
|
111
|
+
print("OpenFOAM Case Developer (CAD + Config Files)")
|
112
|
+
else:
|
113
|
+
print("OpenFOAM Case Developer (Config Files)")
|
114
|
+
print("Author: Sanjeev Bashyal")
|
115
|
+
print("=" * 50)
|
116
|
+
cm = ConfigManager(config_dir=args.config_dir)
|
117
|
+
if not cm.validate_configs():
|
118
|
+
return False
|
119
|
+
|
120
|
+
global_config = cm.get_global_config()
|
121
|
+
block_mesh_config = cm.get_geometry_config()
|
122
|
+
control_config = cm.get_control_config()
|
123
|
+
turbulence_config = cm.get_turbulence_config()
|
124
|
+
dynamic_mesh_config = cm.get_dynamic_mesh_config()
|
125
|
+
config_hfdibdem = cm.get_hfdibdem_config()
|
126
|
+
|
127
|
+
# Get new enhanced configs
|
128
|
+
transport_properties_config = cm.get_config('transport_properties_config')
|
129
|
+
fv_schemes_config = cm.get_config('fv_schemes_config')
|
130
|
+
fv_options_config = cm.get_config('fv_options_config')
|
131
|
+
gravity_field_config = cm.get_config('gravity_field_config')
|
132
|
+
set_fields_config = cm.get_config('set_fields_config')
|
133
|
+
decompose_par_config = cm.get_config('decompose_par_config')
|
134
|
+
snappy_hex_mesh_config = cm.get_config('snappy_hex_mesh_config')
|
135
|
+
|
136
|
+
# Get case name from global config
|
137
|
+
case_name = args.case_name or getattr(global_config, 'case_name', 'pycphyCase')
|
138
|
+
print(f"\nCreating OpenFOAM case: '{case_name}'")
|
139
|
+
|
140
|
+
if global_config.verbose_output:
|
141
|
+
print(f"Case description: {global_config.case_description}")
|
142
|
+
print(f"Author: {global_config.author_name}")
|
143
|
+
print(f"Output directory: {global_config.output_directory}")
|
144
|
+
|
145
|
+
# Create a case manager
|
146
|
+
case_manager = FoamCaseManager(case_name)
|
147
|
+
|
148
|
+
# Set up geometry configuration
|
149
|
+
if use_cad_mode:
|
150
|
+
# CAD-based mesh generation
|
151
|
+
if not setup_cad_based_mesh(case_manager, args, global_config):
|
152
|
+
return False
|
153
|
+
else:
|
154
|
+
# Traditional config-based geometry setup
|
155
|
+
print("\nSetting up geometry from config file...")
|
156
|
+
if global_config.verbose_output:
|
157
|
+
print(f" - Domain: {block_mesh_config.p0} to {block_mesh_config.p1}")
|
158
|
+
print(f" - Cells: {block_mesh_config.cells}")
|
159
|
+
total_cells = block_mesh_config.cells[0] * block_mesh_config.cells[1] * block_mesh_config.cells[2]
|
160
|
+
print(f" - Total cells: {total_cells}")
|
161
|
+
volume = (block_mesh_config.p1[0] - block_mesh_config.p0[0]) * \
|
162
|
+
(block_mesh_config.p1[1] - block_mesh_config.p0[1]) * \
|
163
|
+
(block_mesh_config.p1[2] - block_mesh_config.p0[2])
|
164
|
+
print(f" - Volume: {volume:.6f}")
|
165
|
+
print(f" - Patch names: {block_mesh_config.patch_names}")
|
166
|
+
|
167
|
+
case_manager.setup_geometry(
|
168
|
+
p0=block_mesh_config.p0,
|
169
|
+
p1=block_mesh_config.p1,
|
170
|
+
cells=block_mesh_config.cells,
|
171
|
+
patch_names=block_mesh_config.patch_names,
|
172
|
+
scale=block_mesh_config.scale
|
173
|
+
)
|
174
|
+
|
175
|
+
# Set up control configuration from config file
|
176
|
+
print("\nSetting up control parameters from config file...")
|
177
|
+
if global_config.verbose_output:
|
178
|
+
print(f" - Solver: {control_config.control_params['application']}")
|
179
|
+
print(f" - Time: {control_config.control_params['startTime']} to {control_config.control_params['endTime']}")
|
180
|
+
print(f" - Time step: {control_config.control_params['deltaT']}")
|
181
|
+
print(f" - Write interval: {control_config.control_params['writeInterval']}")
|
182
|
+
print(f" - Write control: {control_config.control_params['writeControl']}")
|
183
|
+
print(f" - Courant number: {control_config.control_params['maxCo']}")
|
184
|
+
|
185
|
+
case_manager.setup_control(control_config.control_params)
|
186
|
+
|
187
|
+
# Set up turbulence configuration from config file
|
188
|
+
print("\nSetting up turbulence model from config file...")
|
189
|
+
sim_type = getattr(turbulence_config, 'SIMULATION_TYPE', 'laminar')
|
190
|
+
if sim_type == "RAS":
|
191
|
+
model_props = getattr(turbulence_config, 'RAS_PROPERTIES', {})
|
192
|
+
model_name = model_props.get('RASModel', 'N/A')
|
193
|
+
elif sim_type == "LES":
|
194
|
+
model_props = getattr(turbulence_config, 'LES_PROPERTIES', {})
|
195
|
+
model_name = model_props.get('LESModel', 'N/A')
|
196
|
+
elif sim_type == "laminar":
|
197
|
+
model_props = getattr(turbulence_config, 'LAMINAR_PROPERTIES', {})
|
198
|
+
model_name = "laminar"
|
199
|
+
else:
|
200
|
+
print(f"Warning: Unknown simulation type '{sim_type}'. Using laminar.")
|
201
|
+
sim_type = "laminar"
|
202
|
+
model_props = {}
|
203
|
+
model_name = "laminar"
|
204
|
+
|
205
|
+
if global_config.verbose_output:
|
206
|
+
print(f" - Simulation type: {sim_type}")
|
207
|
+
print(f" - Model: {model_name}")
|
208
|
+
print(f" - Turbulence on: {turbulence_config.turbulenceOn}")
|
209
|
+
|
210
|
+
case_manager.setup_turbulence(
|
211
|
+
simulation_type=sim_type,
|
212
|
+
model_properties=model_props
|
213
|
+
)
|
214
|
+
|
215
|
+
# Set up dynamic mesh configuration from config file
|
216
|
+
print("\nSetting up dynamic mesh configuration from config file...")
|
217
|
+
write_dynamic_mesh_dict = getattr(dynamic_mesh_config, 'WRITE_DYNAMIC_MESH_DICT', False)
|
218
|
+
mesh_type = getattr(dynamic_mesh_config, 'MESH_TYPE', None)
|
219
|
+
|
220
|
+
# Map mesh type to properties
|
221
|
+
mesh_props_map = {
|
222
|
+
"solidBodyMotion": getattr(dynamic_mesh_config, 'SOLID_BODY_MOTION_PROPS', {}),
|
223
|
+
"multiBodyOverset": getattr(dynamic_mesh_config, 'MULTI_BODY_OVERSET_PROPS', {}),
|
224
|
+
"adaptiveRefinement": getattr(dynamic_mesh_config, 'ADAPTIVE_REFINEMENT_PROPS', {}),
|
225
|
+
"morphingMesh": getattr(dynamic_mesh_config, 'MORPHING_MESH_PROPS', {})
|
226
|
+
}
|
227
|
+
mesh_props = mesh_props_map.get(mesh_type)
|
228
|
+
|
229
|
+
if global_config.verbose_output:
|
230
|
+
print(f" - Write dynamic mesh dict: {write_dynamic_mesh_dict}")
|
231
|
+
if write_dynamic_mesh_dict:
|
232
|
+
print(f" - Mesh type: {mesh_type}")
|
233
|
+
if mesh_props:
|
234
|
+
print(f" - Dynamic mesh properties configured")
|
235
|
+
else:
|
236
|
+
print(f" - Warning: Unknown mesh type '{mesh_type}'")
|
237
|
+
|
238
|
+
if write_dynamic_mesh_dict and mesh_props:
|
239
|
+
case_manager.setup_dynamic_mesh(
|
240
|
+
write_dynamic_mesh_dict=write_dynamic_mesh_dict,
|
241
|
+
mesh_type=mesh_type,
|
242
|
+
mesh_properties=mesh_props
|
243
|
+
)
|
244
|
+
|
245
|
+
# Set up HFDIBDEM configuration from config file
|
246
|
+
print("\nSetting up HFDIBDEM configuration from config file...")
|
247
|
+
write_hfdibdem_dict = getattr(config_hfdibdem, 'WRITE_HFDIBDEM_DICT', False)
|
248
|
+
|
249
|
+
if global_config.verbose_output:
|
250
|
+
print(f" - Write HFDIBDEM dict: {write_hfdibdem_dict}")
|
251
|
+
if write_hfdibdem_dict:
|
252
|
+
selected_bodies = getattr(config_hfdibdem, 'SELECTED_BODY_NAMES', [])
|
253
|
+
print(f" - Selected bodies: {selected_bodies}")
|
254
|
+
print(f" - HFDIBDEM properties configured")
|
255
|
+
|
256
|
+
if write_hfdibdem_dict:
|
257
|
+
# Build HFDIBDEM properties dictionary
|
258
|
+
hfdibdem_props = getattr(config_hfdibdem, 'GLOBAL_SETTINGS', {}).copy()
|
259
|
+
|
260
|
+
# Add selected body names
|
261
|
+
selected_bodies = getattr(config_hfdibdem, 'SELECTED_BODY_NAMES', [])
|
262
|
+
hfdibdem_props["bodyNames"] = selected_bodies
|
263
|
+
|
264
|
+
# Add DEM and VirtualMesh sub-dictionaries
|
265
|
+
hfdibdem_props["DEM"] = getattr(config_hfdibdem, 'DEM_SETTINGS', {})
|
266
|
+
hfdibdem_props["virtualMesh"] = getattr(config_hfdibdem, 'VIRTUAL_MESH_SETTINGS', {})
|
267
|
+
|
268
|
+
# Add individual body configurations
|
269
|
+
available_bodies = getattr(config_hfdibdem, 'AVAILABLE_BODIES', {})
|
270
|
+
for name in selected_bodies:
|
271
|
+
if name in available_bodies:
|
272
|
+
hfdibdem_props[name] = available_bodies[name]
|
273
|
+
else:
|
274
|
+
print(f" Warning: Body '{name}' not found in AVAILABLE_BODIES")
|
275
|
+
|
276
|
+
case_manager.setup_hfdibdem(
|
277
|
+
write_hfdibdem_dict=write_hfdibdem_dict,
|
278
|
+
hfdibdem_properties=hfdibdem_props
|
279
|
+
)
|
280
|
+
|
281
|
+
# Set up transport properties configuration
|
282
|
+
print("\nSetting up transport properties from config file...")
|
283
|
+
write_transport_properties = getattr(transport_properties_config, 'WRITE_TRANSPORT_PROPERTIES', False)
|
284
|
+
transport_model = getattr(transport_properties_config, 'TRANSPORT_MODEL', 'Newtonian')
|
285
|
+
model_properties = getattr(transport_properties_config, f'{transport_model.upper()}_PROPERTIES', {})
|
286
|
+
thermal_properties = getattr(transport_properties_config, 'THERMAL_PROPERTIES', {})
|
287
|
+
species_properties = getattr(transport_properties_config, 'SPECIES_PROPERTIES', {})
|
288
|
+
advanced_properties = getattr(transport_properties_config, 'ADVANCED_PROPERTIES', {})
|
289
|
+
|
290
|
+
if global_config.verbose_output:
|
291
|
+
print(f" - Transport model: {transport_model}")
|
292
|
+
print(f" - Model properties: {list(model_properties.keys())}")
|
293
|
+
|
294
|
+
case_manager.setup_transport_properties(
|
295
|
+
write_transport_properties=write_transport_properties,
|
296
|
+
transport_model=transport_model,
|
297
|
+
model_properties=model_properties,
|
298
|
+
thermal_properties=thermal_properties,
|
299
|
+
species_properties=species_properties,
|
300
|
+
advanced_properties=advanced_properties
|
301
|
+
)
|
302
|
+
|
303
|
+
# Set up finite volume schemes configuration
|
304
|
+
print("\nSetting up finite volume schemes from config file...")
|
305
|
+
write_fv_schemes = getattr(fv_schemes_config, 'WRITE_FV_SCHEMES_DICT', True)
|
306
|
+
ddt_schemes = getattr(fv_schemes_config, 'DDT_SCHEMES', {})
|
307
|
+
grad_schemes = getattr(fv_schemes_config, 'GRAD_SCHEMES', {})
|
308
|
+
div_schemes = getattr(fv_schemes_config, 'DIV_SCHEMES', {})
|
309
|
+
laplacian_schemes = getattr(fv_schemes_config, 'LAPLACIAN_SCHEMES', {})
|
310
|
+
interpolation_schemes = getattr(fv_schemes_config, 'INTERPOLATION_SCHEMES', {})
|
311
|
+
sn_grad_schemes = getattr(fv_schemes_config, 'SN_GRAD_SCHEMES', {})
|
312
|
+
flux_required = getattr(fv_schemes_config, 'FLUX_REQUIRED', {})
|
313
|
+
|
314
|
+
if global_config.verbose_output:
|
315
|
+
print(f" - Write fvSchemes: {write_fv_schemes}")
|
316
|
+
print(f" - DDT schemes: {ddt_schemes.get('default', 'N/A')}")
|
317
|
+
print(f" - Div schemes: {len(div_schemes)} entries")
|
318
|
+
|
319
|
+
case_manager.setup_fv_schemes(
|
320
|
+
write_fv_schemes=write_fv_schemes,
|
321
|
+
ddt_schemes=ddt_schemes,
|
322
|
+
grad_schemes=grad_schemes,
|
323
|
+
div_schemes=div_schemes,
|
324
|
+
laplacian_schemes=laplacian_schemes,
|
325
|
+
interpolation_schemes=interpolation_schemes,
|
326
|
+
sn_grad_schemes=sn_grad_schemes,
|
327
|
+
flux_required=flux_required
|
328
|
+
)
|
329
|
+
|
330
|
+
# Set up finite volume options configuration
|
331
|
+
print("\nSetting up finite volume options from config file...")
|
332
|
+
write_fv_options = getattr(fv_options_config, 'WRITE_FV_OPTIONS_DICT', True)
|
333
|
+
momentum_sources = getattr(fv_options_config, 'MOMENTUM_SOURCES', {})
|
334
|
+
thermal_sources = getattr(fv_options_config, 'THERMAL_SOURCES', {})
|
335
|
+
species_sources = getattr(fv_options_config, 'SPECIES_SOURCES', {})
|
336
|
+
turbulence_sources = getattr(fv_options_config, 'TURBULENCE_SOURCES', {})
|
337
|
+
pressure_sources = getattr(fv_options_config, 'PRESSURE_SOURCES', {})
|
338
|
+
volume_fraction_sources = getattr(fv_options_config, 'VOLUME_FRACTION_SOURCES', {})
|
339
|
+
advanced_sources = getattr(fv_options_config, 'ADVANCED_SOURCES', {})
|
340
|
+
|
341
|
+
if global_config.verbose_output:
|
342
|
+
print(f" - Write fvOptions: {write_fv_options}")
|
343
|
+
print(f" - Momentum sources: {len(momentum_sources)}")
|
344
|
+
print(f" - Thermal sources: {len(thermal_sources)}")
|
345
|
+
|
346
|
+
case_manager.setup_fv_options(
|
347
|
+
write_fv_options=write_fv_options,
|
348
|
+
momentum_sources=momentum_sources,
|
349
|
+
thermal_sources=thermal_sources,
|
350
|
+
species_sources=species_sources,
|
351
|
+
turbulence_sources=turbulence_sources,
|
352
|
+
pressure_sources=pressure_sources,
|
353
|
+
volume_fraction_sources=volume_fraction_sources,
|
354
|
+
advanced_sources=advanced_sources
|
355
|
+
)
|
356
|
+
|
357
|
+
# Set up gravity field configuration
|
358
|
+
print("\nSetting up gravity field from config file...")
|
359
|
+
write_gravity_field = getattr(gravity_field_config, 'WRITE_GRAVITY_FIELD_DICT', True)
|
360
|
+
gravity_value = getattr(gravity_field_config, 'GRAVITY_VALUE', (0, 0, -9.81))
|
361
|
+
dimensions = getattr(gravity_field_config, 'DIMENSIONS', [0, 1, -2, 0, 0, 0, 0])
|
362
|
+
|
363
|
+
if global_config.verbose_output:
|
364
|
+
print(f" - Write gravity field: {write_gravity_field}")
|
365
|
+
print(f" - Gravity value: {gravity_value}")
|
366
|
+
|
367
|
+
case_manager.setup_gravity_field(
|
368
|
+
write_gravity_field=write_gravity_field,
|
369
|
+
gravity_value=gravity_value,
|
370
|
+
dimensions=dimensions
|
371
|
+
)
|
372
|
+
|
373
|
+
# Set up setFields configuration
|
374
|
+
print("\nSetting up setFields from config file...")
|
375
|
+
write_set_fields_dict = getattr(set_fields_config, 'WRITE_SET_FIELDS_DICT', True)
|
376
|
+
default_field_values = getattr(set_fields_config, 'DEFAULT_FIELD_VALUES', {})
|
377
|
+
regions = getattr(set_fields_config, 'REGIONS', [])
|
378
|
+
|
379
|
+
if global_config.verbose_output:
|
380
|
+
print(f" - Write setFields: {write_set_fields_dict}")
|
381
|
+
print(f" - Default field values: {len(default_field_values)}")
|
382
|
+
print(f" - Regions: {len(regions)}")
|
383
|
+
|
384
|
+
case_manager.setup_set_fields(
|
385
|
+
write_set_fields_dict=write_set_fields_dict,
|
386
|
+
default_field_values=default_field_values,
|
387
|
+
regions=regions
|
388
|
+
)
|
389
|
+
|
390
|
+
# Set up decomposePar configuration
|
391
|
+
print("\nSetting up decomposePar from config file...")
|
392
|
+
write_decompose_par_dict = getattr(decompose_par_config, 'WRITE_DECOMPOSE_PAR_DICT', True)
|
393
|
+
number_of_subdomains = getattr(decompose_par_config, 'NUMBER_OF_SUBDOMAINS', 4)
|
394
|
+
method = getattr(decompose_par_config, 'METHOD', 'scotch')
|
395
|
+
coeffs = getattr(decompose_par_config, 'COEFFS', {})
|
396
|
+
options = getattr(decompose_par_config, 'OPTIONS', {})
|
397
|
+
fields = getattr(decompose_par_config, 'FIELDS', [])
|
398
|
+
preserve_patches = getattr(decompose_par_config, 'PRESERVE_PATCHES', [])
|
399
|
+
preserve_cell_zones = getattr(decompose_par_config, 'PRESERVE_CELL_ZONES', [])
|
400
|
+
preserve_face_zones = getattr(decompose_par_config, 'PRESERVE_FACE_ZONES', [])
|
401
|
+
preserve_point_zones = getattr(decompose_par_config, 'PRESERVE_POINT_ZONES', [])
|
402
|
+
|
403
|
+
if global_config.verbose_output:
|
404
|
+
print(f" - Write decomposePar: {write_decompose_par_dict}")
|
405
|
+
print(f" - Number of subdomains: {number_of_subdomains}")
|
406
|
+
print(f" - Method: {method}")
|
407
|
+
|
408
|
+
case_manager.setup_decompose_par(
|
409
|
+
write_decompose_par_dict=write_decompose_par_dict,
|
410
|
+
number_of_subdomains=number_of_subdomains,
|
411
|
+
method=method,
|
412
|
+
coeffs=coeffs,
|
413
|
+
options=options,
|
414
|
+
fields=fields,
|
415
|
+
preserve_patches=preserve_patches,
|
416
|
+
preserve_cell_zones=preserve_cell_zones,
|
417
|
+
preserve_face_zones=preserve_face_zones,
|
418
|
+
preserve_point_zones=preserve_point_zones
|
419
|
+
)
|
420
|
+
|
421
|
+
# Set up snappyHexMesh configuration
|
422
|
+
print("\nSetting up snappyHexMesh from config file...")
|
423
|
+
write_snappy_hex_mesh_dict = getattr(snappy_hex_mesh_config, 'WRITE_SNAPPY_HEX_MESH_DICT', True)
|
424
|
+
geometry = getattr(snappy_hex_mesh_config, 'GEOMETRY', {})
|
425
|
+
castellated_mesh_controls = getattr(snappy_hex_mesh_config, 'CASTELLATED_MESH_CONTROLS', {})
|
426
|
+
snap_controls = getattr(snappy_hex_mesh_config, 'SNAP_CONTROLS', {})
|
427
|
+
add_layers_controls = getattr(snappy_hex_mesh_config, 'ADD_LAYERS_CONTROLS', {})
|
428
|
+
mesh_quality_controls = getattr(snappy_hex_mesh_config, 'MESH_QUALITY_CONTROLS', {})
|
429
|
+
merged_patches = getattr(snappy_hex_mesh_config, 'MERGED_PATCHES', [])
|
430
|
+
write_flags = getattr(snappy_hex_mesh_config, 'WRITE_FLAGS', {})
|
431
|
+
|
432
|
+
if global_config.verbose_output:
|
433
|
+
print(f" - Write snappyHexMesh: {write_snappy_hex_mesh_dict}")
|
434
|
+
print(f" - Geometry: {len(geometry)} entries")
|
435
|
+
print(f" - Max global cells: {castellated_mesh_controls.get('maxGlobalCells', 'N/A')}")
|
436
|
+
|
437
|
+
case_manager.setup_snappy_hex_mesh(
|
438
|
+
write_snappy_hex_mesh_dict=write_snappy_hex_mesh_dict,
|
439
|
+
geometry=geometry,
|
440
|
+
castellated_mesh_controls=castellated_mesh_controls,
|
441
|
+
snap_controls=snap_controls,
|
442
|
+
add_layers_controls=add_layers_controls,
|
443
|
+
mesh_quality_controls=mesh_quality_controls,
|
444
|
+
merged_patches=merged_patches,
|
445
|
+
write_flags=write_flags
|
446
|
+
)
|
447
|
+
|
448
|
+
# Set up zero field configurations (skip if CAD mode - already generated)
|
449
|
+
if not use_cad_mode:
|
450
|
+
print("\nSetting up zero field configurations from config file...")
|
451
|
+
|
452
|
+
# Load zero field configs
|
453
|
+
p_config = cm.get_config('p_config')
|
454
|
+
u_config = cm.get_config('u_config')
|
455
|
+
f_config = cm.get_config('f_config')
|
456
|
+
lambda_config = cm.get_config('lambda_config')
|
457
|
+
else:
|
458
|
+
print("\nSkipping zero field setup (already generated by CAD processing)")
|
459
|
+
# Set dummy values to avoid errors
|
460
|
+
write_p_field = False
|
461
|
+
write_u_field = False
|
462
|
+
write_f_field = False
|
463
|
+
write_lambda_field = False
|
464
|
+
|
465
|
+
# Set up zero fields (only if not in CAD mode)
|
466
|
+
if not use_cad_mode:
|
467
|
+
# Set up pressure field (p)
|
468
|
+
write_p_field = getattr(p_config, 'WRITE_P_FIELD', False)
|
469
|
+
internal_pressure = getattr(p_config, 'INTERNAL_PRESSURE', 0.0)
|
470
|
+
p_boundary_conditions = getattr(p_config, 'BOUNDARY_CONDITIONS', {})
|
471
|
+
ref_pressure_cell = getattr(p_config, 'REF_PRESSURE_CELL', 0)
|
472
|
+
ref_pressure_value = getattr(p_config, 'REF_PRESSURE_VALUE', 0.0)
|
473
|
+
pressure_dimensions = getattr(p_config, 'PRESSURE_DIMENSIONS', [0, 2, -2, 0, 0, 0, 0])
|
474
|
+
|
475
|
+
if global_config.verbose_output:
|
476
|
+
print(f" - Write p field: {write_p_field}")
|
477
|
+
print(f" - Internal pressure: {internal_pressure}")
|
478
|
+
|
479
|
+
case_manager.setup_p_field(
|
480
|
+
write_p_field=write_p_field,
|
481
|
+
internal_pressure=internal_pressure,
|
482
|
+
boundary_conditions=p_boundary_conditions,
|
483
|
+
ref_pressure_cell=ref_pressure_cell,
|
484
|
+
ref_pressure_value=ref_pressure_value,
|
485
|
+
pressure_dimensions=pressure_dimensions
|
486
|
+
)
|
487
|
+
|
488
|
+
# Set up velocity field (U)
|
489
|
+
write_u_field = getattr(u_config, 'WRITE_U_FIELD', False)
|
490
|
+
internal_velocity = getattr(u_config, 'INTERNAL_VELOCITY', (0.0, 0.0, 0.0))
|
491
|
+
u_boundary_conditions = getattr(u_config, 'BOUNDARY_CONDITIONS', {})
|
492
|
+
velocity_dimensions = getattr(u_config, 'VELOCITY_DIMENSIONS', [0, 1, -1, 0, 0, 0, 0])
|
493
|
+
|
494
|
+
if global_config.verbose_output:
|
495
|
+
print(f" - Write U field: {write_u_field}")
|
496
|
+
print(f" - Internal velocity: {internal_velocity}")
|
497
|
+
|
498
|
+
case_manager.setup_u_field(
|
499
|
+
write_u_field=write_u_field,
|
500
|
+
internal_velocity=internal_velocity,
|
501
|
+
boundary_conditions=u_boundary_conditions,
|
502
|
+
velocity_dimensions=velocity_dimensions
|
503
|
+
)
|
504
|
+
|
505
|
+
# Set up force field (f)
|
506
|
+
write_f_field = getattr(f_config, 'WRITE_F_FIELD', False)
|
507
|
+
internal_force = getattr(f_config, 'INTERNAL_FORCE', (0.0, 0.0, 0.0))
|
508
|
+
f_boundary_conditions = getattr(f_config, 'BOUNDARY_CONDITIONS', {})
|
509
|
+
force_dimensions = getattr(f_config, 'FORCE_DIMENSIONS', [0, 1, -2, 0, 0, 0, 0])
|
510
|
+
|
511
|
+
if global_config.verbose_output:
|
512
|
+
print(f" - Write f field: {write_f_field}")
|
513
|
+
print(f" - Internal force: {internal_force}")
|
514
|
+
|
515
|
+
case_manager.setup_f_field(
|
516
|
+
write_f_field=write_f_field,
|
517
|
+
internal_force=internal_force,
|
518
|
+
boundary_conditions=f_boundary_conditions,
|
519
|
+
force_dimensions=force_dimensions
|
520
|
+
)
|
521
|
+
|
522
|
+
# Set up lambda field (λ)
|
523
|
+
write_lambda_field = getattr(lambda_config, 'WRITE_LAMBDA_FIELD', False)
|
524
|
+
internal_lambda = getattr(lambda_config, 'INTERNAL_LAMBDA', 0.0)
|
525
|
+
lambda_boundary_conditions = getattr(lambda_config, 'BOUNDARY_CONDITIONS', {})
|
526
|
+
lambda_dimensions = getattr(lambda_config, 'LAMBDA_DIMENSIONS', [0, 0, 0, 0, 0, 0, 0])
|
527
|
+
|
528
|
+
if global_config.verbose_output:
|
529
|
+
print(f" - Write lambda field: {write_lambda_field}")
|
530
|
+
print(f" - Internal lambda: {internal_lambda}")
|
531
|
+
|
532
|
+
case_manager.setup_lambda_field(
|
533
|
+
write_lambda_field=write_lambda_field,
|
534
|
+
internal_lambda=internal_lambda,
|
535
|
+
boundary_conditions=lambda_boundary_conditions,
|
536
|
+
lambda_dimensions=lambda_dimensions
|
537
|
+
)
|
538
|
+
|
539
|
+
# Create the complete case
|
540
|
+
print(f"\nCreating complete OpenFOAM case...")
|
541
|
+
success = case_manager.create_full_case()
|
542
|
+
|
543
|
+
if success:
|
544
|
+
print(f"\n=== SUCCESS ===")
|
545
|
+
print(f"OpenFOAM case '{case_name}' has been created successfully!")
|
546
|
+
print(f"\nGenerated files:")
|
547
|
+
print(f" - {os.path.join(case_name, 'system', 'blockMeshDict')}")
|
548
|
+
print(f" - {os.path.join(case_name, 'system', 'controlDict')}")
|
549
|
+
print(f" - {os.path.join(case_name, 'constant', 'turbulenceProperties')}")
|
550
|
+
|
551
|
+
# Show dynamicMeshDict if it was created
|
552
|
+
if (write_dynamic_mesh_dict and mesh_props):
|
553
|
+
print(f" - {os.path.join(case_name, 'constant', 'dynamicMeshDict')}")
|
554
|
+
|
555
|
+
# Show HFDIBDEMDict if it was created
|
556
|
+
if write_hfdibdem_dict:
|
557
|
+
print(f" - {os.path.join(case_name, 'constant', 'HFDIBDEMDict')}")
|
558
|
+
|
559
|
+
# Show transport properties if created
|
560
|
+
if write_transport_properties:
|
561
|
+
print(f" - {os.path.join(case_name, 'constant', 'transportProperties')}")
|
562
|
+
|
563
|
+
# Show fvSchemes if created
|
564
|
+
if write_fv_schemes:
|
565
|
+
print(f" - {os.path.join(case_name, 'system', 'fvSchemes')}")
|
566
|
+
|
567
|
+
# Show fvOptions if created
|
568
|
+
if write_fv_options:
|
569
|
+
print(f" - {os.path.join(case_name, 'system', 'fvOptions')}")
|
570
|
+
|
571
|
+
# Show gravity field if created
|
572
|
+
if write_gravity_field:
|
573
|
+
print(f" - {os.path.join(case_name, 'constant', 'g')}")
|
574
|
+
|
575
|
+
# Show setFields if created
|
576
|
+
if write_set_fields_dict:
|
577
|
+
print(f" - {os.path.join(case_name, 'system', 'setFieldsDict')}")
|
578
|
+
|
579
|
+
# Show decomposePar if created
|
580
|
+
if write_decompose_par_dict:
|
581
|
+
print(f" - {os.path.join(case_name, 'system', 'decomposeParDict')}")
|
582
|
+
|
583
|
+
# Show snappyHexMesh if created
|
584
|
+
if write_snappy_hex_mesh_dict:
|
585
|
+
print(f" - {os.path.join(case_name, 'system', 'snappyHexMeshDict')}")
|
586
|
+
|
587
|
+
# Show zero directory files if created
|
588
|
+
if use_cad_mode:
|
589
|
+
# Show CAD-generated zero files
|
590
|
+
print(f" - {os.path.join(case_name, '0', 'p')} (CAD-generated)")
|
591
|
+
print(f" - {os.path.join(case_name, '0', 'U')} (CAD-generated)")
|
592
|
+
print(f" - {os.path.join(case_name, '0', 'f')} (CAD-generated)")
|
593
|
+
print(f" - {os.path.join(case_name, '0', 'lambda')} (CAD-generated)")
|
594
|
+
else:
|
595
|
+
# Show config-generated zero files
|
596
|
+
if write_p_field:
|
597
|
+
print(f" - {os.path.join(case_name, '0', 'p')}")
|
598
|
+
if write_u_field:
|
599
|
+
print(f" - {os.path.join(case_name, '0', 'U')}")
|
600
|
+
if write_f_field:
|
601
|
+
print(f" - {os.path.join(case_name, '0', 'f')}")
|
602
|
+
if write_lambda_field:
|
603
|
+
print(f" - {os.path.join(case_name, '0', 'lambda')}")
|
604
|
+
|
605
|
+
if global_config.verbose_output:
|
606
|
+
print(f"\nCase information:")
|
607
|
+
print(f" - Description: {global_config.case_description}")
|
608
|
+
print(f" - Author: {global_config.author_name}")
|
609
|
+
print(f" - Created: {global_config.creation_date}")
|
610
|
+
print(f" - Solver: {control_config.control_params['application']}")
|
611
|
+
print(f" - Simulation type: {sim_type}")
|
612
|
+
if use_cad_mode and hasattr(case_manager, 'cad_mesh_summary'):
|
613
|
+
cad_summary = case_manager.cad_mesh_summary
|
614
|
+
print(f" - CAD mesh: {cad_summary['total_blocks']} blocks, {cad_summary['total_patches']} patches")
|
615
|
+
|
616
|
+
print(f"\nYou can now run OpenFOAM commands like:")
|
617
|
+
print(f" cd {case_name}")
|
618
|
+
if use_cad_mode:
|
619
|
+
print(f" # Mesh already generated from CAD")
|
620
|
+
else:
|
621
|
+
print(f" blockMesh")
|
622
|
+
print(f" {control_config.control_params['application']}")
|
623
|
+
return True
|
624
|
+
else:
|
625
|
+
print(f"\n=== FAILED ===")
|
626
|
+
print(f"OpenFOAM case creation failed!")
|
627
|
+
return False
|
628
|
+
|
629
|
+
if __name__ == "__main__":
|
630
|
+
try:
|
631
|
+
success = main()
|
632
|
+
sys.exit(0 if success else 1)
|
633
|
+
except KeyboardInterrupt:
|
634
|
+
print("\n\nOperation cancelled by user.")
|
635
|
+
sys.exit(1)
|
636
|
+
except Exception as e:
|
637
|
+
print(f"\nUnexpected error: {e}")
|
638
|
+
import traceback
|
639
|
+
traceback.print_exc()
|
640
|
+
sys.exit(1)
|