Issue with cantera 3.1.0 premixed twin flame python example

231 views
Skip to first unread message

James Stevens

unread,
Apr 3, 2025, 3:29:58 PM4/3/25
to Cantera Users' Group
Hello, 

I recently updated from an old version of cantera to 3.1.0, and had issues with my old codes. I downloaded the premixed twin flame example (Symmetric premixed twin flame — Cantera 3.1.0 documentation) to check my syntax, but the kernel keeps crashing. I confirmed that I have cantera 3.1.0 in my ct-env, and matplotlib 3.10.1 which should both meet the requirements? I believe the issue originates from the line "opposed_flame.show()" but I am not sure. 

Here is the full code if it helps:

"""
Symmetric premixed twin flame
=============================

Simulate two counter-flow jets of premixed reactants shooting into each other. This
simulation differs from the similar :doc:`premixed_counterflow_flame.py
<premixed_counterflow_flame>` example as the latter simulates a jet of reactants
shooting into products.

Requires: cantera >= 3.0, matplotlib >= 2.0

.. tags:: Python, combustion, 1D flow, premixed flame, strained flame, plotting

An illustration of this configuration is shown in the figure below:

.. image:: /_static/images/samples/twin-premixed-flame.svg
   :width: 90%
   :alt: Twin flame established by two opposed jets of fuel + oxidizer mixtures
   :align: center

"""

import sys
from pathlib import Path
import numpy as np
import cantera as ct
print(ct.__version__)


# Differentiation function for data that has variable grid spacing Used here to
# compute normal strain-rate
def derivative(x, y):
    dydx = np.zeros(y.shape, y.dtype.type)

    dx = np.diff(x)
    dy = np.diff(y)
    dydx[0:-1] = dy/dx

    dydx[-1] = (y[-1] - y[-2])/(x[-1] - x[-2])

    return dydx


def compute_strain_rates(opposed_flame):
    # Compute the derivative of axial velocity to obtain normal strain rate
    strain_rates = derivative(opposed_flame.grid, opposed_flame.velocity)

    # Obtain the location of the max. strain rate upstream of the pre-heat zone.
    # This is the characteristic strain rate
    max_strain_location = abs(strain_rates).argmax()
    min_velocity_point = opposed_flame.velocity[:max_strain_location].argmin()

    # Characteristic Strain Rate = K
    strain_rate_point = abs(strain_rates[:min_velocity_point]).argmax()
    K = abs(strain_rates[strain_rate_point])

    return strain_rates, strain_rate_point, K


def compute_consumption_speed(opposed_flame):
    Tb = max(opposed_flame.T)
    Tu = min(opposed_flame.T)
    rho_u = max(opposed_flame.density)

    integrand = opposed_flame.heat_release_rate / opposed_flame.cp

    total_heat_release = np.trapz(integrand, opposed_flame.grid)
    Sc = total_heat_release / (Tb - Tu) / rho_u

    return Sc


# This function is called to run the solver
def solve_opposed_flame(opposed_flame, mass_flux=0.12, loglevel=1,
                        ratio=2, slope=0.3, curve=0.3, prune=0.05):
    """
    Execute this function to run the Opposed Flow Simulation. This function
    takes a CounterFlowTwinPremixedFlame object as the first argument
    """

    opposed_flame.reactants.mdot = mass_flux
    opposed_flame.set_refine_criteria(ratio=ratio, slope=slope,
                                      curve=curve, prune=prune)

    opposed_flame.show()
    opposed_flame.solve(loglevel, auto=True)

    # Compute the strain rate, just before the flame. This is not necessarily
    # the maximum We use the max. strain rate just upstream of the pre-heat zone
    # as this is the strain rate that computations compare against, like when
    # plotting Su vs. K
    strain_rates, strain_rate_point, K = compute_strain_rates(opposed_flame)

    return np.max(opposed_flame.T), K, strain_rate_point

# %%
# Define parameters
# -----------------

# Select the reaction mechanism
gas = ct.Solution('gri30.yaml')

# Create a CH4/Air premixed mixture with equivalence ratio=0.75, and at room
# temperature and pressure.
gas.set_equivalence_ratio(0.75, 'CH4', {'O2': 1.0, 'N2': 3.76})
gas.TP = 300, ct.one_atm

# Set the velocity
axial_velocity = 2.0  # in m/s

# Domain half-width of 2.5 cm, meaning the whole domain is 5 cm wide
width = 0.025

# %%
# Set up the simulation
# ---------------------

# Compute the mass flux, as this is what the Flame object requires
mass_flux = gas.density * axial_velocity  # units kg/m2/s

# Create the flame object
opposed_flame = ct.CounterflowTwinPremixedFlame(gas, width=width)

# Uncomment the following line to use a Multi-component formulation. Default is
# mixture-averaged
# opposed_flame.transport_model = 'multicomponent'

# %%
# Run the solver
# --------------
#
# The solver returns the peak temperature, strain rate and the point which we ascribe to
# the characteristic strain rate.

T, K, strain_rate_point = solve_opposed_flame(opposed_flame, mass_flux, loglevel=1)

# %%
# Compute flame properties
# ------------------------
#
# You can plot/see all state space variables by calling `opposed_flame.foo`, where
# `foo` is `T`, `Y[i]`, and so forth. The spatial variable (distance in meters) is in
# `opposed_flame.grid`. Thus to plot temperature vs distance, use `opposed_flame.grid``
# and `opposed_flame.T`.

Sc = compute_consumption_speed(opposed_flame)

if "native" in ct.hdf_support():
    output = Path() / "premixed_counterflow_twin_flame.h5"
else:
    output = Path() / "premixed_counterflow_twin_flame.yaml"
output.unlink(missing_ok=True)

opposed_flame.save(output, name="mix")

print(f"Peak temperature: {T:.1f} K")
print(f"Strain Rate: {K:.1f} 1/s")
print(f"Consumption Speed: {Sc * 100:.2f} cm/s")
opposed_flame.save("premixed_counterflow_twin_flame.csv", basis="mole", overwrite=True)

# %%
# Plot results
# ------------
#
# Generate plots to see results, if desired.
if '--plot' in sys.argv:

    import matplotlib.pyplot as plt

    plt.figure(figsize=(8, 6), facecolor='white')

    # Axial Velocity Plot
    plt.subplot(1, 2, 1)
    plt.plot(opposed_flame.grid, opposed_flame.velocity, 'r', lw=2)
    plt.xlim(opposed_flame.grid[0], opposed_flame.grid[-1])
    plt.xlabel('Distance (m)')
    plt.ylabel('Axial Velocity (m/s)')

    # Identify the point where the strain rate is calculated
    plt.plot(opposed_flame.grid[strain_rate_point],
             opposed_flame.velocity[strain_rate_point], 'gs')
    plt.annotate('Strain-Rate point',
                 xy=(opposed_flame.grid[strain_rate_point],
                     opposed_flame.velocity[strain_rate_point]),
                 xytext=(0.001, 0.1),
                 arrowprops={'arrowstyle': '->'})

    # Temperature Plot
    plt.subplot(1, 2, 2)
    plt.plot(opposed_flame.grid, opposed_flame.T, 'b', lw=2)
    plt.xlim(opposed_flame.grid[0], opposed_flame.grid[-1])
    plt.xlabel('Distance (m)')
    plt.ylabel('Temperature (K)')

    plt.tight_layout()
    plt.show()

else:
    print('************')
    print('Plotting option not enabled. Re-run script with --plot to see key plots.')
    print('************')

James Stevens

unread,
Apr 3, 2025, 3:40:43 PM4/3/25
to Cantera Users' Group
Update: I also tried a simpler example - laminar flame speed calculation, which runs but reaches the following error despite no modifications to the example file:  

CanteraError Traceback (most recent call last) Cell In[2], line 42 40 # Solve with multi-component transport properties 41 f.transport_model = 'multicomponent' ---> 42 f.solve(loglevel=4) # don't use 'auto' on subsequent solves 43 f.show() 44 print(f"multicomponent flamespeed = {f.velocity[0]:7f} m/s") File ~\anaconda3\envs\ct-env\Lib\site-packages\cantera\onedim.py:701, in FreeFlame.solve(self, loglevel, refine_grid, auto, stage) 698 self.flame.solving_stage = stage 700 if not auto: --> 701 return super().solve(loglevel, refine_grid, auto) 703 # Use a callback function to check that the domain is actually wide 704 # enough to contain the flame after each steady-state solve. If the user 705 # provided a callback, store this so it can called in addition to our 706 # callback, and restored at the end. 707 original_callback = self._steady_callback File build\\python\\cantera\\_onedim.pyx:1061, in cantera._onedim.Sim1D.solve() CanteraError: ******************************************************************************* CanteraError thrown by OneDim::timeStep: Time integration failed. Minimum timestep (1e-16) reached. *******************************************************************************

James Stevens

unread,
Apr 3, 2025, 4:48:26 PM4/3/25
to Cantera Users' Group
Ok - so I found the error, it looks like there is a problem with gri30.yaml in the 3.1 version of cantera, when I changed the mechanism to h2o2.yaml and the fuel to h2, there are no more errors in the premixed twin flame example or any other example. I checked to verify, gri30 is in the ct-env and I did a second clean install of cantera and anaconda, the default gri30 that comes with the cantera install via forge still fails to work and crashes the kernel. 

Anyone else having this problem?

Bryan Weber

unread,
Apr 3, 2025, 6:01:28 PM4/3/25
to Cantera Users' Group
Hi there,

Thanks for reporting this and digging in to do some debugging! I don't think the problem is with gri30.yaml per se, but probably somewhere else and is revealed by the slightly more complicated kinetics in gri30. Can you please provide details about your operating system and how you're trying to execute these notebooks?

For what it's worth, I don't think the problem lies within gri30.yaml because we execute these samples on every change that is made to Cantera, to ensure they don't break. That's why I suspect something more related to your setup, perhaps there's something wrong with the conda package for example.

Best,
Bryan

James Stevens

unread,
Apr 4, 2025, 8:56:25 AM4/4/25
to Cantera Users' Group
Hi and thank you for the response, 

I am using Windows 11 home version 24H2, and have tried both Spyder V6.0.5 and Jupyter Notebook V6.5.7 to execute the twin premixed flame example. My ct-env is active (tested by using base environment which did not recognize the include cantera as ct line in the script), with cantera V3.1.0 and libcantera 3.1.0. Matplotlib version 3.10.1 is also included in the ct-env. Python version is 3.12.7. I tracked down gri30.yaml to make sure it was present with the fresh install of cantera and it is located in the correct folder: C:\Users\jfste\anaconda3\envs\ct-env\Lib\site-packages\cantera\data.

I also tested partial execution of the code, since the kernel crashes with nodebug info or error message and exection of:

from pathlib import Path
import matplotlib.pyplot as plt
import cantera as ct

# parameter values
p = 0.05 * ct.one_atm  # pressure
T_in = 373.0  # inlet temperature
mdot_reactants = 0.12  # kg/m^2/s
mdot_products = 0.06  # kg/m^2/s
rxnmech = 'gri30.yaml'  # reaction mechanism file
comp = 'CH4:1.6, O2:1, AR:7'  # premixed gas composition

generates the attached image in the variables terminal of spyder, so it seems that gri mech is loading in properly as you said. 

The kernel dies upon execution of:

sim.solve(loglevel, auto=True)

but all lines ahead of this run fine: 

"""
Opposed-flow premixed strained flame
====================================

This script simulates a lean hydrogen-oxygen flame stabilized in a strained
flowfield, with an opposed flow consisting of equilibrium products.


Requires: cantera >= 3.0, matplotlib >= 2.0

.. tags:: Python, combustion, 1D flow, premixed flame, strained flame
"""

from pathlib import Path
import matplotlib.pyplot as plt
import cantera as ct

# parameter values
p = 0.05 * ct.one_atm  # pressure
T_in = 373.0  # inlet temperature
mdot_reactants = 0.12  # kg/m^2/s
mdot_products = 0.06  # kg/m^2/s
rxnmech = 'gri30.yaml'  # reaction mechanism file
comp = 'CH4:1.6, O2:1, AR:7'  # premixed gas composition

width = 0.2  # m
loglevel = 1  # amount of diagnostic output (0 to 5)

# Set up the problem
gas = ct.Solution(rxnmech)

# set state to that of the unburned gas at the burner
gas.TPX = T_in, p, comp

# Create the flame simulation object
sim = ct.CounterflowPremixedFlame(gas=gas, width=width)

# Set grid refinement parameters
sim.set_refine_criteria(ratio=3, slope=0.1, curve=0.2, prune=0.02)

# set the boundary flow rates
sim.reactants.mdot = mdot_reactants
sim.products.mdot = mdot_products

sim.set_initial_guess()  # assume adiabatic equilibrium products
sim.show()

Any help with this would be greatly appreciated, apparently I should have kept my old install going haha. 
Screenshot 2025-04-04 085213.png

James Stevens

unread,
Apr 4, 2025, 10:02:59 AM4/4/25
to canter...@googlegroups.com
One more update: I completely wiped anaconda, cantera, and every related file/folder I could find, did an entire new download of everything and followed the cantera conda install instructions (conda create --name ct-env --channel conda-forge cantera ipython matplotlib jupyter pandas spyder) the issue persists with every simulation in the 1-Dim python examples that use gri30 and gri30_ion... 

Really not sure how to fix this problem. 


--
You received this message because you are subscribed to the Google Groups "Cantera Users' Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cantera-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/cantera-users/374b2ef5-9af0-43f3-92e8-c6e91572d393n%40googlegroups.com.

James Stevens

unread,
Apr 4, 2025, 12:10:25 PM4/4/25
to canter...@googlegroups.com
Some more in depth logging :
CODE (example with added logging lines) : 
"""
Symmetric premixed twin flame
=============================

Simulate two counter-flow jets of premixed reactants shooting into each other. This
simulation differs from the similar :doc:`premixed_counterflow_flame.py
<premixed_counterflow_flame>` example as the latter simulates a jet of reactants
shooting into products.

Requires: cantera >= 3.0, matplotlib >= 2.0

.. tags:: Python, combustion, 1D flow, premixed flame, strained flame, plotting

An illustration of this configuration is shown in the figure below:

.. image:: /_static/images/samples/twin-premixed-flame.svg
   :width: 90%
   :alt: Twin flame established by two opposed jets of fuel + oxidizer mixtures
   :align: center

"""
import faulthandler; faulthandler.enable(all_threads=True)

import sys
from pathlib import Path
import numpy as np
import cantera as ct
log_path = Path("cantera_output.log")
sys.stdout = log_path.open("w")
    try:
        opposed_flame.solve(loglevel, auto=True)
    except Exception as e:
        print("Caught a Python-level exception:", e)
sys.stdout.close()
sys.stdout = sys.__stdout__

print(f"✅ Log output saved to: {log_path.resolve()}")







LOG OUTPUT:

%runfile C:/Users/jfste/Downloads/premixed_counterflow_twin_flame.py --wdir
Windows fatal exception: access violation

Thread 0x000070e0 (most recent call first):
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\zmq\utils\garbage.py", line 46 in run
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 980 in _bootstrap_inner
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 937 in _bootstrap

Thread 0x00005044 (most recent call first):
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 312 in wait
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 581 in wait
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\history.py", line 894 in run
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\history.py", line 60 in only_when_enabled
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\decorator.py", line 235 in fun
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 980 in _bootstrap_inner
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 937 in _bootstrap

Thread 0x00002d4c (most recent call first):
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\selectors.py", line 315 in _select
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\selectors.py", line 324 in select
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\base_events.py", line 1869 in _run_once
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\base_events.py", line 601 in run_forever
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\tornado\platform\asyncio.py", line 205 in start
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\control.py", line 23 in run
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 980 in _bootstrap_inner
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 937 in _bootstrap

Thread 0x00004ce0 (most recent call first):
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\heartbeat.py", line 106 in run
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 980 in _bootstrap_inner
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 937 in _bootstrap

Thread 0x00006648 (most recent call first):
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\selectors.py", line 315 in _select
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\selectors.py", line 324 in select
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\base_events.py", line 1869 in _run_once
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\base_events.py", line 601 in run_forever
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\tornado\platform\asyncio.py", line 205 in start
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\iostream.py", line 92 in _thread_main
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 917 in run
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 980 in _bootstrap_inner
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\threading.py", line 937 in _bootstrap

Current thread 0x00003a38 (most recent call first):
  File "c:\users\jfste\downloads\premixed_counterflow_twin_flame.py", line 87 in solve_opposed_flame
  File "c:\users\jfste\downloads\premixed_counterflow_twin_flame.py", line 139 in <module>
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\customize\utils.py", line 209 in exec_encapsulate_locals
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\customize\code_runner.py", line 506 in _exec_code
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\customize\code_runner.py", line 336 in _exec_file
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\customize\code_runner.py", line 165 in runfile
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\interactiveshell.py", line 2456 in run_line_magic
  File "C:\Users\jfste\AppData\Local\Temp\ipykernel_20740\1153884663.py", line 1 in <module>
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\interactiveshell.py", line 3550 in run_code
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\console\shell.py", line 436 in run_code
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\interactiveshell.py", line 3490 in run_ast_nodes
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\interactiveshell.py", line 3308 in run_cell_async
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\async_helpers.py", line 129 in _pseudo_sync_runner
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\interactiveshell.py", line 3103 in _run_cell
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\IPython\core\interactiveshell.py", line 3048 in run_cell
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\zmqshell.py", line 549 in run_cell
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\ipkernel.py", line 449 in do_execute
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\kernelbase.py", line 778 in execute_request
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\ipkernel.py", line 362 in execute_request
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\kernelbase.py", line 437 in dispatch_shell
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\kernelbase.py", line 534 in process_one
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\kernelbase.py", line 545 in dispatch_queue
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\events.py", line 80 in _run
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\base_events.py", line 1905 in _run_once
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\asyncio\base_events.py", line 601 in run_forever
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\tornado\platform\asyncio.py", line 205 in start
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\ipykernel\kernelapp.py", line 739 in start
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\console\start.py", line 204 in main
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\site-packages\spyder_kernels\console\__main__.py", line 24 in <module>
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\runpy.py", line 87 in _run_code
  File "C:\Users\jfste\anaconda3\envs\ct-env\lib\runpy.py", line 197 in _run_module_as_main

The kernel died, restarting...
 

To assess if the error was associated with spyder and ipython I also checked running the example (with logging) in the anaconda prompt and it returns this error: 
(ct-env) C:\Users\jfste>python %USERPROFILE%\Downloads\premixed_counterflow_twin_flame.py
Windows fatal exception: access violation

Current thread 0x00006660 (most recent call first):
  File "C:\Users\jfste\Downloads\premixed_counterflow_twin_flame.py", line 87 in solve_opposed_flame
  File "C:\Users\jfste\Downloads\premixed_counterflow_twin_flame.py", line 139 in <module>

I ran both spyder and anaconda prompt as administrator, no change to this error......

Bryan Weber

unread,
Apr 5, 2025, 3:56:24 PM4/5/25
to Cantera Users' Group
Hi,

Thanks so much for all this debugging information! Unfortunately, I don't have a Windows machine to help test but I have one suggestion. Can you uninstall the conda-forge cantera (conda remove cantera), set up the pip interop (conda config --set pip_interop_enabled True) and use pip to install instead (pip install cantera). You can create a new environment if you want; if you do that, make sure to install the other dependencies like Spyder separately.

Best,
Bryan

James Stevens

unread,
Apr 7, 2025, 11:05:39 AM4/7/25
to canter...@googlegroups.com
Hi Bryan, 

Before I saw this I completely did a clean install of windows, reinstalled via conda, and the issue was still happening with the same output logs. 

After I tried your solution, it is now working in spyder and jupyter notebook.

Thank you for your help... Not sure I would have been able to figure this out without your guidance!

James

Ray Speth

unread,
May 25, 2025, 10:55:59 AM5/25/25
to Cantera Users' Group

Hi James (and anyone else following along),

I finally had a chance to test this out on a Windows machine, and was able to replicate it with a clean Conda environment, created with just:

mamba create -n cttest -c conda-forge cantera=3.1.0 python=3.12 ipython

This currently creates an environment using MKL 2024.2.2 to provide BLAS/LAPACK support, which seems to be the root of the problem. Switching to any other version of MKL for which there is a corresponding libblas package seems to work fine. For example,

mamba install blas=*=*mkl mkl=2024.0.0

Likewise, replacing MKL with OpenBLAS also works fine:

mamba install blas=*=*openblas

So, the problem seems to be with MKL. Cantera’s 1D solver uses a somewhat less-commonly-used set of LAPACK routines for dense banded matrices (DGBTRF and DGBTRS), and it seems like there may be an issue related to these routines in the most recent MKL versions.

Regards,
Ray

Ray Speth

unread,
May 25, 2025, 11:40:59 AM5/25/25
to Cantera Users' Group

Hi,

As a further update, I found the following in the MKL release notes:

“Some BLAS and LAPACK functions may encounter runtime errors on AMD hardware in Windows*. The fix is available starting with oneMKL version 2025.0.1.”

I do happen to be using an AMD CPU, so this may fall under this category. Unfortunately, there’s no link to anything more specific than “some functions”. And currently, it doesn’t seem like the Conda libblas packages have been updated to allow using MKL 2025.x as a BLAS/LAPACK provider. That said, MKL and the Intel compiler have been so persistently hostile to AMD users that I’d be inclined to just switch to OpenBLAS and not look back.

Regards,
Ray

Joaquin Camacho

unread,
Jul 16, 2025, 5:35:35 PM7/16/25
to Cantera Users' Group
Hello all,

I also had this issue on both my HP laptops powered by AMD processors (common Costco products).

This was a clean install using the packages accessed July 2025 as per the cantera.org installation instructions.

Yes, removing MKL 2024.2.2 and replacing with MKL 2024.0.0 works for now. I did not try OpenBLAS to bypass MKL yet.

Thanks for providing a fix!

Joaquin

Reply all
Reply to author
Forward
0 new messages