.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/00-fluent/battery_pack.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_00-fluent_battery_pack.py: .. _battery_pack: Simulating a 1P3S Battery Pack Using the Battery Model ------------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 30-44 Objective --------- This example demonstrates a complete 1P3S battery pack simulation workflow comprising one parallel string and three cells in series using the NTGK (Newman-Tiedemann-Gu-Kim) electrochemical model utilizing PyFluent APIs. The goal is to model and analyze battery pack behavior under a constant 200 W discharge condition. This includes setting up active and passive zones, defining dual-path electrical conductivity using User-Defined Scalars (UDS), and applying convection cooling to simulate heat dissipation. The simulation aims to monitor key performance indicators such as pack voltage, maximum temperature, current flow, and heat generation over a 1500 second transient run, providing insights into thermal and electrical performance relevant to electric vehicle (EV) and energy storage system (ESS) design. .. GENERATED FROM PYTHON SOURCE LINES 46-66 Problem Description ------------------- Simulation of a 1P3S lithium-ion battery pack, consisting of three cells connected in series and no parallel branches, undergoing a constant 200 W discharge to represent a high-load condition. Each cell has a nominal capacity of 14.6 Ah, resulting in a total pack capacity of 14.6 Ah and a nominal voltage range of 10.8–12.6 V, corresponding to an average cell voltage of approximately 3.9 V. The discharge C-rate equates to about 1.17C, and the total energy of roughly 171 Wh means the discharge would last around 51 minutes (3060 seconds). The simulation model includes active zones for the electrochemical cells and passive zones representing conductive components such as tabs and busbars, with defined electrical and thermal material properties. The model also incorporates natural convection cooling with a heat transfer coefficient of 5 W/m²·K and an ambient temperature of 300 K, allowing for realistic thermal management analysis. .. image:: ../../_static/battery_pack_schematic.png :align: center :alt: Battery Pack Schematic .. GENERATED FROM PYTHON SOURCE LINES 68-74 Import modules -------------- .. note:: Importing the following classes offers streamlined access to key solver settings, eliminating the need to manually browse through the full hierarchy of settings APIs structure. .. GENERATED FROM PYTHON SOURCE LINES 74-97 .. code-block:: Python import os import ansys.fluent.core as pyfluent from ansys.fluent.core import examples from ansys.fluent.core.solver import ( Battery, BoundaryConditions, CellZoneConditions, Contour, Controls, General, Graphics, Initialization, Materials, Mesh, ReportDefinitions, RunCalculation, Solution, Vector, ) from ansys.fluent.visualization import GraphicsWindow, Monitor .. GENERATED FROM PYTHON SOURCE LINES 98-100 Launch Fluent in solver mode ---------------------------- .. GENERATED FROM PYTHON SOURCE LINES 100-106 .. code-block:: Python solver = pyfluent.launch_fluent( precision=pyfluent.Precision.DOUBLE, mode=pyfluent.FluentMode.SOLVER, ) .. GENERATED FROM PYTHON SOURCE LINES 107-109 Read mesh --------- .. GENERATED FROM PYTHON SOURCE LINES 109-118 .. code-block:: Python mesh_file = examples.download_file( "1P3S_battery_pack.msh", "pyfluent/battery_pack", save_path=os.getcwd(), ) solver.settings.file.read_mesh(file_name=mesh_file) .. GENERATED FROM PYTHON SOURCE LINES 119-121 Display mesh ------------ .. GENERATED FROM PYTHON SOURCE LINES 121-136 .. code-block:: Python graphics = Graphics(solver) mesh = Mesh(solver, new_instance_name="mesh-1") all_walls = mesh.surfaces_list.allowed_values() graphics.picture.x_resolution = 650 # Horizontal resolution for clear visualization graphics.picture.y_resolution = 450 # Vertical resolution matching typical aspect ratio mesh.surfaces_list = all_walls mesh.options.edges = True mesh.display() graphics.picture.save_picture(file_name="battery_pack_1.png") .. GENERATED FROM PYTHON SOURCE LINES 137-140 .. image:: ../../_static/battery_pack_1.png :align: center :alt: Battery Pack Mesh .. GENERATED FROM PYTHON SOURCE LINES 142-144 Solver settings --------------- .. GENERATED FROM PYTHON SOURCE LINES 144-149 .. code-block:: Python solver_general_settings = General(solver) solver_general_settings.solver.time = "unsteady-1st-order" .. GENERATED FROM PYTHON SOURCE LINES 150-159 Enable Battery Model (NTGK/DCIR) -------------------------------- .. note:: Using wildcards (`*`, `?`, `|`, etc.) instead of explicit zone lists makes the setup more flexible and scalable. For example: - ``cell_*`` → selects all zones starting with ``cell_`` (e.g., ``cell_1``, ``cell_2``, ...) - ``*bar*|*tabzone*`` → selects zones containing either ``bar`` or ``tabzone`` (e.g., ``bar1``, ``n_tabzone_1``,...) .. GENERATED FROM PYTHON SOURCE LINES 159-175 .. code-block:: Python battery_model = Battery(solver) battery_model.enabled = True battery_model.echem_model = "ntgk/dcir" battery_model.eload_condition.eload_settings.eload_type = "specified-system-power" battery_model.eload_condition.eload_settings.power_value = 200 # W (Total pack power) # Conductive zones battery_model.zone_assignment.active_zone = "cell_*" # Active cells battery_model.zone_assignment.passive_zone = "*bar*|*tabzone*" # Bars zones + tab zones # External electrical contacts battery_model.zone_assignment.negative_tab = ["tab_n"] # Negative terminal battery_model.zone_assignment.positive_tab = ["tab_p"] # Positive terminal .. GENERATED FROM PYTHON SOURCE LINES 176-178 Define materials ---------------- .. GENERATED FROM PYTHON SOURCE LINES 178-207 .. code-block:: Python materials = Materials(solver) # Active material (cells): conductivity via UDS-0 and UDS-1 materials.solid.create("e_material") materials.solid["e_material"] = { "chemical_formula": "e", "thermal_conductivity": {"value": 20}, # W/(m·K) "uds_diffusivity": { "option": "defined-per-uds", "uds_diffusivities": { "uds-0": {"value": 1000000}, # S/m (Electronic conductivity) "uds-1": {"value": 1000000}, # S/m (Ionic conductivity) }, }, } # Passive material (busbars & tabs): high constant conductivity materials.solid.create("busbar_material") materials.solid["busbar_material"] = { "chemical_formula": "bus", "uds_diffusivity": { "option": "value", "value": 3.541e7, # S/m (Copper-like conductivity) }, } .. GENERATED FROM PYTHON SOURCE LINES 208-210 Assign materials to cell zones ------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 210-227 .. code-block:: Python cell_zone_conditions = CellZoneConditions(solver) # Assign e_material to cell_1 cell_zone_conditions.solid["cell_1"] = {"general": {"material": "e_material"}} # Copy to cell_2 and cell_3 cell_zone_conditions.copy(from_="cell_1", to="cell_*") # Assign busbar_material to bar1 cell_zone_conditions.solid["bar1"] = {"general": {"material": "busbar_material"}} # Copy to all passive zones cell_zone_conditions.copy(from_="bar1", to="*bar*|*tabzone*") # '*bar*' matches any zone containing 'bar', # '|*tabzone*' matches any zone containing 'tabzone' → OR logic .. GENERATED FROM PYTHON SOURCE LINES 228-230 Boundary conditions ------------------- .. GENERATED FROM PYTHON SOURCE LINES 230-244 .. code-block:: Python conditions = BoundaryConditions(solver) # Convection on wall-cell_1 conditions.wall["wall-cell_1"] = { "thermal": { "thermal_condition": "Convection", "heat_transfer_coeff": {"value": 5}, # W/(m²·K) } } # Copy to all other walls (tabs, busbars, cells) conditions.copy(from_="wall-cell_1", to="wall*") .. GENERATED FROM PYTHON SOURCE LINES 245-247 Define solution controls and monitors --------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 247-261 .. code-block:: Python controls = Controls(solver) # Disable flow and turbulence equations controls.equations = { "flow": False, "kw": False, } solution = Solution(solver) solution.monitor.residual.options.criterion_type = ( "none" # No automatic convergence check ) .. GENERATED FROM PYTHON SOURCE LINES 262-264 Define report definitions ------------------------- .. GENERATED FROM PYTHON SOURCE LINES 264-296 .. code-block:: Python definitions = ReportDefinitions(solver) # Surface report: voltage at positive tab (area-weighted average) definitions.surface["voltage_surface_areaavg"] = { "report_type": "surface-areaavg", "field": "passive-zone-potential", "surface_names": ["tab_p"], "create_report_file": True, "create_report_plot": True, } # Format plot axes report_plot = solver.settings.solution.monitor.report_plots[ "voltage_surface_areaavg-rplot" ] report_plot.axes.x.number_format.precision = 0 # Integer time steps report_plot.axes.y.number_format.precision = 2 # 2 decimal places for voltage # Volume report: maximum temperature in all cell zones definitions.volume["volume_max_temp"] = { "report_type": "volume-max", "field": "temperature", "cell_zones": "*cell|*bar*|*tabzone*", "create_report_file": True, "create_report_plot": True, } # Format plot axes report_plot_1 = solver.settings.solution.monitor.report_plots["volume_max_temp-rplot"] report_plot_1.axes.x.number_format.precision = 0 report_plot_1.axes.y.number_format.precision = 2 .. GENERATED FROM PYTHON SOURCE LINES 297-299 Initialize solution ------------------- .. GENERATED FROM PYTHON SOURCE LINES 299-302 .. code-block:: Python initialize = Initialization(solver) initialize.standard_initialize() .. GENERATED FROM PYTHON SOURCE LINES 303-305 Transient controls ------------------ .. GENERATED FROM PYTHON SOURCE LINES 305-313 .. code-block:: Python Transient_controls = solver.settings.solution.run_calculation.transient_controls Transient_controls.time_step_count = 50 # Number of time steps Transient_controls.time_step_size = 30 # s (30 s per step) calculation = RunCalculation(solver) calculation.calculate() # Run transient simulation .. GENERATED FROM PYTHON SOURCE LINES 314-316 Post-processing --------------- .. GENERATED FROM PYTHON SOURCE LINES 316-331 .. code-block:: Python # Current density vector plot vector = Vector(solver, new_instance_name="current-magnitude-vector") vector.vector_field = "current-density-j" # A/m² (Current density vector) vector.field = "current-magnitude" # A/m² (Magnitude for coloring) vector.surfaces_list = ["tab_n", "tab_p", "wall*"] vector.options.vector_style = "arrow" vector.options.scale = 0.03 # Scale factor for visibility vector.vector_opt.fixed_length = True # Uniform arrow length vector.display() graphics.views.restore_view(view_name="isometric") graphics.picture.save_picture(file_name="battery_pack_2.png") .. GENERATED FROM PYTHON SOURCE LINES 332-335 .. image:: ../../_static/battery_pack_2.png :align: center :alt: Current density vector plot .. GENERATED FROM PYTHON SOURCE LINES 335-347 .. code-block:: Python # Temperature contour temp_contour = Contour(solver, new_instance_name="temp_contour") temp_contour.field = "temperature" # K temp_contour.surfaces_list = ["tab_n", "tab_p", "wall*"] temp_contour.colorings.banded = True temp_contour.display() graphics.views.restore_view(view_name="isometric") graphics.picture.save_picture(file_name="battery_pack_3.png") .. GENERATED FROM PYTHON SOURCE LINES 348-351 .. image:: ../../_static/battery_pack_3.png :align: center :alt: Temperature contour .. GENERATED FROM PYTHON SOURCE LINES 351-363 .. code-block:: Python # Joule heat source contour joule_contour = Contour(solver, new_instance_name="joule_heating_contour") joule_contour.field = "battery-joule-heat-source" # W/m³ joule_contour.surfaces_list = ["tab_n", "tab_p", "wall*"] joule_contour.colorings.banded = True joule_contour.display() graphics.views.restore_view(view_name="isometric") graphics.picture.save_picture(file_name="battery_pack_4.png") .. GENERATED FROM PYTHON SOURCE LINES 364-367 .. image:: ../../_static/battery_pack_4.png :align: center :alt: Joule heat source contour .. GENERATED FROM PYTHON SOURCE LINES 367-379 .. code-block:: Python # Total heat source contour total_heat_contour = Contour(solver, new_instance_name="total_heating_contour") total_heat_contour.field = "total-heat-source" # W/m³ (Joule + reaction heat) total_heat_contour.surfaces_list = ["tab_n", "tab_p", "wall*"] total_heat_contour.colorings.banded = True total_heat_contour.display() graphics.views.restore_view(view_name="isometric") graphics.picture.save_picture(file_name="battery_pack_5.png") .. GENERATED FROM PYTHON SOURCE LINES 380-383 .. image:: ../../_static/battery_pack_5.png :align: center :alt: Total heat source contour .. GENERATED FROM PYTHON SOURCE LINES 385-387 Display monitor plots --------------------- .. GENERATED FROM PYTHON SOURCE LINES 387-399 .. code-block:: Python plot_window = GraphicsWindow(solver) voltage_rplot = Monitor(solver, monitor_set_name="voltage_surface_areaavg-rplot") plot_window.add_plot(voltage_rplot, position=(0, 0)) temp_rplot = Monitor(solver, monitor_set_name="volume_max_temp-rplot") plot_window.add_plot(temp_rplot, position=(1, 1)) plot_window.renderer = "matplotlib" plot_window.show() .. GENERATED FROM PYTHON SOURCE LINES 400-403 .. image:: ../../_static/battery_pack_8.png :align: center :alt: Temperature and voltage Monitor Plot .. GENERATED FROM PYTHON SOURCE LINES 405-407 Save case and data ------------------------ .. GENERATED FROM PYTHON SOURCE LINES 407-409 .. code-block:: Python solver.settings.file.write_case_data(file_name="1P3S_Battery_Pack") .. GENERATED FROM PYTHON SOURCE LINES 410-412 Close Fluent ------------- .. GENERATED FROM PYTHON SOURCE LINES 412-415 .. code-block:: Python solver.exit() .. GENERATED FROM PYTHON SOURCE LINES 416-426 Summary ------- This example provides a complete and reproducible PyFluent workflow for simulating a multi-cell battery pack using the Battery Model with the NTGK sub-model. It demonstrates how to set up active and passive zones, apply constant power discharge, use UDS-based dual-path conductivity, and monitor voltage and temperature behavior during operation. It serves as a template for battery pack analysis, applicable to designs ranging from small modules to full EV packs. .. GENERATED FROM PYTHON SOURCE LINES 428-431 References: ----------- [1] Simulating a 1P3S Battery Pack Using the Battery Model, `Ansys Fluent documentation​ `_. .. _sphx_glr_download_examples_00-fluent_battery_pack.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: battery_pack.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: battery_pack.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: battery_pack.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_