Using PyFluent sessions#

You can obtain a PyFluent session object by calling either of the functions, launch_fluent() or connect_to_fluent().

>>> import ansys.fluent.core as pyfluent
>>> from ansys.fluent.core.examples import download_file
>>> case_file_name = download_file("mixing_elbow.cas.h5", "pyfluent/mixing_elbow")
>>> data_file_name = download_file("mixing_elbow.dat.h5", "pyfluent/mixing_elbow")
>>> solver = pyfluent.launch_fluent(case_data_file_name=case_file_name)

Note: You can find out more about using ref_session_guide, and Launching and connecting to Fluent.

Solution mode sessions#

The above Solver session object exposes a variety of Python child objects that provide access to the data and functions of the connected Fluent solver. A consistent interface style is maintained across those Python objects and each object adopts a specific responsibility that is reflected in its particular interface. For instance, the Solver session provides child objects for solver settings and field data access respectively. You can see these fields and settings children by executing dir(solver). You can discover the children of fields and settings by calling dir(solver.fields) and dir(solver.settings) respectively, and so on:

>>> solver_children = dir(solver)
>>> settings = solver.settings
>>> settings_children = dir(settings)
>>> fields = solver.fields
>>> fields_children = dir(fields)

You can call the Python help() function to find out more about each item in PyFluent.

>>> help(solver.settings.file.read_case)

You can create additional PyFluent sessions. The following code creates a Meshing mode session that starts a second Fluent instance and is independent of your PyFluent Solver session.

>>> import ansys.fluent.core as pyfluent
>>> meshing = pyfluent.launch_fluent(mode=pyfluent.FluentMode.MESHING)

A uniform interface exists across solver settings objects. For instance, get_state(), set_state() and is_active() are ubiquitous methods, and allowed_values(), min() and max() are found on relevant items. Here are some examples using the viscous and discrete_phase models.

>>> viscous_model = settings.setup.models.viscous.model
>>> viscous_model.get_state()
      'k-omega'
>>> from pprint import pprint
>>> pprint(viscous_model.allowed_values())
      ['inviscid',
       'laminar',
       'k-epsilon',
       'k-omega',
       'mixing-length',
       'spalart-allmaras',
       'k-kl-w',
       'transition-sst',
       'reynolds-stress',
       'scale-adaptive-simulation',
       'detached-eddy-simulation',
       'large-eddy-simulation']
>>> viscous_model.set_state("laminar")
>>> viscous_model.get_state()
  'laminar'
>>> discrete_phase = settings.setup.models.discrete_phase
>>> discrete_phase.is_active()
  True
>>> max_num_refinements = discrete_phase.numerics.tracking.accuracy_control.max_num_refinements
>>> max_num_refinements.get_state()
      20
>>> max_num_refinements.min(), max_num_refinements.max()
 (0, 1000000)

Some items in the solver settings object tree are methods that you call to request a particular action in Fluent:

>>> solver.settings.solution.run_calculation.iterate(iter_count=100)

Note: You can find out more about solver settings objects here: Solver settings objects.

Objects under fields provide an interface with a style similar to that of the settings objects:

>>> field_data = fields.field_data
>>> transaction = field_data.new_transaction()
>>> add_scalar_fields = transaction.add_scalar_fields_request
>>> allowed_field_names = add_scalar_fields.field_name.allowed_values()
>>> pprint(allowed_field_names[:min([len(allowed_field_names), 5])])
['abs-angular-coordinate',
 'absolute-pressure',
 'angular-coordinate',
 'anisotropic-adaption-cells',
 'aspect-ratio']
>>> add_scalar_fields.surface_names.allowed_values()
['cold-inlet', 'hot-inlet', 'outlet', 'symmetry-xyplane', 'wall-elbow', 'wall-inlet']
>>> add_scalar_fields(field_name='absolute-pressure', surface_names=['cold-inlet', 'hot-inlet', 'outlet', 'symmetry-xyplane', 'wall-elbow', 'wall-inlet'])
>>> pressure_fields = transaction.get_fields()
>>> solver.fields.reduction.sum_if(
>>>     expression="AbsolutePressure",
>>>     condition="AbsolutePressure > 0[Pa]",
>>>     locations=[settings.setup.boundary_conditions.velocity_inlet["cold-inlet"]],
>>>     weight="Area",
>>> )
15401477.28604886

Meshing mode sessions#

Meshing mode also provides an interface style that is consistent with the above interactions. Here is some task-based meshing workflow code:

>>> watertight = meshing.watertight()
>>> from ansys.fluent.core.examples import download_file
>>> import_file_name = examples.download_file('mixing_elbow.pmdb', 'pyfluent/mixing_elbow')
>>> import_geometry = watertight.import_geometry
>>> import_geometry.file_name.set_state(import_file_name)
>>> length_unit = import_geometry.length_unit
>>> length_unit.get_state()
 "mm"
>>> length_unit.allowed_values()
 ["m", "cm", "mm", "in", "ft", "um", "nm"]
>>> length_unit.set_state("mm")
>>> import_geometry()

Note: You can find out more about meshing workflows here: Meshing workflow.

A Meshing mode session object exposes additional child objects. For instance, meshing has fields and events children. Each has the same interface as the identically named child of the Solver session object respectively.

You can also create a PureMeshing session:

>>> import ansys.fluent.core as pyfluent
>>> pure_meshing = pyfluent.launch_fluent(mode=pyfluent.FluentMode.PURE_MESHING)

The only difference between the two meshing session types is that a pure session cannot be switched to solution mode directly. The existence of the pure session type promotes creation of minimal server images, which becomes significant in the context of containerization.

Switching between sessions#

You switch between meshing and solution modes by calling the switch_to_solver() method.

>>> switched_solver = meshing.switch_to_solver()

The switched_solver session uses the same Fluent instance that was previously used by the Meshing session, which is now unusable.

A similar action with the PureMeshing session raises an exception:

>>> failed_solver = pure_meshing.switch_to_solver() # raises an AttributeError!

Note: there is no method to switch back to meshing mode from solution mode.

Sharing cases between sessions#

An alternative to mode switching is to transfer your case between sessions, an operation that’s allowed both for pure and for regular meshing sessions:

>>> pure_meshing.transfer_mesh_to_solvers(solvers=[solver, switched_solver])

Ending PyFluent sessions#

Just as PyFluent session objects start and exist independently within a single Python interpreter session, each session can be ended independently of the others. Calling the exit() method on the Solver and PureMeshing session objects ends those PyFluent sessions and terminates the connected Fluent sessions:

>>> solver.exit()
>>> pure_meshing.exit()

Each Fluent session terminates in this scenario because both PyFluent Session objects were obtained by calling the launch_fluent() function. If the connect_to_fluent() function were used instead, the Fluent session would terminate upon the exit() method call if and only if the connect_to_fluent() function were called with the argument value cleanup_on_exit=True.

Session exiting can also happen implicitly when Session objects are garbage collected. The same rules apply regarding Fluent termination whether the exit is explicit via an <session>.exit() method call or implicit. Implicit exiting occurs via the Python garbage collector. Calling session.exit() is equivalent to the session being garbage collected:

>>> def run_solver():
>>>     solver = pyfluent.launch_fluent()
>>>     # <insert some PyFluent solver actions>
>>>     # solver is exited at the end of the function

When you end your Python interpreter session, all active PyFluent sessions are exited automatically.