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.
Files changed (67) hide show
  1. pycphy/__init__.py +11 -0
  2. pycphy/cli.py +145 -0
  3. pycphy/config_manager.py +373 -0
  4. pycphy/foamCaseDeveloper/__init__.py +60 -41
  5. pycphy/foamCaseDeveloper/config/__init__.py +69 -26
  6. pycphy/foamCaseDeveloper/config/cad_mesh_config.py +62 -0
  7. pycphy/foamCaseDeveloper/config/config_hfdibdem.py +193 -0
  8. pycphy/foamCaseDeveloper/config/constant/__init__.py +23 -0
  9. pycphy/foamCaseDeveloper/config/constant/dynamic_mesh_config.py +208 -0
  10. pycphy/foamCaseDeveloper/config/constant/gravity_field_config.py +379 -0
  11. pycphy/foamCaseDeveloper/config/constant/transport_properties_config.py +225 -0
  12. pycphy/foamCaseDeveloper/config/constant/turbulence_config.py +617 -0
  13. pycphy/foamCaseDeveloper/config/csv_boundary_reader.py +219 -0
  14. pycphy/foamCaseDeveloper/config/system/__init__.py +31 -0
  15. pycphy/foamCaseDeveloper/config/system/block_mesh_config.py +184 -0
  16. pycphy/foamCaseDeveloper/config/{control_config.py → system/control_config.py} +113 -1
  17. pycphy/foamCaseDeveloper/config/system/decompose_par_config.py +525 -0
  18. pycphy/foamCaseDeveloper/config/system/fv_options_config.py +575 -0
  19. pycphy/foamCaseDeveloper/config/system/fv_schemes_config.py +363 -0
  20. pycphy/foamCaseDeveloper/config/system/set_fields_config.py +640 -0
  21. pycphy/foamCaseDeveloper/config/system/snappy_hex_mesh_config.py +241 -0
  22. pycphy/foamCaseDeveloper/config/zero/U_config.py +135 -0
  23. pycphy/foamCaseDeveloper/config/zero/__init__.py +22 -0
  24. pycphy/foamCaseDeveloper/config/zero/f_config.py +140 -0
  25. pycphy/foamCaseDeveloper/config/zero/lambda_config.py +157 -0
  26. pycphy/foamCaseDeveloper/config/zero/p_config.py +97 -0
  27. pycphy/foamCaseDeveloper/core/__init__.py +30 -18
  28. pycphy/foamCaseDeveloper/core/block_mesh_developer.py +1 -1
  29. pycphy/foamCaseDeveloper/core/cad_block_mesh_developer.py +463 -0
  30. pycphy/foamCaseDeveloper/core/case_builder.py +1217 -0
  31. pycphy/foamCaseDeveloper/core/foam_case_manager.py +370 -111
  32. pycphy/foamCaseDeveloper/develop_case.py +640 -0
  33. pycphy/foamCaseDeveloper/main.py +260 -260
  34. pycphy/foamCaseDeveloper/utils/myAutoCAD.py +418 -0
  35. pycphy/foamCaseDeveloper/writers/__init__.py +37 -4
  36. pycphy/foamCaseDeveloper/writers/constant/__init__.py +25 -0
  37. pycphy/foamCaseDeveloper/writers/constant/dynamic_mesh_dict_writer.py +75 -0
  38. pycphy/foamCaseDeveloper/writers/constant/gravity_field_writer.py +88 -0
  39. pycphy/foamCaseDeveloper/writers/constant/hfdibdem_dict_writer.py +81 -0
  40. pycphy/foamCaseDeveloper/writers/constant/transport_properties_writer.py +202 -0
  41. pycphy/foamCaseDeveloper/writers/{turbulence_properties_writer.py → constant/turbulence_properties_writer.py} +49 -1
  42. pycphy/foamCaseDeveloper/writers/system/__init__.py +31 -0
  43. pycphy/foamCaseDeveloper/writers/{block_mesh_writer.py → system/block_mesh_writer.py} +1 -1
  44. pycphy/foamCaseDeveloper/writers/{control_dict_writer.py → system/control_dict_writer.py} +37 -1
  45. pycphy/foamCaseDeveloper/writers/system/decompose_par_writer.py +228 -0
  46. pycphy/foamCaseDeveloper/writers/system/fv_options_writer.py +188 -0
  47. pycphy/foamCaseDeveloper/writers/system/fv_schemes_writer.py +155 -0
  48. pycphy/foamCaseDeveloper/writers/system/set_fields_writer.py +191 -0
  49. pycphy/foamCaseDeveloper/writers/system/snappy_hex_mesh_writer.py +123 -0
  50. pycphy/foamCaseDeveloper/writers/zero/__init__.py +24 -0
  51. pycphy/foamCaseDeveloper/writers/zero/f_field_writer.py +89 -0
  52. pycphy/foamCaseDeveloper/writers/zero/lambda_field_writer.py +84 -0
  53. pycphy/foamCaseDeveloper/writers/zero/p_field_writer.py +89 -0
  54. pycphy/foamCaseDeveloper/writers/zero/u_field_writer.py +96 -0
  55. pycphy/foamCaseDeveloper/writers/zero/zero_field_factory.py +388 -0
  56. {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/METADATA +154 -6
  57. pycphy-0.2.0.dist-info/RECORD +63 -0
  58. pycphy-0.2.0.dist-info/entry_points.txt +3 -0
  59. pycphy/foamCaseDeveloper/config/block_mesh_config.py +0 -90
  60. pycphy/foamCaseDeveloper/config/turbulence_config.py +0 -187
  61. pycphy/foamCaseDeveloper/core/control_dict_writer.py +0 -55
  62. pycphy/foamCaseDeveloper/core/turbulence_properties_writer.py +0 -68
  63. pycphy-0.1.0.dist-info/RECORD +0 -24
  64. pycphy-0.1.0.dist-info/entry_points.txt +0 -2
  65. {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/WHEEL +0 -0
  66. {pycphy-0.1.0.dist-info → pycphy-0.2.0.dist-info}/licenses/LICENSE +0 -0
  67. {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)