Tips and Tricks for developing with Cantera
Please edit this README file with the tips and tricks that you come up with. As we collect information, we'll try to organize it in a useful way, but we didn't want to impose some organization beforehand. Please try to put your tips into header sections.
Please make your changes in a branch and make a pull request to add it to master. You will not be able to fork this repository to your own account (since this is a private repository), so you will be making branches on this repository. Otherwise, the workflow is basically the same as with a forked repository.
If you want to test your changes with Python, you can use the PYTHONPATH environment variable to add Cantera to the set of directories that Python searches when you import. You can use this to run a script or run the interactive interpreter (regular Python or IPython).
In the GIF below, you can see scons build running and then the magic incantation:
$ PYTHONPATH=build/python pythonThis opens up python add adds the build/python directory to Python's search list. From the root of Cantera's source code, the build/python directory contains the Python module once you run scons build. Then, you can see the __init__.py file being modified, run scons build again, and the changes to __init__.py are reflected when you reload the module.
By using the same trick with PYTHONPATH, you can load IPython, or specify a script name that Python should run.
You can run a subset of the Python tests using the unittest module. Note that this doesn't work for the Google Tests (any C++ tests). There are two tricks to this one. First, you have to add PYTHONPATH=build/python. Then, you need to identify the test(s) you want to run. All of the Python tests are in the folder interfaces/cython/cantera/tests. You can run a single test file:
$ PYTHOPATH=build/python python -m unittest -v cantera.test.test_convertThe PYTHONPATH is the same as the last tip. Then you run python -m unittest, where the -m argument gives Python a module to run, in this case unittest. Then you have -v which is the option for more verbose output, which you can omit if you want. Then you tell unittest where to get the tests. We want tests from cantera in the test module, and in this case, it runs the test_convert.py file.
If you look in any of the test files, you'll see that they include different classes to group the tests together. You can run a single class grouping of tests by putting that after the file name:
$ PYTHONPATH=build/python python -m unittest -v cantera.test.test_thermo.TestThermoPhaseThat would run all the tests in the TestThermoPhase class in the test_thermo.py file. Last, you can run a single test function with:
$ PYTHONPATH=build/python python -m unittest -v cantera.test.test_purefluid.TestPureFluid.test_critical_propertiesJust put the test function name after the class name.
-
You'll need a C++ compiler installed on your system. If you don't already have one, download one of our recommended compilers.
- Tip: You can determine whether you have a C++ compiler set up on your computer by typing
g++ --versionin the terminal.
- Tip: You can determine whether you have a C++ compiler set up on your computer by typing
-
You'll also need a virtual environment manager to host your Cantera build environment and its required packages. This guide uses the conda package management system, which you should install using the official Miniconda installer if you don't already have Miniconda, Anaconda, or Python installed in another way.
-
Tip: You can determine whether you have conda installed on your computer by typing
conda --versionin the terminal. -
Stuck? See our more detailed Conda Requirements.
-
-
Next, you'll need to initialize a development environment for Cantera. As you may have noticed, as soon as it was installed conda created and activated a virtual environment called
base. Project-specific packages are not typically installed intobase, to avoid version conflicts with requirements across different projects. Instead, create a new environment calledcantera-devwith Cantera's default package dependencies preinstalled by typing the following command in the terminal:conda create --name cantera-dev python=3 scons cython boost numpy ruamel_yaml git- For more advanced builds of Cantera, you may need to install additional packages to your environment.
-
You can switch into the
cantera-devvirtual environment by typing the following command in terminal:conda activate cantera-dev- Tip: You can deactivate this environment using the terminal command
conda deactivateat any time. Switch back to your base environment when you're done working on Cantera!
- Tip: You can deactivate this environment using the terminal command
-
Create a personal copy of the official Cantera repository on Github by pressing the "Fork" button at the top right of the page. You can make changes to or experiment with the code in your fork without affecting Cantera's version.
-
Copy your fork from GitHub to your computer by running this code in the terminal:
git clone --recursive https://github.com/{your_username}/cantera.gitBe sure to replace
{your_username}with the username of the GitHub account that you used to fork Cantera. The--recursiveoption is used here to automatically update and initialize Cantera's required submodules.-
Tip: The cloned repository will be stored in a new directory created within your current working directory. Improve organization by first creating a new "Cantera" directory below your home directory, and calling the command from there.
-
Need a different version? See our more detailed Downloading the Cantera Source Code.
-
-
The Cantera source code can be compiled automatically using the SCons build system that was preinstalled in your
cantera-devvirtual environment. In the terminal, switch into your newly cloned copy of thecanterarepository and then issue the build command as follows:cd cantera scons build boost_inc_dir=${CONDA_PREFIX}/include
The part with
${CONDA_PREFIX}is an environment variable replacement. When you build Cantera, SCons will replace${CONDA_PREFIX}with the value of an environment variable with the nameCONDA_PREFIX. This environment variable is set by Conda to point at your currently activated environment.A
boost_inc_dirlocation needs to be specified here because Boost is needed by your system's C++ compiler, which won't be able to find the library on its own since the Conda directories are not a standard location. Standard locations on macOS and Linux systems are/usr/includeand/usr/local/include.-
Tip: You can compile in parallel by adding the
-j #command line flag toscons build, which builds#objects in parallel. Don't set it higher than the number of CPUs that you have in your machine, or it might slow the build down rather than speeding it up! -
For more advanced builds of Cantera, you may specify additional build options.
-
-
The build process may take a while. On successful compilation, you should see a message that looks like:
******************************************************* Compilation completed successfully. - To run the test suite, type 'scons test'. - To install, type '[sudo] scons install'. *******************************************************
As indicated, you may choose to run
scons testto make sure that your code is working correctly.- Stuck? See our more detailed Compile Cantera & Test.
-
Install the compiled code into a directory of your choice by typing the following into the terminal:
scons install prefix={/absolute/path/to/directory}Be sure to replace
{/absolute/path/to/directory}with the absolute path to your desired install directory. By default, the install location will be your localcanteradirectory.-
This command installs a selection of input files, resources, and executable samples into the specified directory. Take a look!
-
Tip: If you created a new "Cantera" directory in your home directory, you can use it as your install location by specifying its absolute path as the prefix.
-
Tip: If you're planning on installing Cantera in a particular location, you can instead specify the
prefixoption during building to avoid recompilations during install:scons build boost_inc_dir=${CONDA_PREFIX}/include prefix={/absolute/path/to/directory} scons install
-
When compiling Cantera on Arch Linux,
$ lsb_release -a
LSB Version: 1.4
Distributor ID: Arch
Description: Arch Linux
Release: rolling
Codename: n/a
$ gcc --version
gcc (GCC) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
I ran into the issue (found inside config.log)
scons: Configure: Checking for double x; log(x) in C library None...
scons: Configure: ".sconf_temp/conftest_15.c" is up to date.
scons: Configure: The original builder output was:
|.sconf_temp/conftest_15.c <-
| |
| |
| |#include "math.h"
| |
| |int
| |main() {
| | double x; log(x);
| |return 0;
| |}
| |
|
scons: Configure: ".sconf_temp/conftest_15.o" is up to date.
scons: Configure: The original builder output was:
|gcc -o .sconf_temp/conftest_15.o -c -pthread -O3 -Wno-inline -g -DNDEBUG -I/home/anthony-walker/.conda/envs/cantera-dev/include .sconf_temp/conftest_15.c
|
scons: Configure: Building ".sconf_temp/conftest_15" failed in a previous run and all its sources are up to date.
scons: Configure: The original builder output was:
|gcc -o .sconf_temp/conftest_15 -pthread .sconf_temp/conftest_15.o
|
scons: Configure: (cached) no
Steps to reproduce the issue:
$ git clone [email protected]:Cantera/cantera.git --recurse-submodules
$ cd cantera
$ conda create --name cantera-dev python=3 scons cython boost numpy ruamel_yaml --yes
$ conda activate cantera-dev
$ echo "boost_inc_dir = '$CONDA_PREFIX/include'" >> cantera.conf
$ echo "python_package = 'full'" >> cantera.conf
$ scons build -j 12
.
.
.
g++ -o build/python/cantera/_cantera.cpython-38-x86_64-linux-gnu.so -pthread -shared build/temp-py/_cantera.os -Lbuild/lib -lcantera
collect2: error: ld returned 1 exit status
scons: *** [build/lib/libcantera_shared.so.2.5.0] Error 1
scons: building terminated because of errors.
Steps to solve issue
My first attempt at a solution was to independently install sundials because it was seemingly causing the problem I tried this from both conda and the AUR. This allowed the code to compile successfully but it would fail during runtime with undefined reference errors to CVODE variables.
The solution I found to this problem was to use a different version of gcc. I installed gcc-7 from the AUR and added CC and CXX paths to the cantera.conf.
cantera.conf:
CXX = '/usr/bin/g++-7'
CC = '/usr/bin/gcc-7'
prefix = '/home/anthony-walker/.conda/envs/cantera-dev'
python_package = 'full'
f90_interface = 'n'
boost_inc_dir = '/home/anthony-walker/.conda/envs/cantera-dev/include'
$ scons clean
$ scons build -j 12
$ scons install prefix=$CONDA_PREFIX
$ source $CONDA_PREFIX/bin/setup_cantera
When you modify Cantera's source code, it is highly likely that you break the code and need to debug it. Following are some ways to debug your code -
- Build the source code with
debugoptions. Modify thecantera.conffile by adding thedebugflags with no optimizations as follows
cantera.conf:
debug_flags='-g -D_GLIBCXX_ASSERTIONS'
optimize = 'no'
The flag D_GLIBCXX_ASSERTIONS is useful to see the stack trace. For more details about debug flags available in Cantera, see debug_options.
-
The error statements inside the source code are pretty self-explanatory. These sentences mention the filename and function name causing the error and point to the exact source of error.
For example, trying to set the negative temperature will generate following error -
$ python.exe test.py Traceback (most recent call last): File "test.py", line 37, in <module> gas.TP = = -500, 101325 File "interfaces\cython\cantera\thermo.pyx", line 1145, in cantera._cantera.ThermoPhase.TP.__set__ cantera._cantera.CanteraError: *********************************************************************** CanteraError thrown by Phase::setTemperature: temperature must be positive. T = -500.0 ***********************************************************************In this case the error is thrown by the function
setTemperatureinPhaseclass (i.e. from the filephase.cpp). -
To debug the code, which I have modified - I typically put print statements inside the source code to check the values of certain variables.
E.g. Inside the source code, if I want to see the value of variable varExample in the function funcExample, then I put the command inside the function as
writelog("In funcExample:: value of varExample is {} \n", varExample);
Here single curly brackets { } act as a placeholder for the variable to be printed. Everything else that is written inside double quotes will get printed as it is on the screen. For example, if varExample = 10, then above command will print
In funcExample:: value of varExample is 10
Tip: One needs to build the source code again before running the main example file. This method is inefficient, but sometimes useful for a quick check.
-
For the segmentation fault errors, using GDB (or similar tools such as LLDB) on Linux is useful. It can be run as follows:
gdb --args /path/to/python/executableIt opens the
gdbprompt. To use GDB with Cantera built from source, the commands are:cd cantera PYTHONPATH=build/python gdb --args /path/to/python/executableThen run the example python file in terminal as
run example.pyThe run stops whenever segmentation fault or other error is encountered. Then type
where. It shows the entire trace of the current run.One can also set the breakpoint as
breakpoint set --name setState_TPIn this case, the run will stop when the function
ThermoPhase::setState_TPis encountered.Tip: The above method works only on Linux.
gdbcan also be used to debug errors in tests in the Python orgtesttest suites. For the Python test suite, you can run a specific test ingdbwith a command like:PYTHONPATH=build/python gdb --args python -m unittest cantera.test.test_kinetics.TestDuplicateReactions.test_forward_multipleRunning one of the
gtesttests is slightly more involved. To run a few tests out of thethermotest suite, the following commands can be used:scons test-thermo cd test/work LD_LIBRARY_PATH=../../build/lib CANTERA_DATA=../../build/data:../data PYTHONPATH=../../build/python gdb --args ../../build/test/thermo/thermo --gtest_filter=WaterProps*By default,
gdbdoes not provide a very readable view of C++ standard library objects such asstd::vector<double>. To use improved "pretty printers", put the following in the.gdbinitfile in your home directory:python import sys sys.path.insert(0, '/usr/share/gcc-10/python') from libstdcxx.v6.printers import register_libstdcxx_printers register_libstdcxx_printers (None) endYou may need to change the number suffix to the directory that is present on your system. The
gcc-10directory should be present on Ubuntu 20.04.
The doc files are under cantera/doc directory. After editing the doc files, run
pip install -U sphinxcontrib-matlabdomain sphinxcontrib.doxylink sphinxcontrib.katex
to install the necessary dependencies. To build the documentation, run
scons build doxygen_docs=Y sphinx_docs=Y
The generated .html files are saved in cantera/build/docs.
Suppose you already have Cantera built in one conda environment, and you want to build it in another conda environment. First activate the new conda environment.
Next, change Prefix and boost_inc_dir parameters in cantera/cantera.conf file to point to the new conda environment.
Make sure SCONS is installed in the new environment. To install SCONS, run
conda install scons
Clean the previous build by
scons clean
, then build Cantera again with
scons build
Please refer to the more detailed compilation instructions here.
