.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/01-introductory-example-static-mixer.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_01-introductory-example-static-mixer.py: .. _ref_static_mixer: Simulate flow in a static mixer =============================== This basic example shows how to launch PyCFX and then set up, run, and postprocess the CFX Static Mixer tutorial case in PyCFX. **Model overview** This example simulates a static mixer with two inlet pipes delivering water into a mixing vessel. The water exits through an outlet pipe. Water enters through both pipes at the same rate but at different temperatures. The first entry is at a rate of 2 m/s and a temperature of 315 K. The second entry is at a rate of 2 m/s and a temperature of 285 K. The mixer radius is 2 m. **Workflow tasks** The static mixer example guides you through these tasks: * Set up a basic case in a PreProcessing session (CFX-Pre). * Run the CFX-Solver. * Perform basic postprocessing in CFD-Post. .. GENERATED FROM PYTHON SOURCE LINES 51-56 .. image:: ../_static/static_mixer_model_setup.png :width: 400 :alt: Model overview. :align: center .. GENERATED FROM PYTHON SOURCE LINES 59-68 Initial setup ~~~~~~~~~~~~~ Perform required imports ------------------------ Perform the required imports. It is assumed that the ``ansys-cfx-core`` package has been installed. .. GENERATED FROM PYTHON SOURCE LINES 68-75 .. code-block:: Python import os import ansys.cfx.core as pycfx from ansys.cfx.core import examples .. GENERATED FROM PYTHON SOURCE LINES 77-80 Download required files ----------------------- .. GENERATED FROM PYTHON SOURCE LINES 80-87 .. code-block:: Python mesh_file_name = examples.download_file( "StaticMixerMesh.gtm", "pycfx/static_mixer", save_path=os.getcwd(), ) .. GENERATED FROM PYTHON SOURCE LINES 88-94 Preprocessing ~~~~~~~~~~~~~ Start a PreProcessing session (CFX-Pre) and create a new case ------------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 94-97 .. code-block:: Python pypre = pycfx.PreProcessing.from_install() pypre.file.new_case() .. GENERATED FROM PYTHON SOURCE LINES 98-104 Import a mesh ------------- The ``StaticMixerMesh.gtm`` mesh file should already have been downloaded to the current working directory earlier in this script. .. GENERATED FROM PYTHON SOURCE LINES 104-106 .. code-block:: Python pypre.file.import_mesh(file_name=mesh_file_name) .. GENERATED FROM PYTHON SOURCE LINES 107-112 Set up the domain ----------------- A default domain is created automatically when a new case is created. .. GENERATED FROM PYTHON SOURCE LINES 112-118 .. code-block:: Python default_domain = pypre.setup.flow["Flow Analysis 1"].domain["Default Domain"] default_domain.fluid_definition["Fluid 1"].material = "Water" default_domain.domain_models.reference_pressure.reference_pressure = "1 [atm]" default_domain.fluid_models.heat_transfer_model.option = "Thermal Energy" default_domain.fluid_models.turbulence_model.option = "k epsilon" .. GENERATED FROM PYTHON SOURCE LINES 119-124 Set up the boundary conditions ------------------------------ Add the first inlet boundary, specifying each setting in turn. .. GENERATED FROM PYTHON SOURCE LINES 124-131 .. code-block:: Python default_domain.boundary["in1"] = {} in1 = default_domain.boundary["in1"] in1.boundary_type = "INLET" in1.location = "in1" in1.boundary_conditions.mass_and_momentum.option = "Normal Speed" in1.boundary_conditions.mass_and_momentum.normal_speed = "2 [m s^-1]" in1.boundary_conditions.heat_transfer.static_temperature = "315 [K]" .. GENERATED FROM PYTHON SOURCE LINES 132-134 Add the second inlet boundary by duplicating the first. .. GENERATED FROM PYTHON SOURCE LINES 134-139 .. code-block:: Python in1_state = default_domain.boundary["in1"].get_state() default_domain.boundary["in2"] = in1_state in2 = default_domain.boundary["in2"] in2.location = "in2" in2.boundary_conditions.heat_transfer.static_temperature = "285 [K]" .. GENERATED FROM PYTHON SOURCE LINES 140-142 Add the outlet boundary. .. GENERATED FROM PYTHON SOURCE LINES 142-149 .. code-block:: Python pypre.setup.flow["Flow Analysis 1"].domain["Default Domain"].boundary["out"] = {} out = pypre.setup.flow["Flow Analysis 1"].domain["Default Domain"].boundary["out"] out.boundary_type = "OUTLET" out.location = "out" out.boundary_conditions.mass_and_momentum.option = "Average Static Pressure" out.boundary_conditions.mass_and_momentum.relative_pressure = "0 [Pa]" .. GENERATED FROM PYTHON SOURCE LINES 150-155 Set up the solver ----------------- Configure the solver control settings. .. GENERATED FROM PYTHON SOURCE LINES 155-159 .. code-block:: Python solver_control = pypre.setup.flow["Flow Analysis 1"].solver_control solver_control.advection_scheme.option = "Upwind" solver_control.convergence_control.timescale_control = "Physical Timescale" solver_control.convergence_control.physical_timescale = "2 [s]" .. GENERATED FROM PYTHON SOURCE LINES 160-162 Set up the CFX-Solver to run in parallel using execution control. .. GENERATED FROM PYTHON SOURCE LINES 162-166 .. code-block:: Python exec_control = pypre.setup.simulation_control.execution_control exec_control.solver_step_control.parallel_environment.start_method = "Intel MPI Local Parallel" exec_control.solver_step_control.parallel_environment.maximum_number_of_processes = 2 .. GENERATED FROM PYTHON SOURCE LINES 167-172 Check for errors ---------------- Check for physics messages to ensure the setup is consistent and no required settings are missing. .. GENERATED FROM PYTHON SOURCE LINES 172-176 .. code-block:: Python physics_messages = pypre.setup.get_physics_messages(severity="All") if physics_messages: print(f"Physics messages: {physics_messages}") .. GENERATED FROM PYTHON SOURCE LINES 177-190 Write the CFX-Solver input file ------------------------------- This example uses a *file-based* workflow, where each of the three PyCFX components (PreProcessing, Solver, and PostProcessing) are run independently, with each component being initialized by a file written by the previous component where possible. This allows each component to be run separately, potentially on a different machine configuration, at a different time, or from a different Python session. In contrast, the :ref:`Fourier Transformation Blade Flutter case ` example shows a workflow where the PyCFX components interact more directly. Write the CFX-Solver input file and close the preprocessing session. .. GENERATED FROM PYTHON SOURCE LINES 190-194 .. code-block:: Python solver_input_file_name = "static_mixer.def" pypre.file.write_solver_input_file(file_name=solver_input_file_name) pypre.exit() .. GENERATED FROM PYTHON SOURCE LINES 195-204 Run the solver ~~~~~~~~~~~~~~ Start a Solver session and launch the CFX-Solver ------------------------------------------------ Launch the CFX-Solver using the execution control settings applied in the preprocessing session. Only local CFX-Solver runs are supported. .. GENERATED FROM PYTHON SOURCE LINES 204-207 .. code-block:: Python pysolve = pycfx.Solver.from_install(solver_input_file_name=solver_input_file_name) pysolve.solution.start_run() .. GENERATED FROM PYTHON SOURCE LINES 208-212 Wait for the run to complete ---------------------------- Wait for the run to complete and determine the results file name. .. GENERATED FROM PYTHON SOURCE LINES 212-216 .. code-block:: Python pysolve.solution.wait_for_run() results_file = pysolve.solution.get_results_file_name() pysolve.exit() .. GENERATED FROM PYTHON SOURCE LINES 217-225 Postprocessing ~~~~~~~~~~~~~~ Start a PostProcessing session (CFD-Post) ----------------------------------------- Start CFD-Post and load the results. .. GENERATED FROM PYTHON SOURCE LINES 225-226 .. code-block:: Python pypost = pycfx.PostProcessing.from_install(results_file_name=results_file) .. GENERATED FROM PYTHON SOURCE LINES 227-230 Find the name of the case object that is automatically created. .. GENERATED FROM PYTHON SOURCE LINES 230-236 .. code-block:: Python case_names = pypost.results.data_reader.case.get_object_names() if case_names: current_case = case_names[0] else: raise RuntimeError("Loading results failed; no cases defined.") .. GENERATED FROM PYTHON SOURCE LINES 237-240 Plot contours on one of the boundaries -------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 240-253 .. code-block:: Python pypost.results.data_reader.case[current_case] = { "boundary": { "Default Domain Default": { "colour_mode": "Variable", "colour_variable": "Pressure", "draw_contours": True, } } } current_case = pypost.results.data_reader.case[current_case] default_boundary = current_case.boundary["Default Domain Default"] default_boundary.show(view="/VIEW:View 1") .. GENERATED FROM PYTHON SOURCE LINES 254-259 Create an image --------------- Set up the image. .. GENERATED FROM PYTHON SOURCE LINES 259-264 .. code-block:: Python hardcopy = pypost.results.hardcopy hardcopy.hardcopy_format = "png" hardcopy.image_height = 1200 hardcopy.image_width = 1200 hardcopy.use_screen_size = False .. GENERATED FROM PYTHON SOURCE LINES 265-267 Save the image. Hide the boundary again so that it is not visible in subsequent images. .. GENERATED FROM PYTHON SOURCE LINES 267-270 .. code-block:: Python pypost.file.save_picture(file_name="static_mixer_boundary.png") default_boundary.hide() .. GENERATED FROM PYTHON SOURCE LINES 271-276 .. image:: ../_static/static_mixer_boundary.png :width: 400pt :alt: Static mixer with boundary plot. :align: center .. GENERATED FROM PYTHON SOURCE LINES 278-285 Create a plane -------------- By default, the plane geometry recalculates every time a setting is modified. When modifying several settings sequentially, suspend the plane object to avoid unnecessary intermediate calculations. Unsuspend the plane after completing the setup to reflect the latest settings. .. GENERATED FROM PYTHON SOURCE LINES 285-292 .. code-block:: Python pypost.results.plane["Plane 1"] = {} plane = pypost.results.plane["Plane 1"] plane.suspend() plane.option = "ZX Plane" plane.plane_type = "Slice" plane.unsuspend() .. GENERATED FROM PYTHON SOURCE LINES 293-299 Create a contour ---------------- Create a contour on the previously defined plane and save the image. Supplying all the settings at once by using a dictionary is another way to avoid unnecessary intermediate calculations. .. GENERATED FROM PYTHON SOURCE LINES 299-312 .. code-block:: Python pypost.results.contour["Contour 1"] = { "colour_variable": "Pressure", "location_list": "/PLANE:Plane 1", "number_of_contours": 11, "contour_range": "Local", "draw_contours": True, "fringe_fill": True, } contour = pypost.results.contour["Contour 1"] contour.show(view="/VIEW:View 1") pypost.file.save_picture(file_name="static_mixer_contour.png") contour.hide() .. GENERATED FROM PYTHON SOURCE LINES 313-318 .. image:: ../_static/static_mixer_contour.png :width: 400pt :alt: Static mixer with contour plot on a plane. :align: center .. GENERATED FROM PYTHON SOURCE LINES 320-325 Set up an expression -------------------- Set up and evaluate an expression. .. GENERATED FROM PYTHON SOURCE LINES 325-334 .. code-block:: Python pypost.results.library.cel.expressions = { "Temperature Difference": {"definition": "maxVal(Temperature)@out - minVal(Temperature)@out"} } expressions = pypost.results.library.cel.expressions print(f"Expressions list: {expressions.list()}") print(f"Expression definitions: \n{expressions.list_properties()}") temperature_difference = expressions["Temperature Difference"].evaluate() print(f"Temperature difference: {temperature_difference}") .. GENERATED FROM PYTHON SOURCE LINES 335-338 Close the postprocessing session -------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 338-339 .. code-block:: Python pypost.exit() .. _sphx_glr_download_examples_01-introductory-example-static-mixer.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 01-introductory-example-static-mixer.ipynb <01-introductory-example-static-mixer.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 01-introductory-example-static-mixer.py <01-introductory-example-static-mixer.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 01-introductory-example-static-mixer.zip <01-introductory-example-static-mixer.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_