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; }