// $Id: gas.hpp,v 1.3 2025/11/27 09:45:57 sqko Exp $
#ifndef GAS_HPP_
#define GAS_HPP_

#include <stdexcept>
#include "pstream.h"

// Note all temperatures in K!

struct gcomp
{
  double H2;
  double N2_cathode;
  double O2_cathode;
  double O2_anode;
  double N2_anode;
  double CH4;
  double CO;
  double CO2;
  double H2O;
  double Air;
};

enum gasmode {L, mol};
enum calc_mode {do_cathode, skip_cathode};
enum gname {H2,H2O,CO,CO2,CH4,O2_anode,N2_anode,O2_cathode,N2_cathode};

class gas
{
public:
  gas(const gas &);
  gas(double temp,double pressure,const gcomp &);
  ~gas();
  static double O2_Air;
  static double equal_cutoff;
  static double carbon_cutoff;
  static double oxygen_anode_cutoff;
  static const double F;
  static const double R;
  static double hartung(double); // returns kp for the water dissociation reaction as a function of temperature.
  static double water(double,double flow = 1);  // returns the water partial pressure for gas in equilibnrium with liquid water with specified temperature
  void current(double I) { current(I,do_cathode); }; // changes gas composition by nernst current
  void current(double, calc_mode mode); // same as above, but with possibility for excluding changes in cathode gas composition
  void display(); 
  void to_mol(); // converts gas composition to moles/sec
  void to_L(); // converts gas compositions to L/hour
  void react_gasses(); // allows O2 and/or CH4 in anode stream to react with the other gasses
  void newT(double t) {temp_ = t; calc_pres();}; // Sets new gas temperature
  void newP(double p) {P_ = p; calc_pres();}; // Sets new gas pressure
  double min_current() const; // returns maximum electrolysis current possible
  double max_current() const; // returns maximum fuel cell current possible
  double get_leak(double);
  __attribute__ ((noinline)) double emf(); // returns calculated emf
  double Xgas(const gname) const;
  double P() const {return P_;};
  double T() const {return temp_;};
  gcomp composition() { return comp_; };
  gcomp pressure() { return pres_; };
  const gcomp & composition() const { return comp_; };
  const gcomp & pressure() const { return pres_; };
  gas & operator=(const gas &);
  gas operator+(const gas &) const;
  gas & operator+=(const gas &);
  bool operator==(const gas &) const;
  bool operator!=(const gas & rhs) const {return !(*this == rhs); };
private:
  void calc_pres(); // calculates partial pressures of gasses, automatically called after any changes in gas composition
  void calc_emf(); // calculates gas emf automatically called at end of calc_pres()
  double temp_;
  double P_;
  gasmode mode_;
  gcomp comp_;
  gcomp pres_;
  double emf_;
  bool valid_emf_;
};


#endif /*GAS_HPP_*/
