GSoC 2020 Project Summary

Google Summer of Code 2020: Developing a 0-D Steady-State Combustion Solver for Cantera

Combustion is a fundamental discipline of modern science, and understanding it has enabled the development of our technologies in electricity production, heating, transportation, and industry. Advancements in combustion science have been facilitated by our ability to simulate the phenomenon, made possible by computer software like Cantera. The goal of this project was to add a new solver to Cantera that would allow users to directly simulate zero-dimensional steady-state combustion, which can occur in reactors when internal chemical processes become perfectly balanced with one another. This type of idealized simulation can be used to quickly and accurately approximate the behavior of real combustion systems.

Read more…

GSoC 2020 Blog Post 4

This summer I've been working to add a dedicated steady-state solver to Cantera's ZeroD reactor network simulation module. Inspired by my study of ZeroD's current ODE time-integration solver, CVodesIntegrator (see this post), I developed a nonlinear algebraic solver class called Cantera_NonLinSol to be used by ReactorNet to solve the steady-state problem:

  • Class Cantera_NonLinSol: A nonlinear algebraic system solver, built upon Cantera's 1D multi-domain damped newton solver as a simplified interface.
    • Implemented in Cantera_NonLinSol.h (see this on GitHub)

This blog post will go into detail about the mathematical theory behind solving steady-state reactor systems, and how Cantera_NonLinSol can be used to facilitate the process.

Read more…

GSoC 2020 Blog Post 3

How Does Cantera's Reactor Network Time Integration Feature Work?

There's a great description of the science behind Cantera's reactor network simulation capabilities available on the Cantera website, here. This post will go into more developer-oriented detail about how the last step, ReactorNet's time integration methods, actually work. A ReactorNet object doesn't perform time integration on its own. It generates a system of ODE's based on the combined governing equations of all contained Reactors, which is then passed off to an Integrator object for solution. What is an Integrator? How does this work?

Read more…

Renaming Cantera's default branch

There has been a growing awareness that the use of the name master for the default branch in Git repositories perpetuates the use of the language of oppression. It has also been shown that the use of the term master in Git likely does stem from the harmful master/slave metaphor, which it inherited from an earlier piece of software.

With the aim of upholding our commitment to fostering an open and welcoming environment as outlined in our Code of Conduct, specifically the standard of using welcoming and inclusive language, we have changed the default branch name in Cantera to main, and recommend this change to others for their forks and local repositories as well.

Adapting to this change will require a few small changes for anyone who has already checked out a copy of the Cantera source code using Git, and instructions which should help in most cases are provided below.

Updating your local repository and GitHub fork

To change the name of Cantera's default branch open a shell, navigate to the Cantera source directory, and run the following commands:

$ git fetch --all
$ git checkout master
$ git branch -m master main
$ git status
On branch main
Your branch is up to date with 'origin/master'.

If your master branch isn't up to date with its upstream, you will want to fix that first using your preferred workflow to synchronize the two branches. If you have made any local changes to the master branch, you should create a feature branch to avoid losing any changes.

Next, we want to update the link between your main branch and the remote repository (here, origin). You can check whether this remote is the main Cantera repository or your fork on GitHub (or a different source) by running the command:

$ git remote --verbose
origin  git@github.com:cantera/cantera.git (fetch)
origin  git@github.com:cantera/cantera.git (push)
myfork  git@github.com:your_username/cantera.git (fetch)
myfork  git@github.com:your_username/cantera.git (push)
Case 1: tracked remote is Cantera/cantera

If the remote being tracked (in this example, origin) is the main Cantera repository, that is, Cantera/cantera.git, then you can set the main branch of Cantera/cantera as the upstream for your main branch:

$ git branch --unset-upstream
$ git branch -u origin/main
$ git fetch
$ git rebase origin/main

Then, you can push the updated main branch to your fork (in this example, myfork) as well:

$ git push main myfork
Case 2: tracked remote is your fork

If the remote listed is your fork of Cantera, then you may want to rename the branch on your fork as well. If the remote name for your fork is myfork, this can be changed by running:

$ git push -u myfork main

Deleting the old branch from your fork

Once you have pushed the new main branch to your fork, visit the GitHub website for your fork, go to Settings, then Branches, then Default Branch, and set the default branch to main.

Once you make sure that the main branch shows any recent commits that you expect to see, you can delete the old branch from your fork:

$ git push origin --delete master

If you get an error message that says

! [remote rejected]     master (refusing to delete the current branch: refs/heads/master)`

this suggests that you haven't successfully changed the default branch on GitHub.

GSoC 2020 Blog Post 2

Developing a 0-D Steady-State Combustion Solver for Cantera

My work since last posting has been characterized by research and experimentation, and this blog post will highlight some of the findings that I've made. I have learned a lot about Cantera and combustion over the past two weeks, but more excitingly, I developed a working proof-of-concept 0-D steady-state solver, PSRv0.2!

The Energy Equation

In my last blog post, I discussed the troubles I was having with reaching convergence in systems that included the energy equation, and introduced some ideas I had that might be potential remedies. After doing some research, I found a great resource that addressed these ideas and the numerical solution of perfectly-stirred reactors as a whole. The report provided a new version of the energy equation that considered time-dependent and heat release properties, derived from transient forms of the species conservation and energy balance equations; see the full report for a detailed derivation. Building off of PSR v0.1 (introduced in the last blog post), I created a version of the solver that used the new energy equation in its solution attempt. Unfortunately, this too had trouble converging without a very good initial guess. Even after introducing time integration and solving the fixed-temperature problem first, the severe nonlinearities of the solution model almost always made convergence impossible.

Time Integration

As just hinted at, the solvers that I developed and discussed in my last blog post hadn't been using time integration! I originally thought that this feature of the Cantera solver worked using only the residual function, but this wasn't the case. Time integration is actually done via the backward Euler method. In Cantera's application, the solution at the previous timestep is obtained using the solver's built-in prevSoln() method, and the timestep value dt is incorporated using its passed-in reciprocal, rdt. Each iteration of the backward Euler method needs to be subtracted from the result of the residual function at the corresponding solution vector—the Cantera solver is set up to extract the information that it needs from this difference. Further, modifying values in the diag pointer is also required at each iteration. diag can be thought of as a mask, and in order to activate time stepping for a specific solution component, its corresponding mask entry needs to be set to 1.

PSR Solver v0.2

Although time integration didn't help convergence with the energy equation, it was exactly what I needed to get PSR v0.1 working! Adding time integration resulted in a capable and accurate PSR solver. I compared this new version of the solver to Cantera's IdealGasReactor based on the example code in combustor.py, and the results were just about exactly the same:

Check out the full code for PSR v0.2 on GitHub! The energy equation and fixed-temperature versions of the solver are built in for reference, although they weren't used to produce the results above.

As always, I appreciate any suggestions or feedback you might have. Feel free to leave a comment on this project's page in the Cantera enhancements repository, or email me at paul_d_blum@yahoo.com.

Until next time,

@paulblum

Keep Reading:

Next Post - GSoC 2020 Blog Post 3

Previous Post - GSoC 2020 Blog Post 1

Start from the Beginning - Introduction

GSoC 2020 Blog Post 1

Developing a 0-D Steady-State Combustion Solver for Cantera

Learning C++ for Cantera Development

My original project proposal called for preliminary development in C and Python, primarily because I’ve worked with these languages in the past and would be able to start writing test code right away. However, I ultimately decided to learn and use C++ instead, and I’m very glad that I did. Most of the Cantera source code is written in C++, and being able to easily read and reference it without guessing at the syntax has proven invaluable in development so far.

I learned C++ by following a free Codecademy tutorial, which I would definitely recommend to beginning and experienced coders alike. The tutorial was detailed and interactive, and only took me a day to complete. After that, I followed Cantera’s C++ Interface Tutorial, another excellent resource that I’d say is essential for any beginning Cantera developer. It introduced Cantera-specific technical details needed for C++ development, and provided simple code examples that illustrated how to use Cantera’s functionality to perform some basic calculations.

Switching Solvers

The heart of this project is a capable numerical solver that can quickly provide a solution to the set of nonlinear equations that characterize 0-D steady-state combustion systems. In my project proposal I suggested the use of KINSOL, an externally developed code module that uses a version of Newton’s method to solve nonlinear algebraic equations. Stemming from discussions with mentors, I found that Cantera has a built-in and similarly implemented damped Newton solver that should be able to provide the equivalent capability. In efforts not to duplicate existing functionality, as well as to maintain consistency with the rest of the source code, I decided it would be best to use Cantera’s solver in this application. The solver was developed for solving 1-D multi-domain problems, but after some quick testing, I determined that it’s also able to solve 0-D problems with ease. These tests were performed by modifying the residual functions and a few input parameters in the Blasius sample program to find solutions to arbitrary sets of equations at a single point, rather than along a 1-D array of points.

Implementing the Simple Solver

My first development objective was to create a basic standalone solver for the well-stirred reactor model. As mentioned previously, solutions for this type of problem are characterized by a set of nonlinear equations that are typically solved by some numerical analysis software, in this case the one that’s built in to Cantera. The Blasius sample code worked well for my initial tests, so I based the structure of my solver on this program, even directly using the simplified boundary value problem interface to Cantera’s solver. Unfortunately, I couldn’t get this to converge to an appropriate solution. Even given the true solution as an initial vector, the slightest of inaccuracies in inputted properties seemed to result in huge residual values of the energy equation, pushing the solver further from an acceptable solution with each iteration. After doing some research on why this might be, I found that it’s likely due to the exponential dependence of reaction rates on temperature, which makes convergence of the 0-D steady-state equation system quite difficult for a numerical solver. There are a few potential solutions to the issue, which I’m planning on studying in more detail in the coming weeks to get this version of the solver working:

  • The energy equation in the model may need to be replaced with one that considers transient properties
  • The system may need to be solved twice, first at a fixed temperature (without the energy equation) to obtain a “consistent” initial guess for a second run which will solve for the true solution
  • Rates of heat release during the reaction may need to be incorporated into the system
  • A more advanced, problem-specific version of the Cantera solver may need to be used rather than the simplified boundary value problem interface
  • Something else?

PSR Solver v0.1

After some brief experimentation with the ideas listed above, I noticed that the well-stirred reactor equations converged very quickly to the correct solution when simulated at arbitrarily fixed temperatures. This confirmed my suspicion that the addition of the energy equation to the system was causing the trouble. At its roots, the energy equation ensures energy conservation through the reactor by forcing the total enthalpy of the exhaust gas mixture at the reactor outlet to match the total enthalpy of the gas mixture at the inlet. The total enthalpy of the exhaust is directly correlated to reactor temperature, which is typically the property that a numerical solver will adjust in attempt to satisfy the energy equation.

I realized that Cantera may provide an alternate way to satisfy the conservation of energy, by keeping total enthalpy fixed via the setState_HP() method of the thermodynamics library. After specifying iteration mass fractions, exhaust enthalpy can be forced to match the inlet enthalpy simply by explicitly setting it this way with setState_HP(). This function will adjust any dependent properties, like temperature, as needed in order to satisfy the laws of thermodynamics. This idea evolved into my first working version of a PSR solver! This experimental version of the solver converges quickly for simple reactions, but has trouble finding solutions to more complicated ones. At this point, I’m not entirely sure of the extent of v0.1’s capabilities, but it will be tested thoroughly in the coming weeks and used in the future as seen fit.

Keep Reading:

Next Post - GSoC 2020 Blog Post 2

Start from the Beginning - Introduction

GSoC 2020 Introduction

Google Summer of Code 2020 - Developing a 0-D Steady-State Combustion Solver for Cantera

Introduction

Hello, world! My name is Paul Blum (@paulblum), and I'm an undergraduate student at the University of Connecticut studying Mechanical Engineering and Computer Science & Engineering. I was introduced to Cantera by @bryanwweber, one of my professors at UConn, as an undergraduate research project that might allow me to jointly apply concepts from both of my fields of study. Since then, I’ve completed some small projects for the Cantera software and its website (Cantera/cantera #709, Cantera/cantera-website #95, Cantera/cantera-website #98).

Cantera has presented me with the opportunity to challenge myself, learn an incredible amount, and develop my skills as a scientist and an engineer. With this perception, I am excited to announce that I will be developing code for Cantera full-time this summer as part of Google Summer of Code 2020.

Project Details

Over the next few months, I'll be working to create a fast and efficient 0-D steady-state combustion solver to integrate as a new feature into Cantera. Solvers for this type of idealized combustion are typically used in applications like studying stabilization and extinction in high velocity combustion, investigating the formation of poisonous nitrogen oxides during burning, determining the values of global reaction parameters in analytical models, and approximating more complex systems like gas-turbine combustors.

Throughout the summer I'll be posting updates on development progress to the Cantera blog and the Cantera enhancements repository, so be sure to stay tuned! In the meantime, you can read more about this project via the official GSoC project description, or my more detailed project proposal.

If you're interested in learning more about this project, or have any questions or suggestions regarding its development, feel free to email me at paul_d_blum@yahoo.com.

Looking forward to a great summer!

Keep Reading:

Next Post - Blog Post 1

NSF awards Cantera Project $2.5M through 2022

NSF awards Cantera Project $2.5M through 2022

We are proud to announce that NSF has awarded funds to members of the development team and steering committee, under the Cyberinfrastructure for Sustained Scientific Innovation (CSSI) program. The proposal, titled Extensible and community-driven thermodynamics, transport, and chemical kinetics modeling with Cantera: expanding to diverse scientific domains, was awarded $2.5M USD to enable new scientific modeling capabilities, improvements to the Cantera software architecture, and perform community development activities. These activities will help further Cantera's primary objective, which is a generalizable software package to assist users in a variety of fields with a range of calculations related to thermodynamics, chemical kinetics, and species transport.

In particular, new capabilities added to Cantera and outreach to new scientific domains will help recruit new users in fields such as electrochemistry, catalysis, and atmospheric chemistry, while continuing to build the current user base. Helping recruit new users while also making it easier for current users to contribute to the software will help further establish Cantera's status as a powerful, user-friendly, and community-driven software package with high impact in multiple fields.

The Cantera Steering Committee is happy to discuss the successful proposal with interested parties. Please email steering@cantera.org for more information, or see the award announcement.