Rev 17747 | Blame | Compare with Previous | Last modification | View Log | RSS feed
// -*- coding: utf-8 -*-
#ifndef CHEMEQ_H
#define CHEMEQ_H
#include <cstring>
#include <sstream>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#define VERSION "2.14"
/* All data and Exact constants from CODATA 2018
Eite Tiesinga, Peter J. Mohr, David B. Newell, Barry N. Taylor;
CODATA Recommended Values of the Fundamental Physical Constants: 2018*.
Journal of Physical and Chemical Reference Data 1 September 2021; 50 (3): 033105.
https://doi.org/10.1063/5.0064853
*/
/* Constante d'Avogadro */
#define Avogadro 6.02214076e+23
/* Charge élémentaire */
#define Electron 1.602176634e-19
/* Constante de Boltzmann */
#define Kb 1.380649e-23
/* D'où la constante de Faraday */
#define Faraday (Avogadro * Electron)
/* D'où la constante des Gaz parfaits
R = 8.31446261815324 J/K.mol */
#define R (Kb * Avogadro)
/* Température de référence pour les réactions chimiques, 25°C */
#define T0 (273.15+25)
/* MINVAL est une valeur impossible tant pour un potentiel standard */
/* que pour une constante d'équilibre */
#define MINVAL -999
typedef struct {
int Zed;
char symb[4];
} atome;
extern atome lesatomes[];
typedef std::pair<std::string,int> AtomeCompte;
class Compteur : public std::map<std::string,float>{
public:
std::ostream & operator << (std::ostream & o)const;
};
std::ostream & operator << (std::ostream & o, const Compteur & c);
class Chemeq;
class fraction{
public:
int i;
int d;
fraction(int numerateur, int denominateur=1):i(numerateur),d(denominateur){};
void inverse(){int n=i; i=d; d=n;};
void simplifie();
};
const fraction & minFraction(const fraction&, const fraction &);
std::ostream & operator << (std::ostream & o, fraction f);
fraction operator * (fraction f, int m);
fraction operator * (int m, fraction f);
fraction operator * (fraction f, fraction m);
fraction operator + (fraction f, fraction g);
fraction operator - (fraction f, fraction g);
bool operator > (fraction f, int i);
bool operator > (fraction f1, fraction f2);
bool operator != (fraction f, int i);
class AtomeListe{
AtomeListe * suiv, *group;
char symb[4];
int Zed, nb, no, sqbr;
public:
AtomeListe(const char* nom, int num, AtomeListe * s=0, AtomeListe * g=0){
strncpy(symb,nom,3); Zed=num; nb=1; sqbr=0;
/* sqbr == 1 quand il y a un square bracket */
suiv = s; group=g;
};
AtomeListe(const AtomeListe & a):
suiv(a.suiv), group(a.group), Zed(a.Zed), nb(a.nb), sqbr(a.sqbr){
strncpy(symb,a.symb,3);
};
const char * symbole() const{return symb;};
int Z()const{return Zed;};
int sq()const{return sqbr;};
void sq(int val){sqbr=val;};
void numerote(int n=0);
void setmolecularite(int n){nb=n;};
int getmolecularite()const{return nb;};
AtomeListe * groupe(){return group;};
void groupe(AtomeListe * al){group= al;};
const AtomeListe * suivant()const{return suiv;};
const AtomeListe * groupe()const{return group;};
void setsuivant(AtomeListe * s){suiv=s;};
void compte (Compteur &c, fraction mult=fraction(1,1))const;
double weight(fraction mult=fraction(1,1))const;
static AtomeListe * triage(AtomeListe * al);
void printcount(std::ostream & o, const fraction&, int multiple) const;
void printnorm(std::ostream & o) const;
bool isEqual(const AtomeListe & a2) const;
void debug(int decal = 0)const{
for (int i=0; i< decal; i++) std::cout << " ";
std::cout << "AtomeListe : ( & = " << this << " symb=\"" << symb << "\" Zed = " << Zed
<< " nb = " << nb << " no = " << no
<< " suiv = " << suiv << " group = " << group
<< ")\n";
if(group) group->debug(2+decal);
if(suiv) suiv->debug(decal);
};
};
typedef enum { aqueous, aqueous_explicit, gas, liquid, sol } moltype;
extern const char* moltypeStr[]; /* les chaînes aq, g,s */
class Membre;
class Molec{
AtomeListe * al;
int ch;
fraction nb;
int no;
moltype t;
public:
Molec(AtomeListe * a, int c = 0, int n=1, int d=1):
al(a), ch(c), nb(n,d), t(aqueous){};
Molec(const Molec & m):
al(m.al), ch(m.ch), nb(m.nb.i,m.nb.d), t(m.t) {}
AtomeListe & liste()const{return *al;};
int charge()const{return ch;};
bool eqMol(const Molec * m) const {
return (al->isEqual(*(m->al))) && (ch== m->ch);
}
void nombre(int n, int d=1){nb=fraction(n,d);};
fraction nombre()const{return nb;};
void add(fraction f);
void sub(fraction f);
moltype typage()const{return t;};
void typage(moltype at){t=at;};
void numero(int n){no=n;};
int numero()const{return no;};
void triage(){al = AtomeListe::triage(al);};
void compte(Compteur & c)const{if (al) al->compte(c,nb);};
double weight(void)const{if (al) return al->weight(nb); else return 0.0;};
const std::string signature()const;
void printNombre(std::ostream & o)const;
bool printcount(std::ostream & o, bool first) const;
bool printelec(std::ostream & o, bool first) const;
bool printspecies(std::ostream & o, bool first) const;
void printnorm(std::ostream & o)const;
void printcoeff(std::ostream & o, int sign)const;
void printweigh(std::ostream & o)const;
void coeff( fraction f);
bool printNernst(std::ostream & o, const char * prefix ="");
bool printNernstWIMS(std::ostream & o, bool wantedlatex);
bool iswater()const;
bool iselectron()const;
fraction nbelectron()const;
/* retire les suffixes _aq */
void delete_aq();
void debug(int decal = 0)const{
for (int i=0; i < decal; i++) std::cout << " ";
std::cout << "Molec : ( " << this << " charge = " << ch
<< " nombre = " << nb << " no = " << no;
al->debug(decal+2);
std::cout << ")\n";
};
// two Molecs are equal if the AtomLists and the charges are equal.
friend Membre operator & (Membre & m1, Membre & m2);
friend Membre operator - (Membre & m1, Membre & m2);
};
std::ostream & operator << (std::ostream & o, const AtomeListe & l);
std::ostream & operator << (std::ostream & o, const Molec & m);
class Membre : public std::vector<Molec *>{
public:
int findMol(const Molec *);
void addMol(const Molec *);
void addMembre(const Membre *);
void eraseNull();
void compte(Compteur & c)const;
void numerote();
void triage();
void printnorm(std::ostream & o) const;
void printcoeff(std::ostream & o, int sign) const;
void printcount(std::ostream & o) const;
void printelec(std::ostream & o) const;
void printspecies(std::ostream & o) const;
void printweight(std::ostream & o) const;
void coeff( fraction f);
void printNernst(std::ostream & o);
void printNernstWIMS(std::ostream & o, bool wantedlatex);
int printableNernst();
bool redox()const;
fraction nbelectron()const;
/* retire les suffixes _aq */
void delete_aq();
void debug(int decal = 0)const{
for (int i=0; i < decal; i++) std::cout << " ";
std::cout << "Membre : ( " << this;
for (unsigned int j=0; j < size(); j++){
std::cout << j << " :\n";
operator[](j)->debug(decal+2);
}
std::cout << "\n";
}
};
// intersection between two Membres
Membre operator & (Membre & m1, Membre & m2);
// members of first set which are not in the second
Membre operator - (Membre & m1, Membre & m2);
std::ostream & operator << (std::ostream & o, const Membre & m);
class Chemeq{
Membre * gauche, * droit;
std::string cste;
long double val;
bool equ; /* false by default, true when an equilibrium must be rendered with \doubleharpoons */
public:
Chemeq(Membre * g, Membre * d, bool equilibrium = false) :
gauche (g), droit(d), val(MINVAL), equ(equilibrium) {
};
const Membre * membredroit()const{return droit;};
const Membre * membregauche()const{return gauche;};
const bool is_equilibrium() const {return equ;};
void addChemeq(const Chemeq *);
void subChemeq(const Chemeq *);
void simplifie(bool tri);
void numerote(){gauche->numerote(); droit->numerote();};
void triage(){gauche->triage(); droit->triage();};
/* ajuste le coefficient pour qu'il y ait 1 mol du premier réactif */
void coeff1();
/* retire les suffixes _aq */
void delete_aq();
/* mutiplie par la fraction num/den */
void multiply(int num, int den);
fraction nbelectron()const{return gauche->nbelectron()-droit->nbelectron();};
/* renvoie val ou nbelectron()*Faraday*val */
long double enthalpy() const;
void normalise(){numerote(); triage(); coeff1(); delete_aq();};
void printnorm(std::ostream & o);
void printcoeff(std::ostream & o) const;
void printcount(std::ostream & o) const;
void printelec(std::ostream & o) const;
void printspecies(std::ostream & o) const;
void printweight(std::ostream & o) const;
void printNernst(std::ostream & o, std::ostream & w, bool wantedlatex=false);
std::string equilibre();
bool redox()const;
const std::string constante()const{ return cste;};
void constante (const std::string s) { cste = s;};
bool valdefined()const;
double valeur()const{return val;};
std::string valeur_latex()const;
void valeur(double r){val=r;};
};
std::ostream & operator << (std::ostream & o, const Chemeq & c);
//struct taken from Kyle Burton's gperiodic
/* structure to hold element data, as initialized from the static
* mendeleiev.c */
enum info_types {
NAME, SYMBOL, NUMBER, WEIGHT, MELTING, BOILING, PAULING,
MAX_INFO_NR /* Has to be the last element */
};
struct table_entry {
const char *info[MAX_INFO_NR];
};
extern struct table_entry table[];
double mendelweight(int i);
int findmendel(const char * symb);
double mendelweight(const char * symb);
#endif