Skip to content

Commit

Permalink
update document
Browse files Browse the repository at this point in the history
  • Loading branch information
jiweiqi committed May 16, 2021
1 parent a2fa173 commit 77df43b
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 229 deletions.
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ makedocs(
"get_started.md",
"concepts.md"
],
"tutorial.md",
"faq.md",
"api.md"
],
Expand Down
6 changes: 2 additions & 4 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# API Documentation
# API

Docstrings for Arrhenius.jl interface members can be [accessed through Julia's built-in documentation system](https://docs.julialang.org/en/v1/manual/documentation/index.html#Accessing-Documentation-1) or in the list below.

You can use `name(Arrhenius)` to print a full list of exported namespace by Arrhenius.jl, and then copy the list below.

```@docs
:C2X
:CreateSolution
Expand All @@ -26,7 +24,7 @@ You can use `name(Arrhenius)` to print a full list of exported namespace by Arrh
:species_index
:wdot_func
```
## Thermo Interface API Documentation
## Thermo Interface API
```@autodocs
Modules = [Arrhenius]
Pages = ["Thermo.jl"]
Expand Down
13 changes: 13 additions & 0 deletions docs/src/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@
## Structure of Arrhenius.jl

![schem.png](./figures/schem.png)

Details of the structure can be found in the publications associated with Arrhenius.jl. Such as

+ [Machine Learning Approaches to Learn HyChem Models](https://www.researchgate.net/publication/350890609_Machine_Learning_Approaches_to_Learn_HyChem_Models): demonstrate 1000 times faster than genetic algorithms using commercial software for optimizing complex kinetic models.
+ [Arrhenius.jl: A Differentiable Combustion Simulation Package](https://www.researchgate.net/publication/350573212_Arrheniusjl_A_Differentiable_Combustion_Simulation_Package): overview of Arrhenius.jl and applications in deep mechanism reduction, uncertainty quantification, mechanism tuning and model discovery.
+ [Neural Differential Equations for Inverse Modeling in Model Combustors](https://www.researchgate.net/publication/351223124_Neural_Differential_Equations_for_Inverse_Modeling_in_Model_Combustors)


## Roadmap

![roadmap](https://user-images.githubusercontent.com/8445647/118387233-4c7af280-b5eb-11eb-9412-06fdc4a81420.png)

You can particpilate the design of roadmap in the [discussions](https://github.com/DENG-MIT/Arrhenius.jl/discussions/68).
4 changes: 3 additions & 1 deletion docs/src/faq.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# FAQ

What's the difference between Arrhenius.jl and Chemkin/Cantera?
What's the difference between Arrhenius.jl and Chemkin/Cantera?

> Arrhenius.jl can be viewed as a differentiable Cantera and Arrhenius.jl aims at exploiting differentiable programming for data-driven combustion modeling.
235 changes: 16 additions & 219 deletions docs/src/get_started.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Get Started
## Basics and Magic functions!

## Basics

We first have to make Arrhenius.jl available in our code (along with other packages you might use):
```julia
using Arrhenius
Expand Down Expand Up @@ -52,222 +54,17 @@ One of the core functionalities of the Arrhenius.jl is its ability to compute th
```julia
w_dot = wdot_func(gas.reaction, T, C, S0, h_mole)
```
## Examples
### JP10 Pyrolysis
Let us compute the evolution of the mass fractions of C10H16 species as JP-10 is subjected to isobaric pyrolysis at 1 atm and an initial temperature of 1200K. We first include all our packages:
```julia
using Arrhenius
using LinearAlgebra
using DifferentialEquations
using ForwardDiff
using DiffEqSensitivity
using Plots
using DelimitedFiles
using Profile
```
Then create the gas object:
```julia
gas = CreateSolution("../../mechanism/JP10skeletal.yaml")
```
Declare the initial conditions as arrays:
```julia
Y0 = zeros(ns)
Y0[species_index(gas, "C10H16")] = 0.05
Y0[species_index(gas, "N2")] = 0.95
T0 = 1200.0 #K
P = one_atm
u0 = vcat(Y0, T0);
```
Create a function to define the ODE problem (for more details on solving differential equations refer to [DifferentialEquations.jl](https://diffeq.sciml.ai/stable/).
```julia
@inbounds function dudt!(du, u, p, t)
T = u[end]
Y = @view(u[1:ns])
mean_MW = 1. / dot(Y, 1 ./ gas.MW)
ρ_mass = P / R / T * mean_MW
X = Y2X(gas, Y, mean_MW)
C = Y2C(gas, Y, ρ_mass)
cp_mole, cp_mass = get_cp(gas, T, X, mean_MW)
h_mole = get_H(gas, T, Y, X)
S0 = get_S(gas, T, P, X)
wdot = wdot_func(gas.reaction, T, C, S0, h_mole)
Ydot = wdot / ρ_mass .* gas.MW
Tdot = -dot(h_mole, wdot) / ρ_mass / cp_mass
du .= vcat(Ydot, Tdot)
end
```
Solve the ODE problem:
```julia
tspan = [0.0, 0.07];
prob = ODEProblem(dudt!, u0, tspan);
sol = solve(prob, TRBDF2(), reltol=1e-6, abstol=1e-9);
```
Great! Let us now compare our solution with cantera by first loading the cantera data:
```julia
cantera_data = readdlm("pyrolysis.dat")
ct_ts= cantera_data[:, 1]
ct_T = cantera_data[:, 2]
ct_Y = cantera_data[:, 3:end];
```
Now plot and compare away:
```julia
plt = plot(sol.t, sol[species_index(gas, "C10H16"), :], lw=2, label="Arrhenius.jl");
plot!(plt, ct_ts, ct_Y[:, species_index(gas, "C10H16")], label="Cantera")
ylabel!(plt, "Mass Fraction of C10H16")
xlabel!(plt, "Time [s]")
pltT = plot(sol.t, sol[end, :], lw=2, label="Arrhenius.jl");
plot!(pltT, ct_ts, ct_T, label="Cantera")
ylabel!(pltT, "Temperature [K]")
xlabel!(pltT, "Time [s]")
title!(plt, "JP10 pyrolysis @1200K/1atm")
pltsum = plot(plt, pltT, legend=true, framestyle=:box)
```
You should get a plot something like this:

![JP10](./figures/JP10.png)
### Sensitivity analysis using Julia's DiffEqSensitivity.jl
In the previous example, we can easily perform a sensitivity analysis using Julia's [```DiffEqSensitivity.jl```](https://diffeq.sciml.ai/latest/analysis/sensitivity/):
```julia
sensealg = ForwardDiffSensitivity()
alg = TRBDF2()
# alg = Tsit5()
function fsol(u0)
sol = solve(prob, u0=u0, alg, tspan = (0.0, 7.e-2),
reltol=1e-3, abstol=1e-6, sensealg=sensealg)
return sol[end, end]
end
u0[end] = 1200.0 + rand()
println("timing ode solver ...")
@time fsol(u0)
@time fsol(u0)
@time ForwardDiff.gradient(fsol, u0)
```
The results are quite promising, with sensitivity computed in less than 2 seconds!
```julia
julia>timing ode solver ...
0.405083 seconds (614.32 k allocations: 45.126 MiB)
0.036229 seconds (16.72 k allocations: 11.618 MiB)
1.517267 seconds (183.25 k allocations: 864.085 MiB, 7.46% gc time)
```
### Exploiting Julia's Auto-Differentiation (AD) package to compute Jacobians
Julia's automatic differentiation packages like [```ForwardDiff.jl```](https://juliadiff.org/ForwardDiff.jl/stable/user/api/) can be exploited thoroughly using Arrhenius.jl to compute the Jacobian that frequently pops up while integrating stiff systems in chemically reactive flows. We present to you an example using the LiDryer 9-species H2 combustion mechanism. So let's import packages:
```julia
using Arrhenius
using LinearAlgebra
using DifferentialEquations
using ForwardDiff
using DiffEqSensitivity
using Plots
using DelimitedFiles
using Profile
```
Next input the YAML:
```julia
gas = CreateSolution(".../../mechanism/LiDryer.yaml")
```
We use a 9-species + 24-reaction model:
```julia
julia> ns = gas.n_species
9
julia> ns = gas.n_species
24
```
View the participating species:
```julia
julia> gas.species_names
9-element Array{String,1}:
"H2"
"O2"
"N2"
"H"
"O"
"OH"
"HO2"
"H2O2"
"H2O"
```
Let's set the initial conditions:
```julia
Y0 = zeros(ns)
Y0[species_index(gas, "H2")] = 0.055463
Y0[species_index(gas, "O2")] = 0.22008
Y0[species_index(gas, "N2")] = 0.724457 #to sum as unity
T0 = 1100.0 #K
P = one_atm * 10.0
u0 = vcat(Y0, T0);
```
Create the differential function:
```julia
function dudt(u)
T = u[end]
Y = @view(u[1:ns])
mean_MW = 1. / dot(Y, 1 ./ gas.MW)
ρ_mass = P / R / T * mean_MW
X = Y2X(gas, Y, mean_MW)
C = Y2C(gas, Y, ρ_mass)
cp_mole, cp_mass = get_cp(gas, T, X, mean_MW)
h_mole = get_H(gas, T, Y, X)
S0 = get_S(gas, T, P, X)
wdot = wdot_func(gas.reaction, T, C, S0, h_mole)
Ydot = wdot / ρ_mass .* gas.MW
Tdot = -dot(h_mole, wdot) / ρ_mass / cp_mass
du = vcat(Ydot, Tdot)
end
```
Now computing the jacobian w/ref to the initial condition vector is as simple as:
```julia
julia> @time du0 = ForwardDiff.jacobian(dudt, u0)
0.026856 seconds (18.37 k allocations: 1.047 MiB)
10×10 Array{Float64,2}:
-0.00227393 -0.000934232 0.000137514 0.000213839 -5.21262e-6
-0.0360919 -0.0148282 0.00218263 0.00334244 -8.27348e-5
0.0 0.0 0.0 0.0 0.0
0.00113697 0.000467116 -6.87571e-5 -0.000106919 2.60631e-6
2.09985e-12 2.28459e-12 -1.26987e-13 2.97389e-12 2.53222e-14
0.0 0.0 0.0 2.74378e-5 0.0
0.0372289 0.0152953 -0.00225138 -0.00344774 8.53411e-5
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 -2.9064e-5 0.0
-27.3692 -47.4374 16.5061 29.0894 -0.306451
```
### Auto-ignition
Here we use the GRI30 methane combustion mechanism to compute the ignition delay time of a premixed methane-air mixture @ 980K/15 atm. The implementation is quite similar. Let's say you want to set ICs in-terms of the mole-fractions, one may eventually convert them to mass-fractions as follows:
```julia
X0 = zeros(ns);
X0[species_index(gas, "CH4")] = 1.0 / 2.0
X0[species_index(gas, "O2")] = 1.0
X0[species_index(gas, "N2")] = 3.76
X0 = X0 ./ sum(X0);
Y0 = X2Y(gas, X0, dot(X0, gas.MW));
```
The integrator function remains the same:
```julia
u0 = vcat(Y0, T0)
@inbounds function dudt!(du, u, p, t)
T = u[end]
Y = @view(u[1:ns])
mean_MW = 1.0 / dot(Y, 1 ./ gas.MW)
ρ_mass = P / R / T * mean_MW
X = Y2X(gas, Y, mean_MW)
C = Y2C(gas, Y, ρ_mass)
cp_mole, cp_mass = get_cp(gas, T, X, mean_MW)
h_mole = get_H(gas, T, Y, X)
S0 = get_S(gas, T, P, X)
wdot = wdot_func(gas.reaction, T, C, S0, h_mole)
Ydot = wdot / ρ_mass .* gas.MW
Tdot = -dot(h_mole, wdot) / ρ_mass / cp_mass
du .= vcat(Ydot, Tdot)
end
```
We then integrate using DifferentialEquations.jl
```julia
tspan = [0.0, 0.1];
prob = ODEProblem(dudt!, u0, tspan);
@time sol = solve(prob, CVODE_BDF(), reltol = 1e-6, abstol = 1e-9)
```
After running [ignition.jl](https://github.com/DENG-MIT/Arrhenius.jl/blob/main/example/ignition/ignition.jl) you should get a plot as follows: \
![plot](./figures/ignition.png)
### Sensitivity analysis of ignition delay times-Active subspaces
### Perfect Stirred reactor
One may refer to the [NN-PSR repo](https://github.com/DENG-MIT/NN-PSR)
### Combustion Diagnostics support- CEMA and CSP
## Input Files

Similar to Chemkin and Canetra, all calculations in Arrhenius.jl require an input file to describe the properties of the relevant phase(s) of mixture. We adopt the `YAML` format maintained in the Cantera community.

> Currently, the package relies on [`Cantera`](https://github.com/Cantera/cantera) and [`ReacTorch`](https://github.com/DENG-MIT/reactorch) for interpreting the reaction mechanism. The kinetic info in the mechanism files are inpreprested and saved into a `.npz` file with the same name as the `.yaml` file. If you want to have a try, you don't need to install Cantera and ReacTorch, since there are already some pre-compiled reaction mechanisms under the folder of `mechanism`.
> Otherwise, you can install [`Cantera`](https://github.com/Cantera/cantera) and [`ReacTorch`](https://github.com/DENG-MIT/reactorch) to compile it using the python script `interpreter.py` under the folder of `mechanism`.
> You can also ask for help in the discussion forum and our developers can compile the model for you.
With Cantera and ReacTorch installed, you can use the following python command in your terminal to generate the `.npz` file.

`python interpreter.py -i gri30.yaml`
14 changes: 10 additions & 4 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# [Arrhenius.jl](https://github.com/DENG-MIT/Arrhenius.jl)
*Combustion Kinetic Modeling Software 2.0.*
*Reacting Flow and Combustion Modeling Software 2.0.*

## Package Features

Expand All @@ -15,17 +15,23 @@
Documentation comes in following forms:

1. How-to examples
2. Explanatory guide
1. Explanatory guide
3. Reference docstrings for the entire interface are avaliable in the API Documentation section.

When updating these documents, make sure this is synced with docs/make.jl !!
> For developers, when updating these documents, make sure this is synced with docs/make.jl !!
### Baiscs
## Baiscs

```@contents
Pages = ["install.md", "get_started.md", "concepts.md"]
```

## Tutorials

```@contents
Pages = ["tutorial.md"]
```

## Reference

```@contents
Expand Down
14 changes: 13 additions & 1 deletion docs/src/install.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# Installation

> pkg> add https://github.com/DENG-MIT/Arrhenius.jl
## For users

`pkg> add https://github.com/DENG-MIT/Arrhenius.jl`

> Note that `] add Arrhenius` might not install the latest version.
## For developers

`clone the github repo to local`

`cd Arrhenius.jl`

`] add .`
Loading

0 comments on commit 77df43b

Please sign in to comment.