import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
import java.math.*;
/*
computes equilibrium of N2 + O2 => 2NO as function of temperature and
initial O2 molar fraction of atmosphere using these equations:
k = [NO]^2 / (([N2] - [NO]/2)([O2] - [NO]/2))
k = (10^(0.5441 - 4725.5 / T))^2
It also computes equilibrium of 2NO + O2 => 2NO2 using the equilibrium
of the previous reaction as its initial state
*/
class NitricOxidesCalculator implements ChangeListener
{
NitricOxidesCalculator()
{
m_frame = new JFrame();
m_frame.setSize(500, 500);
m_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = m_frame.getContentPane();
c.setLayout(new GridLayout(0, 3, 20, 40));
m_temperature_slider = new JSlider(0, 5000);
m_temperature_slider.addChangeListener(this);
c.add(new JLabel("temperature"));
c.add(m_temperature_slider);
c.add(m_temperature_label = new JLabel());
m_o2_0_slider = new JSlider(0, 100);
m_o2_0_slider.addChangeListener(this);
c.add(new JLabel("initial O2 concentration"));
c.add(m_o2_0_slider);
c.add(m_o2_0_label = new JLabel());
c.add(new JLabel("NO concentration after arc"));
c.add(m_no_1_field = new JTextField(10));
c.add(new JLabel("mols/total mols"));
c.add(new JLabel("NO2 concentration"));
c.add(m_no2_2_field = new JTextField(10));
c.add(new JLabel("mols/total mols"));
c.add(new JLabel("NO concentration after NO2 oxidation"));
c.add(m_no_2_field = new JTextField(10));
c.add(new JLabel("mols/total mols"));
m_frame.setVisible(true);
m_temperature_slider.setValue(3500);
m_o2_0_slider.setValue(21);
}
double SolveQuadratic(double a, double b, double c)
{
return (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);
}
public void stateChanged(ChangeEvent e)
{
Object source = e.getSource();
DecimalFormat f = new DecimalFormat();
f.setMaximumFractionDigits(4);
double k = Math.pow(10, 0.5441 - 4725.5 / m_temperature_slider.getValue());
k = k * k;
m_temperature_label.setText(m_temperature_slider.getValue() + " K");
double o2_fraction = m_o2_0_slider.getValue() / 100.0;
m_o2_0_label.setText(f.format(o2_fraction) + " mols/total mols");
// subscript 0 means initial, 1 means after going through arc, 2 means after
// NO reacting with remaining O2.
double o2_0 = o2_fraction / 22.4, // mols/L,
n2_0 = 1 / 22.4 - o2_0,
a = 1 - k, b = k * (n2_0 + o2_0),
c = -k * n2_0 * o2_0,
no_1 = SolveQuadratic(a, b, c),
o2_1 = o2_0 - no_1 / 2,
n2_1 = n2_0 - no_1 / 2;
m_no_1_field.setText(f.format(no_1 / (no_1 + n2_1 + o2_1)));
k = 1000000;
a = 1 - k / 2;
b = k * (no_1 + o2_1);
c = -k * no_1 * o2_1;
double no2_2 = SolveQuadratic(a, b, c),
o2_2 = o2_1 - no2_2 / 2,
no_2 = no_1 - no2_2,
n2_2 = n2_1;
double sum = no2_2 + no_2 + o2_2 + n2_2;
//System.out.println(sum + " " + no2_2 / sum + " " + no_2 / sum + " " + o2_2 / sum + " " + n2_2 / sum);
m_no2_2_field.setText(f.format(no2_2 / (no2_2 + no_2 + o2_2 + n2_2)));
m_no_2_field.setText(f.format(no_2 / (no2_2 + no_2 + o2_2 + n2_2)));
}
public static void main(String[] args)
{
new NitricOxidesCalculator();
}
JFrame m_frame;
JLabel m_temperature_label, m_o2_0_label;
JTextField m_no_1_field, m_no2_2_field, m_no_2_field;
JSlider m_temperature_slider, m_o2_0_slider;
}