Table of Content:
Running PyFLUENT in GUI Session ]-[ Offline Features of PyFLUENT [-] Get list of wall and cell zones ]=[ Rename Zones |=| Define Materials and Boundary Conditions (*) Generate summary of a simulation set-up {*} Various Utility Scripts in Python [*] Utilities related to file system |+| Java vs. Python |*| Python vs JavaScript |+| Download items in an Internet Archive collection |$| ChatGPT Responses Related to Prompts on CFD Simulations |=| Define Input Variables for Meshing {/\} Define Input Variables for Solver Setting [/\] Solver Setup and Solve Workflow
fluent.docs.pyansys.com/ version/ stable/ user_guide/ index.html#ref-user-guide should be the starting point to learn how to use PyFluent. developer.ansys.com/blog/all-you-need-know-about-pyfluents-settings-apis-and-objects is another good reference.
This is a compilation of codes or syntax used in PyFluent. The attempt is to create functions which can be turned on and off based on requirements of the simulation physics. field_data object is an attribute of the Solver object where "field_data = solver.fields .field_data" and solver is a Fluent session started by solver = pyfluent .launch_fluent(mode = pyfluent.FluentMode .SOLVER). When a fluent session is already opened with Python console, session = pyfluent.launch_fluent() is not required though "import ansys.fluent.core as pyfluent" is required.import ansys.fluent.core as pyfluent - the statement to import core functionality. session = pyfluent.launch_fluent(): without any argument, this starts a solver session (i.e. Solution mode) and without GUI. There are two modes of PyFLUENT API: (a) the TUI API which follows syntax similar to FLUENT TUI and (b) Settings API which is equivalent to GUI or Model Tree Approach. In Settings API, the option selected through toggle or check buttons are activated using .enabled = True such as session.setup .models .energy .enabled = True or energy.enabled .set_state(True) or session.setup .models .energy .enabled('yes') where ".enabled = True" is replaced by ('yes'). get_state is used to get the values defined through drop-down menu and check-box. The items which are selected by user is typically provided as arguments: solver.tui .define .units("length", "mm") where the variable 'length' and unit 'mm' are selected by user in the GUI window. Note the equivalent Scheme command is "define units length mm".
Many times the output from PyFLUENT are nested dictionaries. For example, solver.setup.materials.fluid() where the required information can be extracted as solver.setup .materials .fluid() ['air'] ['thermal_conductivity'] ['value']. Following function can be used to print it as tree structure. To get the length of top-level (first-level) keys: len(dict_name). Use list(dict_name) to get top-level keys as a Python list. def printDictKeysAsTree(nested_dict, indent_level=0):
for key, value in nested_dict.items():
print(" " * indent_level + "- " + str(key))
if isinstance(value, dict):
printDictKeysAsTree(value, indent_level + 1) |
| To record TUI commands as PyFLUENT script, type in the TUI: (api-start-python-journal "py_fluent.py"). To stop: (api-stop-python-journal). Like many standard IDE, press tab after dot (.) in the command syntax to get options in drop-down items. For example, session.file.read. and press tab key to get available options. Use keywords arguments and argument_names to get names of arguments required. For example: session.file .read .argument_names. Alternatively, args = session.solver .file .read_case .get_arguments(), print(args). |
Like any OOP-language, following two methods can be used based on users' preferences:
outlet = solver.setup.boundary_conditions.pressure_outlet[b_outlet]
outlet.turbulence.turb_intensity = 2.5
--or--
solver.setup.boundary_conditions.pressure_outlet[b_outlet]
.turbulence.turbulent_intensity = 2.5
solver .setup .boundary_conditions .get_state()['wall'] .keys(): 'wall' type zones |
| As in OOP: the 'object' 'Solver' session provides child 'objects' for solver settings and field data access respectively. Get these fields and settings children by calling dir(solver). To get children of fields and settings, use dir(solver.fields) and dir(solver.settings) respectively. To find out more about each item in PyFluent, use Python help() function: help(solver.settings.file.read_case). The CaseFile class allows you to access Fluent case information without a live Fluent session. The FileSession class mimics the functionality of live session objects, allowing you to access field data and other relevant information without a live Fluent session. |
from pathlib import Path from pprint import pprint import ansys.fluent.core as pyfluent from ansys.fluent.core import examples from ansys.fluent.core.filereader.case_file import CaseFile from ansys.fluent.core.filereader.case_file import DataFile from ansys.fluent.visualization import set_config import ansys.fluent.visualization.pyvista as pv from ansys.units import Quantity |
| Here ansys.fluent.core is the main Python package. Inside it, there are many modules such as filereader, meshing, solver, session_meshing, session_solver... Each Module shall contain multiple classes and associated Methods. In the example offline_reader = CaseFile(case_file_name = "Case1.cas.gz"), offline_reader is an object of class CaseFile. One may also infer class and variables by the naming convention: PyFLUENT uses Pascal case to name Classes and snake case to name objects, variables and methods. One can create own sign convention such as Pascal-snake case combination (e.g. Geom_File_Name) but a convention is needed to make consistent and reusable scripts. PyAnsys: import ansys.meshing.prime as prime is for Ansys (Workbench) Meshing. |
| session.setup.models.viscous() - prints all options for turbulence model currently defined. Note models is an object in FLUENT model-tree. |
| session.setup .materials() - prints currently defined materials and their properties. session.setup .cell_zone_conditions .fluid()- prints all defined cell-zones and their properties |
| session.setup.cell_zone_conditions.fluid['zone_x'](material='water-liquid') - Note that the object "Cell Zone Conditions" in model tree is accessed by cell_zone_conditions. The domain names are specified as list inside [...] and arguments are specified inside (...). |
Longer sentences can be broken into smaller and the name of variables can also be same as built-in variable inside PyFluent. There are different views on dot operator: "It is just a syntactic element that denotes the seperation of variable name holding an object and the object's property or seperates package names and classes." An alternate view is: ". is certainly an operator, a binary operator. The left operand resolves to some module in the program and the right one resolves to a sub-module of the left hand. It has left-to-right associativity." Refer: stackoverflow.com/ ... /what-is-the-purpose-of-java-dot-operator. session = pyfluent.launch_fluent() fields = session.fields field_data = fields.field_data transaction = field_data.new_transaction() pressure_fields = transaction.get_fields() |
The class and function can be directly access such as meshing.File.ReadMesh(FileName = file_name). With Python console, the options generated with Enter key press in classical Scheme console is not available.
|
setup class in PyFluent has sub-classes aligned to the model tree shown below.
Setup | |-- General |-- Models |-- Materials |-- Motion Definitions |-- Cell Zone Conditions |-- Boundary Conditions |-- Mesh Interfaces |-- Auxiliary Geometry Definitions |-- Dynamic Mesh |-- Reference Values |-- Reference Frames |-- Named Expressions `-- Curvilinear Coordinate System'General' accessed as setup.general and others are [models, materials, cell_zone_conditions, boundary_conditions, mesh_interface...]. The 'Models' object expands to [multiphase, energy, viscous, radiation...] which can be accessed by setup.models.multiphase... Get type of output and index of an item in a list: type(solver.rp_vars .allowed_values()) and solver.rp_vars .allowed_values() .index("rf-energy?") |
Get downstream options: solver.setup.materials.child_names which prints ['database', 'fluid', 'solid', 'mixture', 'intert_particle', 'particle-mixture']. is_active() is an useful method to check if something is 'defined': solver .settings . boundary_conditions .mass_flow_inlet .is_active() can be used to check if 'mass-flow-inlet' is defined or not. items() function can be used to get list of objects defined: solver .results .scene .items() gives list of scenes defined in the case file. |
# ------------------------OFFLINE FEATURES-------------------------------------
offline_reader = CaseFile(case_file_name = "Case1.cas.gz")
# Check precision and dimension of set-up
offline_reader.precision()
offline_reader.num_dimensions()
# Get input and output paramters defined in the case as 'dictionaries'
{par.name: par.value for par in offline_reader.input_parameters()}
{par.name: par.units for par in offline_reader.output_parameters()}
offline_reader.get_mesh().get_surface_names()
offline_reader_data = DataFile(data_file_name="Case1-2500.dat.gz",
case_file_handle=CaseFile("Case1.cas.gz")) |
Example code: Generate summary of a simulation set-up:def generate_summary():
# Getting boundary conditions
bc_wall = solver.setup.boundary_conditions.get_state()['wall'].keys()
bc_pr_out = list(solver.setup.boundary_conditions.get_state()
['pressure_outlet'].keys())
solver.setup.boundary_conditions.get_active_child_names()
# Ouput is ['interior', 'pressure_outlet', 'velocity_inlet', 'wall'
'non_reflecting_bc', 'perforated_wall', 'settings']
materials = pyfluent.Materials(session) #Refer PyFLUENT cheatsheet
fluids = materials.fluid
# Get materials: solver.setup.materials.fluid() # returns nested dictionary
mat_fluids = list(solver.setup.materials.fluid) # get list
mat_fluids = solver.setup.materials.fluid.keys() # get dictionary
mat_solids = list(solver.setup.materials.solid)
# Get thermal conductivity of material 'air'
solver.setup.materials.fluid()['air']['thermal_conductivity']['value']
# Getting discretization schemes
discrete_schemes = list(solver.solution.method.discretization_scheme)
# Access pressure
discrete_schemes[0] or list(solver.solution.method.discretization_scheme)[0]
# Get discretization scheme defined for pressure
print(solver.solution.method.discretization_scheme['pressure'].get_state())
# Note that get_state() is used to get the value defined in drop-down
# Print summary
print("-----Simulation Summary-----")
print("\n---Materials:")
for solid in mat_solids:
print(...)
# Call the function to generate the summary
generate_summary() |
#------------------------------------------------------------------------------
#------------------------------------USER INPUTS: MESH-------------------------
geom_file = "D:\Projects\Geom.stp"
save_path = Path("D:\Projects")
mesh_file = "D:\Projects\Case1-Srf.msh.gz"
save_mesh = "D:\Projects\Case1-Vol.msh.gz"
# Configure specific settings
set_config(blocking=True, set_view_on_display="isometric")
# Surface Mesh settings
Curv_Norm_Angle = 6.0
Growth_Rate = 1.2
Max_Size = 5.0
Min_Size = 0.5
SizeFunc = "Curvature"
# Boundary layer settings
BLControlName = "smooth-transition_1"
BL_Num_Layers = 5
BL_GrowthRate = 1.25
BL_Trans_Ratio = 0.5
# BOI settings
BOI_GrowthRate = 1.10
BOI_Size = 0.1
# Volume fill settings
vol_mesh_type = "poly"
|
# # ------------------------------SOLVER INPUTS [SI UNITs]----------------------- case_file = "D:\Projects\Case-1.cas.gz" mesh_file = "D:\Projects\Case-1.msh.gz" journ_file = "D:\Projects\setup.jou" physics_type = "steasy_state" # "transient" viscous_model = "k-epsilon" # "k-omega" wall_func_model = "realizable" # "standard", "scalable" rho_w = 1000 rho_a = 1.178 mu_w = 0.001 mu_a = 1.2e-6 # Zone and boundary names c_fluid = "zn_f_air" c_solid = "zn_s_heatsink" c_porous = "zn_p_cac" b_inlet = "inlet" b_inlet_v = 5.0 b_inlet_p = 500 b_inlet_mf = 0.25 b_inlet_t = 313.15 # "Intensity and Viscosity Ratio" b_inlet_turb = "Intensity and Hydraulic Diameter" b_inlet_ti = 0.05 b_inlet_tvr = 5.0 b_inlet_area = 0.10 b_inlet_dh = 0.025 # Hydraulic diameter at inlet b_outlet = "outlet" b_outlet_t = 313.15 b_outlet_p = 100 w_htc = 20.0 w_htc_ref_t = 298 w_em_default = 0.80 w_em_polished = 0.10 op_pressure = 101325 ref_den = 1.178 init_vx = 0.01 init_vy = 0.01 init_vz = 0.05 init_t = 313.1 init_type = "standard" #"hybrid" # Relaxation factors urf_mom = 0.5 urf_pr = 0.5 urf_ke = 0.5 urf_tv = 0.5 urf_tp = 0.5 m_residual = 1.0e-4 v_residual = 1.0e-5 t_residual = 1.0e-7 ke_residual = 1.0e-4 n_iter = 4000 t_step = 1.0e-3 duration = 10.0 iter_per_step = 20 count_t_steps = duration / t_step # Post-process parameters t_min = 300 t_max = 400 v_max = 10 p_max = 1000 p_min = -250 |
#------------------------------------------------------------------------------
# These statements are valid for BATCH mode session. For GUI mode, replace
# session_solve. with meshing. or solver. for respective modes.
#------------------------------------------------------------------------------
# Launch Fluent session with meshing mode
session_mesh = pyfluent.launch_fluent(mode="meshing", ui_mode="gui",
product_version=pyfluent.FluentVersion.v241,
precision=pyfluent.Precision.DOUBLE, cleanup_on_exit=True,
)
session_mesh.health_check.status()
session_mesh.meshing.File.ReadMesh(FileName=mesh_file)
#session_mesh.meshing.File.WriteMesh(FileName=save_mesh)
session_mesh.journal.start(file_name="pyfluent-journal.py")
workflow = session_mesh.workflow
workflow.InitializeWorkflow(WorkflowType="Watertight Geometry")
session_mesh.GlobalSettings.LengthUnit.set_state(r'mm')
session_mesh.GlobalSettings.AreaUnit.set_state(r'mm^2')
session_mesh.GlobalSettings.VolumeUnit.set_state(r'mm^3')
workflow.TaskObject["Import Geometry"].Arguments = dict(FileName=geom_file)
workflow.TaskObject["Import Geometry"].Execute()
# Add Local Face Sizing
add_local_sizing = workflow.TaskObject["Add Local Sizing"]
add_local_sizing.Arguments = dict( {
"AddChild": "yes",
"BOIControlName": "facesize_front",
"BOIFaceLabelList": ["wall_wake"],
"BOIGrowthRate": BOI_GrowthRate,
"BOISize": BOI_Size,
})
add_local_sizing.Execute()
# Add BOI (Body of Influence) Sizing
add_boi_sizing = workflow.TaskObject["Add Local Sizing"]
add_boi_sizing.InsertCompoundChildTask()
add_boi_sizing.Arguments = dict( {
"AddChild": "yes",
"BOIControlName": "boi_wake",
"BOIExecution": "Body Of Influence",
"BOIFaceLabelList": ["bluff-body-boi"],
"BOISize": BOI_Size,
})
add_boi_sizing.Execute()
add_boi_sizing.InsertCompoundChildTask()
|
# Add Surface Mesh Sizing
generate_surface_mesh = workflow.TaskObject["Generate the Surface Mesh"]
generate_surface_mesh.Arguments = dict( {
"CFDSurfaceMeshControls": {
"CurvNormalAngle": Curv_Norm_Angle,
"GrowthRate": Growth_Rate,
"MaxSize": Max_Size, "MinSize": Min_Size,
"SizeFunctions": "Curvature",
}
} )
generate_surface_mesh.Execute()
generate_surface_mesh.InsertNextTask(CommandName="ImproveSurfaceMesh")
improve_surface_mesh = workflow.TaskObject["Improve Surface Mesh"]
improve_surface_mesh.Arguments.update_dict({"FaceQualityLimit": 0.4})
improve_surface_mesh.Execute()
# Describe Geometry, Update Boundaries, Update Regions
workflow.TaskObject["Describe Geometry"].Arguments = dict(
CappingRequired="No",
SetupType="The geometry consists of only fluid regions with no voids",
#SetupType="The geometry consists of both fluid and solid regions and/or voids",
)
# Get only the mesh surfaces, not all zone names
srf_list = session_mesh.surface_list.allowed_values
#workflow.TaskObject['Describe Geometry'].UpdateChildTasks(SetupTypeChanged=True)
workflow.TaskObject["Describe Geometry"].Execute()
# 'manage' class contains further classes useful to manipulate zones
# 'name', 'list', 'get_material_point', 'id', 'delete' are some of them
list_all_zones = session_mesh.manage.active_list()
# Get all zone names starting with 'w_' as list
zn_filter_list = session_mesh.scheme_eval.scheme_eval(
'(tgapi-util-convert-zone-ids-to-name-strings (get-face-zones-of-filter "w_"))'
)
tasks = workflow.TaskObject
update_boundaries = tasks["Update Boundaries"] # Update/reassign boundary types
update_boundaries.Arguments.set_state({
"BoundaryLabelList": ["new_inlet"],
"BoundaryLabelTypeList": ["pressure-inlet"],
"OldBoundaryLabelList": ["old_inlet"],
"OldBoundaryLabelTypeList": ["velocity-inlet"],
})
update_boundaries.Execute()
workflow.TaskObject["Update Boundaries"].Execute()
workflow.TaskObject["Update Regions"].Execute()
# Create periodic boundaries: In Watertight Workflow, multiple periodic
pair of boundaries are supported. However, different periodic set of boundaries
cannot share edges - they must be separated by a non-periodic face zone.
periodic_task = session.workflow.TaskObject["Setup Periodic Boundaries"]
periodic_task.SetState( {
"Type": "Translational", # or "Rotational"
"Method": "Automatic Pick Both Sides", # "Translation Vector, Manual Pick Reference Side"
"PeriodicBoundary1": "per_zone_1",
"PeriodicBoundary2": "per_zone_2",
# Add parameters for manual method (rotation_axis, angle, translation_vector)
"RemeshAsymmetricMeshBoundaries": "Auto", # or "Yes", "No"
})
periodic_task.Execute()
# Add Boundary Layers: refer to options here
add_boundary_layers = workflow.TaskObject["Add Boundary Layers"]
add_boundary_layers.AddChildToTask()
add_boundary_layers.InsertCompoundChildTask()
workflow.TaskObject["smooth-transition_1"].Arguments.update_dict( {
"BLControlName": "smooth-transition_1",
"NumberOfLayers": BL_Num_Layers,
"Rate": BL_GrowthRate,
"TransitionRatio": BL_Trans_Ratio,
} )
add_boundary_layers.Execute()
#workflow.TaskObject['Add Boundary Layers'].AddChildAndUpdate()
# Generate the Volume Mesh
generate_volume_mesh = workflow.TaskObject["Generate the Volume Mesh"]
generate_volume_mesh.Arguments.update_dict({"VolumeFill": vol_mesh_type})
generate_volume_mesh.Execute()
|
#------------------------------------------------------------------------------ # ---------------Solver Setup and Solve Workflow------------------------------- # These statements are valid for BATCH mode session. For GUI mode, replace # session_solve. with meshing. or solver. for respective modes. #------------------------------------------------------------------------------ # Switch to the Solver Mode or Launch solver directly # session_mesh.excute_tui(r'''/switch-to-solution-mode''') - this will not work # execute_tui is not available for meshing interface solver = session_mesh.switch_to_solver() setup, solution = solver.settings.setup, solver.settings.solution session_solve = pyfluent.launch_fluent(product_version=pyfluent.FluentVersion.v241, precision=pyfluent.Precision.DOUBLE, processor_count=2, dimension=pyfluent.Dimension.THREE, ui_mode="gui", mode="solver", case_data_file_name = case_name or case_file_name = case_name, journal_file_names=journ_name ) session_solve.file.read_mesh(file_name=mesh_file) session_solve.file.read(file_type="mesh", file_name=mesh_file) # file_type="case" is not required for session_solve.file.read_case session_solve.file.read_case(file_name=case_file) session_solve.tui.file.read_case(case_file) session_solve.file.write_case(file_name=case_file) session_solve.mesh.check() session_solve.mesh.quality() |
# ---------------Define Materials and Boundary Conditions----------------------
# -----------------------------------------------------------------------------
session_solve.settings.setup.models.viscous.model = viscous_model
session_solve.settings.setup.models.viscous.k_epsilon_model = wall_func_model
viscous = session_solve.setup.models.viscous
viscous.model = "k-omega"
viscous.k_omega_model = "sst"
session_solve.settings.setup.models.viscous.options.curvature_correction = True
session_solve.setup.models.energy.enabled = True
#session_solve.settings.setup.models.energy = {"enabled": True}
session_solve.setup.models.multiphase.models = "mixture"
session_solve.tui.define.models.multiphase.mixture_parameters("no", "implicit")
session_solve.tui.define.materials.change_create("air", "air", "yes", "constant", ref_den)
air = session_solve.setup.materials.fluid["air"]
air.density.option = "ideal-gas"
air.viscosity.option = "sutherland"
air.viscosity.sutherland.option = "three-coefficient-method"
air.viscosity.sutherland.reference_viscosity = 1.716e-05
air.viscosity.sutherland.reference_temperature = 273.11
air.viscosity.sutherland.effective_temperature = 110.56
#session_solve.setup.materials.copy_database_material_by_name(type="fluid", name="water")
session_solve.setup.materials.database.copy_by_name(type="fluid", name="water-liquid")
session_solve.setup.materials.database.copy_by_name(type="fluid", name="water-vapor")
session_solve.setup.materials.fluid["water-vapor"] = {
"density": {"value": 0.02558},
"viscosity": {"value": 1.26e-06},
}
|
session_solve.tui.define.phases.set_domain_properties.change_phases_names("vapor", "liquid")
session_solve.tui.define.phases.set_domain_properties
.phase_domains.liquid.material("yes", "water-liquid")
session_solve.tui.define.phases.set_domain_properties
.phase_domains.vapor.material("yes", "water-vapor")
session_solve.tui.define.materials.copy("solid", "steel")
session_solve.settings.setup.cell_zone_conditions.solid["heat_sink"].material = "aluminum"
glass = session_solve.settings.setup.materials.solid.create("glass")
glass.set_state(
{
"chemical_formula": "",
"density": {
"option": "constant", "value": 2650,
},
"specific_heat": {
"option": "constant", "value": 1887,
},
"thermal_conductivity": {
"option": "constant", "value": 7.6,
},
"absorption_coefficient": {
"option": "constant", "value": 5.302,
},
"refractive_index": {
"option": "constant", "value": 1.4714,
},
}
)
plastic = session_solve.settings.setup.materials.solid.create("plastic")
plastic.chemical_formula = "pp_pvc"
plastic.density.value = 1250
plastic.specific_heat.value = 750
plastic.thermal_conductivity.value = 0.20
plastic.absorption_coefficient.value = 0
plastic.refractive_index.value = 1
#
session_solve.setup.cell_zone_conditions.fluid["z_fluid"].general.material = "water-liquid"
session_solve.setup.materials.fluid["water-liquid"] = {
"density": {
"option": "constant", "value": rho_w,
},
"viscosity": {
"option": "constant","value": mu_w,
},
} |
# Get list of wall and cell zones
zn_state = session_solve.settings.setup.cell_zone_conditions.get_state()
bc_state = session_solve.settings.setup.boundary_conditions.get_state()
w_zones = list(bc_state["wall"].keys())
# Define Boundary Conditions
b_inlet = pyfluent.VelocityInlet(solver, name="b_inlet") #solver=pyfluent.launch_fluent()
# or
inlet = session_solve.settings.setup.boundary_conditions.velocity_inlet[b_inlet]
# Get turbulence specification allowed values
in_turbulence = b_inlet.turbulence
turb_spec = in_turbulence.turbulence_specification
turb_spec.allowed_values()
turb_spec.set_state("Intensity and Hydraulic Diameter")
# or
inlet.turbulence.turbulence_specification = "Intensity and Hydraulic Diameter"
inlet.turbulence.turbulent_intensity = b_inlet_ti
inlet.momentum.velocity.value = b_inlet_v
inlet.turbulence.turbulent_viscosity_ratio = b_inlet_tvr
inlet.turbulence.hydraulic_diameter = "50 [mm]"
hyd_d = solver.settings.setup.boundary_conditions.velocity_inlet[b_inlet]
.turbulence.hydraulic_diameter
hyd_d.set_state(Quantity(b_inlet_dh, "m"))
inlet.thermal.temperature.value = b_inlet_t
out = session_solve.settings.setup.boundary_conditions.pressure_outlet[b_outlet]
out.turbulence.turb_intensity = b_inlet_tvr/2.0
session_solve.setup.boundary_conditions.pressure_outlet[b_outlet]
.turbulence.turbulent_viscosity_ratio = 4
|
# Define HTC
session_solve.tui.define.boundary_conditions.set.wall(
"wall-outer", "wall-enclosure", "()",
"thermal-bc", "yes", "convection",
"convective-heat-transfer-coefficient",
"no", w_htc, "q",
)
# Copy settings from one zone to other
session_solve.settings.setup.cell_zone_conditions.copy(
from = "bracket",
to = ["tank_up", "tank_dn", "shell_o", "shell_i"])
# Define radiation settings
w_heatsink = session_solve.settings.setup.boundary_conditions.wall["w-heat-sink"]
w_heatsink.thermal.material = "aluminum"
w_heatsink.radiation.radiation_bc = "Opaque"
w_heatsink.radiation.internal_emissivity = w_em_default
w_heatsink.radiation.diffuse_fraction_band = {"s-": 1}
# Define Reference Values
session_solve.settings.setup.reference_values.area = inlet_area
session_solve.settings.setup.reference_values.density = ref_density
session_solve.settings.setup.reference_values.velocity = inlet_velocity
solver.setup.general.operating_conditions.operating_pressure = op_pressure
|
User Defined Functions
udf_lib_name = 'libudf'
session.tui.define.user_defined.use_built_in_compiler('yes')
session.tui.define.user_defined.compiled_functions('compile', udf_lib_name, 'yes',
"udf_func.c"', ',')
session.tui.define.user_defined.compiled_functions ('load', udf_lib_name)
Load a precompiled UDF using: scheme_eval(f' (open-udf-library "{libname}" {udf_name})')
|
# -----------------Define Report Definitions-----------------------------------
# These statements are valid for BATCH mode session. For GUI mode, replace
# session_solve. with meshing. or solver. for respective modes.
#------------------------------------------------------------------------------
session_solve.settings.solution.report_definitions.drag["cd-mon1"] = {}
session_solve.settings.solution.report_definitions.drag["cd-mon1"] = {
"zones": ["wall_x", "wall_y", "wall_z"], "force_vector": [0, 0, 1],
}
session_solve.parameters.output_parameters.report_definitions.create(name="parameter-1")
session_solve.parameters.output_parameters.report_definitions["parameter-1"] = {
"report_definition": "cd-mon1"
}
session_solve.settings.solution.monitor.report_plots.create(name="cd-mon1")
session_solve.settings.solution.monitor.report_plots["cd-mon1"] = {"report_defs": ["cd-mon1"]}
session_solve.settings.solution.report_definitions.volume["max-t-solids"] = {}
session_solve.settings.solution.report_definitions.volume["max-t-solids"].report_type = "volume-max"
session_solve.settings.solution.report_definitions.volume["max-t-solids"] = {
"field": "temperature", "cell_zones": ["hs-1", "hs-2"],
}
session_solve.settings.solution.report_definitions.volume["max-t-fluid"] = {}
session_solve.settings.solution.report_definitions.volume["max-t-fluid"].report_type = "volume-max"
session_solve.settings.solution.report_definitions.volume["max-t-fluid"] = {
"field": "temperature", "cell_zones": ["fluid", "porous"],
}
report_file_path = "max-temperature.out"
session_solve.settings.solution.monitor.report_files.create(name="max-temperature")
session_solve.settings.solution.monitor.report_files["max-temperature"] = {
"report_defs": ["max-t-solids", "max-t-fluid"],
"file_name": str(report_file_path),
}
session_solve.settings.solution.monitor.report_files["max-temperature"].report_defs = [
"max-t-solids",
"max-t-fluid",
"flow-time",
] |
# -----------------------------------------------------------------------------
# -----------------Define, Initialize and Run Solver---------------------------
# -----------------------------------------------------------------------------
# Define Solver Settings
session_solve.tui.solve.set.p_v_coupling(24)
#solver.solution.methods.p_v_coupling.flow_scheme = "Coupled"
session_solve.tui.solve.set.discretization_scheme("pressure", 12)
session_solve.tui.solve.set.discretization_scheme("k", 1)
session_solve.tui.solve.set.discretization_scheme("epsilon", 0.1)
session_solve.tui.solve.initialize.set_defaults("k", 0.001)
methods = solver.solution.methods
methods.discretization_scheme = {
"k": "first-order-upwind",
"mom": "quick", "mp": "quick",
"omega": "first-order-upwind",
"pressure": "presto!",
}
session._solve.settings.solution.monitor.residual.equations["continuity"]
.absolute_criteria = m_residual
'''
resid_eqns = solver.solution.monitor.residual.equations
resid_eqns["continuity"].absolute_criteria = m_residual
session_solve.solution.monitor.residual.options.criterion_type = "none"
session_solve.solution.monitor.residual.options.criterion_type = "absolute"
'''
session_solve.settings.solution.monitor.residual.equations["x-velocity"]
.absolute_criteria = v_residual
session_solve.settings.solution.monitor.residual.equations["y-velocity"]
.absolute_criteria = v_residual
session_solve.settings.solution.monitor.residual.equations["z-velocity"]
.absolute_criteria = v_residual
session_solve.settings.solution.monitor.residual.equations["k"]
.absolute_criteria = ke_residual
session_solve.settings.solution.monitor.residual.equations["epsilon"]
.absolute_criteria = ke_residual
# Disable plotting of residuals during the calculation.
# solver_solve.solution.monitor.residual.options.plot = False
|
solver.solution.initialization.get_state().keys() # dict_keys[...]
solver.solution.initialization.get_state() # print defined settings/values
# Steady State Run
session_solve.settings.solution.run_calculation.iter_count = n_iter
session_solve.settings.solution.initialization.initialization_type = init_type
#solver.solution.initialization.hybrid_initialize()
session_solve.settings.solution.initialization.standard_initialize()
session_solve.tui.solve.set.equations("flow", "no", "kw", "no")
session_solve.settings.solution.run_calculation.iterate(iter_countn=n_iter)
# Transient run
#session_solve.tui.define.models.unsteady_2nd_order("yes")
#session_solve.tui.solve.dual_time_iterate(count_t_steps, iter_per_step)
session_solve.settings.setup.general.solver.time = "unsteady-2nd-order-bounded"
session_solve.settings.solution.run_calculation.transient_controls.time_step_size = t_step
session_solve.settings.solution.run_calculation.dual_time_iterate(
time_step_count=count_t_steps, max_iter_per_step=iter_per_step
)
# From PyFLUENT cheatsheet
setup = pyfluent.solver.Setup(solver)
solver_time = setup.general.solver.time
solver_time.get_state()
solver_time.allowed_values()
solver_time.set_state("unsteady-1st-order")
|
# -----------------Post-Processing Workflow------------------------------------
# These statements are valid for BATCH mode session. For GUI mode, replace
# session_solve. with meshing. or solver. for respective modes.
# -----------------------------------------------------------------------------
# Check mass balance
session_solve.solution.report_definitions.flux["mass_flow_rate"] = {}
mass_flow_rate = session_solve.solution.report_definitions.flux["mass_flow_rate"]
mass_flow_rate.boundaries.allowed_values()
mass_flow_rate.boundaries = [b_inlet, b_outlet]
mass_flow_rate.print_state()
session_solve.solution.report_definitions.compute(report_defs=["mass_flow_rate"])
session_solve.fields.reduction.area_average(
expression="AbsolutePressure",
locations=solver.settings.setup.boundary_conditions.velocity_inlet
)
session_solve.fields.reduction.area(
locations=[solver.settings.setup.boundary_conditions.velocity_inlet[b_inlet]]
)
# or use the context argument
session_solve.fields.reduction.area(locations=["inlet1"], ctxt=session_solve)
graphics = session_solve.results.graphics
if graphics.picture.use_window_resolution.is_active():
graphics.picture.use_window_resolution = False
graphics.picture.x_resolution = 1920
graphics.picture.y_resolution = 1440
session_solve.tui_preferences.graphics.colormap_settings.number_format_type(var)
where 'var' can be ("general" "float" "exponential")
session_solve.results.surfaces.iso_surface.create(name="plane-yz")
session_solve.results.surfaces.iso_surface["plane-yz"].field = "x-coordinate"
session_solve.results.surfaces.iso_surface["plane-yz"] = {"iso_values": [0]}
graphics_session_pv = pv.Graphics(session_solve)
contour1 = graphics_session_pv.Contours["contour-1"]
contour1.field = "velocity-magnitude"
contour1.surfaces_list = ["plane-yz"]
contour1.display("window-1")
contour2 = graphics_session_pv.Contours["contour-2"]
contour2.field.allowed_values
contour2.field = "temperature"
contour2.surfaces_list = ["plane-yz"]
contour2.display("window-2")
graphics.contour["contour_pr"] = {
"coloring": {
"option": "banded", "smooth": False,
}, "field": "pressure", "filled": True,
} |
Quantitative Results:
solver_session.solution.report_definitions.moment['bld_moment']={}
solver_session.solution.report_definitions.moment['bld_moment'].thread_names = w_blades
solver_session.solution.report_definitions.moment['bld_moment'].mom_axis[1, 0, 0]
solver_session.solution.report_definitions.moment['bld_moment'].mon_center(xc, yc, zc]
solver_session.solution.report_definitions.compute(report_defs=["b1d_moment"])
|
# Create and display velocity vectors and export the image as PNG format
graphics = session_solve.results.graphics
graphics.vector["vv_plane_xy"] = {}
velocity_symmetry = solver.results.graphics.vector["vv_plane_xy"]
velocity_symmetry.print_state()
velocity_symmetry.field = "velocity-magnitude"
velocity_symmetry.surfaces_list = ["plane-xy"]
velocity_symmetry.scale.scale_f = 0.1
velocity_symmetry.style = "arrow"
velocity_symmetry.display()
graphics.views.restore_view(view_name="front")
graphics.views.auto_scale()
graphics.picture.save_picture(file_name="vv_plane_xy.png")
session_solve.settings.results.graphics.contour["temperature"] = {}
session_solve.settings.results.graphics.contour["temperature"] = {
"field": "temperature",
"surfaces_list": "wall*",
"color_map": {
"visible": True, "size": 10,
"color": "field-velocity",
"log_scale": False, "format": "%0.1f",
"user_skip": 9, "show_all": True, "position": 1,
"font_name": "Helvetica", "font_automatic": True,
"font_size": 0.032, "length": 0.54, "width": 6,
"bground_transparent": True,
"bground_color": "#CCD3E2",
"title_elements": "Variable and Object Name",
},
"range_option": {
"option": "auto-range-off",
"auto_range_off": {"maximum": t_max, "minimum": t_min, "clip_to_range": False},
},
}
session_solve.settings.results.graphics.views.restore_view(view_name="top")
session_solve.settings.results.graphics.views.camera.zoom(factor=2)
session_solve.settings.results.graphics.views.save_view(view_name="animation-view")
session_solve.settings.solution.calculation_activity
.solution_animations["animate-temperature"] = {}
session_solve.settings.solution.calculation_activity
.solution_animations["animate-temperature"] = {
"animate_on": "temperature",
"frequency_of": "flow-time",
"flow_time_frequency": 0.05,
"view": "animation-view",
} |
# ----------------------------------------------------------------------------- # Post processing with PyVista (3D visualization) # ----------------------------------------------------------------------------- graphics_session_vista = pv.Graphics(session_solve) contour_t = graphics_session1.Contours["temperature"] contour_t() # Check available options and set contour properties contour_t.field = "temperature" contour_t.surfaces_list = ["wall-1", "wall-2", "wall-x", "wall_y" ] contour_t.range.option = "auto-range-off" contour_t.range.auto_range_off.minimum = t_min contour_t.range.auto_range_off.maximum = t_max contour_t.display() # --------- Save and Exit------------------------------------------------------ save_case_data_as = Path(save_path) / "Project_1.cas.h5" session_solve.file.write(file_type="case-data", file_name=str(save_case_data_as)) ''' session_solve.file.batch_options.confirm_overwrite = True session_solve.file.write(file_name="Project_1.cas.h5", file_type="case-data") ''' session_mesh.journal.stop() session_solve.exit() |
Function to rename zones based on their type and strip characters after colon
def rename_zones():
# Get all zones
f_zones = solver.setup.cell_zone_conditions.list()
for zone in f_zones:
original_name = zone
zone_type = zone.type
# Strip characters after colon
if ':' in original_name:
new_name = original_name.split(':')[0]
else:
new_name = original_name
# Combine zone type and new name: zone type as suffix
new_name = f"{zone_type}_{new_name}"
'''
Alternatively, rename zones with only first letter of zone-type
# Get the first letter of the zone type
prefix = zone_type[0].upper() + '_'
# Strip characters after colon
if ':' in original_name:
new_name = prefix + original_name.split(':')[0]
else:
new_name = prefix + original_name
'''
session.setup.zones.rename(zone, new_name)
print(f"Renamed {original_name} to {new_name}")
|
Create images of plots for all pairs of case and data files.def generate_images_from_results(result_files_dir, output_dir):
# Ensure output directory exists
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Loop through each result file in the directory
for result_file in os.listdir(result_files_dir):
if result_file.endswith('.cas.gz'):
# Load the result file
session.file.read_case(os.path.join(result_files_dir, result_file))
session.file.read_data(os.path.join(result_files_dir,
result_file.replace('.cas.gz', '.dat.gz')))
# Extract defined contour plots and scenes
scenes = list(session.results.scenes.items())
# Generate and save images for each scene
for each scene scene_output_dir = os.path.join(output_dir, "scenes")
if not os.path.exists(scene_output_dir):
os.makedirs(scene_output_dir)
for scene in scenes: image_path = os.path.join(scene_output_dir,
f"{result_file}_{scene.name}.png")
scene.export_image(image_path)
print(f"Saved scene image: {image_path}") |
Create images of plots for all transient runs: one case and multiple data files. Note that the case file needs to be read only once:def generate_images_folder(case_file, result_files_dir, output_dir):
session.file.read_case(os.path.join(result_files_dir, case_file))
# Loop through each result file in the directory
for result_file in os.listdir(result_files_dir):
session.file.read_data(result_file)
generate_images_from_results(result_files_dir, output_dir)
# Example usage:
case_file = "D:/Projects/CHT/CHT.cas.gz"
result_files_dir = "D:/Projects/CHT"
output_dir = "D:/Projects/CHT/images"
generate_image_folder(case_file, result_files_dir, output_dir) |
Find a text string in all files of specified type and print the file names. The search is case-insensitive. Remove .upper() to make the search case-sensitive.
import os
def findTextInFiles(root_folder, search_string, extn_with_dot=".py"):
if os.path.isdir(root_folder):
for dirpath, dirnames, filenames in os.walk(root_folder):
for file_name in filenames:
if file_name.endswith(extn_with_dot):
file_path = os.path.join(dirpath, file_name)
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
for line_num, line in enumerate(f, 1):
# Use .upper() to make search case-insensitive
if search_string.upper() in line.upper():
print(f"Found in file: {file_path}")
print(f"Line {line_num}: {line.strip()}")
# Add separator, 10 dashes here for readability
print("-" * 10)
# Move to next file after finding first occurrence
#break
except Exception as e:
print(f"Error reading file {file_path}: {e}")
else:
print("Invalid folder path provided.")
# Example usage:
findTextInFiles("/var/www/html/blog", 'mysqli_connect(', ".php")
Python code to recursively traverse a specified directory and replace leading tabs with spaces in all text files found within that directory and its subdirectories.
import os
def replaceLeadingTabsFile(file_path, num_spaces=2):
try:
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
modified_lines = []
for line in lines:
if line.startswith('\t'):
modified_lines.append(line.replace('\t', ' ' * num_spaces, 1))
else:
modified_lines.append(line)
with open(file_path, 'w', encoding='utf-8') as f:
f.writelines(modified_lines)
print(f"Processed: {file_path}")
except Exception as e:
print(f"Error processing {file_path}: {e}")
def replaceLeadingTabsFolder(folder_path, extn_with_dot=".html", num_spaces=2):
if not os.path.isdir(folder_path):
print(f"Error: '{folder_path}' is not a valid directory.")
return
for root, sub_folder, files in os.walk(folder_path):
for file_name in files:
if file_name.endswith(extn_with_dot):
file_path = os.path.join(root, file)
replaceLeadingTabsFile(file_path, num_spaces)
replaceLeadingTabsFile("index.html", num_spaces=2)
Count number of tabs at the start of a string
def countLeadingTabs_iterative(text_string):
count = 0
for char in text_string:
if char == '\t':
count += 1
# Stop counting when a non-tab character is found
else:
break
return count
Python
Python JavaScript
-----------------------------------------------------------------
def Hello(name): function Hello(name) {
print(f"Hello, {name}!") console.log(`Hello, ${name}!`);
}
Anonymous Function
add = lambda x, y: x + y const add = (x, y) => x + y;
print(add(3, 5)) console.log(add(3, 5));
Dictionary
pyDict = { const jsDict = {
"name": "AK", name: "AK",
"age": 40 age: 40
};
print(pyDict["name"]) console.log(jsDict.name);
JavaScript
PHP vs. JavaScript
| Feature | PHP | JavaScript |
| String Manipulation | strlen(), str_replace(), explode(), implode() | length, replace(), split(), join() |
| Array Handling | array_push(), array_pop(), array_keys(), array_values() | push(), pop(), keys(), values() |
| Type Conversion | (int), (float), (string), intval(), floatval() | parseInt(), parseFloat(), String(), Number() |
| Input/Output | echo, print(), file_get_contents(), file_put_contents() | console.log(), alert(), fetch() (for network I/O) |
| Date & Time | date(), strtotime(), time() | Date object methods: getFullYear(), getMonth(), getTime() |
| Category | PHP | JavaScript | Example Code Snippet |
| Output | echo, print | console.log() | PHP: echo "Hello"; JS: console.log("Hello"); |
| String Length | strlen() | .length property | PHP: strlen("Hello") JS: "Hello".length |
| Substring | substr() | substring() / slice() | PHP: substr("Hello", 1, 3) JS: "Hello".slice(1, 4) |
| String Replace | str_replace() | replace() | PHP: str_replace("a", "b", "cat") JS: "cat".replace("a", "b") |
| Find in String | strpos() | indexOf() | PHP: strpos("Hello", "e") JS: "Hello".indexOf("e") |
| Array Length | count() | .length property | PHP: count([1, 2, 3]) JS: [1, 2, 3].length |
| Array Merge | array_merge() | concat() | PHP: array_merge([1], [2]) JS: [1].concat([2]) |
| Check if in Array | in_array() | includes() | PHP: in_array(2, [1, 2, 3]) JS: [1, 2, 3].includes(2) |
| Loop - For Each | foreach loop | forEach() method | PHP: foreach($arr as $val){} JS: [1,2,3].forEach(v => {}) |
| JSON Encode | json_encode() | JSON.stringify() | PHP: json_encode(["a" => 1]) JS: JSON.stringify({a: 1}) |
| JSON Decode | json_decode() | JSON.parse() | PHP: json_decode('{"a":1}') JS: JSON.parse('{"a":1}') |
| Date/Time Now | date("Y-m-d H:i:s") | new Date() | PHP: date("Y-m-d H:i:s") JS: new Date().toISOString() |
| Math Round | round() | Math.round() | PHP: round(2.5) JS: Math.round(2.5) |
| Random Number | rand(min, max) | Math.random() + scaling | PHP: rand(1, 10) JS: Math.floor(Math.random()*10+1) |
| Type Check | is_array(), is_string(), etc. | typeof, Array.isArray() | PHP: is_array($x) JS: Array.isArray(x) |
| File Read | file_get_contents() | fetch() / FileReader API (async) | PHP: file_get_contents("file.txt") JS: fetch('file.txt') |
| Variable Dump | var_dump(), print_r() | console.log() | PHP: var_dump($x) JS: console.log(x) |
| Set Timeout | Not built-in; use sleep() | setTimeout() | PHP: sleep(2) JS: setTimeout(() => {}, 2000) |
| Define Constant | define() | const keyword | PHP: define("PI", 3.14) JS: const PI = 3.14 |
| Function Declare | function myFunc() {} | function myFunc() {} or arrow function | PHP: function greet() {} JS: const greet = () => {} |
Java vs. Python
| Category | Python Function/Utility | Java Function/Utility | Python Code Snippet | Java Code Snippet |
| Output | print() | System.out.println() | print("Hello") | System.out.println("Hello"); |
| String Length | len() | .length() | len("Hello") | "Hello".length(); |
| Substring | slicing | substring() | "Hello"[1:4] | "Hello".substring(1, 4); |
| String Replace | str.replace() | replace() | "cat".replace("a", "o") | "cat".replace("a", "o"); |
| Find in String | str.find() | indexOf() | "Hello".find("e") | "Hello".indexOf("e"); |
| Array/List Length | len() | .length for arrays, .size() for lists | len([1, 2, 3]) | arr.length or list.size(); |
| Array/List Merge | + operator or extend() | addAll() for lists | [1, 2] + [3] | list1.addAll(list2); |
| Check in List | in keyword | contains() for lists | 2 in [1, 2, 3] | list.contains(2); |
| Loop - For Each | for x in list: | for (type x : list) | for x in [1, 2, 3]: | for (int x : list) {} |
| JSON Encode | json.dumps() | Use Gson or Jackson library | json.dumps({"a": 1}) | new Gson().toJson(map); (with Gson) |
| JSON Decode | json.loads() | Use Gson or Jackson | json.loads('{"a":1}') | new Gson().fromJson(json, Map.class); |
| Current Date/Time | datetime.now() | LocalDateTime.now() | datetime.now() | LocalDateTime.now(); |
| Math Round | round() | Math.round() | round(2.5) | Math.round(2.5); |
| Random Number | random.randint(a, b) | Random.nextInt() + shift | randint(1, 10) | new Random().nextInt(10) + 1; |
| Type Check | isinstance() | instanceof | isinstance(x, list) | x instanceof List |
| File Read | open().read() | Files.readString() (Java 11+) | open("file.txt").read() | Files.readString(Path.of("file.txt")); |
| Variable Dump | print() / pprint() | System.out.println() | print(obj) | System.out.println(obj); |
| Sleep | time.sleep(seconds) | Thread.sleep(milliseconds) | sleep(2) | Thread.sleep(2000); |
| Define Constant | Naming convention (e.g. PI = 3.14) | final keyword | PI = 3.14 | final double PI = 3.14; |
| Function Declare | def my_func(): | public void myFunc() | def greet(): | public void greet() {} |
Find and print PHP function definitions or calls in files within a directory and its subfolders. The code does not use regular expressions and prints built-in functions (except those defined in the list exclude_names). Using dictionary to store file path and function name as key-value pair, the defined and called function names can be printed as two separate groups.
import os
def findPhpFunctions(directory, extn_with_dot=".php"):
exclude_names = ["header", "include", "location", "if", "empty", "for",
"count", "trim"]
for root, subdir, files in os.walk(directory):
for file_name in files:
if file_name.lower().endswith(extn_with_dot):
file_path = os.path.join(root, file_name)
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
for line_num, line in enumerate(f, 1):
# Check for function definitions (case-insensitive)
if "function " in line.lower():
start_index = line.lower().find("function ") + len("function ")
end_index = line.find("(", start_index)
if end_index != -1:
func_name = line[start_index:end_index].strip()
print(f"{file_path}, Line: {line_num}, Function defined: {func_name}")
# Check for function calls (case-insensitive, basic check)
if "(" in line and ")" in line and "->" not in line and "::" not in line:
start_index = line.rfind("(")
if start_index != -1:
f_name = ""
for i in range(start_index - 1, -1, -1):
if line[i].isalnum() or line[i] == '_':
f_name = line[i] + f_name
else:
break
if f_name and not f_name.isdigit() and " " not in f_name:
if f_name not in exclude_names:
print(f"*{file_path}, Line: {line_num}, Function called: {f_name}")
findPhpFunctions("/var/www/html/ToDo", ".php")
Download PDF from given link with option to use file name from url or user specified output file name.
import requests
import os
def downloadPDF(pdf_url, out_filename=None):
try:
response = requests.get(pdf_url, stream=True)
# Raise an exception for bad status codes
response.raise_for_status()
if out_filename is None:
# Extract file_name from URL using 'basename' utility
file_name = os.path.basename(pdf_url)
if not file_name.lower().endswith('.pdf'):
file_name = 'url_pdf.pdf'
else:
filename = out_filename
with open(file_name, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print(f"PDF downloaded successfully to: {file_name}")
except requests.exceptions.RequestException as e:
print(f"Error downloading PDF: {e}")
Download all the items in an Internet Archive collection using Python: Python library internetarchive is a command-line and Python interface to archive.org. The steps to get the collection name is described at archive.org/ developers/ tutorial-find-identifier-item.html
import internetarchive
# replace coll_name with name of the collection such as JaiGyan
search = internetarchive.search_items('collection:coll_name')
for result in search:
print(result['identifier'])
Get meta data of an item: here identifier_string is the string generated in previous step.
from internetarchive import get_item
item = get_item(identifier_string)
for k, v in item.metadata.items():
print(print(k, ":", v))
To download all items in a given Internet Archive collection, use the code available at emerging.commons.gc.cuny.edu/ 2014/03/ downloading-items-internet-archive-collection-using-python
import internetarchive as ia
coll = ia.Search('collection: coll_name')
num = 0
for result in coll.results(): # Loop all items in a collection
num = num + 1
item_id = result['identifier']
print 'Downloading: #' + str(num) + '\t' + item_id
item = ia.Item(item_id)
item.download()
print('\t\t Download success.')
ChatGPT Responses Related to Prompts on CFD Simulations
Can a machine learning tool replace geometry clean-up and mesh generation steps in CFD (Computational Fluid Dynamics) Simulations?. The next question was: How can AI-ML be integrated to improve the proposals generated for CFD simulations as well as reports being delivered to the clients? Answer is here.Open SpaceClaim using PyANSYS module: note that GeometryService has the same script interpreter as Ansys Discovery and Ansys SpaceClaim. Detailed description of Class Library of the API is included as compiled help file (.chm) in the installation folder.
from ansys.geometry.core import launch_modeler_with_spaceclaim
modeler = launch_modeler_with_spaceclaim()
model = modeler.open_file('Case_1.scdoc')
modeler.run_discovery_script_file(file_path=r'exportDD.py', import_design=True)
To open SpaceClaim in batch mode: "C:\Program Files\ANSYS Inc\v232\scdm\SpaceClaim.exe" /Welcome=False /Splash=False /RunScript="E:\Projects\geo_script.py" /ExitAfterScript=True /Headless=True where geo_script.py should contain IronPython script.
Export Driving Dimensions in Excel
'Window' class refers to the graphical interaction window where parts and drawings are shown in GUI. This script is not tested, the class names and method taken from public domain (including AI) seems to be not present in SCDM API.'''
Script to open *.scdoc files and export Driving Dimensions in Excel file.
The script will create an Excel file: DrivingDimensions.xlsx
One sheet per model named after the file (up to 31 characters: limitation
of the excel application). Each sheet has: Dimension Name, Value in columns
clr module in Python refers to component of the Python for .NET project which
enables programmers to integrate with the .NET Common Language Runtime (CLR).
.NET Directory.GetFiles: returns names of files that meet specified criteria
'''
import os, sys
import clr
clr.AddReference("Microsoft.Office.Interop.Excel")
from Microsoft.Office.Interop import Excel
from System import Array
from System.IO import Directory
from SpaceClaim.Api.V242 import Application, Document, Dimension
# SpaceClaim API has DimensionType enum class
folder_path = r"C:\Users\Projects"
excel_path = os.path.join(folder_path, "DrivingDimensions.xlsx")
excel_app = Excel.ApplicationClass()
excel_app.Visible = False
workbook = excel_app.Workbooks.Add()
sht_idx = 1
def extractDriveDim2Excel(scdm_doc, sheet):
row = 2
sheet.Cells[row, 2].Value2 = "Dimension Name"
sheet.Cells[row, 3].Value2 = "Value"
row = row + 1
for designDimension in scdm_doc.MainPart.Dimensions:
if designDimension.Type == DimensionType.Driver:
sheet.Cells[row, 1].Value2 = designDimension.Name
sheet.Cells[row, 2].Value2 = designDimension.Value
row = row + 1
files = Directory.GetFiles(folder_path, "*.scdoc")
app = Application.GetApplication()
for file_path in files:
try:
scdm_doc = app.OpenFile(file_path)
file_name = os.path.splitext(os.path.basename(file_path))[0]
# Create new worksheet for each file
if sht_idx > 1:
sheet = workbook.Sheets.Add()
else:
sheet = workbook.Sheets.Item(sht_idx)
sheet.Name = file_name[:31]
extractDriveDim2Excel(scdm_doc, sheet)
# Close SpaceClaim model / document without saving
Window.Close(GetActiveWindow())
sht_idx = sht_idx + 1
except Exception as e:
print("Error opening or processing file:", file_path)
print(str(e))
workbook.SaveAs(excel_path)
workbook.Close(False)
excel_app.Quit()
Utilities related to file system
Normalize the path (replace \\ with \): path = os.path.normpath(path_string), split path using path separator: path.split(os.sep). Tuple: path, file = os.path.split(file_path), drive, tail = os.path.splitdrive(path_drive), root, extn = os.path.splitext(file_path). In Linux, backslash '\' is an allowed character in file names, whereas on Windows a forward slash '/' is not the allowed character.
For file_path = "C:\\Users\\Projects\\File.txt", the output for Linux and Windows respectively are described below.Output on Ubuntu: where file_path = "C:\\Users\\Projects\\File.txt" from pathlib import Path path_parths = Path(file_path) # Extract the filename with extension path_parths.name = C:\Users\Projects\File.txt # Extract the filename without extension path_parts.stem = C:\Users\Projects\File # Extract the extension path_parts.suffix = .txt # Extract the parent directory: note the path is Window style path_parts.parent = .
def checkOpSysType(): import platform, os os_sep = os.sep # '/' for Linux, '\' for Windows return os_sep, platform.system() # 'Windows', 'Linux', 'Darwin'
Get the list of absolute paths for all files with the given extension within a specified folder and its subdirectories.
def getFilesByExtension(folder_path, extension):
absolute_file_paths = []
# Check and add a dot to 'extension' string
if not extension.startswith('.'):
extension = '.' + extension
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.endswith(extension):
absolute_file_paths.append(os.path.abspath(os.path.join(root, file)))
return absolute_file_paths
Example: Renames files of a given extension in a folder and its sub-directories, adding sub-directory names as prefixes (separated by underscore), excluding the uppermost parent directory.
def renameFilesSubdirPrefix(root_dir, extension):
for dirpath, dirnames, filenames in os.walk(root_dir):
# Construct prefix from subdirectory names, exclude root_dir itself
relative_path = os.path.relpath(dirpath, root_dir)
if relative_path == ".":
prefix = ""
else:
# Split relative path into directory components joined by underscore
prefix_parts = relative_path.split(os.sep)
prefix = "_".join(prefix_parts) + "_"
for file_name in filenames:
if file_name.endswith(extension):
old_filepath = os.path.join(dirpath, file_name)
# Create the new file_name with the prefix
new_filename = prefix + file_name
new_filepath = os.path.join(dirpath, new_filename)
try:
os.rename(old_filepath, new_filepath)
print(f"Renamed: {old_filepath} -> {new_filepath}")
except OSError as e:
print(f"Error renaming {old_filepath}: {e}")
Example: Renames files of a given extension in a directory and its subdirectories. The new file names include subdirectory names (including parent folder) as prefix, separated by underscore.
def renameFilesAllSubdirPrefix(root_dir, extension):
for root, _, files in os.walk(root_dir):
for file_name in files:
if file_name.endswith(extension):
old_filepath = os.path.join(root, file_name)
# Get relative path from root_dir to current directory of the file
relative_path = os.path.relpath(root, root_dir)
# Construct prefix from subdirectory names, avoid adding '.' as prefix
if relative_path != '.':
sub_dir_prefix = relative_path.replace(os.sep, '_') + '_'
else:
sub_dir_prefix = ''
# Create the new file name
new_filename = sub_dir_prefix + file_name
new_filepath = os.path.join(root, new_filename)
try:
os.rename(old_filepath, new_filepath)
print(f"Renamed: '{old_filepath}' to '{new_filepath}'")
except OSError as e:
print(f"Error renaming '{old_filepath}': {e}")
Example-3: Rename files by removing substring
import os
def removeTextFromFileNames(root_path, extension, str_to_remove):
file_found = False
for file_name in os.listdir(root_path):
old_path = os.path.join(root_path, file_name)
if file_name.endswith(extension):
if os.path.isfile(old_path) and str_to_remove in file_name:
file_found = True
new_filename = file_name.replace(str_to_remove, "")
new_path = os.path.join(root_path, new_filename)
# Avoid overwriting
if not os.path.exists(new_path):
os.rename(old_path, new_path)
print(f"Renamed: {file_name} -->> {new_filename}")
else:
print(f"Skipped (target exists): {new_filename}")
if not file_found:
print("No file name containing specified string found!")
removeTextFromFileNames(".", ".pdf", "substr")
Add Boundary Layer Class: BoundaryLayers(service, rules, command, path=None)
Determine whether or not boundary layers will be added to various portions of the model. Once a boundary layer is defined, global boundary layer settings are determined in the Create Volume Mesh task. Parameters are:The content on CFDyna.com is being constantly refined and improvised with on-the-job experience, testing, and training. Examples might be simplified to improve insight into the physics and basic understanding. Linked pages, articles, references, and examples are constantly reviewed to reduce errors, but we cannot warrant full correctness of all content.
Template by OS Templates