Quick Start Guide
Prerequisites
Make sure you have Python >=3.9 installed:
Installation
From source:
Your First Network
Let's load and explore a chemical reaction network.
Step 1: Load a Network
from jaff import Network
# Load a network file
net = Network("networks/react_COthin")
# Display basic information
print(f"Network label: {net.label}")
print(f"Number of species: {len(net.species)}")
print(f"Number of reactions: {len(net.reactions)}")
Output:
Step 2: Explore Species
# List first 5 species
for i, species in enumerate(net.species[:5]):
print(f"{i}: {species.name} (mass={species.mass:.2f} amu, charge={species.charge})")
Output:
0: H (mass=1.01 amu, charge=0)
1: H2 (mass=2.02 amu, charge=0)
2: C (mass=12.01 amu, charge=0)
3: O (mass=16.00 amu, charge=0)
4: CO (mass=28.01 amu, charge=0)
Step 3: Explore Reactions
# Display first 3 reactions
for i, reaction in enumerate(net.reactions[:3]):
print(f"{i}: {reaction.verbatim}")
Output:
Generating Code
Now let's generate code for rate calculations.
Step 1: Create a Template
Create a file named rates_template.cpp:
// rates_template.cpp
#include <cmath>
// $JAFF SUB nreact
const int NUM_REACTIONS = $nreact$;
// $JAFF END
// Calculate reaction rates
void compute_rates(double* rate, const double* n, const double* k, double T) {
// $JAFF REPEAT idx, rate IN rates
rate[$idx$] = $rate$;
// $JAFF END
}
// Reaction names
// $JAFF REPEAT idx, reaction IN reactions
const char* reaction_names[$idx$] = "$reaction$";
// $JAFF END
Step 2: Generate Code
from jaff import Network
from jaff.file_parser import Fileparser
from pathlib import Path
# Load network
net = Network("networks/react_COthin")
# Parse template
parser = Fileparser(net, Path("rates_template.cpp"))
output = parser.parse_file()
# Save output
with open("rates.cpp", "w") as f:
f.write(output)
print("Generated rates.cpp!")
Step 3: View Generated Code
The generated rates.cpp will contain:
#include <cmath>
const int NUM_REACTIONS = 127;
void compute_rates(double* rate, const double* n, const double* k, double T) {
rate[0] = ... // H + O -> OH
rate[1] = ... // H2 + O -> OH + H
rate[2] = ... // C + O2 -> CO + O
// ... more rates
}
const char* reaction_names[0] = "H + O -> OH";
const char* reaction_names[1] = "H2 + O -> OH + H";
const char* reaction_names[2] = "C + O2 -> CO + O";
// ... more names
Using the Command Line
You can also use the CLI for quick code generation without writing Python scripts:
Basic Usage
Using the installed command:
This creates output/rates_template.cpp with the generated code.
Using Predefined Templates
JAFF supports predefined template collections:
# Use a predefined template collection
jaffgen --network networks/react_COthin --template kokkos_ode --outdir output/
This processes all files in the jaff/templates/generator/chemistry_solver/ directory.
Processing Multiple Files
# Process all templates in a directory
jaffgen --network networks/react_COthin --indir templates/microphysic --outdir output/
# Process multiple specific files
jaffgen --network networks/react_COthin --files template1.cpp template2.f90 model.py --outdir output/
# Process multiple specific files and folders
jaffgen --network networks/react_COthin --indir templates/microphysics --files template1.cpp template2.f90 model.py --outdir output/
Specifying Language
For files with non-standard extensions, specify a default language:
# Generate Rust code from a text template
jaffgen --network networks/react_COthin --files template.txt --lang rust --outdir output/
# Generate Julia code
jaffgen --network networks/react_COthin --files custom.template --lang julia --outdir output/
You will need to provide the language if you are using the --indir and the input directory contains unsupported files
Supported languages: c, cxx , fortran , python , rust , julia and r
Common Use Cases
1. List All Species
from jaff import Network
net = Network("networks/react_COthin")
print("All species:")
for species in net.species:
print(f" {species.name}")
2. Find Species by Name
from jaff import Network
net = Network("networks/react_COthin")
# Get species index
co_index = net.species_dict["CO"]
co = net.species[co_index]
print(f"CO: index={co_index}, mass={co.mass}, charge={co.charge}")
3. View rate
from jaff import Network
net = Network("networks/react_COthin")
# Get first reaction
reaction = net.reactions[0]
k = reaction.rate
print(f"Rate coefficient: {k}")
4. Check Element Properties
from jaff import Network
from jaff.elements import Elements
net = Network("networks/react_COthin")
elem = Elements(net)
print(f"Network contains {elem.nelems} elements:")
print(elem.elements)
# Get element density matrix
density = elem.get_element_density_matrix()
print(f"\nElement density matrix shape: {len(density)} x {len(density[0])}")
5. Generate ODEs
Create odes_template.cpp:
// $JAFF SUB nspec
const int NUM_SPECIES = $nspec$;
// $JAFF END
void compute_odes(double* dydt, const double* y, const double* rate) {
// Initialize to zero
for (int i = 0; i < NUM_SPECIES; i++) {
dydt[i] = 0.0;
}
// $JAFF REPEAT idx, ode IN odes
dydt[$idx$] += $ode$;
// $JAFF END
}
Generate the code:
from jaff import Network
from jaff.file_parser import Fileparser
from pathlib import Path
net = Network("networks/react_COthin")
parser = Fileparser(net, Path("odes_template.cpp"))
output = parser.parse_file()
with open("odes.cpp", "w") as f:
f.write(output)
Next Steps
Now that you've completed the quick start:
- Learn the Basics: Read about Basic Concepts to understand chemical networks
- User Guide: Explore the detailed User Guide
- Templates: Understand Template Syntax for custom code generation
- API Reference: Browse the complete API documentation
Getting Help
- Documentation: Browse the full documentation
- Examples: Check the
examples/directory in the repository - Issues: Report bugs at GitHub Issues
- Discussions: Ask questions in GitHub Discussions
Tips & Tricks
Pro Tip: Network Validation
Always check your network for errors when loading:
python
net = Network("networks/mynetwork.dat", errors=True)
Pro Tip: Species Lookup
Use the species dictionary for fast lookups:
python
idx = net.species_dict["CO"] # Much faster than searching
Pro Tip: Template Testing
Test templates on small networks first before using large ones:
# Use a small test network
net = Network("networks/test.dat")
parser = Fileparser(net, Path("template.cpp"))
print(parser.parse_file()) # Check output
Watch Out: File Extensions
The parser determines language from file extension: - .cpp, .cxx, .cc → C++ - .c → C - .f90, .f95 → Fortran
Make sure your template has the correct extension!
Example Networks
JAFF comes with several example networks:
networks/test.dat- Small test networknetworks/react_COthin- CO chemistrynetworks/gas_reactions_kida.uva.2024.in- KIDA format
Try them out:
from jaff import Network
# Try different networks
networks = [
"networks/test.dat",
"networks/react_COthin",
]
for network_file in networks:
net = Network(network_file)
print(f"{network_file}: {len(net.species)} species, {len(net.reactions)} reactions")