Giter VIP home page Giter VIP logo

reactorch's Introduction

ReacTorch: A Differentiable Reacting Flow Simulation Package in PyTorch

DOI

ReacTorch is a package for simulating chemically reacting flows in PyTorch. The capability of auto-differentiation enables us to efficiently compute the derivatives of the solutions to all of the species concentrations (obtaining Jacobian matrix) as well as model parameters (performing sensitivity analysis) at almost no cost. It also natively supports GPU computation with PyTorch. In addition, the capability of differentiating the entire reacting model is the foundation of adopting many recent hybrid physics-neural network algorithms. This package is aimed at providing an easily accessible platform for implementing those emerging hardware and software infrastructures from the deep learning community in chemically reacting flow simulations.

Installation

git clone [email protected]:DENG-MIT/reactorch.git
cd reactorch
python setup.py install

Requirements

  • PyTorch
  • Cantera >= 2.5.0
  • ruamel.yaml

Detailed instructions on installing the dependent packages can be found in the wiki page.

Usage

import reactorch as rt

Sample code can be found in test/Solution_test.py and examples folder. For example, the autoignition case demonstrates that you can compute jacobian matrix with only couple lines of code!

Credit

If you use ReacTorch in a publication, we would appreciate if you cited ReacTorch. This helps to improve the reproducibility of your work, as well as giving credit to the many authors who have contributed their time to developing ReacTorch. The recommended citation for ReacTorch is as follows:

Weiqi Ji, Sili Deng. ReacTorch: A Differentiable Reacting Flow Simulation Package in PyTorch, https://github.com/DENG-MIT/reactorch, 2020.

ReacTorch was initially developed in Deng Energy and Nanotechnology Group lead by Prof. Sili Deng at MIT.

reactorch's People

Contributors

jiweiqi avatar suxy15 avatar taosong1999 avatar weilunqiu avatar zeracesharon avatar zhiyushi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactorch's Issues

Evaluate the rate constants in batch

for i in range(self.n_reactions):

Currently, in order to avoid in-place operation, we iteratively evaluate the forward rates by looping the reactions. It seems that we can evaluate it in matrix form by some careful coding without in-place operation. Initial thoughts are having a mask to evaluate the normal reactions in batch and the pressure-dependent reaction iteratively. Since the pressure-dependent reactions are usually only a small portion, and related to C0-C1 core mechanism.

Results sensitive on inital composition and setting parameters

See the testing code, and try to evaluate different initial mole fraction on N2, you will find various digree of mismatch on the results from cantera and reactorch. This phenomenon happends for reduced mechanism for IC8H18 as well as NC7H16.

Runing Solution_test with the same initial parameters, with tolerance delta=1e-4๏ผŒ No obvious difference is observed, which may means the kf (forward_rate_constants) kc (equilibrium_constants) kr (reverse_rate_constants) are correct.

The reasons of such mismatch are still unknown.

Testing Code:

"""
Solve a constant pressure ignition problem where the governing equations are
implemented in Python.

This demonstrates an approach for solving problems where Cantera's reactor
network model cannot be configured to describe the system in question. Here,
Cantera is used for evaluating thermodynamic properties and kinetic rates while
an external ODE solver is used to integrate the resulting equations. In this
case, the SciPy wrapper for VODE is used, which uses the same variable-order BDF
methods as the Sundials CVODES solver used by Cantera.
"""

# TODO: the reactorch class seems to be very slow here, will figure out later

import cantera as ct
import numpy as np
import reactorch as rt
from scipy.integrate import solve_ivp
import torch
from torch.autograd.functional import jacobian as jacobian
from time import perf_counter




class ReactorOde(object):
    def __init__(self, gas):
        # Parameters of the ODE system and auxiliary data are stored in the
        # ReactorOde object.
        self.gas = gas
        self.P = gas.P

    def __call__(self, t, y):
        """the ODE function, y' = f(t,y) """

        # State vector is [T, Y_1, Y_2, ... Y_K]
        self.gas.set_unnormalized_mass_fractions(y[1:])
        self.gas.TP = y[0], self.P
        rho = self.gas.density

        wdot = self.gas.net_production_rates
        dTdt = - (np.dot(self.gas.partial_molar_enthalpies, wdot) /
                  (rho * self.gas.cp))
        dYdt = wdot * self.gas.molecular_weights / rho
        #print('cantera',np.hstack((dTdt, dYdt)))

        return np.hstack((dTdt, dYdt))


class ReactorOdeRT(object):
    def __init__(self, sol):
        # Parameters of the ODE system and auxiliary data are stored in the
        # ReactorOde object.
        self.sol = sol
        self.gas = sol.gas

    def __call__(self, t, y):
        """the ODE function, y' = f(t,y) """

        TPY = torch.Tensor(y).T

        with torch.no_grad():

            self.sol.set_states(TPY)

            TYdot = self.sol.TYdot_func()
        #print('reactorch',TYdot.T)
        
        return TYdot.T.detach().cpu().numpy()

    def TYdot_jac(self, TPY):

        TPY = torch.Tensor(TPY).unsqueeze(0)

        sol.set_states(TPY)

        return sol.TYdot_func().squeeze(0)

    def jac(self, t, y):

        TPY = torch.Tensor(y)

        TPY.requires_grad = True

        jac_ = jacobian(self.TYdot_jac, TPY, create_graph=False)

        return jac_

t0_start = perf_counter()
mech_yaml = '../../data/chem.yaml'

sol = rt.Solution(mech_yaml=mech_yaml, device=None,vectorize=True)

gas = ct.Solution(mech_yaml)


# Initial condition
P = ct.one_atm * 1
T = 1800

composition = 'IC8H18:0.5,O2:12.5,N2:34.0'

gas.TPX = T, P, composition
y0 = np.hstack((gas.T, gas.Y))

# Set up objects representing the ODE and the solver
ode = ReactorOde(gas)

# Integrate the equations using Cantera
t_end = 1e-3
states = ct.SolutionArray(gas, 1, extra={'t': [0.0]})
dt = 1e-5
t = 0
ode_success = True
y = y0
t1 = perf_counter()
print('before integration','time spent {:.1e} [s]'.format(t1 - t0_start))
while ode_success and t < t_end:
    odesol = solve_ivp(ode,
                       t_span=(t, t + dt),
                       y0=y,
                       method='BDF',
                       vectorized=False, jac=None)
    # print('nfev',odesol.nfev,'njev',odesol.njev,'nlu',odesol.nlu)
    t = odesol.t[-1]
    y = odesol.y[:, -1]
    ode_successful = odesol.success

    gas.TPY = odesol.y[0, -1], P, odesol.y[1:, -1]
    states.append(gas.state, t=t)


sol.gas.TPX = T, P, composition
sol.set_pressure(sol.gas.P)
ode_rt = ReactorOdeRT(sol=sol)

t_stop1 = perf_counter()
print('finish cantera integration')
print('time spent {:.1e} [s]'.format(t_stop1 - t1))


# Integrate the equations using ReacTorch
states_rt = ct.SolutionArray(sol.gas, 1, extra={'t': [0.0]})
t = 0
ode_success = True
y = y0
dt = 1e-5

# Diable AD for jacobian seems more effient for this case.
print('reacotrch')
while ode_success and t < t_end:
    
    odesol = solve_ivp(ode_rt,
                       t_span=(t, t + dt),
                       y0=y,
                       method='BDF',
                       vectorized=True, jac=None)

    t = odesol.t[-1]
    y = odesol.y[:, -1]
    ode_successful = odesol.success

    #print('t {} T {}'.format(t, y[0]))

    # print('nfev',odesol.nfev,'njev',odesol.njev,'nlu',odesol.nlu)
    sol.gas.TPY = odesol.y[0, -1], P, odesol.y[1:, -1]
    states_rt.append(sol.gas.state, t=t)
    
t_stop = perf_counter()
print('time spent {:.1e} [s]'.format(t_stop - t_stop1))
#Plot the results
try:
    import matplotlib.pyplot as plt
    L1 = plt.plot(states.t, states.T, ls='--',
                  color='r', label='T Cantera', lw=1)
    L1_rt = plt.plot(states_rt.t, states_rt.T, ls='-',
                      color='r', label='T ReacTorch', lw=1)
    plt.xlabel('Time (s)')
    plt.ylabel('Temperature (K)')

    plt.twinx()
    L2 = plt.plot(states.t, states('OH').Y, ls='--', label='OH Cantera', lw=1)
    L2_rt = plt.plot(states_rt.t, states_rt('OH').Y,
                      ls='-',
                      label='OH ReacTorch',
                      lw=1)
    plt.ylabel('Mass Fraction')

    plt.legend(L1+L2+L1_rt+L2_rt, [line.get_label()
                                    for line in L1+L2+L1_rt+L2_rt], loc='best')

    plt.savefig('cantera_reactorch_validation.png', dpi=300)
    plt.show()
except ImportError:
    print('Matplotlib not found. Unable to plot results.')

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.